/* tslint:disable component-selector */ import { AfterContentInit, AfterViewInit, Component, ElementRef, Input, ViewChild } from '@angular/core'; import { Location } from '@angular/common'; import { CONTENT_URL_PREFIX } from 'app/documents/document.service'; import { AttrMap, boolFromValue, getAttrs, getAttrValue } from 'app/shared/attribute-utils'; const LIVE_EXAMPLE_BASE = CONTENT_URL_PREFIX + 'live-examples/'; const ZIP_BASE = CONTENT_URL_PREFIX + 'zips/'; /** * Angular.io Live Example Embedded Component * * Renders a link to a live/host example of the doc page. * * All attributes and the text content are optional * * Usage: * // text for live example link and tooltip * text // higher precedence way to specify text for live example link and tooltip * * Example: *

Run Try the live example

. * // ~/resources/live-examples/{page}/stackblitz.json * *

Run this example

. * // ~/resources/live-examples/toh-pt1/stackblitz.json * * // Link to the default stackblitz in the toh-pt1 sample * // The title overrides default ("live example") with "Tour of Heroes - Part 1" *

Run

. * // ~/resources/live-examples/toh-pt1/stackblitz.json * *

Run

. * // ~/resources/live-examples/{page}/minimal.stackblitz.json * * // Embed the current page's default stackblitz * // Text within tag is "live example" * // No title (no tooltip) * * // ~/resources/live-examples/{page}/stackblitz.json * * // Displays within the document page as an embedded style stackblitz editor * Tour of Heroes - Part 1 * // ~/resources/live-examples/toh-pt1/minimal.stackblitz.json */ @Component({ selector: 'live-example', templateUrl: 'live-example.component.html' }) export class LiveExampleComponent implements AfterContentInit { readonly mode: 'default' | 'embedded' | 'downloadOnly'; readonly enableDownload: boolean; readonly stackblitz: string; readonly zip: string; title: string; @ViewChild('content', { static: true }) private content: ElementRef; constructor(elementRef: ElementRef, location: Location) { const attrs = getAttrs(elementRef); const exampleDir = this.getExampleDir(attrs, location.path(false)); const stackblitzName = this.getStackblitzName(attrs); this.mode = this.getMode(attrs); this.enableDownload = this.getEnableDownload(attrs); this.stackblitz = this.getStackblitz(exampleDir, stackblitzName, this.mode === 'embedded'); this.zip = this.getZip(exampleDir, stackblitzName); this.title = this.getTitle(attrs); } ngAfterContentInit() { // Angular will sanitize this title when displayed, so it should be plain text. const textContent = this.content.nativeElement.textContent.trim(); if (textContent) { this.title = textContent; } } private getEnableDownload(attrs: AttrMap) { const downloadDisabled = boolFromValue(getAttrValue(attrs, 'noDownload')); return !downloadDisabled; } private getExampleDir(attrs: AttrMap, path: string) { let exampleDir = getAttrValue(attrs, 'name'); if (!exampleDir) { // Take the last path segment, excluding query params and hash fragment. const match = path.match(/[^/?#]+(?=\/?(?:\?|#|$))/); exampleDir = match ? match[0] : 'index'; } return exampleDir.trim(); } private getMode(this: LiveExampleComponent, attrs: AttrMap): typeof this.mode { const downloadOnly = boolFromValue(getAttrValue(attrs, 'downloadOnly')); const isEmbedded = boolFromValue(getAttrValue(attrs, 'embedded')); return downloadOnly ? 'downloadOnly' : isEmbedded ? 'embedded' : 'default'; } private getStackblitz(exampleDir: string, stackblitzName: string, isEmbedded: boolean) { const urlQuery = isEmbedded ? '?ctl=1' : ''; return `${LIVE_EXAMPLE_BASE}${exampleDir}/${stackblitzName}stackblitz.html${urlQuery}`; } private getStackblitzName(attrs: AttrMap) { const attrValue = (getAttrValue(attrs, 'stackblitz') || '').trim(); return attrValue && `${attrValue}.`; } private getTitle(attrs: AttrMap) { return (getAttrValue(attrs, 'title') || 'live example').trim(); } private getZip(exampleDir: string, stackblitzName: string) { const zipName = exampleDir.split('/')[0]; return `${ZIP_BASE}${exampleDir}/${stackblitzName}${zipName}.zip`; } } ///// EmbeddedStackblitzComponent /// /** * Hides the `, styles: [ 'iframe { min-height: 400px; }' ] }) export class EmbeddedStackblitzComponent implements AfterViewInit { @Input() src: string; @ViewChild('iframe', { static: true }) iframe: ElementRef; ngAfterViewInit() { // DEVELOPMENT TESTING ONLY // this.src = 'https://angular.io/resources/live-examples/quickstart/ts/stackblitz.json'; if (this.iframe) { // security: the `src` is always authored by the documentation team // and is considered to be safe this.iframe.nativeElement.src = this.src; } } }