diff --git a/.travis.yml b/.travis.yml index 48358bc56e..0a4b3fe77a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,10 +18,6 @@ before_install: before_script: - sh -e /etc/init.d/xvfb start install: - - npm install --no-optional - - npm install --prefix public/docs/_examples - - npm install --prefix public/docs/_examples/_protractor - - npm run webdriver:update --prefix public/docs/_examples/_protractor - - gulp add-example-boilerplate + - ./script/install.sh script: - gulp $SCRIPT diff --git a/public/_includes/_util-fns.jade b/public/_includes/_util-fns.jade index 8976996bb6..d9317707f3 100644 --- a/public/_includes/_util-fns.jade +++ b/public/_includes/_util-fns.jade @@ -97,14 +97,15 @@ mixin makeExcerpt(_filePath, _region, _title, stylePatterns) - var filePath = adjustments.filePath; - var title = adjustments.title; - var region = _region || parenText; - - var excerpt = !region || parenText === '' ? 'excerpt' : region; + - var excerpt = !region || parenText === '' ? 'excerpt' : parenText || region; - if (title) title = title + ' (' + excerpt + ')'; +makeExample(filePath, region, title, stylePatterns)(format='.') -//- Extract the doc example name from `current`. +//- Get the doc example name either from `_example` if set, or +//- extract the example name from `current`. - var getExampleName = function() { - var dir = current.path[current.path.length - 1]; -- return dir == 'latest' ? current.source : dir; +- return _example ? _example : dir == 'latest' ? current.source : dir; - }; mixin makeTabs(filePaths, regions, tabNames, stylePatterns) diff --git a/public/docs/_examples/toh-6/ts/app/app.component.css b/public/docs/_examples/toh-6/ts/app/app.component.css index 137e9be7be..f4e8082ea1 100644 --- a/public/docs/_examples/toh-6/ts/app/app.component.css +++ b/public/docs/_examples/toh-6/ts/app/app.component.css @@ -1,5 +1,4 @@ -/* #docplaster */ -/* #docregion css */ +/* #docregion */ h1 { font-size: 1.2em; color: #999; @@ -28,4 +27,3 @@ nav a:hover { nav a.router-link-active { color: #039be5; } -/* #enddocregion css */ diff --git a/public/docs/_examples/toh-6/ts/app/hero-detail.component.html b/public/docs/_examples/toh-6/ts/app/hero-detail.component.html index f532eb0109..38af5f707e 100644 --- a/public/docs/_examples/toh-6/ts/app/hero-detail.component.html +++ b/public/docs/_examples/toh-6/ts/app/hero-detail.component.html @@ -9,5 +9,7 @@ + - \ No newline at end of file + + diff --git a/public/docs/_examples/toh-6/ts/app/hero-detail.component.ts b/public/docs/_examples/toh-6/ts/app/hero-detail.component.ts index bce249dcc1..8da8978a08 100644 --- a/public/docs/_examples/toh-6/ts/app/hero-detail.component.ts +++ b/public/docs/_examples/toh-6/ts/app/hero-detail.component.ts @@ -50,11 +50,11 @@ export class HeroDetailComponent implements OnInit { .catch(error => this.error = error); // TODO: Display error message } // #enddocregion save - // #docregion goback + // #docregion goBack goBack(savedHero: Hero = null) { this.close.emit(savedHero); if (this.navigated) { window.history.back(); } } - // #enddocregion goback + // #enddocregion goBack } diff --git a/public/docs/_examples/toh-6/ts/app/hero.service.ts b/public/docs/_examples/toh-6/ts/app/hero.service.ts index fa1e1ac4e4..8995a3dd96 100644 --- a/public/docs/_examples/toh-6/ts/app/hero.service.ts +++ b/public/docs/_examples/toh-6/ts/app/hero.service.ts @@ -12,11 +12,11 @@ import { Hero } from './hero'; @Injectable() export class HeroService { + // #docregion getHeroes private heroesUrl = 'app/heroes'; // URL to web api constructor(private http: Http) { } - // #docregion get-heroes getHeroes(): Promise { return this.http.get(this.heroesUrl) // #docregion to-promise @@ -29,7 +29,7 @@ export class HeroService { .catch(this.handleError); // #enddocregion catch } - // #enddocregion get-heroes + // #enddocregion getHeroes getHero(id: number) { return this.getHeroes() @@ -45,7 +45,7 @@ export class HeroService { } // #enddocregion save - // #docregion delete-hero + // #docregion delete delete(hero: Hero) { let headers = new Headers(); headers.append('Content-Type', 'application/json'); @@ -57,9 +57,9 @@ export class HeroService { .toPromise() .catch(this.handleError); } - // #enddocregion delete-hero + // #enddocregion delete - // #docregion post-hero + // #docregion post // Add new Hero private post(hero: Hero): Promise { let headers = new Headers({ @@ -71,9 +71,9 @@ export class HeroService { .then(res => res.json().data) .catch(this.handleError); } - // #enddocregion post-hero + // #enddocregion post - // #docregion put-hero + // #docregion put // Update existing Hero private put(hero: Hero) { let headers = new Headers(); @@ -87,13 +87,13 @@ export class HeroService { .then(() => hero) .catch(this.handleError); } - // #enddocregion put-hero + // #enddocregion put - // #docregion error-handler + // #docregion handleError private handleError(error: any) { console.error('An error occurred', error); return Promise.reject(error.message || error); } - // #enddocregion error-handler + // #enddocregion handleError } -// #enddocregion + diff --git a/public/docs/_examples/toh-6/ts/app/heroes.component.html b/public/docs/_examples/toh-6/ts/app/heroes.component.html index 705c67677f..05afc9ea2f 100644 --- a/public/docs/_examples/toh-6/ts/app/heroes.component.html +++ b/public/docs/_examples/toh-6/ts/app/heroes.component.html @@ -5,18 +5,19 @@ {{hero.id}} {{hero.name}} - - - + + + - + +
{{error}}
- +

diff --git a/public/docs/_examples/toh-6/ts/app/heroes.component.ts b/public/docs/_examples/toh-6/ts/app/heroes.component.ts index df3f26c69b..1573b96be6 100644 --- a/public/docs/_examples/toh-6/ts/app/heroes.component.ts +++ b/public/docs/_examples/toh-6/ts/app/heroes.component.ts @@ -18,7 +18,9 @@ export class HeroesComponent implements OnInit { heroes: Hero[]; selectedHero: Hero; addingHero = false; + // #docregion error error: any; + // #enddocregion error constructor( private router: Router, @@ -28,10 +30,10 @@ export class HeroesComponent implements OnInit { this.heroService .getHeroes() .then(heroes => this.heroes = heroes) - .catch(error => this.error = error); // TODO: Display error message + .catch(error => this.error = error); } - // #docregion add + // #docregion addHero addHero() { this.addingHero = true; this.selectedHero = null; @@ -41,10 +43,10 @@ export class HeroesComponent implements OnInit { this.addingHero = false; if (savedHero) { this.getHeroes(); } } - // #enddocregion add + // #enddocregion addHero - // #docregion delete - delete(hero: Hero, event: any) { + // #docregion deleteHero + deleteHero(hero: Hero, event: any) { event.stopPropagation(); this.heroService .delete(hero) @@ -52,9 +54,9 @@ export class HeroesComponent implements OnInit { this.heroes = this.heroes.filter(h => h !== hero); if (this.selectedHero === hero) { this.selectedHero = null; } }) - .catch(error => this.error = error); // TODO: Display error message + .catch(error => this.error = error); } - // #enddocregion delete + // #enddocregion deleteHero ngOnInit() { this.getHeroes(); diff --git a/public/docs/_examples/toh-6/ts/app/in-memory-data.service.ts b/public/docs/_examples/toh-6/ts/app/in-memory-data.service.ts index 791b6ae2c5..261795a641 100644 --- a/public/docs/_examples/toh-6/ts/app/in-memory-data.service.ts +++ b/public/docs/_examples/toh-6/ts/app/in-memory-data.service.ts @@ -1,4 +1,4 @@ -// #docregion +// #docregion , init export class InMemoryDataService { createDb() { let heroes = [ diff --git a/public/docs/_examples/toh-6/ts/sample.css b/public/docs/_examples/toh-6/ts/sample.css index 042f0494f6..0c99008d2d 100644 --- a/public/docs/_examples/toh-6/ts/sample.css +++ b/public/docs/_examples/toh-6/ts/sample.css @@ -1,8 +1,7 @@ +/* #docregion */ +.error {color:red;} button.delete-button{ float:right; background-color: gray !important; color:white; } - - - diff --git a/public/docs/js/latest/guide/_data.json b/public/docs/js/latest/guide/_data.json index a0f8270eec..567324b649 100644 --- a/public/docs/js/latest/guide/_data.json +++ b/public/docs/js/latest/guide/_data.json @@ -73,11 +73,6 @@ "intro": "Learn how to apply CSS styles to components." }, - "security": { - "title": "Security", - "intro": "Prevent security vulnerabilities" - }, - "hierarchical-dependency-injection": { "title": "Hierarchical Dependency Injectors", "navTitle": "Hierarchical Injectors", @@ -115,6 +110,11 @@ "intro": "Discover the basics of screen navigation with the Angular 2 router." }, + "security": { + "title": "Security", + "intro": "Prevent security vulnerabilities" + }, + "structural-directives": { "title": "Structural Directives", "intro": "Angular has a powerful template engine that lets us easily manipulate the DOM structure of our elements." @@ -141,11 +141,5 @@ "title": "Webpack: an introduction", "intro": "Create your Angular 2 applications with a Webpack based tooling", "hide": true - }, - - "glossary": { - "title": "Glossary", - "intro": "Brief definitions of the most important words in the Angular 2 vocabulary", - "basics": true } } diff --git a/public/docs/ts/latest/cookbook/_data.json b/public/docs/ts/latest/cookbook/_data.json index 5e3e931132..bf940d2d0c 100644 --- a/public/docs/ts/latest/cookbook/_data.json +++ b/public/docs/ts/latest/cookbook/_data.json @@ -35,6 +35,12 @@ "hide": true }, + "dynamic-form": { + "title": "Dynamic Forms", + "intro": "Render dynamic forms with NgFormModel", + "basics": true + }, + "set-document-title": { "title": "设置文档标题", "intro": "使用Title服务来设置文档标题或窗口标题" diff --git a/public/docs/ts/latest/guide/_data.json b/public/docs/ts/latest/guide/_data.json index 4c34e19b16..b4a623fe5c 100644 --- a/public/docs/ts/latest/guide/_data.json +++ b/public/docs/ts/latest/guide/_data.json @@ -117,7 +117,6 @@ "intro": "管道可以在模板中转换显示的内容。" }, - "router-deprecated": { "title": "Router (Deprecated Beta)", "intro": "The deprecated Beta Router.", @@ -129,6 +128,11 @@ "intro": "揭示如何通过Angular 2路由进行基本的屏幕导航。" }, + "security": { + "title": "Security", + "intro": "Developing for content security in Angular applications" + }, + "structural-directives": { "title": "结构型指令", "intro": "Angular有一个强力的模板引擎,它能让你轻松维护元素的DOM树结构。" diff --git a/public/docs/ts/latest/guide/security.jade b/public/docs/ts/latest/guide/security.jade index a28fc416ae..285b772e97 100644 --- a/public/docs/ts/latest/guide/security.jade +++ b/public/docs/ts/latest/guide/security.jade @@ -121,6 +121,13 @@ h2#xss 防止跨站脚本(XSS) 当值从模版通过属性(Property)、DOM元素属性(Attribte)、CSS类绑定或者插值表达式等方式被插入到COM的时候, Angular将对值进行无害化,去掉不可信的值。 + **Angular templates are the same as executable code**: HTML, attributes, and binding expressions + (but not the values bound!) in templates are trusted to be safe. That means applications must + prevent potentially attacker controlled values from ever making it into the source code of a + template. Never generate template source code by concatenating user input and templates! Using + the [offline template compiler](#offline-template-compiler) is an effective way to prevent these + vulnerabilities, also known as template injection. + ### Sanitization and security contexts ### 无害化和安全环境 @@ -208,15 +215,14 @@ figure.image-display ### 内容安全策略 - A [Content Security Policy (CSP)](https://developer.mozilla.org/en- - US/docs/Web/Security/CSP/Introducing_Content_Security_Policy) is a defense-in-depth technique to - prevent XSS. To enable CSP, configure your web server to return an appropriate - `Content-Security-Policy` HTTP header. Learn more at - [OWASP](https://www.owasp.org/index.php/Content_Security_Policy). + A [Content Security Policy (CSP)] + (http://www.html5rocks.com/en/tutorials/security/content-security-policy/) is a defense-in-depth + technique to prevent XSS. To enable CSP, configure your web server to return an appropriate + `Content-Security-Policy` HTTP header. [内容安全策略(CSP)](https://developer.mozilla.org/en- US/docs/Web/Security/CSP/Introducing_Content_Security_Policy)是用来防止XSS的深度防御技术。 - 为了打开CSP,配置你的Web服务器,让它返回合适的`Content_Security_Policy` HTTP头字段。参见[OWASP](https://www.owasp.org/index.php/Content_Security_Policy)。 + 为了打开CSP,配置你的Web服务器,让它返回合适的`Content_Security_Policy` HTTP头字段。 ### Use the Offline Template Compiler @@ -238,11 +244,12 @@ figure.image-display ### 服务器端XSS保护 - HTML constructed on the server is vulnerable to injection attacks. When generating server side - HTML, e.g. for the initial page load of the Angular application, make sure to use a templating - language that automatically escapes values to prevent XSS vulnerabilities on the server. Do not - generate Angular templates on the server side using a templating language, this carries a high - risk of introducing template injection vulnerabilities. + HTML constructed on the server is vulnerable to injection attacks. Injecting template code into an + Angular application is the same as injecting executable code (e.g. JavaScript) into the + application; it gives the attacker full control over the application. To prevent this, make sure + to use a templating language that automatically escapes values to prevent XSS vulnerabilities on + the server. Do not generate Angular templates on the server side using a templating language, this + carries a high risk of introducing template injection vulnerabilities. 服务器端构造的HTML很容易被注入攻击。当在服务器端生成HTML,比如Angular应用程序的初始化页面加载时, 确保在服务器端使用一个能够自动无害化值以防止XSS漏洞的模版语言。不要在服务器端使用一个模版语言生成Angular模版, @@ -295,10 +302,10 @@ figure.image-display :marked If we need to convert user input into a trusted value, it can be convenient to do so in a controller method. The template below allows users to enter a YouTube video ID, and load the - corresponding video in an `