Compare commits
10 Commits
Author | SHA1 | Date | |
---|---|---|---|
6b57928d35 | |||
47471ee49e | |||
b0ae464695 | |||
34403cda60 | |||
e5c9bbcbdd | |||
80fe41a88e | |||
af652a7c8b | |||
de36f8a3b9 | |||
b658fa9ea0 | |||
2a123463ac |
@ -23,9 +23,9 @@ cache:
|
||||
|
||||
env:
|
||||
global:
|
||||
# GITHUB_TOKEN_ANGULAR
|
||||
# GITHUB_TOKEN_ANGULAR=<github token, a personal access token of the angular-builds account, account access in valentine>
|
||||
# This is needed for the e2e Travis matrix task to publish packages to github for continuous packages delivery.
|
||||
- secure: "fq/U7VDMWO8O8SnAQkdbkoSe2X92PVqg4d044HmRYVmcf6YbO48+xeGJ8yOk0pCBwl3ISO4Q2ot0x546kxfiYBuHkZetlngZxZCtQiFT9kyId8ZKcYdXaIW9OVdw3Gh3tQyUwDucfkVhqcs52D6NZjyE2aWZ4/d1V4kWRO/LMgo="
|
||||
- secure: "rNqXoy2gqjbF5tBXlRBy+oiYntO3BtzcxZuEtlLMzNaTNzC4dyMOFub0GkzIPWwOzkARoEU9Kv+bC97fDVbCBUKeyzzEqxqddUKhzRxeaYjsefJ6XeTvBvDxwo7wDwyxZSuWdBeGAe4eARVHm7ypsd+AlvqxtzjyS27TK2BzdL4="
|
||||
matrix:
|
||||
# Order: a slower build first, so that we don't occupy an idle travis worker waiting for others to complete.
|
||||
- CI_MODE=js
|
||||
|
26
CHANGELOG.md
26
CHANGELOG.md
@ -1,3 +1,29 @@
|
||||
<a name="2.4.10"></a>
|
||||
## [2.4.10](https://github.com/angular/angular/compare/2.4.9...2.4.10) (2017-03-17)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **compiler:** fix decoding surrogate pairs ([#15154](https://github.com/angular/angular/issues/15154)) ([e5c9bbc](https://github.com/angular/angular/commit/e5c9bbc))
|
||||
* **router:** do not finish bootstrap until all the routes are resolved ([#15121](https://github.com/angular/angular/issues/15121)) ([34403cd](https://github.com/angular/angular/commit/34403cd))
|
||||
|
||||
|
||||
<a name="2.4.9"></a>
|
||||
## [2.4.9](https://github.com/angular/angular/compare/2.4.8...2.4.9) (2017-03-02)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **http:** Make ResponseOptionsArgs an interface ([b658fa9](https://github.com/angular/angular/commit/b658fa9)), closes [#13708](https://github.com/angular/angular/issues/13708)
|
||||
* **router:** improve robustness ([#14602](https://github.com/angular/angular/issues/14602)) ([2a12346](https://github.com/angular/angular/commit/2a12346))
|
||||
|
||||
|
||||
### Reverts
|
||||
|
||||
* fix(router): do not finish bootstrap until all the routes are resolved ([#14327](https://github.com/angular/angular/issues/14327)) ([de36f8a](https://github.com/angular/angular/commit/de36f8a)), closes [#14681](https://github.com/angular/angular/issues/14681) [#14588](https://github.com/angular/angular/issues/14588)
|
||||
|
||||
|
||||
|
||||
<a name="2.4.8"></a>
|
||||
## [2.4.8](https://github.com/angular/angular/compare/2.4.7...2.4.8) (2017-02-18)
|
||||
|
||||
|
@ -206,47 +206,38 @@ enum Endian {
|
||||
Big,
|
||||
}
|
||||
|
||||
function utf8Encode(str: string): string {
|
||||
let encoded: string = '';
|
||||
|
||||
export function utf8Encode(str: string): string {
|
||||
let encoded = '';
|
||||
for (let index = 0; index < str.length; index++) {
|
||||
const codePoint = decodeSurrogatePairs(str, index);
|
||||
let codePoint = str.charCodeAt(index);
|
||||
|
||||
// decode surrogate
|
||||
// see https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
|
||||
if (codePoint >= 0xd800 && codePoint <= 0xdbff && str.length > (index + 1)) {
|
||||
const low = str.charCodeAt(index + 1);
|
||||
if (low >= 0xdc00 && low <= 0xdfff) {
|
||||
index++;
|
||||
codePoint = ((codePoint - 0xd800) << 10) + low - 0xdc00 + 0x10000;
|
||||
}
|
||||
}
|
||||
|
||||
if (codePoint <= 0x7f) {
|
||||
encoded += String.fromCharCode(codePoint);
|
||||
} else if (codePoint <= 0x7ff) {
|
||||
encoded += String.fromCharCode(0xc0 | codePoint >>> 6, 0x80 | codePoint & 0x3f);
|
||||
encoded += String.fromCharCode(((codePoint >> 6) & 0x1F) | 0xc0, (codePoint & 0x3f) | 0x80);
|
||||
} else if (codePoint <= 0xffff) {
|
||||
encoded += String.fromCharCode(
|
||||
0xe0 | codePoint >>> 12, 0x80 | codePoint >>> 6 & 0x3f, 0x80 | codePoint & 0x3f);
|
||||
(codePoint >> 12) | 0xe0, ((codePoint >> 6) & 0x3f) | 0x80, (codePoint & 0x3f) | 0x80);
|
||||
} else if (codePoint <= 0x1fffff) {
|
||||
encoded += String.fromCharCode(
|
||||
0xf0 | codePoint >>> 18, 0x80 | codePoint >>> 12 & 0x3f, 0x80 | codePoint >>> 6 & 0x3f,
|
||||
0x80 | codePoint & 0x3f);
|
||||
((codePoint >> 18) & 0x07) | 0xf0, ((codePoint >> 12) & 0x3f) | 0x80,
|
||||
((codePoint >> 6) & 0x3f) | 0x80, (codePoint & 0x3f) | 0x80);
|
||||
}
|
||||
}
|
||||
|
||||
return encoded;
|
||||
}
|
||||
|
||||
// see https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
|
||||
function decodeSurrogatePairs(str: string, index: number): number {
|
||||
if (index < 0 || index >= str.length) {
|
||||
throw new Error(`index=${index} is out of range in "${str}"`);
|
||||
}
|
||||
|
||||
const high = str.charCodeAt(index);
|
||||
|
||||
if (high >= 0xd800 && high <= 0xdfff && str.length > index + 1) {
|
||||
const low = byteAt(str, index + 1);
|
||||
if (low >= 0xdc00 && low <= 0xdfff) {
|
||||
return (high - 0xd800) * 0x400 + low - 0xdc00 + 0x10000;
|
||||
}
|
||||
}
|
||||
|
||||
return high;
|
||||
}
|
||||
|
||||
function add32(a: number, b: number): number {
|
||||
return add32to64(a, b)[1];
|
||||
}
|
||||
|
@ -6,7 +6,7 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {computeMsgId, sha1} from '../../src/i18n/digest';
|
||||
import {computeMsgId, sha1, utf8Encode} from '../../src/i18n/digest';
|
||||
|
||||
export function main(): void {
|
||||
describe('digest', () => {
|
||||
@ -100,7 +100,46 @@ export function main(): void {
|
||||
}
|
||||
expect(computeMsgId(result, '')).toEqual('2122606631351252558');
|
||||
});
|
||||
});
|
||||
|
||||
describe('utf8encode', () => {
|
||||
// tests from https://github.com/mathiasbynens/wtf-8
|
||||
it('should encode to utf8', () => {
|
||||
const tests = [
|
||||
['abc', 'abc'],
|
||||
// // 1-byte
|
||||
['\0', '\0'],
|
||||
// // 2-byte
|
||||
['\u0080', '\xc2\x80'],
|
||||
['\u05ca', '\xd7\x8a'],
|
||||
['\u07ff', '\xdf\xbf'],
|
||||
// // 3-byte
|
||||
['\u0800', '\xe0\xa0\x80'],
|
||||
['\u2c3c', '\xe2\xb0\xbc'],
|
||||
['\uffff', '\xef\xbf\xbf'],
|
||||
// //4-byte
|
||||
['\uD800\uDC00', '\xF0\x90\x80\x80'],
|
||||
['\uD834\uDF06', '\xF0\x9D\x8C\x86'],
|
||||
['\uDBFF\uDFFF', '\xF4\x8F\xBF\xBF'],
|
||||
// unmatched surrogate halves
|
||||
// high surrogates: 0xD800 to 0xDBFF
|
||||
['\uD800', '\xED\xA0\x80'],
|
||||
['\uD800\uD800', '\xED\xA0\x80\xED\xA0\x80'],
|
||||
['\uD800A', '\xED\xA0\x80A'],
|
||||
['\uD800\uD834\uDF06\uD800', '\xED\xA0\x80\xF0\x9D\x8C\x86\xED\xA0\x80'],
|
||||
['\uD9AF', '\xED\xA6\xAF'],
|
||||
['\uDBFF', '\xED\xAF\xBF'],
|
||||
// low surrogates: 0xDC00 to 0xDFFF
|
||||
['\uDC00', '\xED\xB0\x80'],
|
||||
['\uDC00\uDC00', '\xED\xB0\x80\xED\xB0\x80'],
|
||||
['\uDC00A', '\xED\xB0\x80A'],
|
||||
['\uDC00\uD834\uDF06\uDC00', '\xED\xB0\x80\xF0\x9D\x8C\x86\xED\xB0\x80'],
|
||||
['\uDEEE', '\xED\xBB\xAE'],
|
||||
['\uDFFF', '\xED\xBF\xBF'],
|
||||
];
|
||||
tests.forEach(
|
||||
([input, output]: [string, string]) => { expect(utf8Encode(input)).toEqual(output); });
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -66,9 +66,11 @@ export interface RequestArgs extends RequestOptionsArgs { url: string; }
|
||||
*
|
||||
* @experimental
|
||||
*/
|
||||
export type ResponseOptionsArgs = {
|
||||
body?: string | Object | FormData | ArrayBuffer | Blob; status?: number; statusText?: string;
|
||||
export interface ResponseOptionsArgs {
|
||||
body?: string|Object|FormData|ArrayBuffer|Blob;
|
||||
status?: number;
|
||||
statusText?: string;
|
||||
headers?: Headers;
|
||||
type?: ResponseType;
|
||||
url?: string;
|
||||
};
|
||||
}
|
||||
|
@ -12,7 +12,6 @@ import {APP_INITIALIZER, NgZone, OpaqueToken} from '@angular/core';
|
||||
import {WebWorkerPlatformLocation} from './platform_location';
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Those providers should be added when the router is used in a worker context in addition to the
|
||||
* {@link ROUTER_PROVIDERS} and after them.
|
||||
|
@ -278,6 +278,7 @@ type NavigationParams = {
|
||||
source: NavigationSource,
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
@ -290,7 +291,6 @@ function defaultRouterHook(snapshot: RouterStateSnapshot): Observable<void> {
|
||||
return of (null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Does not detach any subtrees. Reuses routes as long as their route config is the same.
|
||||
*/
|
||||
@ -340,6 +340,7 @@ export class Router {
|
||||
navigated: boolean = false;
|
||||
|
||||
/**
|
||||
* Extracts and merges URLs. Used for Angular 1 to Angular 2 migrations.
|
||||
* Used by RouterModule. This allows us to
|
||||
* pause the navigation either before preactivation or after it.
|
||||
* @internal
|
||||
@ -350,7 +351,7 @@ export class Router {
|
||||
};
|
||||
|
||||
/**
|
||||
* Extracts and merges URLs. Used for Angular 1 to Angular 2 migrations.
|
||||
* Extracts and merges URLs. Used for AngularJS to Angular migrations.
|
||||
*/
|
||||
urlHandlingStrategy: UrlHandlingStrategy = new DefaultUrlHandlingStrategy();
|
||||
|
||||
|
@ -44,10 +44,13 @@ export class RouterConfigLoader {
|
||||
if (typeof loadChildren === 'string') {
|
||||
return fromPromise(this.loader.load(loadChildren));
|
||||
} else {
|
||||
const offlineMode = this.compiler instanceof Compiler;
|
||||
return mergeMap.call(
|
||||
wrapIntoObservable(loadChildren()),
|
||||
(t: any) => offlineMode ? of (<any>t) : fromPromise(this.compiler.compileModuleAsync(t)));
|
||||
return mergeMap.call(wrapIntoObservable(loadChildren()), (t: NgModuleFactory<any>| any) => {
|
||||
if (t instanceof NgModuleFactory) {
|
||||
return of (t);
|
||||
} else {
|
||||
return fromPromise(this.compiler.compileModuleAsync(t));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -112,7 +112,7 @@ export function routerNgProbeToken() {
|
||||
* In addition, we often want to split applications into multiple bundles and load them on demand.
|
||||
* Doing this transparently is not trivial.
|
||||
*
|
||||
* The Angular router solves these problems. Using the router, you can declaratively specify
|
||||
* The Angular 2 router solves these problems. Using the router, you can declaratively specify
|
||||
* application states, manage state transitions while taking care of the URL, and load bundles on
|
||||
* demand.
|
||||
*
|
||||
@ -210,6 +210,32 @@ export function provideRoutes(routes: Routes): any {
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @whatItDoes Represents an option to configure when the initial navigation is performed.
|
||||
*
|
||||
* @description
|
||||
* * 'enabled' - the initial navigation starts before the root component is created.
|
||||
* The bootstrap is blocked until the initial navigation is complete.
|
||||
* * 'disabled' - the initial navigation is not performed. The location listener is set up before
|
||||
* the root component gets created.
|
||||
* * 'legacy_enabled'- the initial navigation starts after the root component has been created.
|
||||
* The bootstrap is not blocked until the initial navigation is complete. @deprecated
|
||||
* * 'legacy_disabled'- the initial navigation is not performed. The location listener is set up
|
||||
* after @deprecated
|
||||
* the root component gets created.
|
||||
* * `true` - same as 'legacy_enabled'. @deprecated
|
||||
* * `false` - same as 'legacy_disabled'. @deprecated
|
||||
*
|
||||
* The 'enabled' option should be used for applications unless there is a reason to have
|
||||
* more control over when the router starts its initial navigation due to some complex
|
||||
* initialization logic. In this case, 'disabled' should be used.
|
||||
*
|
||||
* The 'legacy_enabled' and 'legacy_disabled' should not be used for new applications.
|
||||
*
|
||||
* @experimental
|
||||
*/
|
||||
export type InitialNavigation =
|
||||
boolean | 'enabled' | 'disabled' | 'legacy_enabled' | 'legacy_disabled';
|
||||
|
||||
/**
|
||||
* @whatItDoes Represents options to configure the router.
|
||||
@ -230,7 +256,7 @@ export interface ExtraOptions {
|
||||
/**
|
||||
* Disables the initial navigation.
|
||||
*/
|
||||
initialNavigation?: boolean;
|
||||
initialNavigation?: InitialNavigation;
|
||||
|
||||
/**
|
||||
* A custom error handler.
|
||||
@ -293,7 +319,7 @@ export function rootRoute(router: Router): ActivatedRoute {
|
||||
*/
|
||||
@Injectable()
|
||||
export class RouterInitializer {
|
||||
private initNavigation: boolean;
|
||||
private initNavigation: boolean = false;
|
||||
private resultOfPreactivationDone = new Subject<void>();
|
||||
|
||||
constructor(private injector: Injector) {}
|
||||
@ -306,9 +332,14 @@ export class RouterInitializer {
|
||||
const router = this.injector.get(Router);
|
||||
const opts = this.injector.get(ROUTER_CONFIGURATION);
|
||||
|
||||
if (opts.initialNavigation === false) {
|
||||
if (this.isLegacyDisabled(opts) || this.isLegacyEnabled(opts)) {
|
||||
resolve(true);
|
||||
|
||||
} else if (opts.initialNavigation === 'disabled') {
|
||||
router.setUpLocationChangeListener();
|
||||
} else {
|
||||
resolve(true);
|
||||
|
||||
} else if (opts.initialNavigation === 'enabled') {
|
||||
router.hooks.afterPreactivation = () => {
|
||||
// only the initial navigation should be delayed
|
||||
if (!this.initNavigation) {
|
||||
@ -322,6 +353,9 @@ export class RouterInitializer {
|
||||
}
|
||||
};
|
||||
router.initialNavigation();
|
||||
|
||||
} else {
|
||||
throw new Error(`Invalid initialNavigation options: '${opts.initialNavigation}'`);
|
||||
}
|
||||
|
||||
return res;
|
||||
@ -329,20 +363,35 @@ export class RouterInitializer {
|
||||
}
|
||||
|
||||
bootstrapListener(bootstrappedComponentRef: ComponentRef<any>): void {
|
||||
const opts = this.injector.get(ROUTER_CONFIGURATION);
|
||||
const preloader = this.injector.get(RouterPreloader);
|
||||
const router = this.injector.get(Router);
|
||||
const ref = this.injector.get(ApplicationRef);
|
||||
|
||||
if (bootstrappedComponentRef !== ref.components[0]) {
|
||||
return;
|
||||
}
|
||||
|
||||
const preloader = this.injector.get(RouterPreloader);
|
||||
if (this.isLegacyEnabled(opts)) {
|
||||
router.initialNavigation();
|
||||
} else if (this.isLegacyDisabled(opts)) {
|
||||
router.setUpLocationChangeListener();
|
||||
}
|
||||
|
||||
preloader.setUpPreloading();
|
||||
|
||||
const router = this.injector.get(Router);
|
||||
router.resetRootComponentType(ref.componentTypes[0]);
|
||||
|
||||
this.resultOfPreactivationDone.next(null);
|
||||
this.resultOfPreactivationDone.complete();
|
||||
}
|
||||
|
||||
private isLegacyEnabled(opts: ExtraOptions): boolean {
|
||||
return opts.initialNavigation === 'legacy_enabled' || opts.initialNavigation === true ||
|
||||
opts.initialNavigation === undefined;
|
||||
}
|
||||
|
||||
private isLegacyDisabled(opts: ExtraOptions): boolean {
|
||||
return opts.initialNavigation === 'legacy_disabled' || opts.initialNavigation === false;
|
||||
}
|
||||
}
|
||||
|
||||
export function getAppInitializer(r: RouterInitializer) {
|
||||
|
@ -8,25 +8,26 @@
|
||||
|
||||
import {APP_BASE_HREF} from '@angular/common';
|
||||
import {ApplicationRef, CUSTOM_ELEMENTS_SCHEMA, Component, NgModule, destroyPlatform} from '@angular/core';
|
||||
import {inject} from '@angular/core/testing';
|
||||
import {BrowserModule, DOCUMENT} from '@angular/platform-browser';
|
||||
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
|
||||
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
||||
import {Resolve, Router, RouterModule} from '@angular/router';
|
||||
import {NavigationEnd, Resolve, Router, RouterModule} from '@angular/router';
|
||||
import {getDOM} from '../src/private_import_platform-browser';
|
||||
|
||||
|
||||
describe('bootstrap', () => {
|
||||
let log: any[] = [];
|
||||
let testProviders: any[] = null;
|
||||
|
||||
@Component({selector: 'test-app', template: 'root <router-outlet></router-outlet>'})
|
||||
class RootCmp {
|
||||
constructor() { log.push('RootCmp'); }
|
||||
}
|
||||
|
||||
@Component({selector: 'test-app2', template: 'root <router-outlet></router-outlet>'})
|
||||
class SecondRootCmp {
|
||||
}
|
||||
|
||||
@Component({selector: 'test', template: 'test'})
|
||||
class TestCmp {
|
||||
}
|
||||
|
||||
class TestResolver implements Resolve<any> {
|
||||
resolve() {
|
||||
let resolve: any = null;
|
||||
@ -36,38 +37,154 @@ describe('bootstrap', () => {
|
||||
}
|
||||
}
|
||||
|
||||
let testProviders: any[] = null;
|
||||
|
||||
beforeEach(() => {
|
||||
beforeEach(inject([DOCUMENT], (doc: any) => {
|
||||
destroyPlatform();
|
||||
const fakeDoc = getDOM().createHtmlDocument();
|
||||
const el1 = getDOM().createElement('test-app', fakeDoc);
|
||||
const el2 = getDOM().createElement('test-app2', fakeDoc);
|
||||
getDOM().appendChild(fakeDoc.body, el1);
|
||||
getDOM().appendChild(fakeDoc.body, el2);
|
||||
testProviders =
|
||||
[{provide: DOCUMENT, useValue: fakeDoc}, {provide: APP_BASE_HREF, useValue: ''}];
|
||||
});
|
||||
|
||||
it('should wait for resolvers to complete', (done) => {
|
||||
const el1 = getDOM().createElement('test-app', doc);
|
||||
const el2 = getDOM().createElement('test-app2', doc);
|
||||
getDOM().appendChild(doc.body, el1);
|
||||
getDOM().appendChild(doc.body, el2);
|
||||
|
||||
log = [];
|
||||
testProviders = [{provide: APP_BASE_HREF, useValue: ''}];
|
||||
}));
|
||||
|
||||
afterEach(inject([DOCUMENT], (doc: any) => {
|
||||
const oldRoots = getDOM().querySelectorAll(doc, 'test-app,test-app2');
|
||||
for (let i = 0; i < oldRoots.length; i++) {
|
||||
getDOM().remove(oldRoots[i]);
|
||||
}
|
||||
}));
|
||||
|
||||
it('should wait for resolvers to complete when initialNavigation = enabled', (done) => {
|
||||
@Component({selector: 'test', template: 'test'})
|
||||
class TestCmpEnabled {
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
BrowserModule,
|
||||
RouterModule.forRoot(
|
||||
[{path: '**', component: TestCmp, resolve: {test: TestResolver}}], {useHash: true})
|
||||
BrowserModule, RouterModule.forRoot(
|
||||
[{path: '**', component: TestCmpEnabled, resolve: {test: TestResolver}}],
|
||||
{useHash: true, initialNavigation: 'enabled'})
|
||||
],
|
||||
declarations: [SecondRootCmp, RootCmp, TestCmp],
|
||||
declarations: [RootCmp, TestCmpEnabled],
|
||||
bootstrap: [RootCmp],
|
||||
providers: [...testProviders, TestResolver],
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA]
|
||||
})
|
||||
class TestModule {
|
||||
constructor(router: Router) {
|
||||
log.push('TestModule');
|
||||
router.events.subscribe(e => log.push(e.constructor.name));
|
||||
}
|
||||
}
|
||||
|
||||
platformBrowserDynamic([]).bootstrapModule(TestModule).then(res => {
|
||||
const router = res.injector.get(Router);
|
||||
const data = router.routerState.snapshot.root.firstChild.data;
|
||||
expect(data['test']).toEqual('test-data');
|
||||
expect(log).toEqual(
|
||||
['TestModule', 'NavigationStart', 'RoutesRecognized', 'RootCmp', 'NavigationEnd']);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should NOT wait for resolvers to complete when initialNavigation = legacy_enabled',
|
||||
(done) => {
|
||||
@Component({selector: 'test', template: 'test'})
|
||||
class TestCmpLegacyEnabled {
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
BrowserModule,
|
||||
RouterModule.forRoot(
|
||||
[{path: '**', component: TestCmpLegacyEnabled, resolve: {test: TestResolver}}],
|
||||
{useHash: true, initialNavigation: 'legacy_enabled'})
|
||||
],
|
||||
declarations: [RootCmp, TestCmpLegacyEnabled],
|
||||
bootstrap: [RootCmp],
|
||||
providers: [...testProviders, TestResolver],
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA]
|
||||
})
|
||||
class TestModule {
|
||||
constructor(router: Router) {
|
||||
log.push('TestModule');
|
||||
router.events.subscribe(e => log.push(e.constructor.name));
|
||||
}
|
||||
}
|
||||
|
||||
platformBrowserDynamic([]).bootstrapModule(TestModule).then(res => {
|
||||
const router = res.injector.get(Router);
|
||||
expect(router.routerState.snapshot.root.firstChild).toBeNull();
|
||||
// NavigationEnd has not been emitted yet because bootstrap returned too early
|
||||
expect(log).toEqual(['TestModule', 'RootCmp', 'NavigationStart', 'RoutesRecognized']);
|
||||
|
||||
router.events.subscribe((e: any) => {
|
||||
if (e instanceof NavigationEnd) {
|
||||
done();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should not run navigation when initialNavigation = disabled', (done) => {
|
||||
@Component({selector: 'test', template: 'test'})
|
||||
class TestCmpDiabled {
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
BrowserModule, RouterModule.forRoot(
|
||||
[{path: '**', component: TestCmpDiabled, resolve: {test: TestResolver}}],
|
||||
{useHash: true, initialNavigation: 'disabled'})
|
||||
],
|
||||
declarations: [RootCmp, TestCmpDiabled],
|
||||
bootstrap: [RootCmp],
|
||||
providers: [...testProviders, TestResolver],
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA]
|
||||
})
|
||||
class TestModule {
|
||||
constructor(router: Router) {
|
||||
log.push('TestModule');
|
||||
router.events.subscribe(e => log.push(e.constructor.name));
|
||||
}
|
||||
}
|
||||
|
||||
platformBrowserDynamic([]).bootstrapModule(TestModule).then(res => {
|
||||
const router = res.injector.get(Router);
|
||||
expect(log).toEqual(['TestModule', 'RootCmp']);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should not run navigation when initialNavigation = legacy_disabled', (done) => {
|
||||
@Component({selector: 'test', template: 'test'})
|
||||
class TestCmpLegacyDisabled {
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
BrowserModule,
|
||||
RouterModule.forRoot(
|
||||
[{path: '**', component: TestCmpLegacyDisabled, resolve: {test: TestResolver}}],
|
||||
{useHash: true, initialNavigation: 'legacy_disabled'})
|
||||
],
|
||||
declarations: [RootCmp, TestCmpLegacyDisabled],
|
||||
bootstrap: [RootCmp],
|
||||
providers: [...testProviders, TestResolver],
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA]
|
||||
})
|
||||
class TestModule {
|
||||
constructor(router: Router) {
|
||||
log.push('TestModule');
|
||||
router.events.subscribe(e => log.push(e.constructor.name));
|
||||
}
|
||||
}
|
||||
|
||||
platformBrowserDynamic([]).bootstrapModule(TestModule).then(res => {
|
||||
const router = res.injector.get(Router);
|
||||
expect(log).toEqual(['TestModule', 'RootCmp']);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
@ -5,14 +5,14 @@
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {APP_BOOTSTRAP_LISTENER, ComponentRef, OpaqueToken} from '@angular/core';
|
||||
import {Router} from '@angular/router';
|
||||
import {UpgradeModule} from '@angular/upgrade/static';
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @whatItDoes Creates an initializer that in addition to setting up the Angular
|
||||
* @whatItDoes Creates an initializer that in addition to setting up the Angular 2
|
||||
* router sets up the ngRoute integration.
|
||||
*
|
||||
* @howToUse
|
||||
@ -72,4 +72,4 @@ export function setUpLocationSync(ngUpgrade: UpgradeModule) {
|
||||
url.href = next;
|
||||
router.navigateByUrl(url.pathname);
|
||||
});
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "angular-srcs",
|
||||
"version": "2.4.8",
|
||||
"version": "2.4.10",
|
||||
"private": true,
|
||||
"branchPattern": "2.0.*",
|
||||
"description": "Angular 2 - a web framework for modern web apps",
|
||||
|
6
tools/public_api_guard/http/index.d.ts
vendored
6
tools/public_api_guard/http/index.d.ts
vendored
@ -191,14 +191,14 @@ export declare class ResponseOptions {
|
||||
}
|
||||
|
||||
/** @experimental */
|
||||
export declare type ResponseOptionsArgs = {
|
||||
export interface ResponseOptionsArgs {
|
||||
body?: string | Object | FormData | ArrayBuffer | Blob;
|
||||
headers?: Headers;
|
||||
status?: number;
|
||||
statusText?: string;
|
||||
headers?: Headers;
|
||||
type?: ResponseType;
|
||||
url?: string;
|
||||
};
|
||||
}
|
||||
|
||||
/** @experimental */
|
||||
export declare enum ResponseType {
|
||||
|
2
tools/public_api_guard/router/index.d.ts
vendored
2
tools/public_api_guard/router/index.d.ts
vendored
@ -76,7 +76,7 @@ export declare type Event = NavigationStart | NavigationEnd | NavigationCancel |
|
||||
export interface ExtraOptions {
|
||||
enableTracing?: boolean;
|
||||
errorHandler?: ErrorHandler;
|
||||
initialNavigation?: boolean;
|
||||
initialNavigation?: InitialNavigation;
|
||||
preloadingStrategy?: any;
|
||||
useHash?: boolean;
|
||||
}
|
||||
|
Reference in New Issue
Block a user