fix(ngUpgrade): make AoT ngUpgrade work with the testability API and resumeBootstrap() (#12910)
This commit is contained in:
parent
d6ba092a27
commit
42198cd7d5
|
@ -13,6 +13,9 @@ export const $INJECTOR = '$injector';
|
|||
export const $PARSE = '$parse';
|
||||
export const $ROOT_SCOPE = '$rootScope';
|
||||
export const $SCOPE = '$scope';
|
||||
export const $PROVIDE = '$provide';
|
||||
export const $DELEGATE = '$delegate';
|
||||
export const $$TESTABILITY = '$$testability';
|
||||
|
||||
export const $COMPILE = '$compile';
|
||||
export const $TEMPLATE_CACHE = '$templateCache';
|
||||
|
|
|
@ -6,13 +6,14 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {Injector, NgModule, NgZone} from '@angular/core';
|
||||
import {Injector, NgModule, NgZone, Testability} from '@angular/core';
|
||||
|
||||
import * as angular from '../angular_js';
|
||||
import {controllerKey} from '../util';
|
||||
|
||||
import {angular1Providers, setTempInjectorRef} from './angular1_providers';
|
||||
import {$INJECTOR, INJECTOR_KEY, UPGRADE_MODULE_NAME} from './constants';
|
||||
import {$$TESTABILITY, $DELEGATE, $INJECTOR, $PROVIDE, $ROOT_SCOPE, INJECTOR_KEY, UPGRADE_MODULE_NAME} from './constants';
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
@ -40,6 +41,37 @@ export class UpgradeModule {
|
|||
|
||||
.value(INJECTOR_KEY, this.injector)
|
||||
|
||||
.config([
|
||||
$PROVIDE, $INJECTOR,
|
||||
($provide: angular.IProvideService, $injector: angular.IInjectorService) => {
|
||||
if ($injector.has($$TESTABILITY)) {
|
||||
$provide.decorator($$TESTABILITY, [
|
||||
$DELEGATE,
|
||||
(testabilityDelegate: angular.ITestabilityService) => {
|
||||
const originalWhenStable: Function = testabilityDelegate.whenStable;
|
||||
const injector = this.injector;
|
||||
// Cannot use arrow function below because we need to grab the context
|
||||
const newWhenStable = function(callback: Function) {
|
||||
const whenStableContext: any = this;
|
||||
originalWhenStable.call(this, function() {
|
||||
const ng2Testability: Testability = injector.get(Testability);
|
||||
if (ng2Testability.isStable()) {
|
||||
callback.apply(this, arguments);
|
||||
} else {
|
||||
ng2Testability.whenStable(
|
||||
newWhenStable.bind(whenStableContext, callback));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
testabilityDelegate.whenStable = newWhenStable;
|
||||
return testabilityDelegate;
|
||||
}
|
||||
]);
|
||||
}
|
||||
}
|
||||
])
|
||||
|
||||
.run([
|
||||
$INJECTOR,
|
||||
($injector: angular.IInjectorService) => {
|
||||
|
@ -59,7 +91,22 @@ export class UpgradeModule {
|
|||
}
|
||||
]);
|
||||
|
||||
// Make sure resumeBootstrap() only exists if the current bootstrap is deferred
|
||||
const windowAngular = (window as any /** TODO #???? */)['angular'];
|
||||
windowAngular.resumeBootstrap = undefined;
|
||||
|
||||
// Bootstrap the angular 1 application inside our zone
|
||||
this.ngZone.run(() => { angular.bootstrap(element, [upgradeModule.name], config); });
|
||||
|
||||
// Patch resumeBootstrap() to run inside the ngZone
|
||||
if (windowAngular.resumeBootstrap) {
|
||||
const originalResumeBootstrap: () => void = windowAngular.resumeBootstrap;
|
||||
const ngZone = this.ngZone;
|
||||
windowAngular.resumeBootstrap = function() {
|
||||
let args = arguments;
|
||||
windowAngular.resumeBootstrap = originalResumeBootstrap;
|
||||
ngZone.run(() => { windowAngular.resumeBootstrap.apply(this, args); });
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
*/
|
||||
|
||||
import {NgModule, Testability, destroyPlatform} from '@angular/core';
|
||||
import {NgZone} from '@angular/core/src/zone/ng_zone';
|
||||
import {fakeAsync, tick} from '@angular/core/testing';
|
||||
import {BrowserModule} from '@angular/platform-browser';
|
||||
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
|
||||
|
@ -28,7 +29,11 @@ export function main() {
|
|||
|
||||
it('should handle deferred bootstrap', fakeAsync(() => {
|
||||
let applicationRunning = false;
|
||||
const ng1Module = angular.module('ng1', []).run(() => { applicationRunning = true; });
|
||||
let stayedInTheZone: boolean;
|
||||
const ng1Module = angular.module('ng1', []).run(() => {
|
||||
applicationRunning = true;
|
||||
stayedInTheZone = NgZone.isInAngularZone();
|
||||
});
|
||||
|
||||
const element = html('<div></div>');
|
||||
window.name = 'NG_DEFER_BOOTSTRAP!' + window.name;
|
||||
|
@ -40,6 +45,7 @@ export function main() {
|
|||
expect(applicationRunning).toEqual(false);
|
||||
tick(100);
|
||||
expect(applicationRunning).toEqual(true);
|
||||
expect(stayedInTheZone).toEqual(true);
|
||||
}));
|
||||
|
||||
it('should wait for ng2 testability', fakeAsync(() => {
|
||||
|
|
Loading…
Reference in New Issue