├── hello-mobile
├── public
│ └── .npmignore
├── src
│ ├── app
│ │ ├── shared
│ │ │ └── index.ts
│ │ ├── index.ts
│ │ ├── environment.ts
│ │ ├── hello-mobile.component.spec.ts
│ │ └── hello-mobile.component.ts
│ ├── typings.d.ts
│ ├── system-import.js
│ ├── favicon.ico
│ ├── icons
│ │ ├── icon.png
│ │ ├── favicon-16x16.png
│ │ ├── favicon-32x32.png
│ │ ├── favicon-96x96.png
│ │ ├── mstile-70x70.png
│ │ ├── mstile-144x144.png
│ │ ├── mstile-150x150.png
│ │ ├── mstile-310x150.png
│ │ ├── mstile-310x310.png
│ │ ├── apple-touch-icon.png
│ │ ├── android-chrome-36x36.png
│ │ ├── android-chrome-48x48.png
│ │ ├── android-chrome-72x72.png
│ │ ├── android-chrome-96x96.png
│ │ ├── android-chrome-144x144.png
│ │ ├── android-chrome-192x192.png
│ │ ├── apple-touch-icon-57x57.png
│ │ ├── apple-touch-icon-60x60.png
│ │ ├── apple-touch-icon-72x72.png
│ │ ├── apple-touch-icon-76x76.png
│ │ ├── apple-touch-icon-114x114.png
│ │ ├── apple-touch-icon-120x120.png
│ │ ├── apple-touch-icon-144x144.png
│ │ ├── apple-touch-icon-152x152.png
│ │ ├── apple-touch-icon-180x180.png
│ │ ├── apple-touch-icon-precomposed.png
│ │ └── safari-pinned-tab.svg
│ ├── main.ts
│ ├── main-app-shell.ts
│ ├── manifest.webapp
│ ├── index.html
│ └── system-config.ts
├── e2e
│ ├── typings.d.ts
│ ├── app.po.ts
│ ├── app.e2e.ts
│ └── tsconfig.json
├── config
│ ├── environment.dev.ts
│ ├── environment.prod.ts
│ ├── environment.js
│ ├── protractor.conf.js
│ ├── karma-test-shim.js
│ └── karma.conf.js
├── .clang-format
├── README.md
├── .editorconfig
├── typings.json
├── .gitignore
├── angular-cli-build.js
├── angular-cli.json
├── package.json
└── tslint.json
├── app-shell
├── src
│ ├── index.ts
│ ├── experimental
│ │ └── shell-parser
│ │ │ ├── ast
│ │ │ ├── index.ts
│ │ │ └── ast-node.ts
│ │ │ ├── node-matcher
│ │ │ ├── css-selector
│ │ │ │ ├── index.ts
│ │ │ │ ├── css-selector.ts
│ │ │ │ └── css-selector.spec.ts
│ │ │ ├── index.ts
│ │ │ ├── node-matcher.ts
│ │ │ ├── css-node-matcher.ts
│ │ │ └── css-node-matcher.spec.ts
│ │ │ ├── template-parser
│ │ │ ├── index.ts
│ │ │ ├── template-parser.ts
│ │ │ └── parse5
│ │ │ │ ├── parse5-template-parser.ts
│ │ │ │ ├── tokenizer-case-sensitivity-patch.spec.ts
│ │ │ │ ├── drop-named-entities-patch.spec.ts
│ │ │ │ ├── tokenizer-case-sensitivity-patch.ts
│ │ │ │ ├── parse5-template-parser.spec.ts
│ │ │ │ └── drop-named-entities-patch.ts
│ │ │ ├── testing
│ │ │ ├── index.ts
│ │ │ ├── context-mock.ts
│ │ │ ├── mock-requests.ts
│ │ │ └── mock-caches.ts
│ │ │ ├── node-visitor
│ │ │ ├── index.ts
│ │ │ ├── resource-inline
│ │ │ │ ├── index.ts
│ │ │ │ ├── stylesheet-resource-inline-visitor.ts
│ │ │ │ ├── inline-style-resource-inline-visitor.ts
│ │ │ │ ├── resource-inline-visitor.ts
│ │ │ │ ├── inline-style-resource-inline-visitor.spec.ts
│ │ │ │ └── stylesheet-resource-inline-visitor.spec.ts
│ │ │ ├── node-visitor.ts
│ │ │ ├── template-strip-visitor.ts
│ │ │ └── template-strip-visitor.spec.ts
│ │ │ ├── index.ts
│ │ │ ├── context.ts
│ │ │ ├── config.ts
│ │ │ ├── shell-parser-factory.ts
│ │ │ └── shell-parser.ts
│ ├── app
│ │ ├── index.ts
│ │ ├── prerender.ts
│ │ ├── prerender.spec.ts
│ │ ├── module.ts
│ │ ├── shell.ts
│ │ └── shell.spec.ts
│ └── unit_tests.ts
├── .clang-format
├── .vscode
│ └── settings.json
├── .editorconfig
├── tsconfig.json
├── .gitignore
├── tsconfig.es5.json
├── tsconfig.esm.json
├── package.json
├── tslint.json
├── README.md
└── gulpfile.ts
├── service-worker
├── worker
│ ├── src
│ │ ├── index.ts
│ │ ├── test
│ │ │ ├── e2e
│ │ │ │ ├── harness
│ │ │ │ │ ├── client
│ │ │ │ │ │ ├── debug
│ │ │ │ │ │ │ ├── hello.txt
│ │ │ │ │ │ │ ├── full.txt
│ │ │ │ │ │ │ ├── ngsw-manifest.json.js
│ │ │ │ │ │ │ └── ngsw-manifest.json
│ │ │ │ │ │ ├── manifest.webapp
│ │ │ │ │ │ ├── main.ts
│ │ │ │ │ │ └── index.html
│ │ │ │ │ └── server
│ │ │ │ │ │ ├── push.ts
│ │ │ │ │ │ ├── server.ts
│ │ │ │ │ │ └── page-object.ts
│ │ │ │ └── spec
│ │ │ │ │ └── protractor.config.js
│ │ │ └── webpack
│ │ │ │ ├── ignored.js
│ │ │ │ ├── other.js
│ │ │ │ ├── index.js
│ │ │ │ └── ngsw-manifest.json
│ │ ├── build
│ │ │ ├── index.ts
│ │ │ ├── assets
│ │ │ │ ├── register-basic.js
│ │ │ │ └── register-basic.min.js
│ │ │ ├── gulp.ts
│ │ │ └── webpack.ts
│ │ ├── testing
│ │ │ ├── index.ts
│ │ │ └── mock.spec.ts
│ │ ├── webpack.ts
│ │ ├── companion
│ │ │ ├── index.ts
│ │ │ └── module.ts
│ │ ├── typings
│ │ │ ├── jshashes.d.ts
│ │ │ └── service-worker.d.ts
│ │ ├── worker
│ │ │ ├── facade
│ │ │ │ ├── index.ts
│ │ │ │ ├── adapter.ts
│ │ │ │ ├── events.ts
│ │ │ │ ├── cache.ts
│ │ │ │ └── fetch.ts
│ │ │ ├── index.ts
│ │ │ ├── manifest.ts
│ │ │ ├── builds
│ │ │ │ ├── basic.ts
│ │ │ │ └── test.ts
│ │ │ ├── url.ts
│ │ │ ├── cache.ts
│ │ │ ├── api.ts
│ │ │ ├── bootstrap.ts
│ │ │ ├── logging.ts
│ │ │ ├── common.ts
│ │ │ └── worker.ts
│ │ └── plugins
│ │ │ ├── dynamic
│ │ │ ├── index.ts
│ │ │ ├── manifest.ts
│ │ │ ├── strategy
│ │ │ │ ├── performance.ts
│ │ │ │ └── freshness.ts
│ │ │ ├── linked.spec.ts
│ │ │ └── dynamic.ts
│ │ │ ├── external
│ │ │ └── index.ts
│ │ │ ├── push
│ │ │ └── index.ts
│ │ │ ├── routes
│ │ │ └── index.ts
│ │ │ └── static
│ │ │ └── index.ts
│ ├── .gitignore
│ ├── .npmignore
│ ├── .vscode
│ │ └── settings.json
│ ├── tsconfig.json
│ ├── tsconfig.esm.json
│ ├── tsconfig.es5.json
│ └── package.json
└── example
│ ├── typings.json
│ ├── webroot
│ ├── manifest.appcache
│ └── index.html
│ ├── gulpfile.js
│ ├── tsconfig.json
│ ├── src
│ └── index.html
│ ├── package.json
│ └── gulpfile.ts
├── test.sh
├── guides
├── img
│ ├── app-shell-spinner.png
│ └── app-shell-pre-bootstrap.png
├── cli-setup.md
├── service-worker.md
└── web-app-manifest.md
├── install.sh
├── .travis.yml
├── README.md
├── .gitignore
├── LICENSE
└── ROADMAP.md
/hello-mobile/public/.npmignore:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/hello-mobile/src/app/shared/index.ts:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app-shell/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './app';
2 |
--------------------------------------------------------------------------------
/service-worker/worker/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './companion';
--------------------------------------------------------------------------------
/service-worker/worker/src/test/e2e/harness/client/debug/hello.txt:
--------------------------------------------------------------------------------
1 | Hello world!
--------------------------------------------------------------------------------
/hello-mobile/e2e/typings.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/service-worker/worker/src/test/e2e/harness/client/debug/full.txt:
--------------------------------------------------------------------------------
1 | This is full text.
--------------------------------------------------------------------------------
/hello-mobile/src/typings.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
3 |
--------------------------------------------------------------------------------
/service-worker/worker/src/test/webpack/ignored.js:
--------------------------------------------------------------------------------
1 | console.log('i should not make it');
--------------------------------------------------------------------------------
/app-shell/src/experimental/shell-parser/ast/index.ts:
--------------------------------------------------------------------------------
1 | export * from './ast-node';
2 |
3 |
--------------------------------------------------------------------------------
/service-worker/worker/.gitignore:
--------------------------------------------------------------------------------
1 | dist/
2 | node_modules/
3 | /typings
4 | /ngsw-config.json
5 |
--------------------------------------------------------------------------------
/hello-mobile/config/environment.dev.ts:
--------------------------------------------------------------------------------
1 | export const environment = {
2 | production: false
3 | };
4 |
--------------------------------------------------------------------------------
/hello-mobile/config/environment.prod.ts:
--------------------------------------------------------------------------------
1 | export const environment = {
2 | production: true
3 | };
4 |
--------------------------------------------------------------------------------
/hello-mobile/src/system-import.js:
--------------------------------------------------------------------------------
1 | System.import('main')
2 | .catch(console.error.bind(console));
3 |
--------------------------------------------------------------------------------
/service-worker/worker/src/build/index.ts:
--------------------------------------------------------------------------------
1 | export * from './gulp';
2 | export * from './webpack';
3 |
--------------------------------------------------------------------------------
/service-worker/worker/src/test/e2e/harness/client/debug/ngsw-manifest.json.js:
--------------------------------------------------------------------------------
1 | /* needed for SW to run */
--------------------------------------------------------------------------------
/service-worker/worker/src/testing/index.ts:
--------------------------------------------------------------------------------
1 | export * from './mock';
2 | export * from './mock_cache';
--------------------------------------------------------------------------------
/app-shell/.clang-format:
--------------------------------------------------------------------------------
1 | Language: JavaScript
2 | BasedOnStyle: Google
3 | ColumnLimit: 100
4 |
--------------------------------------------------------------------------------
/test.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | cd ./service-worker/worker
3 | gulp test
4 | cd ../../app-shell
5 | gulp test
6 |
--------------------------------------------------------------------------------
/hello-mobile/.clang-format:
--------------------------------------------------------------------------------
1 | Language: JavaScript
2 | BasedOnStyle: Google
3 | ColumnLimit: 100
4 |
--------------------------------------------------------------------------------
/service-worker/worker/.npmignore:
--------------------------------------------------------------------------------
1 | build/
2 | node_modules/
3 | typings/
4 | dist/src/
5 | /ngsw-config.json
6 |
--------------------------------------------------------------------------------
/service-worker/worker/src/test/webpack/other.js:
--------------------------------------------------------------------------------
1 | // This is another file.
2 | console.log('this is another file');
--------------------------------------------------------------------------------
/app-shell/src/app/index.ts:
--------------------------------------------------------------------------------
1 | export * from './module';
2 | export * from './prerender';
3 | export * from './shell';
4 |
--------------------------------------------------------------------------------
/app-shell/src/experimental/shell-parser/node-matcher/css-selector/index.ts:
--------------------------------------------------------------------------------
1 | export * from './css-selector';
2 |
3 |
--------------------------------------------------------------------------------
/hello-mobile/src/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/mobile-toolkit/HEAD/hello-mobile/src/favicon.ico
--------------------------------------------------------------------------------
/guides/img/app-shell-spinner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/mobile-toolkit/HEAD/guides/img/app-shell-spinner.png
--------------------------------------------------------------------------------
/hello-mobile/src/icons/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/mobile-toolkit/HEAD/hello-mobile/src/icons/icon.png
--------------------------------------------------------------------------------
/service-worker/worker/src/test/webpack/index.js:
--------------------------------------------------------------------------------
1 | // This is a test.
2 | require('./other');
3 |
4 | console.log('testing');
--------------------------------------------------------------------------------
/guides/img/app-shell-pre-bootstrap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/mobile-toolkit/HEAD/guides/img/app-shell-pre-bootstrap.png
--------------------------------------------------------------------------------
/hello-mobile/src/icons/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/mobile-toolkit/HEAD/hello-mobile/src/icons/favicon-16x16.png
--------------------------------------------------------------------------------
/hello-mobile/src/icons/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/mobile-toolkit/HEAD/hello-mobile/src/icons/favicon-32x32.png
--------------------------------------------------------------------------------
/hello-mobile/src/icons/favicon-96x96.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/mobile-toolkit/HEAD/hello-mobile/src/icons/favicon-96x96.png
--------------------------------------------------------------------------------
/hello-mobile/src/icons/mstile-70x70.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/mobile-toolkit/HEAD/hello-mobile/src/icons/mstile-70x70.png
--------------------------------------------------------------------------------
/hello-mobile/src/icons/mstile-144x144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/mobile-toolkit/HEAD/hello-mobile/src/icons/mstile-144x144.png
--------------------------------------------------------------------------------
/hello-mobile/src/icons/mstile-150x150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/mobile-toolkit/HEAD/hello-mobile/src/icons/mstile-150x150.png
--------------------------------------------------------------------------------
/hello-mobile/src/icons/mstile-310x150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/mobile-toolkit/HEAD/hello-mobile/src/icons/mstile-310x150.png
--------------------------------------------------------------------------------
/hello-mobile/src/icons/mstile-310x310.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/mobile-toolkit/HEAD/hello-mobile/src/icons/mstile-310x310.png
--------------------------------------------------------------------------------
/service-worker/worker/src/test/webpack/ngsw-manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "other": true,
3 | "static.ignore": [
4 | "^\/test\/ig.*$"
5 | ]
6 | }
--------------------------------------------------------------------------------
/service-worker/worker/src/webpack.ts:
--------------------------------------------------------------------------------
1 | import {AngularServiceWorkerPlugin} from './build';
2 | export default AngularServiceWorkerPlugin;
3 |
--------------------------------------------------------------------------------
/app-shell/src/app/prerender.ts:
--------------------------------------------------------------------------------
1 | import {OpaqueToken} from '@angular/core';
2 |
3 | export const IS_PRERENDER = new OpaqueToken('IsPrerender');
4 |
--------------------------------------------------------------------------------
/hello-mobile/src/app/index.ts:
--------------------------------------------------------------------------------
1 | export {environment} from './environment';
2 | export {HelloMobileAppComponent} from './hello-mobile.component';
3 |
--------------------------------------------------------------------------------
/hello-mobile/src/icons/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/mobile-toolkit/HEAD/hello-mobile/src/icons/apple-touch-icon.png
--------------------------------------------------------------------------------
/service-worker/example/typings.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@angular/service-worker-example",
3 | "version": false,
4 | "dependencies": {}
5 | }
6 |
--------------------------------------------------------------------------------
/hello-mobile/src/icons/android-chrome-36x36.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/mobile-toolkit/HEAD/hello-mobile/src/icons/android-chrome-36x36.png
--------------------------------------------------------------------------------
/hello-mobile/src/icons/android-chrome-48x48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/mobile-toolkit/HEAD/hello-mobile/src/icons/android-chrome-48x48.png
--------------------------------------------------------------------------------
/hello-mobile/src/icons/android-chrome-72x72.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/mobile-toolkit/HEAD/hello-mobile/src/icons/android-chrome-72x72.png
--------------------------------------------------------------------------------
/hello-mobile/src/icons/android-chrome-96x96.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/mobile-toolkit/HEAD/hello-mobile/src/icons/android-chrome-96x96.png
--------------------------------------------------------------------------------
/hello-mobile/src/icons/android-chrome-144x144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/mobile-toolkit/HEAD/hello-mobile/src/icons/android-chrome-144x144.png
--------------------------------------------------------------------------------
/hello-mobile/src/icons/android-chrome-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/mobile-toolkit/HEAD/hello-mobile/src/icons/android-chrome-192x192.png
--------------------------------------------------------------------------------
/hello-mobile/src/icons/apple-touch-icon-57x57.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/mobile-toolkit/HEAD/hello-mobile/src/icons/apple-touch-icon-57x57.png
--------------------------------------------------------------------------------
/hello-mobile/src/icons/apple-touch-icon-60x60.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/mobile-toolkit/HEAD/hello-mobile/src/icons/apple-touch-icon-60x60.png
--------------------------------------------------------------------------------
/hello-mobile/src/icons/apple-touch-icon-72x72.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/mobile-toolkit/HEAD/hello-mobile/src/icons/apple-touch-icon-72x72.png
--------------------------------------------------------------------------------
/hello-mobile/src/icons/apple-touch-icon-76x76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/mobile-toolkit/HEAD/hello-mobile/src/icons/apple-touch-icon-76x76.png
--------------------------------------------------------------------------------
/service-worker/worker/src/companion/index.ts:
--------------------------------------------------------------------------------
1 | export {NgServiceWorker, NgPushRegistration} from './comm';
2 | export {ServiceWorkerModule} from './module';
3 |
--------------------------------------------------------------------------------
/service-worker/worker/src/typings/jshashes.d.ts:
--------------------------------------------------------------------------------
1 | declare module 'jshashes' {
2 | export class SHA1 {
3 | hex(data: string): string;
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/app-shell/src/experimental/shell-parser/template-parser/index.ts:
--------------------------------------------------------------------------------
1 | export * from './template-parser';
2 | export * from './parse5/parse5-template-parser';
3 |
4 |
--------------------------------------------------------------------------------
/hello-mobile/src/icons/apple-touch-icon-114x114.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/mobile-toolkit/HEAD/hello-mobile/src/icons/apple-touch-icon-114x114.png
--------------------------------------------------------------------------------
/hello-mobile/src/icons/apple-touch-icon-120x120.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/mobile-toolkit/HEAD/hello-mobile/src/icons/apple-touch-icon-120x120.png
--------------------------------------------------------------------------------
/hello-mobile/src/icons/apple-touch-icon-144x144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/mobile-toolkit/HEAD/hello-mobile/src/icons/apple-touch-icon-144x144.png
--------------------------------------------------------------------------------
/hello-mobile/src/icons/apple-touch-icon-152x152.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/mobile-toolkit/HEAD/hello-mobile/src/icons/apple-touch-icon-152x152.png
--------------------------------------------------------------------------------
/hello-mobile/src/icons/apple-touch-icon-180x180.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/mobile-toolkit/HEAD/hello-mobile/src/icons/apple-touch-icon-180x180.png
--------------------------------------------------------------------------------
/service-worker/worker/src/worker/facade/index.ts:
--------------------------------------------------------------------------------
1 | export * from './adapter';
2 | export * from './cache';
3 | export * from './events';
4 | export * from './fetch';
--------------------------------------------------------------------------------
/hello-mobile/src/icons/apple-touch-icon-precomposed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angular/mobile-toolkit/HEAD/hello-mobile/src/icons/apple-touch-icon-precomposed.png
--------------------------------------------------------------------------------
/app-shell/src/experimental/shell-parser/testing/index.ts:
--------------------------------------------------------------------------------
1 | export * from './context-mock';
2 | export * from './mock-requests';
3 | export * from './mock-caches';
4 |
5 |
--------------------------------------------------------------------------------
/install.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | npm config set registry http://registry.npmjs.org/
3 | cd ./service-worker/worker
4 | npm install
5 | cd ../../app-shell
6 | npm install
7 |
8 |
--------------------------------------------------------------------------------
/app-shell/src/experimental/shell-parser/node-matcher/index.ts:
--------------------------------------------------------------------------------
1 | export * from './css-selector';
2 | export * from './node-matcher';
3 | export * from './css-node-matcher';
4 |
5 |
--------------------------------------------------------------------------------
/app-shell/src/experimental/shell-parser/node-visitor/index.ts:
--------------------------------------------------------------------------------
1 | export * from './node-visitor';
2 | export * from './resource-inline';
3 | export * from './template-strip-visitor';
4 |
5 |
--------------------------------------------------------------------------------
/hello-mobile/README.md:
--------------------------------------------------------------------------------
1 | This directory is an example app created by [Angular CLI](https://cli.angular.io)
2 | to correspond with the [Progressive Web App guides](../guides/cli-setup.md).
3 |
--------------------------------------------------------------------------------
/service-worker/example/webroot/manifest.appcache:
--------------------------------------------------------------------------------
1 | CACHE MANIFEST
2 | CACHE:
3 | # sw.group: html
4 | # sw.hash: f0c9884014ec6ff4496d44810713969c2f1a9710
5 | /index.html
6 | NETWORK:
7 | *
8 |
--------------------------------------------------------------------------------
/app-shell/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | // Place your settings in this file to overwrite default and user settings.
2 | {
3 | "files.exclude": {
4 | "**/.git": true,
5 | "**/.DS_Store": true
6 | }
7 | }
--------------------------------------------------------------------------------
/app-shell/src/experimental/shell-parser/node-matcher/node-matcher.ts:
--------------------------------------------------------------------------------
1 | import {ASTNode} from '../ast';
2 |
3 | export abstract class NodeMatcher {
4 | abstract match(node: ASTNode): boolean;
5 | }
6 |
7 |
--------------------------------------------------------------------------------
/service-worker/example/gulpfile.js:
--------------------------------------------------------------------------------
1 | // Set up ts-node to enable loading of TypeScript files.
2 | require('ts-node').register({
3 | noProject: true,
4 | });
5 |
6 | // Trampoline into gulpfile.ts.
7 | require('./gulpfile.ts');
--------------------------------------------------------------------------------
/service-worker/worker/src/plugins/dynamic/index.ts:
--------------------------------------------------------------------------------
1 | export {Dynamic, DynamicImpl} from './dynamic';
2 | export {FreshnessStrategy} from './strategy/freshness';
3 | export {PerformanceStrategy} from './strategy/performance';
4 |
--------------------------------------------------------------------------------
/service-worker/worker/src/test/e2e/harness/client/manifest.webapp:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Angular Service Worker Test Harness",
3 | "short_name": "ngsw harness",
4 | "start_url": "/index.html",
5 | "display": "standalone"
6 | }
--------------------------------------------------------------------------------
/service-worker/worker/src/companion/module.ts:
--------------------------------------------------------------------------------
1 | import {NgModule} from '@angular/core';
2 | import {NgServiceWorker} from './comm';
3 |
4 | @NgModule({
5 | providers: [NgServiceWorker],
6 | })
7 | export class ServiceWorkerModule {}
8 |
--------------------------------------------------------------------------------
/app-shell/src/experimental/shell-parser/node-visitor/resource-inline/index.ts:
--------------------------------------------------------------------------------
1 | export * from './resource-inline-visitor';
2 | export * from './stylesheet-resource-inline-visitor';
3 | export * from './inline-style-resource-inline-visitor';
4 |
5 |
--------------------------------------------------------------------------------
/hello-mobile/config/environment.js:
--------------------------------------------------------------------------------
1 | /* jshint node: true */
2 |
3 | module.exports = function(environment) {
4 | return {
5 | environment: environment,
6 | baseURL: '/',
7 | locationType: 'auto'
8 | };
9 | };
10 |
11 |
--------------------------------------------------------------------------------
/hello-mobile/e2e/app.po.ts:
--------------------------------------------------------------------------------
1 | export class HelloMobilePage {
2 | navigateTo() {
3 | return browser.get('/');
4 | }
5 |
6 | getParagraphText() {
7 | return element(by.css('hello-mobile-app h1')).getText();
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/app-shell/src/experimental/shell-parser/template-parser/template-parser.ts:
--------------------------------------------------------------------------------
1 | import {ASTNode} from '../ast';
2 |
3 | export abstract class TemplateParser {
4 | abstract parse(template: string): ASTNode;
5 | abstract serialize(node: ASTNode): string;
6 | }
7 |
8 |
--------------------------------------------------------------------------------
/service-worker/worker/src/build/assets/register-basic.js:
--------------------------------------------------------------------------------
1 | if ('serviceWorker' in navigator) {
2 | navigator
3 | .serviceWorker
4 | .register('worker-basic.js')
5 | .catch(function(err) {
6 | console.error('Error registering service worker:', err);
7 | });
8 | }
9 |
--------------------------------------------------------------------------------
/service-worker/worker/src/test/e2e/harness/client/debug/ngsw-manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "static": {
3 | "urls": {
4 | "/hello.txt": "test"
5 | }
6 | },
7 | "external": {
8 | "urls": [
9 | {"url": "http://localhost:8080/full.txt"}
10 | ]
11 | }
12 | }
--------------------------------------------------------------------------------
/service-worker/worker/src/build/assets/register-basic.min.js:
--------------------------------------------------------------------------------
1 | if ('serviceWorker' in navigator) {
2 | navigator
3 | .serviceWorker
4 | .register('worker-basic.min.js')
5 | .catch(function(err) {
6 | console.error('Error registering service worker:', err);
7 | });
8 | }
9 |
--------------------------------------------------------------------------------
/hello-mobile/src/app/environment.ts:
--------------------------------------------------------------------------------
1 | // The file for the current environment will overwrite this one during build
2 | // Different environments can be found in config/environment.{dev|prod}.ts
3 | // The build system defaults to the dev environment
4 |
5 | export const environment = {
6 | production: false
7 | };
8 |
--------------------------------------------------------------------------------
/app-shell/.editorconfig:
--------------------------------------------------------------------------------
1 | # http://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | charset = utf-8
6 | indent_style = space
7 | indent_size = 2
8 | end_of_line = lf
9 | insert_final_newline = true
10 | trim_trailing_whitespace = true
11 |
12 | [*.md]
13 | max_line_length = 0
14 | trim_trailing_whitespace = false
15 |
--------------------------------------------------------------------------------
/app-shell/src/experimental/shell-parser/ast/ast-node.ts:
--------------------------------------------------------------------------------
1 | export interface ASTAttribute {
2 | name: string;
3 | value: string;
4 | }
5 |
6 | export interface ASTNode {
7 | attrs: ASTAttribute[];
8 | childNodes?: ASTNode[];
9 | parentNode?: ASTNode;
10 | nodeName: string;
11 | value?: string;
12 | }
13 |
14 |
--------------------------------------------------------------------------------
/hello-mobile/.editorconfig:
--------------------------------------------------------------------------------
1 | # http://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | charset = utf-8
6 | indent_style = space
7 | indent_size = 2
8 | end_of_line = lf
9 | insert_final_newline = true
10 | trim_trailing_whitespace = true
11 |
12 | [*.md]
13 | max_line_length = 0
14 | trim_trailing_whitespace = false
15 |
--------------------------------------------------------------------------------
/service-worker/worker/src/worker/index.ts:
--------------------------------------------------------------------------------
1 | export * from './api';
2 | export * from './bootstrap';
3 | export * from './cache';
4 | export * from './common';
5 | export * from './driver';
6 | export * from './facade';
7 | export * from './manifest';
8 | export * from './logging';
9 | export * from './url';
10 | export * from './worker';
11 |
--------------------------------------------------------------------------------
/app-shell/src/experimental/shell-parser/index.ts:
--------------------------------------------------------------------------------
1 | import {ShellParser} from './shell-parser';
2 | import {shellParserFactory} from './shell-parser-factory';
3 | import {RouteDefinition, ShellParserConfig} from './config';
4 |
5 | export {
6 | shellParserFactory,
7 | ShellParser,
8 | RouteDefinition,
9 | ShellParserConfig
10 | };
11 |
12 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js: "4.2.1"
3 |
4 | before_install:
5 | - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then export CHROME_BIN=chromium-browser; fi # Karma CI
6 | - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then export DISPLAY=:99.0; fi
7 | - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sh -e /etc/init.d/xvfb start; fi
8 |
9 | install: ./install.sh
10 | script: ./test.sh
11 |
12 |
--------------------------------------------------------------------------------
/hello-mobile/e2e/app.e2e.ts:
--------------------------------------------------------------------------------
1 | import { HelloMobilePage } from './app.po';
2 |
3 | describe('hello-mobile App', function() {
4 | let page: HelloMobilePage;
5 |
6 | beforeEach(() => {
7 | page = new HelloMobilePage();
8 | });
9 |
10 | it('should display message saying app works', () => {
11 | page.navigateTo();
12 | expect(page.getParagraphText()).toEqual('hello-mobile works!');
13 | });
14 | });
15 |
--------------------------------------------------------------------------------
/service-worker/worker/src/worker/manifest.ts:
--------------------------------------------------------------------------------
1 | import {SHA1} from 'jshashes';
2 |
3 | export interface Manifest {
4 | [key: string]: any;
5 | _hash: string;
6 | _json: string;
7 | }
8 |
9 | export function parseManifest(data: string): Manifest {
10 | const manifest: Manifest = JSON.parse(data) as Manifest;
11 | manifest._json = data;
12 | manifest._hash = new SHA1().hex(data);
13 | return manifest;
14 | }
15 |
--------------------------------------------------------------------------------
/hello-mobile/src/main.ts:
--------------------------------------------------------------------------------
1 | import { bootstrap } from '@angular/platform-browser-dynamic';
2 | import { enableProdMode } from '@angular/core';
3 | import { HelloMobileAppComponent, environment } from './app/';
4 | import { APP_SHELL_RUNTIME_PROVIDERS } from '@angular/app-shell';
5 |
6 | if (environment.production) {
7 | enableProdMode();
8 | }
9 |
10 | bootstrap(HelloMobileAppComponent, [ APP_SHELL_RUNTIME_PROVIDERS ]);
11 |
12 |
--------------------------------------------------------------------------------
/service-worker/worker/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | // Place your settings in this file to overwrite default and user settings.
2 | {
3 | "typescript.tsdk": "node_modules/typescript/lib",
4 | "editor.insertSpaces": true,
5 | "editor.tabSize": 2,
6 | "files.exclude": {
7 | "**/.git": true,
8 | "**/.svn": true,
9 | "**/.hg": true,
10 | "**/.DS_Store": true,
11 | "tmp": true,
12 | "node_modules": true
13 | }
14 | }
--------------------------------------------------------------------------------
/service-worker/worker/src/testing/mock.spec.ts:
--------------------------------------------------------------------------------
1 | import {TestWorkerDriver} from './mock';
2 |
3 | class TestWorker {}
4 |
5 | describe('TestWorkerDriver (mock)', () => {
6 | let driver: TestWorkerDriver;
7 | beforeEach(() => {
8 | driver = new TestWorkerDriver(() => new TestWorker);
9 | });
10 | it('properly passes install events through', (done) => {
11 | driver.triggerInstall().then(() => done());
12 | });
13 | });
14 |
--------------------------------------------------------------------------------
/app-shell/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "commonjs",
4 | "target": "es5",
5 | "noImplicitAny": false,
6 | "emitDecoratorMetadata": true,
7 | "experimentalDecorators": true,
8 | "declaration": true,
9 | "outDir": "dist",
10 | "sourceMap": false,
11 | "moduleResolution": "node",
12 | "rootDir": ".",
13 | "baseUrl": "."
14 | },
15 | "exclude": [
16 | "node_modules"
17 | ]
18 | }
19 |
--------------------------------------------------------------------------------
/service-worker/example/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "system",
4 | "target": "es5",
5 | "noImplicitAny": false,
6 | "emitDecoratorMetadata": true,
7 | "experimentalDecorators": true,
8 | "outDir": "dist",
9 | "sourceMap": false,
10 | "moduleResolution": "node",
11 | "rootDir": "."
12 | },
13 | "exclude": [
14 | "node_modules",
15 | "typings/main.d.ts",
16 | "typings/main"
17 | ]
18 | }
--------------------------------------------------------------------------------
/hello-mobile/e2e/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compileOnSave": false,
3 | "compilerOptions": {
4 | "declaration": false,
5 | "emitDecoratorMetadata": true,
6 | "experimentalDecorators": true,
7 | "mapRoot": "",
8 | "module": "commonjs",
9 | "moduleResolution": "node",
10 | "noEmitOnError": true,
11 | "noImplicitAny": false,
12 | "rootDir": ".",
13 | "sourceMap": true,
14 | "sourceRoot": "/",
15 | "target": "es5"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/hello-mobile/typings.json:
--------------------------------------------------------------------------------
1 | {
2 | "globalDevDependencies": {
3 | "angular-protractor": "registry:dt/angular-protractor#1.5.0+20160425143459",
4 | "jasmine": "registry:dt/jasmine#2.2.0+20160412134438",
5 | "selenium-webdriver": "registry:dt/selenium-webdriver#2.44.0+20160317120654"
6 | },
7 | "globalDependencies": {
8 | "es6-shim": "registry:dt/es6-shim#0.31.2+20160317120654",
9 | "node": "registry:dt/node#4.0.0+20160509154515"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/app-shell/.gitignore:
--------------------------------------------------------------------------------
1 | # See http://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # compiled output
4 | /dist
5 | /tmp
6 |
7 | # dependencies
8 | /node_modules
9 | /bower_components
10 |
11 | # IDEs and editors
12 | /.idea
13 |
14 | # misc
15 | /.sass-cache
16 | /connect.lock
17 | /coverage/*
18 | /libpeerconnection.log
19 | npm-debug.log
20 | testem.log
21 | /typings
22 |
23 | # e2e
24 | /e2e/*.js
25 | /e2e/*.map
26 |
27 | #System Files
28 | .DS_Store
29 |
--------------------------------------------------------------------------------
/service-worker/example/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Test Service Worker Page
5 |
14 |
15 |
16 | Service Worker Test
17 |
18 |
19 |
--------------------------------------------------------------------------------
/hello-mobile/.gitignore:
--------------------------------------------------------------------------------
1 | # See http://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # compiled output
4 | /dist
5 | /tmp
6 |
7 | # dependencies
8 | /node_modules
9 | /bower_components
10 |
11 | # IDEs and editors
12 | /.idea
13 |
14 | # misc
15 | /.sass-cache
16 | /connect.lock
17 | /coverage/*
18 | /libpeerconnection.log
19 | npm-debug.log
20 | testem.log
21 | /typings
22 |
23 | # e2e
24 | /e2e/*.js
25 | /e2e/*.map
26 |
27 | #System Files
28 | .DS_Store
29 | Thumbs.db
30 |
--------------------------------------------------------------------------------
/service-worker/example/webroot/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Test Service Worker Page
5 |
14 |
15 |
16 | Service Worker Test
17 |
18 |
19 |
--------------------------------------------------------------------------------
/service-worker/example/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@angular/service-worker-example",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "",
10 | "license": "ISC",
11 | "devDependencies": {
12 | "@angular/service-worker": "^0.1.0",
13 | "gulp": "^3.9.1",
14 | "jshashes": "^1.0.5",
15 | "ts-node": "^0.7.2",
16 | "typings": "^0.7.12"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/app-shell/tsconfig.es5.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "commonjs",
4 | "target": "es5",
5 | "noImplicitAny": false,
6 | "emitDecoratorMetadata": true,
7 | "experimentalDecorators": true,
8 | "declaration": false,
9 | "outDir": "tmp/es5",
10 | "sourceMap": false,
11 | "moduleResolution": "node",
12 | "rootDir": ".",
13 | "baseUrl": ".",
14 | "lib": ["es2015", "dom"]
15 | },
16 | "files": [
17 | "src/index.ts",
18 | "src/unit_tests.ts"
19 | ]
20 | }
21 |
--------------------------------------------------------------------------------
/app-shell/tsconfig.esm.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "es2015",
4 | "target": "es5",
5 | "noImplicitAny": false,
6 | "emitDecoratorMetadata": true,
7 | "experimentalDecorators": true,
8 | "declaration": true,
9 | "outDir": "tmp/esm",
10 | "sourceMap": true,
11 | "moduleResolution": "node",
12 | "rootDir": ".",
13 | "baseUrl": ".",
14 | "lib": ["es2015", "dom"]
15 | },
16 | "files": [
17 | "src/index.ts"
18 | ],
19 | "angularCompilerOptions": {
20 | "skipTemplateCodegen": true
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/hello-mobile/angular-cli-build.js:
--------------------------------------------------------------------------------
1 | /* global require, module */
2 |
3 | var Angular2App = require('angular-cli/lib/broccoli/angular2-app');
4 |
5 | module.exports = function(defaults) {
6 | return new Angular2App(defaults, {
7 | vendorNpmFiles: [
8 | 'systemjs/dist/system-polyfills.js',
9 | 'systemjs/dist/system.src.js',
10 | 'zone.js/dist/*.js',
11 | 'es6-shim/es6-shim.js',
12 | 'reflect-metadata/*.js',
13 | 'rxjs/**/*.js',
14 | '@angular/**/*.js',
15 | '@angular2-material/**/*.+(js|css|map)'
16 | ]
17 | });
18 | };
19 |
--------------------------------------------------------------------------------
/service-worker/worker/src/worker/facade/adapter.ts:
--------------------------------------------------------------------------------
1 | export interface NgSwAdapter {
2 | newRequest(req: string | Request, init?: Object): Request;
3 | newResponse(body: string | Blob, init?: Object): Response;
4 | readonly scope: string;
5 | }
6 |
7 | export interface Clock {
8 | dateNow(): number;
9 | setTimeout(fn: Function, delay: number);
10 | }
11 |
12 | export class BrowserClock implements Clock {
13 | dateNow(): number {
14 | return Date.now();
15 | }
16 |
17 | setTimeout(fn: Function, delay: number) {
18 | return setTimeout(fn, delay);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/service-worker/worker/src/plugins/dynamic/manifest.ts:
--------------------------------------------------------------------------------
1 | import {UrlConfig} from '../../worker';
2 |
3 | export interface DynamicManifest {
4 | group: GroupManifest[];
5 | }
6 |
7 | export type GroupStrategy = "backup" | "cache" | "staleWhileRefresh";
8 |
9 | export type UrlConfigMap = {[url: string]: UrlConfig};
10 |
11 | export interface CacheConfig {
12 | optimizeFor: string;
13 |
14 | strategy: "lru" | "lfu" | "fifo";
15 | maxAgeMs?: number;
16 | maxSizeBytes?: number;
17 | maxEntries: number;
18 | }
19 |
20 | export interface GroupManifest {
21 | name: string;
22 | urls: UrlConfigMap;
23 | cache: CacheConfig;
24 | }
25 |
--------------------------------------------------------------------------------
/hello-mobile/angular-cli.json:
--------------------------------------------------------------------------------
1 | {
2 | "project": {
3 | "version": "1.0.0-beta.4",
4 | "name": "hello-mobile"
5 | },
6 | "apps": [
7 | {
8 | "main": "src/main.ts",
9 | "tsconfig": "src/tsconfig.json",
10 | "mobile": true
11 | }
12 | ],
13 | "addons": [],
14 | "packages": [],
15 | "e2e": {
16 | "protractor": {
17 | "config": "config/protractor.conf.js"
18 | }
19 | },
20 | "test": {
21 | "karma": {
22 | "config": "config/karma.conf.js"
23 | }
24 | },
25 | "defaults": {
26 | "prefix": "app",
27 | "sourceDir": "src",
28 | "styleExt": "css"
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/app-shell/src/experimental/shell-parser/node-visitor/node-visitor.ts:
--------------------------------------------------------------------------------
1 | import {ASTNode} from '../ast';
2 |
3 | export abstract class NodeVisitor {
4 |
5 | abstract process(node: ASTNode): Promise;
6 |
7 | visit(currentNode: ASTNode): Promise {
8 | return this.process(currentNode)
9 | .then((node: ASTNode) => {
10 | if (node) {
11 | return Promise
12 | .all((node.childNodes || [])
13 | .slice()
14 | .map(this.visit.bind(this)))
15 | .then(() => node);
16 | } else {
17 | return null;
18 | }
19 | })
20 | }
21 |
22 | }
23 |
24 |
--------------------------------------------------------------------------------
/app-shell/src/unit_tests.ts:
--------------------------------------------------------------------------------
1 | import 'reflect-metadata';
2 | import 'zone.js';
3 | import 'zone.js/dist/long-stack-trace-zone.js';
4 | import 'zone.js/dist/proxy.js';
5 | import 'zone.js/dist/sync-test.js';
6 | import 'zone.js/dist/jasmine-patch.js';
7 | import 'zone.js/dist/async-test.js';
8 | import 'zone.js/dist/fake-async-test.js';
9 |
10 | import {TestBed} from '@angular/core/testing';
11 | import {platformServerTesting, ServerTestingModule} from '@angular/platform-server/testing';
12 |
13 | import prerenderTests from './app/prerender.spec';
14 | import shellTests from './app/shell.spec';
15 |
16 | TestBed.initTestEnvironment(ServerTestingModule, platformServerTesting());
17 |
18 | prerenderTests();
19 | shellTests();
20 |
--------------------------------------------------------------------------------
/app-shell/src/experimental/shell-parser/node-visitor/template-strip-visitor.ts:
--------------------------------------------------------------------------------
1 | import {ASTNode} from '../ast';
2 | import {NodeVisitor} from './node-visitor';
3 | import {WorkerScope} from '../context';
4 | import {CssNodeMatcher} from '../node-matcher';
5 |
6 | export class TemplateStripVisitor extends NodeVisitor {
7 |
8 | constructor(private matcher: CssNodeMatcher) {
9 | super();
10 | }
11 |
12 | process(node: ASTNode) {
13 | if (this.matcher.match(node)) {
14 | if (node.parentNode) {
15 | const c = node.parentNode.childNodes;
16 | c.splice(c.indexOf(node), 1);
17 | }
18 | return Promise.resolve(null);
19 | }
20 | return Promise.resolve(node);
21 | }
22 |
23 | }
24 |
25 |
--------------------------------------------------------------------------------
/hello-mobile/src/app/hello-mobile.component.spec.ts:
--------------------------------------------------------------------------------
1 | import {
2 | beforeEachProviders,
3 | describe,
4 | expect,
5 | it,
6 | inject
7 | } from '@angular/core/testing';
8 | import { HelloMobileAppComponent } from '../app/hello-mobile.component';
9 |
10 | beforeEachProviders(() => [HelloMobileAppComponent]);
11 |
12 | describe('App: HelloMobile', () => {
13 | it('should create the app',
14 | inject([HelloMobileAppComponent], (app: HelloMobileAppComponent) => {
15 | expect(app).toBeTruthy();
16 | }));
17 |
18 | it('should have as title \'hello-mobile works!\'',
19 | inject([HelloMobileAppComponent], (app: HelloMobileAppComponent) => {
20 | expect(app.title).toEqual('hello-mobile works!');
21 | }));
22 | });
23 |
--------------------------------------------------------------------------------
/service-worker/worker/src/worker/builds/basic.ts:
--------------------------------------------------------------------------------
1 | import {bootstrapServiceWorker} from '../bootstrap';
2 | import {Dynamic, FreshnessStrategy, PerformanceStrategy} from '../../plugins/dynamic';
3 | import {ExternalContentCache} from '../../plugins/external';
4 | import {RouteRedirection} from '../../plugins/routes';
5 | import {StaticContentCache} from '../../plugins/static';
6 | import {Push} from '../../plugins/push';
7 |
8 | bootstrapServiceWorker({
9 | manifestUrl: 'ngsw-manifest.json',
10 | plugins: [
11 | StaticContentCache(),
12 | Dynamic([
13 | new FreshnessStrategy(),
14 | new PerformanceStrategy(),
15 | ]),
16 | ExternalContentCache(),
17 | RouteRedirection(),
18 | Push(),
19 | ],
20 | });
21 |
--------------------------------------------------------------------------------
/app-shell/src/experimental/shell-parser/template-parser/parse5/parse5-template-parser.ts:
--------------------------------------------------------------------------------
1 | import {ASTNode} from '../../ast';
2 | import {TemplateParser} from '../template-parser';
3 |
4 | import './tokenizer-case-sensitivity-patch';
5 | import './drop-named-entities-patch';
6 |
7 | var Parser = require('../../../../vendor/parse5/lib/parser');
8 | var Serializer = require('../../../../vendor/parse5/lib/serializer');
9 |
10 | export class Parse5TemplateParser extends TemplateParser {
11 | parse(template: string): ASTNode {
12 | var parser = new Parser();
13 | return parser.parse(template);
14 | }
15 |
16 | serialize(node: ASTNode): string {
17 | var serializer = new Serializer(node);
18 | return serializer.serialize();
19 | }
20 | }
21 |
22 |
--------------------------------------------------------------------------------
/app-shell/src/app/prerender.spec.ts:
--------------------------------------------------------------------------------
1 | import {inject, TestBed} from '@angular/core/testing';
2 | import {IS_PRERENDER} from './prerender';
3 | import {AppShellModule} from './module';
4 |
5 | export default function () {
6 | describe('IS_PRERENDER', () => {
7 | it('should be true at prerender time', () => {
8 | const prerender = TestBed
9 | .configureTestingModule({imports: [AppShellModule.prerender()]})
10 | .get(IS_PRERENDER);
11 | expect(prerender).toBeTruthy();
12 | });
13 | it('should be false at runtime', () => {
14 | const prerender = TestBed
15 | .configureTestingModule({imports: [AppShellModule.runtime()]})
16 | .get(IS_PRERENDER);
17 | expect(prerender).toBeFalsy();
18 | });
19 | });
20 | }
21 |
--------------------------------------------------------------------------------
/app-shell/src/app/module.ts:
--------------------------------------------------------------------------------
1 | import {ModuleWithProviders, NgModule} from '@angular/core';
2 | import {IS_PRERENDER} from './prerender';
3 | import {ShellNoRender, ShellRender} from './shell';
4 |
5 | @NgModule({
6 | declarations: [
7 | ShellNoRender,
8 | ShellRender,
9 | ],
10 | exports: [
11 | ShellNoRender,
12 | ShellRender,
13 | ],
14 | })
15 | export class AppShellModule {
16 | static prerender(): ModuleWithProviders {
17 | return {
18 | ngModule: AppShellModule,
19 | providers: [{provide: IS_PRERENDER, useValue: true}]
20 | }
21 | }
22 |
23 | static runtime(): ModuleWithProviders {
24 | return {
25 | ngModule: AppShellModule,
26 | providers: [{provide: IS_PRERENDER, useValue: false}],
27 | };
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/hello-mobile/config/protractor.conf.js:
--------------------------------------------------------------------------------
1 | /*global jasmine */
2 | var SpecReporter = require('jasmine-spec-reporter');
3 |
4 | exports.config = {
5 | allScriptsTimeout: 11000,
6 | specs: [
7 | '../e2e/**/*.e2e.ts'
8 | ],
9 | capabilities: {
10 | 'browserName': 'chrome'
11 | },
12 | directConnect: true,
13 | baseUrl: 'http://localhost:4200/',
14 | framework: 'jasmine',
15 | jasmineNodeOpts: {
16 | showColors: true,
17 | defaultTimeoutInterval: 30000,
18 | print: function() {}
19 | },
20 | useAllAngular2AppRoots: true,
21 | beforeLaunch: function() {
22 | require('ts-node').register({
23 | project: 'e2e'
24 | });
25 | },
26 | onPrepare: function() {
27 | jasmine.getEnv().addReporter(new SpecReporter());
28 | }
29 | };
30 |
--------------------------------------------------------------------------------
/app-shell/src/experimental/shell-parser/context.ts:
--------------------------------------------------------------------------------
1 | export abstract class WorkerScope {
2 | abstract fetch(url: string | Request): Promise;
3 | abstract newRequest(input: string | Request, init?: RequestInit): Request;
4 | abstract newResponse(body?: BodyInit, init?: ResponseInit): Response;
5 | caches: CacheStorage;
6 | }
7 |
8 | export class BrowserWorkerScope {
9 | fetch(url: string | Request): Promise {
10 | return fetch(url);
11 | }
12 |
13 | get caches() {
14 | return caches;
15 | }
16 |
17 | newRequest(input: string | Request, init?: RequestInit): Request {
18 | return new Request(input, init);
19 | }
20 |
21 | newResponse(body?: BodyInit, init?: ResponseInit) {
22 | return new Response(body, init);
23 | }
24 | }
25 |
26 |
--------------------------------------------------------------------------------
/service-worker/worker/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "commonjs",
4 | "target": "es5",
5 | "noImplicitAny": false,
6 | "emitDecoratorMetadata": true,
7 | "experimentalDecorators": true,
8 | "declaration": true,
9 | "outDir": "tmp/es5",
10 | "sourceMap": false,
11 | "moduleResolution": "node",
12 | "rootDir": ".",
13 | "baseUrl": ".",
14 | "paths": {
15 | "@angular/service-worker": ["src"],
16 | "@angular/service-worker/worker": ["src/worker"]
17 | },
18 | "lib": [
19 | "dom",
20 | "es2015"
21 | ],
22 | "types": [
23 | "jasmine",
24 | "protractor",
25 | "node",
26 | "selenium-webdriver"
27 | ]
28 | },
29 | "exclude": [
30 | "node_modules"
31 | ]
32 | }
--------------------------------------------------------------------------------
/hello-mobile/src/app/hello-mobile.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 | import { APP_SHELL_DIRECTIVES } from '@angular/app-shell';
3 | import { MdToolbar } from '@angular2-material/toolbar';
4 | import { MdSpinner } from '@angular2-material/progress-circle';
5 |
6 | @Component({
7 | moduleId: module.id,
8 | selector: 'hello-mobile-app',
9 | template: `
10 |
11 | {{title}}
12 |
13 |
14 | App is Fully Rendered
15 | `,
16 | styles: [`
17 | md-spinner {
18 | margin: 24px auto 0;
19 | }
20 | `],
21 | directives: [APP_SHELL_DIRECTIVES, MdToolbar, MdSpinner]
22 | })
23 | export class HelloMobileAppComponent {
24 | title = 'Hello Mobile';
25 | }
26 |
--------------------------------------------------------------------------------
/app-shell/src/experimental/shell-parser/node-visitor/resource-inline/stylesheet-resource-inline-visitor.ts:
--------------------------------------------------------------------------------
1 | import {ASTNode} from '../../ast';
2 | import {ResourceInlineVisitor} from './resource-inline-visitor';
3 | import {WorkerScope} from '../../context';
4 |
5 | const URL_REGEXP = /:\s+url\(['"]?(.*?)['"]?\)/gmi;
6 |
7 | export class StylesheetResourceInlineVisitor extends ResourceInlineVisitor {
8 |
9 | process(node: ASTNode): Promise {
10 | if (node.nodeName.toLowerCase() === 'style') {
11 | const styleNode = node.childNodes[0];
12 | return this.inlineAssets(styleNode.value)
13 | .then((content: string) => {
14 | styleNode.value = content;
15 | return node;
16 | });
17 | }
18 | return Promise.resolve(node);
19 | }
20 |
21 | }
22 |
23 |
--------------------------------------------------------------------------------
/service-worker/worker/src/test/e2e/harness/server/push.ts:
--------------------------------------------------------------------------------
1 | declare interface WebPushParams {
2 | TTL?: number;
3 | vapidDetails: {
4 | subject: string;
5 | publicKey: string;
6 | privateKey: string;
7 | };
8 | }
9 |
10 | declare interface WebPush {
11 | sendNotification(subscription: any, message: any, options: WebPushParams): Promise;
12 | }
13 |
14 | let push: WebPush = require('web-push');
15 |
16 | export function sendPush(subscription: any, payload?: Object): Promise {
17 | return push.sendNotification(subscription, JSON.stringify(payload), {
18 | vapidDetails: {
19 | subject: 'mailto:test@angular.io',
20 | publicKey: 'BLRl_fG1TCTc1D2JwzOpdZjaRcJucXtG8TAd5g9vuYjl6KUUDxgoRjQPCgjZfY-_Rusd_qtjNvanHXeFvOFlxH4',
21 | privateKey: 't3JtFOflouvPUxFKeSSmZdjuVidnD_0dNGFM1v-N4PI',
22 | },
23 | });
24 | }
25 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://travis-ci.org/angular/mobile-toolkit)
2 |
3 | # Angular Mobile Toolkit
4 |
5 | This repo is a series of tools and guides to help build Progressive
6 | Web Apps. All guides are currently based on Angular CLI, and all tools
7 | should be considered alpha quality. In the future, more guides and recipes
8 | to cover different tools and use cases will be added here and on
9 | [mobile.angular.io](https://mobile.angular.io).
10 |
11 | ## Guides
12 |
13 | 1. [Create an installable mobile web app with Angular CLI](./guides/cli-setup.md)
14 | 2. [Make the App Installable with Web App Manifest](./guides/web-app-manifest.md)
15 | 3. [Add an app shell component to the App](./guides/app-shell.md)
16 | 4. [Add basic offline capabilities with Service Worker](./guides/service-worker.md)
17 |
--------------------------------------------------------------------------------
/app-shell/src/experimental/shell-parser/node-visitor/resource-inline/inline-style-resource-inline-visitor.ts:
--------------------------------------------------------------------------------
1 | import {ASTNode, ASTAttribute} from '../../ast';
2 | import {ResourceInlineVisitor} from './resource-inline-visitor';
3 | import {WorkerScope} from '../../context';
4 |
5 | const URL_REGEXP = /:\s+url\(['"]?(.*?)['"]?\)/gmi;
6 |
7 | export class InlineStyleResourceInlineVisitor extends ResourceInlineVisitor {
8 |
9 | process(node: ASTNode): Promise {
10 | const styleAttr = (node.attrs || [])
11 | .filter((a: ASTAttribute) => a.name === 'style')
12 | .pop();
13 | if (styleAttr) {
14 | return this.inlineAssets(styleAttr.value)
15 | .then((content: string) => {
16 | styleAttr.value = content;
17 | return node;
18 | });
19 | }
20 | return Promise.resolve(node);
21 | }
22 |
23 | }
24 |
25 |
--------------------------------------------------------------------------------
/hello-mobile/src/main-app-shell.ts:
--------------------------------------------------------------------------------
1 | import { provide } from '@angular/core';
2 | import { APP_BASE_HREF } from '@angular/common';
3 | import { APP_SHELL_BUILD_PROVIDERS } from '@angular/app-shell';
4 | import { HelloMobileAppComponent } from './app/';
5 | import {
6 | REQUEST_URL,
7 | ORIGIN_URL
8 | } from 'angular2-universal';
9 |
10 | export const options = {
11 | directives: [
12 | // The component that will become the main App Shell
13 | HelloMobileAppComponent
14 | ],
15 | platformProviders: [
16 | APP_SHELL_BUILD_PROVIDERS,
17 | provide(ORIGIN_URL, {
18 | useValue: ''
19 | })
20 | ],
21 | providers: [
22 | // What URL should Angular be treating the app as if navigating
23 | provide(APP_BASE_HREF, {useValue: '/'}),
24 | provide(REQUEST_URL, {useValue: '/'})
25 | ],
26 | async: false,
27 | preboot: false
28 | };
29 |
30 |
--------------------------------------------------------------------------------
/service-worker/example/gulpfile.ts:
--------------------------------------------------------------------------------
1 | declare var require;
2 |
3 | let gulp = require('gulp');
4 | let ngsw = require('@angular/service-worker');
5 |
6 | gulp.task('default', ['copy:static', 'copy:sw', 'build:manifest'])
7 |
8 | gulp.task('copy:sw/dev', () => gulp
9 | .src([
10 | '../worker/dist/worker.js'
11 | ])
12 | .pipe(gulp.dest('webroot')));
13 |
14 | gulp.task('copy:static', () => gulp
15 | .src([
16 | 'src/**/*.html'
17 | ])
18 | .pipe(gulp.dest('webroot')));
19 |
20 | gulp.task('copy:sw', () => gulp
21 | .src([
22 | 'node_modules/@angular/service-worker/dist/worker.js'
23 | ])
24 | .pipe(gulp.dest('webroot')));
25 |
26 | gulp.task('build:manifest', () => ngsw
27 | .gulpGenManifest({
28 | group: [
29 | {
30 | name: 'html',
31 | sources: gulp.src('src/**/*.html')
32 | }
33 | ]
34 | })
35 | .pipe(gulp.dest('webroot')));
--------------------------------------------------------------------------------
/service-worker/worker/src/worker/builds/test.ts:
--------------------------------------------------------------------------------
1 | import {bootstrapServiceWorker} from '../bootstrap';
2 | import {Dynamic, FreshnessStrategy, PerformanceStrategy} from '../../plugins/dynamic';
3 | import {ExternalContentCache} from '../../plugins/external';
4 | import {RouteRedirection} from '../../plugins/routes';
5 | import {StaticContentCache} from '../../plugins/static';
6 | import {Push} from '../../plugins/push';
7 | import {Verbosity, HttpHandler} from '../logging';
8 |
9 | bootstrapServiceWorker({
10 | manifestUrl: '/ngsw-manifest.json',
11 | plugins: [
12 | StaticContentCache(),
13 | Dynamic([
14 | new FreshnessStrategy(),
15 | new PerformanceStrategy(),
16 | ]),
17 | ExternalContentCache(),
18 | RouteRedirection(),
19 | Push(),
20 | ],
21 | logLevel: Verbosity.DEBUG,
22 | logHandlers: [
23 | new HttpHandler('/ngsw-log'),
24 | ],
25 | });
26 |
--------------------------------------------------------------------------------
/service-worker/worker/src/worker/facade/events.ts:
--------------------------------------------------------------------------------
1 | export interface Callback {
2 | (event: T): void;
3 | }
4 |
5 | function nop(event: any): void {}
6 |
7 | export class NgSwEvents {
8 | install: Callback = nop;
9 | activate: Callback = nop;
10 | fetch: Callback = nop;
11 | message: Callback = nop;
12 | push: Callback = nop;
13 |
14 | constructor(scope: ServiceWorkerGlobalScope) {
15 | scope.addEventListener('install', (event: InstallEvent) => this.install(event));
16 | scope.addEventListener('activate', (event: ActivateEvent) => this.activate(event));
17 | scope.addEventListener('fetch', (event: FetchEvent) => this.fetch(event));
18 | scope.addEventListener('message', (event: MessageEvent) => this.message(event));
19 | scope.addEventListener('push', (event: PushEvent) => this.push(event));
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_STORE
2 |
3 | # Don’t commit the following directories created by pub.
4 | packages
5 | pubspec.lock
6 | .pub
7 | .packages
8 |
9 | /dist/
10 | .buildlog
11 | node_modules
12 | bower_components
13 |
14 | # Or broccoli working directory
15 | tmp
16 |
17 | # Or the files created by dart2js.
18 | *.dart.js
19 | *.dart.precompiled.js
20 | *.js_
21 | *.js.deps
22 | *.js.map
23 |
24 | # Files created by the template compiler
25 | **/*.ngfactory.ts
26 | **/*.css.ts
27 | **/*.css.shim.ts
28 |
29 | # Or type definitions we mirror from github
30 | # (NB: these lines are removed in publish-build-artifacts.sh)
31 | **/typings/**/*.d.ts
32 | **/typings/tsd.cached.json
33 | !/service-worker/worker/src/typings
34 |
35 | # Include when developing application packages.
36 | pubspec.lock
37 | .c9
38 | .idea/
39 | .settings/
40 | *.swo
41 | .vscode
42 |
43 | # Don't check in secret files
44 | *secret.js
45 |
46 | # Ignore npm debug log
47 | npm-debug.log
48 |
--------------------------------------------------------------------------------
/service-worker/worker/src/worker/url.ts:
--------------------------------------------------------------------------------
1 | export type UrlMatchType = "exact" | "prefix" | "regex";
2 |
3 | export interface UrlConfig {
4 | match?: UrlMatchType;
5 | }
6 |
7 | export class UrlMatcher {
8 | match: UrlMatchType;
9 |
10 | private _regex: RegExp;
11 |
12 | constructor(public pattern: string, config: UrlConfig = {}, public scope: string) {
13 | this.match = config.match || "exact";
14 | if (this.match === 'regex') {
15 | this._regex = new RegExp(pattern);
16 | }
17 | }
18 |
19 | matches(url: string): boolean {
20 | // Strip the scope from the URL if present.
21 | if (url.startsWith(this.scope)) {
22 | url = url.substr(this.scope.length);
23 | }
24 | switch (this.match) {
25 | case 'exact':
26 | return this.pattern === url;
27 | case 'prefix':
28 | return url.startsWith(this.pattern);
29 | case 'regex':
30 | return this._regex.test(url);
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/app-shell/src/experimental/shell-parser/config.ts:
--------------------------------------------------------------------------------
1 | export type RouteDefinition = string;
2 |
3 | const SHELL_PARSER_CACHE_NAME = 'mobile-toolkit:app-shell';
4 | const APP_SHELL_URL = './app_shell.html';
5 | const NO_RENDER_CSS_SELECTOR = '[shellNoRender]';
6 | const ROUTE_DEFINITIONS: RouteDefinition[] = [];
7 | const INLINE_IMAGES: string[] = ['png', 'svg', 'jpg'];
8 |
9 | // TODO(mgechev): use if we decide to include @angular/core
10 | // export const SHELL_PARSER_CONFIG = new OpaqueToken('ShellRuntimeParserConfig');
11 |
12 | export interface ShellParserConfig {
13 | APP_SHELL_URL?: string;
14 | SHELL_PARSER_CACHE_NAME?: string;
15 | NO_RENDER_CSS_SELECTOR?: string;
16 | ROUTE_DEFINITIONS?: RouteDefinition[];
17 | INLINE_IMAGES?: string[];
18 | }
19 |
20 | export const SHELL_PARSER_DEFAULT_CONFIG: ShellParserConfig = {
21 | SHELL_PARSER_CACHE_NAME,
22 | APP_SHELL_URL,
23 | NO_RENDER_CSS_SELECTOR,
24 | ROUTE_DEFINITIONS,
25 | INLINE_IMAGES
26 | };
27 |
28 |
--------------------------------------------------------------------------------
/service-worker/worker/tsconfig.esm.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "es2015",
4 | "target": "es5",
5 | "noImplicitAny": false,
6 | "emitDecoratorMetadata": true,
7 | "experimentalDecorators": true,
8 | "declaration": true,
9 | "outDir": "tmp/esm",
10 | "sourceMap": true,
11 | "moduleResolution": "node",
12 | "rootDir": ".",
13 | "baseUrl": ".",
14 | "paths": {
15 | "@angular/service-worker/worker": ["src/worker"]
16 | },
17 | "lib": ["es2015", "dom"]
18 | },
19 | "files": [
20 | "src/index.ts",
21 | "src/plugins/push/index.ts",
22 | "src/plugins/routes/index.ts",
23 | "src/plugins/static/index.ts",
24 | "src/worker/builds/basic.ts",
25 | "src/worker/builds/test.ts",
26 | "src/worker/index.ts",
27 | "src/typings/jshashes.d.ts",
28 | "src/typings/service-worker.d.ts"
29 | ],
30 | "angularCompilerOptions": {
31 | "skipTemplateCodegen": true
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/service-worker/worker/src/test/e2e/harness/client/main.ts:
--------------------------------------------------------------------------------
1 |
2 | import {Component, NgModule} from '@angular/core';
3 | import {FormsModule} from '@angular/forms';
4 | import {BrowserModule} from '@angular/platform-browser';
5 | import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
6 | import {ControllerCmp} from './src/controller';
7 | import {ServiceWorkerModule} from '@angular/service-worker';
8 |
9 |
10 | @Component({
11 | selector: 'sw-testing-harness',
12 | template: `
13 | Service Worker Testing Harness
14 |
15 | `,
16 | })
17 | class SwTestingHarnessCmp {}
18 |
19 | @NgModule({
20 | declarations: [
21 | SwTestingHarnessCmp,
22 | ControllerCmp,
23 | ],
24 | imports: [
25 | BrowserModule,
26 | FormsModule,
27 | ServiceWorkerModule,
28 | ],
29 | bootstrap: [SwTestingHarnessCmp],
30 | })
31 | export class SwTestingHarnessModule {}
32 |
33 | platformBrowserDynamic().bootstrapModule(SwTestingHarnessModule);
34 |
--------------------------------------------------------------------------------
/app-shell/src/experimental/shell-parser/testing/context-mock.ts:
--------------------------------------------------------------------------------
1 | import {MockRequest, MockResponse} from './mock-requests';
2 | import {MockCacheStorage} from './mock-caches';
3 | import {WorkerScope} from '../context';
4 |
5 | export class MockWorkerScope {
6 | mockResponses: {[key: string]: Response} = {};
7 | currentCaches: MockCacheStorage;
8 |
9 | fetch(url: string | Request): Promise {
10 | const requestUrl: string = url;
11 | if (this.mockResponses[requestUrl]) {
12 | return Promise.resolve(this.mockResponses[requestUrl]);
13 | }
14 | const resp = new MockResponse('');
15 | resp.ok = false;
16 | resp.status = 404;
17 | resp.statusText = 'File Not Found';
18 | return Promise.resolve(resp);
19 | }
20 |
21 | get caches(): CacheStorage {
22 | return this.currentCaches;
23 | }
24 |
25 | newRequest(input: string | Request, init?: RequestInit): Request {
26 | return new MockRequest(input, init);
27 | }
28 |
29 | newResponse(body?: BodyInit, init?: ResponseInit) {
30 | return new MockResponse(body, init);
31 | }
32 | }
33 |
34 |
--------------------------------------------------------------------------------
/hello-mobile/src/manifest.webapp:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Hello Mobile",
3 | "short_name": "Hello Mobile",
4 | "icons": [
5 | {
6 | "src": "/icons/android-chrome-36x36.png",
7 | "sizes": "36x36",
8 | "type": "image/png",
9 | "density": 0.75
10 | },
11 | {
12 | "src": "/icons/android-chrome-48x48.png",
13 | "sizes": "48x48",
14 | "type": "image/png",
15 | "density": 1
16 | },
17 | {
18 | "src": "/icons/android-chrome-72x72.png",
19 | "sizes": "72x72",
20 | "type": "image/png",
21 | "density": 1.5
22 | },
23 | {
24 | "src": "/icons/android-chrome-96x96.png",
25 | "sizes": "96x96",
26 | "type": "image/png",
27 | "density": 2
28 | },
29 | {
30 | "src": "/icons/android-chrome-144x144.png",
31 | "sizes": "144x144",
32 | "type": "image/png",
33 | "density": 3
34 | },
35 | {
36 | "src": "/icons/android-chrome-192x192.png",
37 | "sizes": "192x192",
38 | "type": "image/png",
39 | "density": 4
40 | }
41 | ],
42 | "theme_color": "#000000",
43 | "background_color": "#e0e0e0",
44 | "start_url": "/index.html",
45 | "display": "standalone",
46 | "orientation": "portrait"
47 | }
48 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License
2 |
3 | Copyright (c) 2014-2016 Google, Inc. http://angular.io
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/app-shell/src/app/shell.ts:
--------------------------------------------------------------------------------
1 | import { Directive, Inject, OnInit, ViewContainerRef, TemplateRef } from '@angular/core';
2 | import {IS_PRERENDER} from './prerender';
3 |
4 | @Directive({
5 | selector: '[shellNoRender]'
6 | })
7 | export class ShellNoRender implements OnInit {
8 |
9 | constructor(
10 | private _viewContainer: ViewContainerRef,
11 | private _templateRef: TemplateRef