diff --git a/aio/content/marketing/test.html b/aio/content/marketing/test.html index 3a0c48a9fb..9a56e08e02 100644 --- a/aio/content/marketing/test.html +++ b/aio/content/marketing/test.html @@ -4,9 +4,11 @@

No linenums at code-tabs level

- class { - foo(param: string) {} -} + + class { + foo(param: string) {} + } + <h1>Heading</h1> { "key": "value" } @@ -14,9 +16,11 @@

linenums=true at code-tabs level

- class { - foo(param: string) {} -} + + class { + foo(param: string) {} + } + <h1>Heading</h1> { "key": "value" } @@ -24,9 +28,11 @@

No linenums at code-tabs level; linenums=true for HTML pane

- class { - foo(param: string) {} -} + + class { + foo(param: string) {} + } + <h1>Heading</h1> { "key": "value" } @@ -77,4 +83,27 @@ </hero-details> -

More text follows ...

\ No newline at end of file +

<live-example>

+ +

Plain live-example

+Try this . + +

live-example with title atty

+ + +

live-example with title body

+Try this great example + +

live-example with name

+ + +

live-example with spacey name and plnkr

+ + +

live-example with name and plnkr but no download

+ + +

live-example embedded with name and plnkr

+ + +

More text follows ...

diff --git a/aio/src/app/embedded/embedded.module.ts b/aio/src/app/embedded/embedded.module.ts index 588d6bf089..4d360ea1c2 100644 --- a/aio/src/app/embedded/embedded.module.ts +++ b/aio/src/app/embedded/embedded.module.ts @@ -17,12 +17,13 @@ import { ApiListComponent } from './api/api-list.component'; import { CodeExampleComponent } from './code/code-example.component'; import { CodeTabsComponent } from './code/code-tabs.component'; import { DocTitleComponent } from './doc-title.component'; +import { LiveExampleComponent, EmbeddedPlunkerComponent } from './live-example/live-example.component'; /** Components that can be embedded in docs * such as CodeExampleComponent, LiveExampleComponent,... */ export const embeddedComponents: any[] = [ - ApiListComponent, CodeExampleComponent, DocTitleComponent, CodeTabsComponent + ApiListComponent, CodeExampleComponent, DocTitleComponent, CodeTabsComponent, LiveExampleComponent ]; /** Injectable class w/ property returning components that can be embedded in docs */ @@ -34,7 +35,8 @@ export class EmbeddedComponents { imports: [ CommonModule, MdTabsModule ], declarations: [ embeddedComponents, - CodeComponent + CodeComponent, + EmbeddedPlunkerComponent ], providers: [ EmbeddedComponents, diff --git a/aio/src/app/embedded/live-example/live-example.component.html b/aio/src/app/embedded/live-example/live-example.component.html new file mode 100644 index 0000000000..33a53fabb4 --- /dev/null +++ b/aio/src/app/embedded/live-example/live-example.component.html @@ -0,0 +1,15 @@ + + {{title}} + + / download example + + +
+
+ +
+ {{title}} +

+ You can also download this example. +

+
diff --git a/aio/src/app/embedded/live-example/live-example.component.spec.ts b/aio/src/app/embedded/live-example/live-example.component.spec.ts new file mode 100644 index 0000000000..e966e231a6 --- /dev/null +++ b/aio/src/app/embedded/live-example/live-example.component.spec.ts @@ -0,0 +1,265 @@ +/* tslint:disable:no-unused-variable */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { Component, DebugElement, ElementRef } from '@angular/core'; +import { Location } from '@angular/common'; + +import { LiveExampleComponent, EmbeddedPlunkerComponent } from './live-example.component'; + +const defaultTestPath = '/test'; + +describe('LiveExampleComponent', () => { + let hostComponent: HostComponent; + let liveExampleDe: DebugElement; + let liveExampleComponent: LiveExampleComponent; + let fixture: ComponentFixture; + let testPath: string; + let liveExampleContent: string; + + //////// test helpers //////// + + @Component({ + selector: 'aio-host-comp', + template: `` + }) + class HostComponent { } + + class TestLocation { + path() { return testPath; } + } + + function setHostTemplate(template: string) { + TestBed.overrideComponent(HostComponent, {set: {template}}); + } + + function testComponent(testFn: () => void) { + return TestBed + .compileComponents() + .then(() => { + fixture = TestBed.createComponent(HostComponent); + hostComponent = fixture.componentInstance; + liveExampleDe = fixture.debugElement.children[0]; + liveExampleComponent = liveExampleDe.componentInstance; + + // Copy the LiveExample's innerHTML (content) + // into the `liveExampleContent` property as the DocViewer does + liveExampleDe.nativeElement.liveExampleContent = liveExampleContent; + + fixture.detectChanges(); + }) + .then(testFn); + } + + //////// tests //////// + beforeEach(() => { + TestBed.configureTestingModule({ + declarations: [ HostComponent, LiveExampleComponent, EmbeddedPlunkerComponent ], + providers: [ {provide: Location, useClass: TestLocation }] + }) + // Disable the `, + styles: [ 'iframe { min-height: 400px; }'] +}) +export class EmbeddedPlunkerComponent implements AfterViewInit { + @Input() src: string; + + @ViewChild('iframe') iframe: ElementRef; + + ngAfterViewInit() { + // DEVELOPMENT TESTING ONLY + // this.src = 'https://angular.io/resources/live-examples/quickstart/ts/eplnkr.html'; + + 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; + } + } +} diff --git a/aio/src/app/shared/location.service.ts b/aio/src/app/shared/location.service.ts index 2cf2a21eb3..4990a0e453 100644 --- a/aio/src/app/shared/location.service.ts +++ b/aio/src/app/shared/location.service.ts @@ -90,8 +90,13 @@ export class LocationService { return true; } - // check for external link + // don't navigate if external link or zip const { pathname, search, hash } = anchor; + + if (anchor.getAttribute('download') != null) { + return true; // let the download happen + } + const relativeUrl = pathname + search + hash; this.urlParser.href = relativeUrl; if (anchor.href !== this.urlParser.href) { diff --git a/aio/src/assets/images/plunker/placeholder.png b/aio/src/assets/images/plunker/placeholder.png index 585cd11696..54c3369ee2 100644 Binary files a/aio/src/assets/images/plunker/placeholder.png and b/aio/src/assets/images/plunker/placeholder.png differ