build(aio): migrate plunker to stackblitz (#20165)

PR Close #20165
This commit is contained in:
Jesus Rodriguez 2017-11-03 18:08:28 +01:00 committed by Miško Hevery
parent 1e9cd95f5c
commit 1a75934cc0
123 changed files with 735 additions and 1317 deletions

View File

@ -4,7 +4,7 @@ Everything in this folder is part of the documentation project. This includes
* the web site for displaying the documentation
* the dgeni configuration for converting source files to rendered files that can be viewed in the web site.
* the tooling for setting up examples for development; and generating plunkers and zip files from the examples.
* the tooling for setting up examples for development; and generating live-example and zip files from the examples.
## Developer tasks
@ -13,7 +13,7 @@ You should run all these tasks from the `angular/aio` folder.
Here are the most important tasks you might need to use:
* `yarn` - install all the dependencies.
* `yarn setup` - install all the dependencies, boilerplate, plunkers, zips and run dgeni on the docs.
* `yarn setup` - install all the dependencies, boilerplate, stackblitz, zips and run dgeni on the docs.
* `yarn setup-local` - same as `setup`, but use the locally built Angular packages for aio and docs examples boilerplate.
* `yarn build` - create a production build of the application (after installing dependencies, boilerplate, etc).
@ -32,7 +32,7 @@ Here are the most important tasks you might need to use:
* `yarn boilerplate:add` - generate all the boilerplate code for the examples, so that they can be run locally. Add the option `--local` to use your local version of Angular contained in the "dist" folder.
* `yarn boilerplate:remove` - remove all the boilerplate code that was added via `yarn boilerplate:add`.
* `yarn generate-plunkers` - generate the plunker files that are used by the `live-example` tags in the docs.
* `yarn generate-stackblitz` - generate the stackblitz files that are used by the `live-example` tags in the docs.
* `yarn generate-zips` - generate the zip files from the examples. Zip available via the `live-example` tags in the docs.
* `yarn example-e2e` - run all e2e tests for examples

View File

@ -76,8 +76,8 @@ aot-compiler/**/*.factory.d.ts
# universal
!universal/webpack.server.config.js
# plunkers
*plnkr.no-link.html
# stackblitz
*stackblitz.no-link.html
# ngUpgrade testing
!upgrade-phonecat-*/**/karma.conf.js

View File

@ -1,6 +1,5 @@
{
"description": "AngularJS to Angular Quick Reference",
"basePath": "src/",
"files":[
"!**/*.d.ts",
"!**/*.js",

View File

@ -1,6 +1,5 @@
{
"description": "Angular Animations",
"basePath": "src/",
"files":[
"!**/*.d.ts",
"!**/*.js"

View File

@ -1,9 +1,9 @@
{
"description": "Intro to Angular",
"basePath": "src/",
"files":[
"!**/*.d.ts",
"!**/*.js",
"!app/hero-list.component.1.*"
]
"!**/*.[1].*"
],
"file": "src/app/app.module.ts"
}

View File

@ -1,4 +1,4 @@
// Not used. Keep away from plunker
// Not used. Keep away from stackblitz
// Keeps ATLS from complaining about undeclared directives.
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

View File

@ -1,10 +1,9 @@
{
"description": "Attribute Directive",
"basePath": "src/",
"files":[
"!**/*.d.ts",
"!**/*.js",
"!app/*.[0,1,2,3].*"
"!**/*.[1,2,3].*"
],
"tags": ["attribute", "directive"]
}

View File

@ -1,6 +1,5 @@
{
"description": "Component Communication Cookbook samples",
"basePath": "src/",
"files":[
"!**/*.d.ts",
"!**/*.js"

View File

@ -1,6 +1,5 @@
{
"description": "Component Styles",
"basePath": "src/",
"files": [
"!**/*.d.ts",
"!**/*.js",

View File

@ -1,6 +1,5 @@
{
"description": "Dependency Injection",
"basePath": "src/",
"files":[
"!**/*.d.ts",
"!**/*.js",

View File

@ -1,6 +1,5 @@
{
"description": "Dependency Injection",
"basePath": "src/",
"files":[
"!**/*.d.ts",
"!**/*.js",

View File

@ -1,6 +1,5 @@
{
"description": "Displaying Data",
"basePath": "src/",
"files": [
"!**/*.d.ts",
"!**/*.js",

View File

@ -1,9 +0,0 @@
{
"description": "Second authors style guide plunker (non-executing)",
"basePath": "src/",
"files": [
"index.2.html"
],
"main": "index.2.html",
"tags": ["author", "style guide"]
}

View File

@ -0,0 +1,8 @@
{
"description": "Second authors style guide stackblitz (non-executing)",
"files": [
"src/index.2.html"
],
"main": "src/index.2.html",
"tags": ["author", "style guide"]
}

View File

@ -1,6 +1,5 @@
{
"description": "Authors style guide",
"basePath": "src/",
"files": [
"!**/*.d.ts",
"!**/*.js",

View File

@ -1,6 +1,5 @@
{
"description": "Dynamic Component Loader",
"basePath": "src/",
"files":[
"!**/*.d.ts",
"!**/*.js"

View File

@ -1,6 +1,5 @@
{
"description": "Dynamic Form",
"basePath": "src/",
"files":[
"!**/*.d.ts",
"!**/*.js",

View File

@ -1,6 +1,5 @@
{
"description": "Validation",
"basePath": "src/",
"files":[
"!**/*.d.ts",
"!**/*.js"

View File

@ -1,6 +1,5 @@
{
"description": "Forms",
"basePath": "src/",
"files":[
"!**/*.d.ts",
"!**/*.js"

View File

@ -1,6 +1,5 @@
{
"description": "Hierarchical Dependency Injection",
"basePath": "src/",
"files":[
"!**/*.d.ts",
"!**/*.js"

View File

@ -1,6 +1,5 @@
{
"description": "Http",
"basePath": "src/",
"files":[
"!**/*.d.ts",
"!**/*.js",

View File

@ -1,6 +1,5 @@
{
"description": "Lifecycle Hooks",
"basePath": "src/",
"files":["!**/*.d.ts", "!**/*.js"],
"tags": ["lifecycle", "hooks",
"OnInit", "OnDestroy", "OnChange", "DoCheck",

View File

@ -1,6 +1,5 @@
{
"description": "<ng-container>",
"basePath": "src/",
"files": [
"!**/*.d.ts",
"!**/*.js"

View File

@ -1,13 +1,15 @@
<!DOCTYPE html>
<html lang="en">
<head>
<base href="/">
<title>NgModule Minimal</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<app-root></app-root>
</body>
<head>
<base href="/">
<title>NgModule Minimal</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<app-root></app-root>
</body>
</html>

View File

@ -0,0 +1,24 @@
{
"description": "Contact NgModule v.1",
"files": [
"src/app/app.component.1b.ts",
"src/app/app.module.1b.ts",
"src/app/highlight.directive.ts",
"src/app/title.component.html",
"src/app/title.component.ts",
"src/app/user.service.ts",
"src/app/contact/awesome.pipe.ts",
"src/app/contact/contact.component.css",
"src/app/contact/contact.component.html",
"src/app/contact/contact.component.3.ts",
"src/app/contact/contact.service.ts",
"src/app/contact/contact-highlight.directive.ts",
"src/main.1b.ts",
"src/styles.css",
"src/index.1b.html"
],
"main": "src/index.1b.html",
"tags": ["NgModule"]
}

View File

@ -0,0 +1,26 @@
{
"description": "Contact NgModule v.2",
"files": [
"src/app/app.component.2.ts",
"src/app/app.module.2.ts",
"src/app/highlight.directive.ts",
"src/app/title.component.html",
"src/app/title.component.ts",
"src/app/user.service.ts",
"src/app/contact/contact.component.css",
"src/app/contact/contact.component.html",
"src/app/contact/contact.service.ts",
"src/app/contact/awesome.pipe.ts",
"src/app/contact/contact.component.3.ts",
"src/app/contact/contact.module.2.ts",
"src/app/contact/contact-highlight.directive.ts",
"src/main.2.ts",
"src/styles.css",
"src/index.2.html"
],
"main": "src/index.2.html",
"tags": ["NgModule"]
}

View File

@ -0,0 +1,12 @@
{
"description": "Minimal NgModule",
"files": [
"src/app/app.component.0.ts",
"src/app/app.module.0.ts",
"src/main.0.ts",
"src/styles.css",
"src/index.0.html"
],
"main": "src/index.0.html",
"tags": ["NgModule"]
}

View File

@ -0,0 +1,40 @@
{
"description": "NgModule v.3",
"files": [
"src/app/app.component.3.ts",
"src/app/app.module.3.ts",
"src/app/app-routing.module.3.ts",
"src/app/highlight.directive.ts",
"src/app/title.component.html",
"src/app/title.component.ts",
"src/app/user.service.ts",
"src/app/contact/contact.component.css",
"src/app/contact/contact.component.html",
"src/app/contact/contact.service.ts",
"src/app/contact/awesome.pipe.ts",
"src/app/contact/contact.component.3.ts",
"src/app/contact/contact.module.3.ts",
"src/app/contact/contact-routing.module.3.ts",
"src/app/contact/contact-highlight.directive.ts",
"src/app/crisis/*.ts",
"src/app/hero/hero-detail.component.ts",
"src/app/hero/hero-list.component.ts",
"src/app/hero/hero.service.ts",
"src/app/hero/hero.component.3.ts",
"src/app/hero/hero.module.3.ts",
"src/app/hero/hero-routing.module.3.ts",
"src/app/hero/highlight.directive.ts",
"src/main.3.ts",
"src/styles.css",
"src/index.3.html"
],
"main": "src/index.3.html",
"tags": ["NgModule"]
}

View File

@ -0,0 +1,40 @@
{
"description": "NgModule Final",
"files": [
"src/app/app.component.ts",
"src/app/app.module.ts",
"src/app/app-routing.module.ts",
"src/app/contact/contact.component.css",
"src/app/contact/contact.component.html",
"src/app/contact/contact.service.ts",
"src/app/contact/contact.component.ts",
"src/app/contact/contact.module.ts",
"src/app/contact/contact-routing.module.ts",
"src/app/crisis/*.ts",
"src/app/hero/hero-detail.component.ts",
"src/app/hero/hero-list.component.ts",
"src/app/hero/hero.service.ts",
"src/app/hero/hero.component.ts",
"src/app/hero/hero.module.ts",
"src/app/hero/hero-routing.module.ts",
"src/app/core/*.css",
"src/app/core/*.html",
"src/app/core/*.ts",
"src/app/shared/*.css",
"src/app/shared/*.html",
"src/app/shared/*.ts",
"src/main.ts",
"src/styles.css",
"src/index.html"
],
"main": "src/index.html",
"tags": ["NgModule"]
}

View File

@ -1,6 +1,5 @@
{
"description": "Pipes",
"basePath": "src/",
"files":[
"!**/*.d.ts",
"!**/*.js"],

View File

@ -0,0 +1,20 @@
{
"description": "Angular Reactive Forms (final)",
"files":[
"src/styles.css",
"src/app/app.component.ts",
"src/app/app.module.ts",
"src/app/data-model.ts",
"src/app/hero.service.ts",
"src/app/hero-detail.component.html",
"src/app/hero-detail.component.ts",
"src/app/hero-list.component.html",
"src/app/hero-list.component.ts",
"src/main-final.ts",
"src/index-final.html"
],
"main": "src/index-final.html",
"tags": ["reactive", "forms"]
}

View File

@ -1,15 +1,17 @@
<!DOCTYPE html>
<!-- #docregion -->
<html lang="en">
<head>
<title>Hero Form</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://unpkg.com/bootstrap@3.3.7/dist/css/bootstrap.min.css">
</head>
<body>
<app-root></app-root>
</body>
<head>
<title>Hero Form</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- #docregion bootstrap -->
<link rel="stylesheet" href="https://unpkg.com/bootstrap@3.3.7/dist/css/bootstrap.min.css">
</head>
<body>
<app-root></app-root>
</body>
</html>

View File

@ -1,15 +1,14 @@
{
"description": "Angular Reactive Forms (Demo runner)",
"basePath": "src/",
"files":[
"!**/*.d.ts",
"!**/*.js",
"!app/app.component.1.ts",
"!app/hero-list.component.1.html",
"!src/app/app.component.1.ts",
"!src/app/hero-list.component.1.html",
"!app/main-final.ts",
"!index-final.html"
"!src/app/main-final.ts",
"!src/index-final.html"
],
"tags": ["reactive", "forms"]
}

View File

@ -1,12 +1,11 @@
{
"description": "Router",
"basePath": "src/",
"files":[
"!**/*.d.ts",
"!**/*.js",
"!**/*.[0-9].*",
"!app/crisis-list.component.ts",
"!app/hero-list.component.ts"
"!src/app/crisis-list.component.ts",
"!src/app/hero-list.component.ts"
],
"tags": ["router"]
}

View File

@ -1,6 +1,5 @@
{
"description": "Content Security",
"basePath": "src/",
"files": [
"!**/*.d.ts",
"!**/*.js"

View File

@ -1,6 +1,5 @@
{
"description": "Set The Document Title In Angular",
"basePath": "src/",
"files": [
"!**/*.d.ts",
"!**/*.js",

View File

@ -1,10 +1,9 @@
{
"description": "Structural directives",
"basePath": "src/",
"files": [
"!**/*.d.ts",
"!**/*.js",
"!app/scrap.txt"
"!src/app/scrap.txt"
],
"tags": [
"structural", "directives", "template", "ngIf",

View File

@ -1,9 +0,0 @@
{
"description": "Style Guide",
"basePath": "src/",
"files":[
"!**/*.d.ts",
"!**/*.js"
],
"tags": ["style guide, styleguide"]
}

View File

@ -1,6 +1,5 @@
{
"description": "Template Syntax Collection",
"basePath": "src/",
"files":["!**/*.d.ts", "!**/*.js"],
"tags": ["template"]
}

View File

@ -1,14 +0,0 @@
{
"description": "Testing - 1st.specs",
"basePath": "src/",
"files":[
"browser-test-shim.js",
"styles.css",
"app/1st.spec.ts",
"1st-specs.html"
],
"main": "1st-specs.html",
"open": "app/1st.spec.ts",
"tags": ["testing"]
}

View File

@ -1,24 +0,0 @@
{
"description": "Testing - app.specs",
"basePath": "src/",
"files":[
"browser-test-shim.js",
"systemjs.config.extras.js",
"styles.css",
"app/**/*.css",
"app/**/*.html",
"app/**/*.ts",
"app/**/*.spec.ts",
"testing/*.ts",
"!main.ts",
"!app/bag/*.*",
"!app/1st.spec.ts",
"app-specs.html"
],
"main": "app-specs.html",
"tags": ["testing"]
}

View File

@ -1,21 +0,0 @@
{
"description": "Testing - bag.specs",
"basePath": "src/",
"files":[
"browser-test-shim.js",
"systemjs.config.extras.js",
"styles.css",
"app/bag/**/*.html",
"app/bag/**/*.ts",
"app/bag/**/*.spec.ts",
"!app/bag/bag-main.ts",
"testing/*.ts",
"bag-specs.html"
],
"main": "bag-specs.html",
"tags": ["testing"]
}

View File

@ -1,14 +0,0 @@
{
"description": "Running the bag",
"basePath": "src/",
"files":[
"styles.css",
"app/bag/bag.ts",
"app/bag/bag-external-template.html",
"app/bag/bag-main.ts",
"bag.html"
],
"main": "bag.html",
"tags": ["testing"]
}

View File

@ -1,15 +0,0 @@
{
"description": "Testing - banner-inline.component.specs",
"basePath": "src/",
"files":[
"browser-test-shim.js",
"systemjs.config.extras.js",
"app/banner-inline.component.ts",
"app/banner-inline.component.spec.ts",
"banner-inline-specs.html"
],
"main": "banner-inline-specs.html",
"open": "app/banner-inline.component.spec.ts",
"tags": ["testing"]
}

View File

@ -1,17 +0,0 @@
{
"description": "Testing - banner.component.specs",
"basePath": "src/",
"files":[
"browser-test-shim.js",
"systemjs.config.extras.js",
"app/banner.component.css",
"app/banner.component.html",
"app/banner.component.ts",
"app/banner.component.spec.ts",
"banner-specs.html"
],
"main": "banner-specs.html",
"open": "app/banner.component.spec.ts",
"tags": ["testing"]
}

View File

@ -0,0 +1,3 @@
{
"projectType": "testing"
}

View File

@ -1,18 +0,0 @@
{
"description": "Heroes Test App",
"basePath": "src/",
"files":[
"styles.css",
"systemjs.config.extras.js",
"app/**/*.css",
"app/**/*.html",
"app/**/*.ts",
"!app/bag/*.*",
"main.ts",
"index.html"
],
"tags": ["testing"]
}

View File

@ -0,0 +1,25 @@
{
"description": "Testing - app.specs",
"files":[
"src/styles.css",
"src/app/**/*.css",
"src/app/**/*.html",
"src/app/**/*.ts",
"src/app/**/*.spec.ts",
"src/testing/*.ts",
"!src/main.ts",
"!src/app/bag/*.*",
"!src/app/1st.spec.ts",
"src/expected.ts",
"src/test.css",
"src/tests.sb.ts",
"src/main-specs.ts",
"src/index-specs.html"
],
"main": "src/index-specs.html",
"tags": ["testing"]
}

View File

@ -1,41 +0,0 @@
<!-- Run application specs in a browser -->
<!-- #docregion -->
<!DOCTYPE html>
<html>
<head>
<base href="/">
<title>1st Specs</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="styles.css">
<link rel="stylesheet" href="node_modules/jasmine-core/lib/jasmine-core/jasmine.css">
</head>
<body>
<!-- Polyfills -->
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="node_modules/jasmine-core/lib/jasmine-core/jasmine.js"></script>
<script src="node_modules/jasmine-core/lib/jasmine-core/jasmine-html.js"></script>
<script src="node_modules/jasmine-core/lib/jasmine-core/boot.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/zone.js/dist/long-stack-trace-zone.js"></script>
<script src="node_modules/zone.js/dist/proxy.js"></script>
<script src="node_modules/zone.js/dist/sync-test.js"></script>
<script src="node_modules/zone.js/dist/jasmine-patch.js"></script>
<script src="node_modules/zone.js/dist/async-test.js"></script>
<script src="node_modules/zone.js/dist/fake-async-test.js"></script>
<!-- #docregion files -->
<script>
var __spec_files__ = [
'app/1st.spec'
];
</script>
<!-- #enddocregion files-->
<script src="browser-test-shim.js"></script>
</body>
</html>

View File

@ -1,56 +0,0 @@
<!-- Run application specs in a browser -->
<!-- #docregion -->
<!DOCTYPE html>
<html>
<head>
<base href="/">
<title>Sample App Specs</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="styles.css">
<link rel="stylesheet" href="node_modules/jasmine-core/lib/jasmine-core/jasmine.css">
</head>
<body>
<!-- Polyfills -->
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="node_modules/jasmine-core/lib/jasmine-core/jasmine.js"></script>
<script src="node_modules/jasmine-core/lib/jasmine-core/jasmine-html.js"></script>
<script src="node_modules/jasmine-core/lib/jasmine-core/boot.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/zone.js/dist/long-stack-trace-zone.js"></script>
<script src="node_modules/zone.js/dist/proxy.js"></script>
<script src="node_modules/zone.js/dist/sync-test.js"></script>
<script src="node_modules/zone.js/dist/jasmine-patch.js"></script>
<script src="node_modules/zone.js/dist/async-test.js"></script>
<script src="node_modules/zone.js/dist/fake-async-test.js"></script>
<script>
var __spec_files__ = [
'app/about.component.spec',
'app/app.component.spec',
'app/app.component.router.spec',
'app/banner.component.spec',
'app/banner.component.detect-changes.spec',
'app/banner-inline.component.spec',
'app/dashboard/dashboard.component.spec',
'app/dashboard/dashboard.component.no-testbed.spec',
'app/dashboard/dashboard-hero.component.spec',
'app/hero/hero-list.component.spec',
'app/hero/hero-detail.component.spec',
'app/hero/hero-detail.component.no-testbed.spec',
'app/model/hero.spec',
'app/model/http-hero.service.spec',
'app/shared/title-case.pipe.spec',
'app/shared/twain.component.spec',
'app/welcome.component.spec'
];
</script>
<script src="browser-test-shim.js"></script>
</body>
</html>

View File

@ -17,11 +17,11 @@ import { By } from '@angular/platform-browser';
import { DebugElement, Type } from '@angular/core';
import { Location } from '@angular/common';
import { AppModule } from './app.module';
import { AppComponent } from './app.component';
import { AboutComponent } from './about.component';
import { DashboardHeroComponent } from './dashboard/dashboard-hero.component';
import { TwainService } from './shared/twain.service';
import { AppModule } from './app.module';
import { AppComponent } from './app.component';
import { AboutComponent } from './about.component';
import { DashboardComponent } from './dashboard/dashboard.component';
import { TwainService } from './shared/twain.service';
let comp: AppComponent;
let fixture: ComponentFixture<AppComponent>;
@ -41,7 +41,7 @@ describe('AppComponent & RouterTestingModule', () => {
it('should navigate to "Dashboard" immediately', fakeAsync(() => {
createComponent();
expect(location.path()).toEqual('/dashboard', 'after initialNavigation()');
expectElementOf(DashboardHeroComponent);
expectElementOf(DashboardComponent);
}));
it('should navigate to "About" on click', fakeAsync(() => {
@ -52,17 +52,12 @@ describe('AppComponent & RouterTestingModule', () => {
advance();
expectPathToBe('/about');
expectElementOf(AboutComponent);
page.expectEvents([
[r.NavigationStart, '/about'], [r.RoutesRecognized, '/about'],
[r.NavigationEnd, '/about']
]);
}));
it('should navigate to "About" w/ browser location URL change', fakeAsync(() => {
createComponent();
location.simulateHashChange('/about');
// location.go('/about'); // also works ... except in plunker
// location.go('/about'); // also works ... except, perhaps, in Stackblitz
advance();
expectPathToBe('/about');
expectElementOf(AboutComponent);

View File

@ -450,7 +450,7 @@ describe('TestBed Component Overrides:', () => {
tcProvider = fixture.debugElement.injector.get(FancyService);
tpcProvider = fixture.debugElement.children[0].injector.get(FancyService) as FakeFancyService;
expect(testBedProvider).not.toBe(tcProvider, 'testBed/tc not same providers');
expect(testBedProvider).not.toBe(<any> tcProvider, 'testBed/tc not same providers');
expect(testBedProvider).not.toBe(tpcProvider, 'testBed/tpc not same providers');
expect(testBedProvider instanceof FancyService).toBe(true, 'testBedProvider is FancyService');

View File

@ -235,7 +235,7 @@ export class MyIfComponent {
providers: [FancyService]
})
export class TestProvidersComponent {
constructor(private fancyService: FancyService) {}
constructor(public fancyService: FancyService) {}
}
@ -245,7 +245,7 @@ export class TestProvidersComponent {
viewProviders: [FancyService]
})
export class TestViewProvidersComponent {
constructor(private fancyService: FancyService) {}
constructor(public fancyService: FancyService) {}
}
@Component({
@ -271,14 +271,6 @@ export class ExternalTemplateComponent implements OnInit {
})
export class InnerCompWithExternalTemplateComponent { }
@Component({
selector: 'bad-template-comp',
templateUrl: './non-existent.html'
})
export class BadTemplateUrlComponent { }
@Component({selector: 'needs-content', template: '<ng-content></ng-content>'})
export class NeedsContentComponent {
// children with #content local variable

View File

@ -123,7 +123,7 @@ function overrideSetup() {
it('fixture injected service is not the component injected service',
inject([HeroDetailService], (service: HeroDetailService) => {
expect(service).toEqual({}, 'service injected from fixture');
expect(service).toEqual(<any> {}, 'service injected from fixture');
expect(hdsSpy).toBeTruthy('service injected into component');
}));
}

View File

@ -42,7 +42,7 @@ describe('HeroListComponent', () => {
it('1st hero should match 1st test hero', () => {
const expectedHero = HEROES[0];
const actualHero = page.heroRows[0].textContent;
expect(actualHero).toContain(expectedHero.id, 'hero.id');
expect(actualHero).toContain(expectedHero.id.toString(), 'hero.id');
expect(actualHero).toContain(expectedHero.name, 'hero.name');
});
@ -118,7 +118,7 @@ class Page {
/** Hero line elements */
heroRows: HTMLLIElement[];
/** Highlighted element */
/** Highlighted DebugElement */
highlightDe: DebugElement;
/** Spy on router navigate method */

View File

@ -0,0 +1,3 @@
export * from './hero';
export * from './hero.service';
export * from './user.service';

View File

@ -0,0 +1 @@
export * from './fake-hero.service';

View File

@ -1,42 +0,0 @@
<!-- Run the "bag" specs in a browser -->
<!-- #docregion -->
<!DOCTYPE html>
<html>
<head>
<base href="/">
<title>Specs Bag</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="styles.css">
<link rel="stylesheet" href="node_modules/jasmine-core/lib/jasmine-core/jasmine.css">
</head>
<body>
<!-- Polyfills -->
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="node_modules/jasmine-core/lib/jasmine-core/jasmine.js"></script>
<script src="node_modules/jasmine-core/lib/jasmine-core/jasmine-html.js"></script>
<script src="node_modules/jasmine-core/lib/jasmine-core/boot.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/zone.js/dist/long-stack-trace-zone.js"></script>
<script src="node_modules/zone.js/dist/proxy.js"></script>
<script src="node_modules/zone.js/dist/sync-test.js"></script>
<script src="node_modules/zone.js/dist/jasmine-patch.js"></script>
<script src="node_modules/zone.js/dist/async-test.js"></script>
<script src="node_modules/zone.js/dist/fake-async-test.js"></script>
<script>
var __spec_files__ = [
'app/bag/bag.spec',
'app/bag/bag.no-testbed.spec',
'app/bag/async-helper.spec'
];
</script>
<script src="browser-test-shim.js"></script>
</body>
</html>

View File

@ -1,40 +0,0 @@
<!-- Run application specs in a browser -->
<!-- #docregion -->
<!DOCTYPE html>
<html>
<head>
<base href="/">
<title>Banner Component (inline template) Specs</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="node_modules/jasmine-core/lib/jasmine-core/jasmine.css">
</head>
<body>
<!-- Polyfills -->
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="node_modules/jasmine-core/lib/jasmine-core/jasmine.js"></script>
<script src="node_modules/jasmine-core/lib/jasmine-core/jasmine-html.js"></script>
<script src="node_modules/jasmine-core/lib/jasmine-core/boot.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/zone.js/dist/long-stack-trace-zone.js"></script>
<script src="node_modules/zone.js/dist/proxy.js"></script>
<script src="node_modules/zone.js/dist/sync-test.js"></script>
<script src="node_modules/zone.js/dist/jasmine-patch.js"></script>
<script src="node_modules/zone.js/dist/async-test.js"></script>
<script src="node_modules/zone.js/dist/fake-async-test.js"></script>
<!-- #docregion files -->
<script>
var __spec_files__ = [
'app/banner-inline.component.spec'
];
</script>
<!-- #enddocregion files-->
<script src="browser-test-shim.js"></script>
</body>
</html>

View File

@ -1,40 +0,0 @@
<!-- Run application specs in a browser -->
<!-- #docregion -->
<!DOCTYPE html>
<html>
<head>
<base href="/">
<title>Banner Component Specs</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="node_modules/jasmine-core/lib/jasmine-core/jasmine.css">
</head>
<body>
<!-- Polyfills -->
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="node_modules/jasmine-core/lib/jasmine-core/jasmine.js"></script>
<script src="node_modules/jasmine-core/lib/jasmine-core/jasmine-html.js"></script>
<script src="node_modules/jasmine-core/lib/jasmine-core/boot.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/zone.js/dist/long-stack-trace-zone.js"></script>
<script src="node_modules/zone.js/dist/proxy.js"></script>
<script src="node_modules/zone.js/dist/sync-test.js"></script>
<script src="node_modules/zone.js/dist/jasmine-patch.js"></script>
<script src="node_modules/zone.js/dist/async-test.js"></script>
<script src="node_modules/zone.js/dist/fake-async-test.js"></script>
<!-- #docregion files -->
<script>
var __spec_files__ = [
'app/banner.component.spec'
];
</script>
<!-- #enddocregion files-->
<script src="browser-test-shim.js"></script>
</body>
</html>

View File

@ -1,87 +0,0 @@
// BROWSER TESTING SHIM
// Keep it in-sync with what karma-test-shim does
// #docregion
/*global jasmine, __karma__, window*/
(function () {
Error.stackTraceLimit = 0; // "No stacktrace"" is usually best for app testing.
// Uncomment to get full stacktrace output. Sometimes helpful, usually not.
// Error.stackTraceLimit = Infinity; //
jasmine.DEFAULT_TIMEOUT_INTERVAL = 3000;
var baseURL = document.baseURI;
baseURL = baseURL + baseURL[baseURL.length-1] ? '' : '/';
System.config({
baseURL: baseURL,
// Extend usual application package list with test folder
packages: { 'testing': { main: 'index.js', defaultExtension: 'js' } },
// Assume npm: is set in `paths` in systemjs.config
// Map the angular testing umd bundles
map: {
'@angular/core/testing': 'npm:@angular/core/bundles/core-testing.umd.js',
'@angular/common/testing': 'npm:@angular/common/bundles/common-testing.umd.js',
'@angular/compiler/testing': 'npm:@angular/compiler/bundles/compiler-testing.umd.js',
'@angular/platform-browser/testing': 'npm:@angular/platform-browser/bundles/platform-browser-testing.umd.js',
'@angular/platform-browser-dynamic/testing': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic-testing.umd.js',
'@angular/http/testing': 'npm:@angular/http/bundles/http-testing.umd.js',
'@angular/router/testing': 'npm:@angular/router/bundles/router-testing.umd.js',
'@angular/forms/testing': 'npm:@angular/forms/bundles/forms-testing.umd.js',
},
});
System.import('systemjs.config.js')
.then(importSystemJsExtras)
.then(initTestBed)
.then(initTesting);
/** Optional SystemJS configuration extras. Keep going w/o it */
function importSystemJsExtras(){
return System.import('systemjs.config.extras.js')
.catch(function(reason) {
console.log(
'Note: System.import could not load "systemjs.config.extras.js" where you might have added more configuration. It is an optional file so we will continue without it.'
);
console.log(reason);
});
}
function initTestBed(){
return Promise.all([
System.import('@angular/core/testing'),
System.import('@angular/platform-browser-dynamic/testing')
])
.then(function (providers) {
var coreTesting = providers[0];
var browserTesting = providers[1];
coreTesting.TestBed.initTestEnvironment(
browserTesting.BrowserDynamicTestingModule,
browserTesting.platformBrowserDynamicTesting());
})
}
// Import all spec files defined in the html (__spec_files__)
// and start Jasmine testrunner
function initTesting () {
console.log('loading spec files: '+__spec_files__.join(', '));
return Promise.all(
__spec_files__.map(function(spec) {
return System.import(spec);
})
)
// After all imports load, re-execute `window.onload` which
// triggers the Jasmine test-runner start or explain what went wrong
.then(success, console.error.bind(console));
function success () {
console.log('Spec files loaded; starting Jasmine testrunner');
window.onload();
}
}
})();

View File

@ -0,0 +1 @@
/* Ignore. Satisfies static analysis of router config in app.component.router.spec.ts */

View File

@ -0,0 +1,4 @@
<!--
Intentionally empty placeholder for Stackblitz.
Do not need index.html in zip-download either as you should run tests with `npm test`
-->

View File

@ -0,0 +1,45 @@
import './testing/global-jasmine';
import 'jasmine-core/lib/jasmine-core/jasmine-html.js';
import 'jasmine-core/lib/jasmine-core/boot.js';
declare var jasmine;
import './polyfills';
import 'zone.js/dist/async-test';
import 'zone.js/dist/fake-async-test';
import 'zone.js/dist/long-stack-trace-zone';
import 'zone.js/dist/proxy.js';
import 'zone.js/dist/sync-test';
import 'zone.js/dist/jasmine-patch';
import { getTestBed } from '@angular/core/testing';
import {
BrowserDynamicTestingModule,
platformBrowserDynamicTesting
} from '@angular/platform-browser-dynamic/testing';
// Spec files to include in the Stackblitz tests
import './tests.sb.ts';
//
bootstrap();
//
function bootstrap () {
if (window['jasmineRef']) {
location.reload();
return;
} else {
window.onload(undefined);
window['jasmineRef'] = jasmine.getEnv();
}
// First, initialize the Angular testing environment.
getTestBed().initTestEnvironment(
BrowserDynamicTestingModule,
platformBrowserDynamicTesting()
);
}

View File

@ -0,0 +1 @@
@import "~jasmine-core/lib/jasmine-core/jasmine.css"

View File

@ -0,0 +1,3 @@
import jasmineRequire from 'jasmine-core/lib/jasmine-core/jasmine.js';
window['jasmineRequire'] = jasmineRequire;

View File

@ -0,0 +1,18 @@
// Import spec files individually for Stackblitz
import './app/about.component.spec.ts';
import './app/app.component.spec.ts';
import './app/app.component.router.spec.ts';
import './app/banner.component.spec.ts';
import './app/banner.component.detect-changes.spec.ts';
import './app/banner-inline.component.spec.ts';
import './app/dashboard/dashboard.component.spec.ts';
import './app/dashboard/dashboard.component.no-testbed.spec.ts';
import './app/dashboard/dashboard-hero.component.spec.ts';
import './app/hero/hero-list.component.spec.ts';
import './app/hero/hero-detail.component.spec.ts';
import './app/hero/hero-detail.component.no-testbed.spec.ts';
import './app/model/hero.spec.ts';
import './app/model/http-hero.service.spec.ts';
import './app/shared/title-case.pipe.spec.ts';
import './app/shared/twain.component.spec.ts';
import './app/welcome.component.spec.ts';

View File

@ -0,0 +1,19 @@
{
"description": "Heroes Test App",
"files":[
"src/styles.css",
"src/app/**/*.css",
"src/app/**/*.html",
"src/app/**/*.ts",
"!src/app/bag/*.*",
"!src/test.ts",
"src/test.css",
"src/main.ts",
"src/index.html"
],
"tags": ["testing"]
}

View File

@ -1,6 +1,5 @@
{
"description": "Tour of Heroes: Part 0",
"basePath": "src/",
"files":[
"!**/*.d.ts",
"!**/*.js",

View File

@ -1,6 +1,5 @@
{
"description": "Tour of Heroes: Part 1",
"basePath": "src/",
"files":[
"!**/*.d.ts",
"!**/*.js",

View File

@ -1,6 +1,5 @@
{
"description": "Tour of Heroes: Part 2",
"basePath": "src/",
"files":[
"!**/*.d.ts",
"!**/*.js",

View File

@ -1,6 +1,5 @@
{
"description": "Tour of Heroes: Part 3",
"basePath": "src/",
"files":[
"!**/*.d.ts",
"!**/*.js",

View File

@ -1,6 +1,5 @@
{
"description": "Tour of Heroes: Part 4",
"basePath": "src/",
"files":[
"!**/*.d.ts",
"!**/*.js",

View File

@ -1,6 +1,5 @@
{
"description": "Tour of Heroes: Part 5",
"basePath": "src/",
"files":[
"!**/*.d.ts",
"!**/*.js",

View File

@ -1,6 +1,5 @@
{
"description": "Tour of Heroes: Part 6",
"basePath": "src/",
"files":[
"!**/*.d.ts",
"!**/*.js",

View File

@ -1,6 +1,5 @@
{
"description": "User Input",
"basePath": "src/",
"files": [
"!**/*.d.ts",
"!**/*.js"

View File

@ -9,8 +9,7 @@ with components, enabling a more modular design than regular stylesheets.
This page describes how to load and apply these component styles.
You can run the <live-example></live-example> in Plunker and download the code from there.
You can run the <live-example></live-example> in Stackblitz and download the code from there.
## Using component styles

View File

@ -23,7 +23,7 @@ The [aio/README.md](https://github.com/angular/angular/blob/master/aio/README.md
Here are a few essential commands for guide page authors.
1. `yarn setup` &mdash; installs packages; builds docs, plunkers, and zips.
1. `yarn setup` &mdash; installs packages; builds docs, stackblitz, and zips.
1. `yarn docs-watch --watch-only` &mdash; watches for saved content changes and refreshes the browser. The (optional) `--watch-only` flag skips the initial docs rebuild.
@ -549,7 +549,7 @@ Different file types have different comment syntax so adjust accordingly.
```
The doc generation process erases these comments before displaying them in the doc viewer.
It also strips them from plunkers and sample code downloads.
It also strips them from stackblitz and sample code downloads.
<div class="alert is-important">
@ -711,24 +711,24 @@ app.component.2.ts
You'll find many such files among the samples in the Angular documentation.
Remember to exclude these files from plunkers by listing them in the `plnkr.json` as illustrated here.
Remember to exclude these files from stackblitz by listing them in the `stackblitz.json` as illustrated here.
<code-example
path="docs-style-guide/plnkr.json"
title="plnkr.json"></code-example>
path="docs-style-guide/stackblitz.json"
title="stackblitz.json"></code-example>
{@a live-examples}
## Live examples
By adding `<live-example>` to the page you generate links that run sample code in the Plunker live coding environment and download that code to the reader's file system.
By adding `<live-example>` to the page you generate links that run sample code in the Stackblitz live coding environment and download that code to the reader's file system.
Live examples (AKA "plunkers") are defined by one or more `plnkr.json` files in the root of a code sample folder. Each sample folder usually has a single unnamed definition file, the default `plnkr.json`.
Live examples (AKA "stackblitz") are defined by one or more `stackblitz.json` files in the root of a code sample folder. Each sample folder usually has a single unnamed definition file, the default `stackblitz.json`.
<div class="l-sub-section">
You can create additional, named definition files in the form `name.plnkr.json`. See `content/examples/testing` for examples.
You can create additional, named definition files in the form `name.stackblitz.json`. See `content/examples/testing` for examples.
The schema for a `plnkr.json` hasn't been documented yet but looking at the `plnkr.json` files in the example folders should tell you most of what you need to know.
The schema for a `stackblitz.json` hasn't been documented yet but looking at the `stackblitz.json` files in the example folders should tell you most of what you need to know.
</div>
@ -736,11 +736,11 @@ Adding `<live-example></live-example>` to the page generates the two default lin
<live-example></live-example>
1. a link to the plunker defined by the default `plnkr.json` file located in the code sample folder with the same name as the guide page.
1. a link to the Stackblitz defined by the default `stackblitz.json` file located in the code sample folder with the same name as the guide page.
2. a link that downloads that sample.
Clicking the first link opens the code sample in a new browser tab in the "embedded plunker" style.
Clicking the first link opens the code sample in a new browser tab in the "embedded Stackblitz" style.
You can change the appearance and behavior of the live example with attributes and classes.
@ -765,7 +765,7 @@ You can achieve the same effect by putting the label between the `<live-example>
<h3 class="no-toc">Live example from another guide</h3>
To link to a plunker in a folder whose name is not the same as the current guide page, set the `name` attribute to the name of that folder.
To link to a Stackblitz in a folder whose name is not the same as the current guide page, set the `name` attribute to the name of that folder.
<live-example name="router">Live Example from the Router guide</live-example>
@ -773,29 +773,29 @@ To link to a plunker in a folder whose name is not the same as the current guide
<live-example name="router">Live Example from the Router guide</live-example>
```
<h3 class="no-toc">Live Example for named plunker</h3>
<h3 class="no-toc">Live Example for named Stackblitz</h3>
To link to a plunker defined by a named `plnkr.json` file, set the `plnkr` attribute. The following example links to the plunker defined by `second.plnkr.json` in the current guide's directory.
To link to a Stackblitz defined by a named `stackblitz.json` file, set the `stackblitz` attribute. The following example links to the Stackblitz defined by `second.stackblitz.json` in the current guide's directory.
<live-example plnkr="second"></live-example>
<live-example stackblitz="second"></live-example>
```html
<live-example plnkr="second"></live-example>
<live-example stackblitz="second"></live-example>
```
<h3 class="no-toc">Live Example without download</h3>
To skip the download link, add the `noDownload` attribute.
<live-example noDownload>Just the plunker</live-example>
<live-example noDownload>Just the Stackblitz</live-example>
```html
<live-example noDownload>Just the plunker</live-example>
<live-example noDownload>Just the Stackblitz</live-example>
```
<h3 class="no-toc">Live Example with download-only</h3>
To skip the live plunker link and only link to the download, add the `downloadOnly` attribute.
To skip the live Stackblitz link and only link to the download, add the `downloadOnly` attribute.
<live-example downloadOnly>Download only</live-example>
@ -805,21 +805,21 @@ To skip the live plunker link and only link to the download, add the `downloadOn
<h3 class="no-toc">Embedded live example</h3>
By default, a live example link opens a plunker in a separate browser tab.
You can embed the plunker within the guide page itself by adding the `embedded` attribute.
By default, a live example link opens a Stackblitz in a separate browser tab.
You can embed the Stackblitz within the guide page itself by adding the `embedded` attribute.
For performance reasons, the plunker does not start right away. The reader sees an image instead. Clicking the image starts the sometimes-slow process of launching the embedded plunker within an iframe on the page.
For performance reasons, the Stackblitz does not start right away. The reader sees an image instead. Clicking the image starts the sometimes-slow process of launching the embedded Stackblitz within an iframe on the page.
You usually replace the default plunker image with a custom image that better represents the sample.
You usually replace the default Stackblitz image with a custom image that better represents the sample.
Store that image in the `content/images` directory in a folder with a name matching the corresponding example folder.
Here's an embedded live example for this guide. It has a custom image created from a snapshot of the running app, overlayed with `content/images/plunker/unused/click-to-run.png`.
Here's an embedded live example for this guide. It has a custom image created from a snapshot of the running app, overlayed with `content/images/Stackblitz/unused/click-to-run.png`.
```html
<live-example embedded img="guide/docs-style-guide/docs-style-guide-plunker.png"></live-example>
<live-example embedded img="guide/docs-style-guide/docs-style-guide-Stackblitz.png"></live-example>
```
<live-example embedded img="guide/docs-style-guide/docs-style-guide-plunker.png"></live-example>
<live-example embedded img="guide/docs-style-guide/docs-style-guide-Stackblitz.png"></live-example>
{@a anchors}

View File

@ -20,7 +20,7 @@ This page shows you how to build a simple form from scratch. Along the way you'l
* Display validation errors to users and enable/disable form controls.
* Share information across HTML elements using template reference variables.
You can run the <live-example></live-example> in Plunker and download the code from there.
You can run the <live-example></live-example> in Stackblitz and download the code from there.
{@a template-driven}

View File

@ -16,7 +16,7 @@ In fact, you might like to apply them in your HTML templates as you do styles.
Introducing Angular pipes, a way to write display-value transformations that you can declare in your HTML.
You can run the <live-example></live-example> in Plunker and download the code from there.
You can run the <live-example></live-example> in Stackblitz and download the code from there.
## Using pipes

View File

@ -6,9 +6,9 @@ This guide explains reactive forms as you follow the steps to build a "Hero Deta
{@a toc}
Try the <live-example plnkr="final" title="Reactive Forms (final) in Plunker">Reactive Forms live-example</live-example>.
Try the <live-example stackblitz="final" title="Reactive Forms (final) in Stackblitz">Reactive Forms live-example</live-example>.
You can also run the <live-example title="Reactive Forms Demo in Plunker">Reactive Forms Demo</live-example> version
You can also run the <live-example title="Reactive Forms Demo in Stackblitz">Reactive Forms Demo</live-example> version
and choose one of the intermediate steps from the "demo picker" at the top.
@ -1390,7 +1390,7 @@ Clicking the revert button triggers a call to the component's `revert` method.
Users now can save or revert changes.
This is the final step in the demo.
Try the <live-example plnkr="final" title="Reactive Forms (final) in Plunker"></live-example>.
Try the <live-example stackblitz="final" title="Reactive Forms (final) in Stackblitz"></live-example>.
@ -1456,4 +1456,4 @@ The key files of the final version are as follows:
You can download the complete source for all steps in this guide
from the <live-example title="Reactive Forms Demo in Plunker">Reactive Forms Demo</live-example> live example.
from the <live-example title="Reactive Forms Demo in Stackblitz">Reactive Forms Demo</live-example> live example.

View File

@ -797,7 +797,7 @@ set the `href` value in **`index.html`** *exactly* as shown here.
A live coding environment like Plunker sets the application base address dynamically so you can't specify a fixed address.
A live coding environment like Stackblitz sets the application base address dynamically so you can't specify a fixed address.
That's why the example code replaces the `<base href...>` with a script that writes the `<base>` tag on the fly.
@ -4039,7 +4039,7 @@ to see the finished route configuration.
## Wrap up and final app
You've covered a lot of ground in this guide and the application is too big to reprint here.
Please visit the <live-example title="Router Sample in Plunker"></live-example>
Please visit the <live-example title="Router Sample in Stackblitz"></live-example>
where you can download the final source code.

View File

@ -7,7 +7,7 @@ this user?_) and authorization (_What can this user do?_).
For more information about the attacks and mitigations described below, see [OWASP Guide Project](https://www.owasp.org/index.php/Category:OWASP_Guide_Project).
You can run the <live-example></live-example> in Plunker and download the code from there.
You can run the <live-example></live-example> in Stackblitz and download the code from there.

View File

@ -7,16 +7,6 @@ This cookbook explains how to do it.
See the <live-example name="set-document-title"></live-example>.
<div class="l-sub-section">
<img src='generated/images/plunker/plunker-switch-to-editor-button.png'alt="pop out the window" class="right">
<img src='generated/images/plunker/plunker-separate-window-button.png' alt="pop out the window" class="right">
To see the browser title bar change in the live example,
open it again in the Plunker editor by clicking the icon in the upper right,
then pop out the preview window by clicking the blue 'X' button in the upper right corner.
</div>
## The problem with *&lt;title&gt;*
The obvious approach is to bind a property of the component to the HTML `<title>` like this:

View File

@ -273,7 +273,7 @@ The following are all in `src/`
[bootstraps](guide/bootstrapping)
the application's main module (`AppModule`) to run in the browser.
The JIT compiler is a reasonable choice during the development of most projects and
it's the only viable choice for a sample running in a _live-coding_ environment like Plunker.
it's the only viable choice for a sample running in a _live-coding_ environment like Stackblitz.
You'll learn about alternative compiling and [deployment](guide/deployment) options later in the documentation.
</td>
@ -326,7 +326,7 @@ use other versions of node and npm.
## Appendix: Why develop locally
<live-example title="QuickStart Seed in Plunker">Live coding</live-example> in the browser is a great way to explore Angular.
<live-example title="QuickStart Seed in Stackblitz">Live coding</live-example> in the browser is a great way to explore Angular.
Links on almost every documentation page open completed samples in the browser.
You can play with the sample code, share your changes with friends, and download and run the code on your own machine.
@ -338,12 +338,12 @@ The other samples are based on the QuickStart seed.
As much fun as this is ...
* you can't ship your app in plunker
* you can't ship your app in Stackblitz
* you aren't always online when writing code
* transpiling TypeScript in the browser is slow
* the type support, refactoring, and code completion only work in your local IDE
Use the <live-example title="QuickStart Seed in Plunker">live coding</live-example> environment as a _playground_,
Use the <live-example title="QuickStart Seed in Stackblitz">live coding</live-example> environment as a _playground_,
a place to try the documentation samples and experiment on your own.
It's the perfect place to reproduce a bug when you want to
<a href="https://github.com/angular/angular/issues/new" title="File a documentation issue">file a documentation issue</a> or

View File

@ -12,13 +12,8 @@ the focus is on testing applications written with Angular.
This guide presents tests of a sample application that is much like the [_Tour of Heroes_ tutorial](tutorial).
The sample application and all tests in this guide are available as live examples for inspection, experiment, and download:
* <live-example plnkr="1st-specs" embedded-style>A spec to verify the test environment</live-example>.
* <live-example plnkr="banner-inline-specs" embedded-style>The first component spec with inline template</live-example>.
* <live-example plnkr="banner-specs" embedded-style>A component spec with external template</live-example>.
* <live-example name="setup" plnkr="quickstart-specs" embedded-style>The QuickStart seed's AppComponent spec</live-example>.
* <live-example embedded-style>The sample application to be tested</live-example>.
* <live-example plnkr="app-specs" embedded-style>All specs that test the sample application</live-example>.
* <live-example plnkr="bag-specs" embedded-style>A grab bag of additional specs</live-example>.
* <live-example stackblitz="specs" embedded-style>All specs that test the sample application</live-example>.
<hr/>
@ -352,15 +347,6 @@ Debug specs in the browser in the same way that you debug an application.
</figure>
{@a live-karma-example}
### Try the live example
You can also try this test as a <live-example plnkr="1st-specs" title="First spec" embedded-style></live-example> in plunker.
All of the tests in this guide are available as [live examples](guide/testing#live-examples "Live examples of these tests").
<hr/>
@ -554,14 +540,6 @@ It gives the tester an opportunity to inspect or change the state of
the component _before Angular initiates data binding or calls lifecycle hooks_.
{@a try-example}
### Try the live example
Take a moment to explore this component spec as a <live-example plnkr="banner-inline-specs" title="Spec for component with inline template" embedded-style></live-example> and
lock in these fundamentals of component unit testing.
{@a auto-detect-changes}
@ -748,21 +726,10 @@ into a `compileComponents().then(...)` callback and write only one `beforeEach`.
Most developers find that hard to read.
The two `beforeEach` calls are widely preferred.
{@a live-external-template-example}
### Try the live example
Take a moment to explore this component spec as a <live-example plnkr="banner-specs" title="Spec for component with external template" embedded-style></live-example>.
<div class="l-sub-section">
The [Quickstart seed](guide/setup) provides a similar test of its `AppComponent`
as you can see in _this_ <live-example name="setup" plnkr="quickstart-specs" title="QuickStart seed spec" embedded-style></live-example>.
It too calls `compileComponents` although it doesn't have to because the `AppComponent`'s template is inline.
There's no harm in it and you might call `compileComponents` anyway
in case you decide later to re-factor the template into a separate file.
The tests in this guide only call `compileComponents` when necessary.
@ -1664,7 +1631,8 @@ New heroes have `id=0` and a blank `name`. This test confirms that the component
Inspect and download _all_ of the guide's application test code with this <live-example plnkr="app-specs" embedded-style>live example</live-example>.
Inspect and download _all_ of the guide's application test code with this
<live-example stackblitz="specs" embedded-style>live example</live-example>.
</div>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

View File

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

@ -3,7 +3,7 @@
Angular is a platform that makes it easy to build applications with the web. Angular combines declarative templates, dependency injection, end to end tooling, and integrated best practices to solve development challenges. Angular empowers developers to build applications that live on the web, mobile, or the desktop
<div class="card-container">
<a href="generated/live-examples/quickstart/eplnkr.html" target="_blank" class="docs-card"
<a href="generated/live-examples/toh-pt1/stackblitz.html" target="_blank" class="docs-card"
title="Experience Angular in a live coding environment">
<section>Get a Glimpse of Angular</section>
<p>A quick look at an Angular "hello world" application.</p>

View File

@ -19,7 +19,7 @@
"routing": {
"index": "/index.html",
"routes": {
"^(?!/docs/.|(?:/guide/(?:cli-quickstart|metadata|ngmodule|service-worker-(?:getstart|comm|configref)|learning-angular)|/news/?)$|/testing|/api/(?:common/NgModel|platform-browser/AnimationDriver|testing|api)).*/(?!e?plnkr|(?:NgFor|MaxLengthValidator)-|Control(?:Group)?|AnimationStateDeclarationMetadata|CORE_DIRECTIVES|PLATFORM_PIPES|DirectiveMetadata|HTTP_PROVIDERS)[^/.]*$": {
"^(?!/docs/.|(?:/guide/(?:cli-quickstart|metadata|ngmodule|service-worker-(?:getstart|comm|configref)|learning-angular)|/news/?)$|/testing|/api/(?:common/NgModel|platform-browser/AnimationDriver|testing|api)).*/(?!e?stackblitz|(?:NgFor|MaxLengthValidator)-|Control(?:Group)?|AnimationStateDeclarationMetadata|CORE_DIRECTIVES|PLATFORM_PIPES|DirectiveMetadata|HTTP_PROVIDERS)[^/.]*$": {
"match": "regex"
}
}

View File

@ -23,7 +23,7 @@
"preinstall": "node ../tools/yarn/check-yarn.js",
"presetup": "yarn install --frozen-lockfile && yarn ~~check-env && yarn boilerplate:remove",
"setup": "yarn aio-use-npm && yarn example-use-npm",
"postsetup": "yarn boilerplate:add && yarn build-ie-polyfills && yarn generate-plunkers && yarn generate-zips && yarn docs",
"postsetup": "yarn boilerplate:add && yarn build-ie-polyfills && yarn generate-stackblitz && yarn generate-zips && yarn docs",
"presetup-local": "yarn presetup",
"setup-local": "yarn aio-use-local && yarn example-use-local",
"postsetup-local": "yarn postsetup",
@ -49,7 +49,7 @@
"boilerplate:add": "node ./tools/examples/example-boilerplate add",
"boilerplate:remove": "node ./tools/examples/example-boilerplate remove",
"boilerplate:test": "node tools/examples/test.js",
"generate-plunkers": "node ./tools/plunker-builder/generatePlunkers",
"generate-stackblitz": "node ./tools/stackblitz-builder/generateStackblitz",
"generate-zips": "node ./tools/example-zipper/generateZips",
"sw-manifest": "ngu-sw-manifest --dist dist --in ngsw-manifest.json --out dist/ngsw-manifest.json",
"sw-copy": "cp node_modules/@angular/service-worker/bundles/worker-basic.min.js dist/",

View File

@ -5,7 +5,7 @@
"inline": 1602,
"main": 459119,
"polyfills": 40264,
"embedded": 72537,
"embedded": 71711,
"prettify": 14888
}
}

View File

@ -25,7 +25,7 @@ import { ContributorListComponent } from './contributor/contributor-list.compone
import { ContributorComponent } from './contributor/contributor.component';
import { CurrentLocationComponent } from './current-location.component';
import { FileNotFoundSearchComponent } from './search/file-not-found-search.component';
import { LiveExampleComponent, EmbeddedPlunkerComponent } from './live-example/live-example.component';
import { LiveExampleComponent, EmbeddedStackblitzComponent } from './live-example/live-example.component';
import { ResourceListComponent } from './resource/resource-list.component';
import { ResourceService } from './resource/resource.service';
@ -50,7 +50,7 @@ export const embeddedComponents: Type<any>[] = [
embeddedComponents,
CodeComponent,
ContributorComponent,
EmbeddedPlunkerComponent
EmbeddedStackblitzComponent
],
providers: [
ApiService,

View File

@ -1,10 +1,9 @@
<span [ngSwitch]="mode">
<span *ngSwitchCase="'disabled'">{{title}} <em>(not available on this device)</em></span>
<span *ngSwitchCase="'embedded'">
<div *ngIf="showEmbedded" title="{{title}}">
<aio-embedded-plunker [src]="plnkr"></aio-embedded-plunker>
<div title="{{title}}">
<aio-embedded-stackblitz [src]="stackblitz"></aio-embedded-stackblitz>
</div>
<img *ngIf="!showEmbedded" (click)="toggleEmbedded()" [src]="plnkrImg" alt="{{title}}">
<p *ngIf="enableDownload">
You can also <a [href]="zip" download title="Download example">download this example</a>.
</p>
@ -13,7 +12,7 @@
<a [href]="zip" download title="{{title}}">{{title}}</a>
</span>
<span *ngSwitchDefault>
<a [href]="plnkr" target="_blank" title="{{title}}">{{title}}</a>
<a [href]="stackblitz" target="_blank" title="{{title}}">{{title}}</a>
<span *ngIf="enableDownload">
/ <a [href]="zip" download title="Download example">download example</a>
</span>

View File

@ -3,12 +3,11 @@ import { By } from '@angular/platform-browser';
import { Component, DebugElement } from '@angular/core';
import { Location } from '@angular/common';
import { LiveExampleComponent, EmbeddedPlunkerComponent } from './live-example.component';
import { LiveExampleComponent, EmbeddedStackblitzComponent } from './live-example.component';
const defaultTestPath = '/test';
describe('LiveExampleComponent', () => {
let hostComponent: HostComponent;
let liveExampleDe: DebugElement;
let liveExampleComponent: LiveExampleComponent;
let fixture: ComponentFixture<HostComponent>;
@ -39,7 +38,6 @@ describe('LiveExampleComponent', () => {
function testComponent(testFn: () => void) {
fixture = TestBed.createComponent(HostComponent);
hostComponent = fixture.componentInstance;
liveExampleDe = fixture.debugElement.children[0];
liveExampleComponent = liveExampleDe.componentInstance;
@ -57,13 +55,13 @@ describe('LiveExampleComponent', () => {
//////// tests ////////
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [ HostComponent, LiveExampleComponent, EmbeddedPlunkerComponent ],
declarations: [ HostComponent, LiveExampleComponent, EmbeddedStackblitzComponent ],
providers: [
{ provide: Location, useClass: TestLocation }
]
})
// Disable the <iframe> within the EmbeddedPlunkerComponent
.overrideComponent(EmbeddedPlunkerComponent, {set: {template: 'NO IFRAME'}});
// Disable the <iframe> within the EmbeddedStackblitzComponent
.overrideComponent(EmbeddedStackblitzComponent, {set: {template: 'NO IFRAME'}});
testPath = defaultTestPath;
liveExampleContent = null;
@ -78,68 +76,68 @@ describe('LiveExampleComponent', () => {
});
});
it('should have expected plunker & download hrefs', () => {
it('should have expected stackblitz & download hrefs', () => {
testPath = '/tutorial/toh-pt1';
testComponent(() => {
const hrefs = getHrefs();
expect(hrefs[0]).toContain('/toh-pt1/eplnkr.html');
expect(hrefs[0]).toContain('/toh-pt1/stackblitz.html');
expect(hrefs[1]).toContain('/toh-pt1/toh-pt1.zip');
});
});
it('should have expected plunker & download hrefs even when path has # frag', () => {
it('should have expected stackblitz & download hrefs even when path has # frag', () => {
testPath = '/tutorial/toh-pt1#somewhere';
testComponent(() => {
const hrefs = getHrefs();
expect(hrefs[0]).toContain('/toh-pt1/eplnkr.html');
expect(hrefs[0]).toContain('/toh-pt1/stackblitz.html');
expect(hrefs[1]).toContain('/toh-pt1/toh-pt1.zip');
});
});
it('should have expected plunker & download hrefs even when path has ? params', () => {
it('should have expected stackblitz & download hrefs even when path has ? params', () => {
testPath = '/tutorial/toh-pt1?foo=1&bar="bar"';
testComponent(() => {
const hrefs = getHrefs();
expect(hrefs[0]).toContain('/toh-pt1/eplnkr.html');
expect(hrefs[0]).toContain('/toh-pt1/stackblitz.html');
expect(hrefs[1]).toContain('/toh-pt1/toh-pt1.zip');
});
});
it('should have expected flat-style plunker when has `flat-style`', () => {
it('should have expected flat-style stackblitz when has `flat-style`', () => {
testPath = '/tutorial/toh-pt1';
setHostTemplate('<live-example flat-style></live-example>');
testComponent(() => {
// The file should be "plnkr.html", not "eplnkr.html"
expect(getLiveExampleAnchor().href).toContain('/plnkr.html');
// The file should be "stackblitz.html", not "stackblitz.html"
expect(getLiveExampleAnchor().href).toContain('/stackblitz.html');
});
});
it('should have expected plunker & download hrefs when has example directory (name)', () => {
it('should have expected stackblitz & download hrefs when has example directory (name)', () => {
testPath = '/guide/somewhere';
setHostTemplate('<live-example name="toh-pt1"></live-example>');
testComponent(() => {
const hrefs = getHrefs();
expect(hrefs[0]).toContain('/toh-pt1/eplnkr.html');
expect(hrefs[0]).toContain('/toh-pt1/stackblitz.html');
expect(hrefs[1]).toContain('/toh-pt1/toh-pt1.zip');
});
});
it('should have expected plunker & download hrefs when has `plnkr`', () => {
it('should have expected stackblitz & download hrefs when has `stackblitz`', () => {
testPath = '/testing';
setHostTemplate('<live-example plnkr="app-specs"></live-example>');
setHostTemplate('<live-example stackblitz="app-specs"></live-example>');
testComponent(() => {
const hrefs = getHrefs();
expect(hrefs[0]).toContain('/testing/app-specs.eplnkr.html');
expect(hrefs[0]).toContain('/testing/app-specs.stackblitz.html');
expect(hrefs[1]).toContain('/testing/app-specs.testing.zip');
});
});
it('should have expected plunker & download hrefs when has `name` & `plnkr`', () => {
it('should have expected stackblitz & download hrefs when has `name` & `stackblitz`', () => {
testPath = '/guide/somewhere';
setHostTemplate('<live-example name="testing" plnkr="app-specs"></live-example>');
setHostTemplate('<live-example name="testing" stackblitz="app-specs"></live-example>');
testComponent(() => {
const hrefs = getHrefs();
expect(hrefs[0]).toContain('/testing/app-specs.eplnkr.html');
expect(hrefs[0]).toContain('/testing/app-specs.stackblitz.html');
expect(hrefs[1]).toContain('/testing/app-specs.testing.zip');
});
});
@ -148,7 +146,7 @@ describe('LiveExampleComponent', () => {
setHostTemplate('<live-example></live-example>');
testComponent(() => {
const hrefs = getHrefs();
expect(hrefs[0]).toContain(defaultTestPath + '/eplnkr.html');
expect(hrefs[0]).toContain(defaultTestPath + '/stackblitz.html');
});
});
@ -156,7 +154,7 @@ describe('LiveExampleComponent', () => {
setHostTemplate('<live-example flat-style></live-example>');
testComponent(() => {
const hrefs = getHrefs();
expect(hrefs[0]).toContain(defaultTestPath + '/plnkr.html');
expect(hrefs[0]).toContain(defaultTestPath + '/stackblitz.html');
});
});
@ -164,8 +162,8 @@ describe('LiveExampleComponent', () => {
setHostTemplate('<live-example noDownload></live-example>');
testComponent(() => {
const hrefs = getHrefs();
expect(hrefs.length).toBe(1, 'only the plunker live-example anchor');
expect(hrefs[0]).toContain('plnkr.html');
expect(hrefs.length).toBe(1, 'only the stackblitz live-example anchor');
expect(hrefs[0]).toContain('stackblitz.html');
});
});
@ -211,7 +209,7 @@ describe('LiveExampleComponent', () => {
setHostTemplate('<live-example name="testing/ts"></live-example>');
testComponent(() => {
const hrefs = getHrefs();
expect(hrefs[0]).toContain('/testing/ts/eplnkr.html');
expect(hrefs[0]).toContain('/testing/ts/stackblitz.html');
expect(hrefs[1]).toContain('/testing/ts/testing.zip');
});
});
@ -224,77 +222,33 @@ describe('LiveExampleComponent', () => {
return anchor && anchor.nativeElement as HTMLAnchorElement;
}
function getEmbeddedPlunkerComponent() {
const compDe = liveExampleDe.query(By.directive(EmbeddedPlunkerComponent));
return compDe && compDe.componentInstance as EmbeddedPlunkerComponent;
function getEmbeddedStackblitzComponent() {
const compDe = liveExampleDe.query(By.directive(EmbeddedStackblitzComponent));
return compDe && compDe.componentInstance as EmbeddedStackblitzComponent;
}
function getImg() {
const img = liveExampleDe.query(By.css('img'));
return img && img.nativeElement as HTMLImageElement;
}
describe('before click', () => {
it('should have hidden, embedded plunker', () => {
setHostTemplate('<live-example embedded></live-example>');
testComponent(() => {
expect(liveExampleComponent.mode).toBe('embedded', 'component is embedded');
expect(liveExampleComponent.showEmbedded).toBe(false, 'component.showEmbedded');
expect(getEmbeddedPlunkerComponent()).toBeNull('no EmbeddedPlunkerComponent');
});
it('should have hidden, embedded stackblitz', () => {
setHostTemplate('<live-example embedded></live-example>');
testComponent(() => {
expect(liveExampleComponent.mode).toBe('embedded', 'component is embedded');
expect(getEmbeddedStackblitzComponent()).toBeTruthy('EmbeddedStackblitzComponent');
});
it('should have default plunker placeholder image', () => {
setHostTemplate('<live-example embedded></live-example>');
testComponent(() => {
expect(getImg().src).toContain('plunker/placeholder.png');
});
});
it('should have specified plunker placeholder image', () => {
const expectedSrc = 'example/demo.png';
setHostTemplate(`<live-example embedded img="${expectedSrc}"></live-example>`);
testComponent(() => {
expect(getImg().src).toContain(expectedSrc);
});
});
it('should have download paragraph with expected anchor href', () => {
testPath = '/tutorial/toh-pt1';
setHostTemplate('<live-example embedded></live-example>');
testComponent(() => {
expect(getDownloadAnchor().href).toContain('/toh-pt1/toh-pt1.zip');
});
});
it('should not have download paragraph when has `nodownload`', () => {
testPath = '/tutorial/toh-pt1';
setHostTemplate('<live-example embedded nodownload></live-example>');
testComponent(() => {
expect(getDownloadAnchor()).toBeNull();
});
});
});
describe('after click', () => {
function clickImg() {
getImg().click();
fixture.detectChanges();
}
it('should show plunker in the page', () => {
setHostTemplate('<live-example embedded></live-example>');
testComponent(() => {
clickImg();
expect(liveExampleComponent.mode).toBe('embedded', 'component is embedded');
expect(liveExampleComponent.showEmbedded).toBe(true, 'component.showEmbedded');
expect(getEmbeddedPlunkerComponent()).toBeDefined('has EmbeddedPlunkerComponent');
});
it('should have download paragraph with expected anchor href', () => {
testPath = '/tutorial/toh-pt1';
setHostTemplate('<live-example embedded></live-example>');
testComponent(() => {
expect(getDownloadAnchor().href).toContain('/toh-pt1/toh-pt1.zip');
});
});
it('should not have download paragraph when has `nodownload`', () => {
testPath = '/tutorial/toh-pt1';
setHostTemplate('<live-example embedded nodownload></live-example>');
testComponent(() => {
expect(getDownloadAnchor()).toBeNull();
});
});
});
@ -306,7 +260,7 @@ describe('LiveExampleComponent', () => {
liveExampleComponent.onResize(600); // narrow
fixture.detectChanges();
const hrefs = getHrefs();
expect(hrefs[0]).toContain(defaultTestPath + '/eplnkr.html');
expect(hrefs[0]).toContain(defaultTestPath + '/stackblitz.html');
});
});
@ -316,7 +270,7 @@ describe('LiveExampleComponent', () => {
liveExampleComponent.onResize(600); // narrow
fixture.detectChanges();
const hrefs = getHrefs();
expect(hrefs[0]).toContain(defaultTestPath + '/eplnkr.html');
expect(hrefs[0]).toContain(defaultTestPath + '/stackblitz.html');
});
});
});

View File

@ -5,8 +5,6 @@ import { CONTENT_URL_PREFIX } from 'app/documents/document.service';
import { boolFromValue, getAttrs, getAttrValue } from 'app/shared/attribute-utils';
const defaultPlnkrImg = 'plunker/placeholder.png';
const imageBase = CONTENT_URL_PREFIX + 'images/';
const liveExampleBase = CONTENT_URL_PREFIX + 'live-examples/';
const zipBase = CONTENT_URL_PREFIX + 'zips/';
@ -19,49 +17,38 @@ const zipBase = CONTENT_URL_PREFIX + 'zips/';
*
* Usage:
* <live-example
* [name="..."] // name of the example directory
* [plnkr="...""] // name of the plunker file (becomes part of zip file name as well)
* [embedded] // embed the plunker in the doc page, else display in new browser tab (default)
* [img="..."] // image to display if embedded in doc page
* [embedded-style] // show plnkr in embedded style (default and on narrow screens)
* [flat-style] // show plnkr in flat (original) style
* [noDownload] // no downloadable zip option
* [downloadOnly] // just the zip
* [title="..."]> // text for live example link and tooltip
* text // higher precedence way to specify text for live example link and tooltip
* [name="..."] // name of the example directory
* [stackblitz="...""] // name of the stackblitz file (becomes part of zip file name as well)
* [embedded] // embed the stackblitz in the doc page, else display in new browser tab (default)
* [noDownload] // no downloadable zip option
* [downloadOnly] // just the zip
* [title="..."]> // text for live example link and tooltip
* text // higher precedence way to specify text for live example link and tooltip
* </live-example>
* Example:
* <p>Run <live-example>Try the live example</live-example></p>.
* // ~/resources/live-examples/{page}/plnkr.html
* // ~/resources/live-examples/{page}/stackblitz.json
*
* <p>Run <live-example name="toh-pt1">this example</live-example></p>.
* // ~/resources/live-examples/toh-pt1/plnkr.html
* // ~/resources/live-examples/toh-pt1/stackblitz.json
*
* // Link to the default plunker in the toh-pt1 sample
* // Link to the default stackblitz in the toh-pt1 sample
* // The title overrides default ("live example") with "Tour of Heroes - Part 1"
* <p>Run <live-example name="toh-pt1" title="Tour of Heroes - Part 1"></live-example></p>.
* // ~/resources/live-examples/toh-pt1/plnkr.html
* // ~/resources/live-examples/toh-pt1/stackblitz.json
*
* <p>Run <live-example plnkr="minimal"></live-example></p>.
* // ~/resources/live-examples/{page}/minimal.plnkr.html
* <p>Run <live-example stackblitz="minimal"></live-example></p>.
* // ~/resources/live-examples/{page}/minimal.stackblitz.json
*
* // Embed the current page's default plunker
* // Embed the current page's default stackblitz
* // Text within tag is "live example"
* // No title (no tooltip)
* <live-example embedded title=""></live-example>
* // ~/resources/live-examples/{page}/eplnkr.html
* // ~/resources/live-examples/{page}/stackblitz.json
*
* // Links to a *new* browser tab as an embedded style plunker editor
* <live-example embedded-style>this example</live-example>
* // ~/resources/live-examples/{page}/eplnkr.html
*
* // Links to a *new* browser tab in the flat (original editor) style plunker editor
* <live-example flat-style>this example</live-example>
* // ~/resources/live-examples/{page}/plnkr.html
*
* // Displays within the document page as an embedded style plunker editor
* <live-example name="toh-pt1" embedded plnkr="minimal" img="toh>Tour of Heroes - Part 1</live-example>
* // ~/resources/live-examples/toh-pt1/minimal.eplnkr.html
* // Displays within the document page as an embedded style stackblitz editor
* <live-example name="toh-pt1" embedded stackblitz="minimal">Tour of Heroes - Part 1</live-example>
* // ~/resources/live-examples/toh-pt1/minimal.stackblitz.json
*/
@Component({
selector: 'live-example',
@ -78,10 +65,8 @@ export class LiveExampleComponent implements OnInit {
exampleDir: string;
isEmbedded = false;
mode = 'disabled';
plnkr: string;
plnkrName: string;
plnkrImg: string;
showEmbedded = false;
stackblitz: string;
stackblitzName: string;
title: string;
zip: string;
zipName: string;
@ -98,46 +83,32 @@ export class LiveExampleComponent implements OnInit {
}
this.exampleDir = exampleDir.trim();
this.zipName = exampleDir.indexOf('/') === -1 ? this.exampleDir : exampleDir.split('/')[0];
this.plnkrName = attrs.plnkr ? attrs.plnkr.trim() + '.' : '';
this.zip = `${zipBase}${exampleDir}/${this.plnkrName}${this.zipName}.zip`;
this.stackblitzName = attrs.stackblitz ? attrs.stackblitz.trim() + '.' : '';
this.zip = `${zipBase}${exampleDir}/${this.stackblitzName}${this.zipName}.zip`;
this.enableDownload = !boolFromValue(getAttrValue(attrs, 'nodownload'));
this.plnkrImg = imageBase + (attrs.img || defaultPlnkrImg);
if (boolFromValue(getAttrValue(attrs, 'downloadonly'))) {
this.mode = 'downloadOnly';
}
}
calcPlnkrLink(width: number) {
calcStackblitzLink(width: number) {
const attrs = this.attrs;
const exampleDir = this.exampleDir;
let urlQuery = '';
let plnkrStyle = 'eplnkr'; // embedded style by default
this.mode = 'default'; // display in another browser tab by default
this.isEmbedded = boolFromValue(attrs.embedded);
if (this.isEmbedded) {
this.mode = 'embedded'; // display embedded in the doc
} else {
// Not embedded in doc page; determine if is embedded- or flat-style in another browser tab.
// Embedded style if on tiny screen (reg. plunker no good on narrow screen)
// If wide enough, choose style based on style attributes
if (width > this.narrowWidth) {
// Make flat style with `flat-style` or `embedded-style="false`; support atty aliases
const flatStyle = getAttrValue(attrs, ['flat-style', 'flatstyle']);
const isFlatStyle = boolFromValue(flatStyle);
const embeddedStyle = getAttrValue(attrs, ['embedded-style', 'embeddedstyle']);
const isEmbeddedStyle = boolFromValue(embeddedStyle, !isFlatStyle);
plnkrStyle = isEmbeddedStyle ? 'eplnkr' : 'plnkr';
}
urlQuery = '?ctl=1';
}
this.plnkr = `${liveExampleBase}${exampleDir}/${this.plnkrName}${plnkrStyle}.html`;
this.stackblitz = `${liveExampleBase}${exampleDir}/${this.stackblitzName}stackblitz.html${urlQuery}`;
}
ngOnInit() {
@ -152,31 +123,29 @@ export class LiveExampleComponent implements OnInit {
@HostListener('window:resize', ['$event.target.innerWidth'])
onResize(width: number) {
if (this.mode !== 'downloadOnly') {
this.calcPlnkrLink(width);
this.calcStackblitzLink(width);
}
}
toggleEmbedded () { this.showEmbedded = !this.showEmbedded; }
}
///// EmbeddedPlunkerComponent ///
///// EmbeddedStackblitzComponent ///
/**
* Hides the <iframe> so we can test LiveExampleComponent without actually triggering
* a call to plunker to load the iframe
* a call to stackblitz to load the iframe
*/
@Component({
selector: 'aio-embedded-plunker',
selector: 'aio-embedded-stackblitz',
template: `<iframe #iframe frameborder="0" width="100%" height="100%"></iframe>`,
styles: [ 'iframe { min-height: 400px; }']
})
export class EmbeddedPlunkerComponent implements AfterViewInit {
export class EmbeddedStackblitzComponent 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';
// 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

View File

@ -44,14 +44,13 @@ runnable project packaged as a zip file. These zip files are generated by the ut
See the [README.md](example-zipper/README.md) for more details.
## plunker-builder
## stackblitz-builder
In the AIO application, we can embed a running version of the example as a [Plunker](http://plnkr.co/).
We can also provide a link to create a runnable version of the example in the [Plunker](http://plnkr.co/edit)
In the AIO application, we can embed a running version of the example as a [Stackblitz](https://stackblitz.com/) session.
We can also provide a link to create a runnable version of the example in the [Stackblitz](https://stackblitz.com/)
editor.
This folder contains three utilities: `regularPlunker.js`, `embeddedPlunker.js`, `generatePlunkers.js`.
See the [README.md](plunker-builder/README.md) for more details.
See the [README.md](stackblitz-builder/README.md) for more details.
## transforms

View File

@ -14,6 +14,11 @@ There, select all the packages that are updated on the new Angular release.
**2)** Changes to the tsconfig.json? There is one to update at `/aio/tools/examples/shared/boilerplate/src/tsconfig.json`
**3)** The file `/aio/tools/examples/shared/boilerplate/src/systemjs.config.web.js` contains the configuration for plunkers. It has some hardcoded versions that could be updated.
**3)** The file `/aio/tools/examples/shared/boilerplate/src/systemjs.config.web.js` contains the configuration for plunkers. It has some hardcoded versions that could be updated.
>N.B.: Plunkers have been replaced by Stackblitz and (almost) all examples have be replaced by CLI/WebPack-based examples that do not use SystemJS.
The upgrade examples may still rely on SystemJS.
**4)** As in step 3, more hardcoded versions at `/aio/tools/plunker-builder/translator/rules/indexHtml.js`
>Note the same caveat about migration from plunker to Stackblitz.

Some files were not shown because too many files have changed in this diff Show More