feat(upgrade): return a function (instead of array) from `downgradeInjectable()` (#14037)
This makes it more consistent with the dynamic version of `upgrade` and makes it possible to share code between the dynamic and static versions. This commit also refactors the file layout, moving common and dynamic-specific files to `common/` and `dynamic/` directories respectively and renaming `aot/` to `static/`. Some private keys, used as AngularJS DI tokens, have also been renamed, but this should not affect apps, since these keys are undocumented and not supposed to be used externally. BREAKING CHANGE: Previously, `upgrade/static/downgradeInjectable` returned an array of the form: ```js ['dep1', 'dep2', ..., function factory(dep1, dep2, ...) { ... }] ``` Now it returns a function with an `$inject` property: ```js factory.$inject = ['dep1', 'dep2', ...]; function factory(dep1, dep2, ...) { ... } ``` It shouldn't affect the behavior of apps, since both forms are equally suitable to be used for registering AngularJS injectable services, but it is possible that type-checking might fail or that current code breaks if it relies on the returned value being an array.
This commit is contained in:
parent
49fce37013
commit
1f90f29369
|
@ -9,7 +9,10 @@
|
|||
/**
|
||||
* @module
|
||||
* @description
|
||||
* Entry point for all public APIs of the upgrade package.
|
||||
* Entry point for all public APIs of the upgrade/dynamic package, allowing
|
||||
* Angular 1 and Angular 2+ to run side by side in the same application.
|
||||
*/
|
||||
export * from './src/upgrade';
|
||||
// This file only reexports content of the `src` folder. Keep it that way.
|
||||
export {VERSION} from './src/common/version';
|
||||
export {UpgradeAdapter, UpgradeAdapterRef} from './src/dynamic/upgrade_adapter';
|
||||
|
||||
// This file only re-exports content of the `src` folder. Keep it that way.
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
export type Ng1Token = string;
|
||||
|
||||
export type Ng1Expression = string | Function;
|
||||
|
||||
export interface IAnnotatedFunction extends Function { $inject?: Ng1Token[]; }
|
||||
|
||||
export type IInjectable = (Ng1Token | Function)[] | IAnnotatedFunction;
|
||||
|
@ -42,12 +44,10 @@ export interface IRootScopeService {
|
|||
$id: string;
|
||||
$parent: IScope;
|
||||
$root: IScope;
|
||||
$watch(expr: any, fn?: (a1?: any, a2?: any) => void): Function;
|
||||
$watch(exp: Ng1Expression, fn?: (a1?: any, a2?: any) => void): Function;
|
||||
$on(event: string, fn?: (event?: any, ...args: any[]) => void): Function;
|
||||
$destroy(): any;
|
||||
$apply(): any;
|
||||
$apply(exp: string): any;
|
||||
$apply(exp: Function): any;
|
||||
$apply(exp?: Ng1Expression): any;
|
||||
$digest(): any;
|
||||
$evalAsync(): any;
|
||||
$on(event: string, fn?: (event?: any, ...args: any[]) => void): Function;
|
||||
|
@ -142,6 +142,10 @@ export interface ICacheObject {
|
|||
get(key: string): any;
|
||||
}
|
||||
export interface ITemplateCacheService extends ICacheObject {}
|
||||
export interface ITemplateRequestService {
|
||||
(template: string|any /* TrustedResourceUrl */, ignoreRequestError?: boolean): Promise<string>;
|
||||
totalPendingRequests: number;
|
||||
}
|
||||
export type IController = string | IInjectable;
|
||||
export interface IControllerService {
|
||||
(controllerConstructor: IController, locals?: any, later?: any, ident?: any): any;
|
|
@ -6,19 +6,26 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
export const UPGRADE_MODULE_NAME = '$$UpgradeModule';
|
||||
export const INJECTOR_KEY = '$$angularInjector';
|
||||
export const REQUIRE_NG1_MODEL = '?ngModel';
|
||||
|
||||
export const $COMPILE = '$compile';
|
||||
export const $CONTROLLER = '$controller';
|
||||
export const $DELEGATE = '$delegate';
|
||||
export const $HTTP_BACKEND = '$httpBackend';
|
||||
export const $INJECTOR = '$injector';
|
||||
export const $PARSE = '$parse';
|
||||
export const $PROVIDE = '$provide';
|
||||
export const $ROOT_SCOPE = '$rootScope';
|
||||
export const $SCOPE = '$scope';
|
||||
export const $PROVIDE = '$provide';
|
||||
export const $DELEGATE = '$delegate';
|
||||
export const $TEMPLATE_CACHE = '$templateCache';
|
||||
export const $TEMPLATE_REQUEST = '$templateRequest';
|
||||
|
||||
export const $$TESTABILITY = '$$testability';
|
||||
|
||||
export const $COMPILE = '$compile';
|
||||
export const $TEMPLATE_CACHE = '$templateCache';
|
||||
export const $HTTP_BACKEND = '$httpBackend';
|
||||
export const $CONTROLLER = '$controller';
|
||||
export const COMPILER_KEY = '$$angularCompiler';
|
||||
export const COMPONENT_FACTORY_REF_MAP_KEY = '$$angularComponentFactoryRefMap';
|
||||
export const INJECTOR_KEY = '$$angularInjector';
|
||||
export const NG_ZONE_KEY = '$$angularNgZone';
|
||||
|
||||
export const REQUIRE_INJECTOR = '?^^' + INJECTOR_KEY;
|
||||
export const REQUIRE_NG_MODEL = '?ngModel';
|
||||
|
||||
export const UPGRADE_MODULE_NAME = '$$UpgradeModule';
|
|
@ -51,6 +51,9 @@ import {INJECTOR_KEY} from './constants';
|
|||
*
|
||||
* @experimental
|
||||
*/
|
||||
export function downgradeInjectable(token: any) {
|
||||
return [INJECTOR_KEY, (i: Injector) => i.get(token)];
|
||||
}
|
||||
export function downgradeInjectable(token: any): Function {
|
||||
const factory = function(i: Injector) { return i.get(token); };
|
||||
(factory as any).$inject = [INJECTOR_KEY];
|
||||
|
||||
return factory;
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
export const NG2_COMPILER = 'ng2.Compiler';
|
||||
export const NG2_INJECTOR = 'ng2.Injector';
|
||||
export const NG2_COMPONENT_FACTORY_REF_MAP = 'ng2.ComponentFactoryRefMap';
|
||||
export const NG2_ZONE = 'ng2.NgZone';
|
||||
|
||||
export const NG1_PROVIDE = '$provide';
|
||||
export const NG1_CONTROLLER = '$controller';
|
||||
export const NG1_SCOPE = '$scope';
|
||||
export const NG1_ROOT_SCOPE = '$rootScope';
|
||||
export const NG1_COMPILE = '$compile';
|
||||
export const NG1_HTTP_BACKEND = '$httpBackend';
|
||||
export const NG1_INJECTOR = '$injector';
|
||||
export const NG1_PARSE = '$parse';
|
||||
export const NG1_TEMPLATE_CACHE = '$templateCache';
|
||||
export const NG1_TESTABILITY = '$$testability';
|
||||
export const REQUIRE_INJECTOR = '?^^' + NG2_INJECTOR;
|
||||
export const REQUIRE_NG1_MODEL = '?ngModel';
|
|
@ -8,8 +8,9 @@
|
|||
|
||||
import {ChangeDetectorRef, ComponentFactory, ComponentRef, EventEmitter, Injector, OnChanges, ReflectiveInjector, SimpleChange, SimpleChanges} from '@angular/core';
|
||||
|
||||
import * as angular from './angular_js';
|
||||
import {NG1_SCOPE} from './constants';
|
||||
import * as angular from '../common/angular1';
|
||||
import {$SCOPE} from '../common/constants';
|
||||
|
||||
import {ComponentInfo} from './metadata';
|
||||
import {hookupNgModel} from './util';
|
||||
|
||||
|
@ -35,7 +36,7 @@ export class DowngradeNg2ComponentAdapter {
|
|||
|
||||
bootstrapNg2(projectableNodes: Node[][]) {
|
||||
const childInjector = ReflectiveInjector.resolveAndCreate(
|
||||
[{provide: NG1_SCOPE, useValue: this.componentScope}], this.parentInjector);
|
||||
[{provide: $SCOPE, useValue: this.componentScope}], this.parentInjector);
|
||||
|
||||
this.componentRef =
|
||||
this.componentFactory.create(childInjector, projectableNodes, this.element[0]);
|
|
@ -10,12 +10,14 @@ import {CssSelector, SelectorMatcher, createElementCssSelector} from '@angular/c
|
|||
import {Compiler, CompilerOptions, ComponentFactory, Injector, NgModule, NgModuleRef, NgZone, Provider, Testability, Type} from '@angular/core';
|
||||
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
|
||||
|
||||
import * as angular from './angular_js';
|
||||
import {NG1_COMPILE, NG1_INJECTOR, NG1_PARSE, NG1_ROOT_SCOPE, NG1_TESTABILITY, NG2_COMPILER, NG2_COMPONENT_FACTORY_REF_MAP, NG2_INJECTOR, NG2_ZONE, REQUIRE_INJECTOR, REQUIRE_NG1_MODEL} from './constants';
|
||||
import * as angular from '../common/angular1';
|
||||
import {$$TESTABILITY, $COMPILE, $INJECTOR, $PARSE, $ROOT_SCOPE, COMPILER_KEY, COMPONENT_FACTORY_REF_MAP_KEY, INJECTOR_KEY, NG_ZONE_KEY, REQUIRE_INJECTOR, REQUIRE_NG_MODEL} from '../common/constants';
|
||||
import {downgradeInjectable} from '../common/downgrade_injectable';
|
||||
import {Deferred, controllerKey, getAttributesAsArray, onError} from '../common/util';
|
||||
|
||||
import {DowngradeNg2ComponentAdapter} from './downgrade_ng2_adapter';
|
||||
import {ComponentInfo, getComponentInfo} from './metadata';
|
||||
import {UpgradeNg1ComponentAdapterBuilder} from './upgrade_ng1_adapter';
|
||||
import {Deferred, controllerKey, getAttributesAsArray, onError} from './util';
|
||||
|
||||
let upgradeCount: number = 0;
|
||||
|
||||
|
@ -138,8 +140,8 @@ export class UpgradeAdapter {
|
|||
* 2. Even thought the component is instantiated in AngularJS, it will be using Angular
|
||||
* syntax. This has to be done, this way because we must follow Angular components do not
|
||||
* declare how the attributes should be interpreted.
|
||||
* 3. ng-model is controlled by AngularJS v1 and communicates with the downgraded Ng2 component
|
||||
* by way of the ControlValueAccessor interface from @angular/forms. Only components that
|
||||
* 3. `ng-model` is controlled by AngularJS and communicates with the downgraded Angular component
|
||||
* by way of the `ControlValueAccessor` interface from @angular/forms. Only components that
|
||||
* implement this interface are eligible.
|
||||
*
|
||||
* ## Supported Features
|
||||
|
@ -397,7 +399,7 @@ export class UpgradeAdapter {
|
|||
});
|
||||
|
||||
Promise.all([this.ng2BootstrapDeferred.promise, ng1BootstrapPromise]).then(([ng1Injector]) => {
|
||||
angular.element(element).data(controllerKey(NG2_INJECTOR), this.moduleRef.injector);
|
||||
angular.element(element).data(controllerKey(INJECTOR_KEY), this.moduleRef.injector);
|
||||
this.moduleRef.injector.get(NgZone).run(
|
||||
() => { (<any>upgrade)._bootstrapDone(this.moduleRef, ng1Injector); });
|
||||
}, onError);
|
||||
|
@ -440,7 +442,7 @@ export class UpgradeAdapter {
|
|||
this.providers.push({
|
||||
provide: token,
|
||||
useFactory: (ng1Injector: angular.IInjectorService) => ng1Injector.get(name),
|
||||
deps: [NG1_INJECTOR]
|
||||
deps: [$INJECTOR]
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -465,12 +467,7 @@ export class UpgradeAdapter {
|
|||
*
|
||||
* ```
|
||||
*/
|
||||
public downgradeNg2Provider(token: any): Function {
|
||||
const factory = function(injector: Injector) { return injector.get(token); };
|
||||
(<any>factory).$inject = [NG2_INJECTOR];
|
||||
return factory;
|
||||
}
|
||||
|
||||
downgradeNg2Provider(token: any): Function { return downgradeInjectable(token); }
|
||||
|
||||
/**
|
||||
* Declare the AngularJS upgrade module for this adapter without bootstrapping the whole
|
||||
|
@ -500,14 +497,14 @@ export class UpgradeAdapter {
|
|||
|
||||
this.ngZone = new NgZone({enableLongStackTrace: Zone.hasOwnProperty('longStackTraceZoneSpec')});
|
||||
this.ng2BootstrapDeferred = new Deferred();
|
||||
ng1Module.factory(NG2_INJECTOR, () => this.moduleRef.injector.get(Injector))
|
||||
.constant(NG2_ZONE, this.ngZone)
|
||||
.constant(NG2_COMPONENT_FACTORY_REF_MAP, componentFactoryRefMap)
|
||||
.factory(NG2_COMPILER, () => this.moduleRef.injector.get(Compiler))
|
||||
ng1Module.factory(INJECTOR_KEY, () => this.moduleRef.injector.get(Injector))
|
||||
.constant(NG_ZONE_KEY, this.ngZone)
|
||||
.constant(COMPONENT_FACTORY_REF_MAP_KEY, componentFactoryRefMap)
|
||||
.factory(COMPILER_KEY, () => this.moduleRef.injector.get(Compiler))
|
||||
.config([
|
||||
'$provide', '$injector',
|
||||
(provide: angular.IProvideService, ng1Injector: angular.IInjectorService) => {
|
||||
provide.decorator(NG1_ROOT_SCOPE, [
|
||||
provide.decorator($ROOT_SCOPE, [
|
||||
'$delegate',
|
||||
function(rootScopeDelegate: angular.IRootScopeService) {
|
||||
// Capture the root apply so that we can delay first call to $apply until we
|
||||
|
@ -522,8 +519,8 @@ export class UpgradeAdapter {
|
|||
return rootScope = rootScopeDelegate;
|
||||
}
|
||||
]);
|
||||
if (ng1Injector.has(NG1_TESTABILITY)) {
|
||||
provide.decorator(NG1_TESTABILITY, [
|
||||
if (ng1Injector.has($$TESTABILITY)) {
|
||||
provide.decorator($$TESTABILITY, [
|
||||
'$delegate',
|
||||
function(testabilityDelegate: angular.ITestabilityService) {
|
||||
const originalWhenStable: Function = testabilityDelegate.whenStable;
|
||||
|
@ -558,8 +555,8 @@ export class UpgradeAdapter {
|
|||
const DynamicNgUpgradeModule =
|
||||
NgModule({
|
||||
providers: [
|
||||
{provide: NG1_INJECTOR, useFactory: () => ng1Injector},
|
||||
{provide: NG1_COMPILE, useFactory: () => ng1Injector.get(NG1_COMPILE)},
|
||||
{provide: $INJECTOR, useFactory: () => ng1Injector},
|
||||
{provide: $COMPILE, useFactory: () => ng1Injector.get($COMPILE)},
|
||||
this.providers
|
||||
],
|
||||
imports: [this.ng2AppModule]
|
||||
|
@ -620,7 +617,7 @@ class ParentInjectorPromise {
|
|||
|
||||
constructor(private element: angular.IAugmentedJQuery) {
|
||||
// store the promise on the element
|
||||
element.data(controllerKey(NG2_INJECTOR), this);
|
||||
element.data(controllerKey(INJECTOR_KEY), this);
|
||||
}
|
||||
|
||||
then(callback: (injector: Injector) => any) {
|
||||
|
@ -635,7 +632,7 @@ class ParentInjectorPromise {
|
|||
this.injector = injector;
|
||||
|
||||
// reset the element data to point to the real injector
|
||||
this.element.data(controllerKey(NG2_INJECTOR), injector);
|
||||
this.element.data(controllerKey(INJECTOR_KEY), injector);
|
||||
|
||||
// clean out the element to prevent memory leaks
|
||||
this.element = null;
|
||||
|
@ -648,8 +645,7 @@ class ParentInjectorPromise {
|
|||
|
||||
|
||||
function ng1ComponentDirective(info: ComponentInfo, idPrefix: string): Function {
|
||||
(<any>directiveFactory).$inject =
|
||||
[NG1_INJECTOR, NG1_COMPILE, NG2_COMPONENT_FACTORY_REF_MAP, NG1_PARSE];
|
||||
(<any>directiveFactory).$inject = [$INJECTOR, $COMPILE, COMPONENT_FACTORY_REF_MAP_KEY, $PARSE];
|
||||
function directiveFactory(
|
||||
ng1Injector: angular.IInjectorService, ng1Compile: angular.ICompileService,
|
||||
componentFactoryRefMap: ComponentFactoryRefMap,
|
||||
|
@ -659,7 +655,7 @@ function ng1ComponentDirective(info: ComponentInfo, idPrefix: string): Function
|
|||
return {
|
||||
restrict: 'E',
|
||||
terminal: true,
|
||||
require: [REQUIRE_INJECTOR, REQUIRE_NG1_MODEL],
|
||||
require: [REQUIRE_INJECTOR, REQUIRE_NG_MODEL],
|
||||
compile: (templateElement: angular.IAugmentedJQuery, templateAttributes: angular.IAttributes,
|
||||
transclude: angular.ITranscludeFunction) => {
|
||||
// We might have compile the contents lazily, because this might have been triggered by the
|
||||
|
@ -671,11 +667,12 @@ function ng1ComponentDirective(info: ComponentInfo, idPrefix: string): Function
|
|||
let id = idPrefix + (idCount++);
|
||||
(<any>element[0]).id = id;
|
||||
|
||||
let parentInjector: Injector|ParentInjectorPromise = required[0];
|
||||
const ngModel: angular.INgModelController = required[1];
|
||||
let parentInjector: Injector | ParentInjectorPromise = required[0];
|
||||
let injectorPromise = new ParentInjectorPromise(element);
|
||||
|
||||
const ng2Compiler = ng1Injector.get(NG2_COMPILER) as Compiler;
|
||||
const ngModel: angular.INgModelController = required[1];
|
||||
|
||||
const ng2Compiler = ng1Injector.get(COMPILER_KEY) as Compiler;
|
||||
const ngContentSelectors = ng2Compiler.getNgContentSelectors(info.type);
|
||||
const linkFns = compileProjectedNodes(templateElement, ngContentSelectors);
|
||||
|
||||
|
@ -693,7 +690,7 @@ function ng1ComponentDirective(info: ComponentInfo, idPrefix: string): Function
|
|||
return projectedClone;
|
||||
});
|
||||
|
||||
parentInjector = parentInjector || ng1Injector.get(NG2_INJECTOR);
|
||||
parentInjector = parentInjector || ng1Injector.get(INJECTOR_KEY);
|
||||
|
||||
if (parentInjector instanceof ParentInjectorPromise) {
|
||||
parentInjector.then((resolvedInjector: Injector) => downgrade(resolvedInjector));
|
||||
|
@ -748,7 +745,7 @@ export class UpgradeAdapterRef {
|
|||
this.ng2ModuleRef = ngModuleRef;
|
||||
this.ng2Injector = ngModuleRef.injector;
|
||||
this.ng1Injector = ng1Injector;
|
||||
this.ng1RootScope = ng1Injector.get(NG1_ROOT_SCOPE);
|
||||
this.ng1RootScope = ng1Injector.get($ROOT_SCOPE);
|
||||
this._readyFn && this._readyFn(this);
|
||||
}
|
||||
|
||||
|
@ -765,7 +762,7 @@ export class UpgradeAdapterRef {
|
|||
* Dispose of running hybrid AngularJS / Angular application.
|
||||
*/
|
||||
public dispose() {
|
||||
this.ng1Injector.get(NG1_ROOT_SCOPE).$destroy();
|
||||
this.ng1Injector.get($ROOT_SCOPE).$destroy();
|
||||
this.ng2ModuleRef.destroy();
|
||||
}
|
||||
}
|
|
@ -8,9 +8,10 @@
|
|||
|
||||
import {Directive, DoCheck, ElementRef, EventEmitter, Inject, OnChanges, OnInit, SimpleChange, SimpleChanges, Type} from '@angular/core';
|
||||
|
||||
import * as angular from './angular_js';
|
||||
import {NG1_COMPILE, NG1_CONTROLLER, NG1_HTTP_BACKEND, NG1_SCOPE, NG1_TEMPLATE_CACHE} from './constants';
|
||||
import {controllerKey} from './util';
|
||||
import * as angular from '../common/angular1';
|
||||
import {$COMPILE, $CONTROLLER, $HTTP_BACKEND, $SCOPE, $TEMPLATE_CACHE} from '../common/constants';
|
||||
import {controllerKey} from '../common/util';
|
||||
|
||||
|
||||
interface IBindingDestination {
|
||||
[key: string]: any;
|
||||
|
@ -55,7 +56,7 @@ export class UpgradeNg1ComponentAdapterBuilder {
|
|||
Directive({selector: selector, inputs: this.inputsRename, outputs: this.outputsRename})
|
||||
.Class({
|
||||
constructor: [
|
||||
new Inject(NG1_SCOPE), ElementRef,
|
||||
new Inject($SCOPE), ElementRef,
|
||||
function(scope: angular.IScope, elementRef: ElementRef) {
|
||||
return new UpgradeNg1ComponentAdapter(
|
||||
self.linkFn, scope, self.directive, elementRef, self.$controller, self.inputs,
|
||||
|
@ -188,10 +189,10 @@ export class UpgradeNg1ComponentAdapterBuilder {
|
|||
exportedComponents: {[name: string]: UpgradeNg1ComponentAdapterBuilder},
|
||||
injector: angular.IInjectorService): Promise<angular.ILinkFn[]> {
|
||||
const promises: Promise<angular.ILinkFn>[] = [];
|
||||
const compile: angular.ICompileService = injector.get(NG1_COMPILE);
|
||||
const templateCache: angular.ITemplateCacheService = injector.get(NG1_TEMPLATE_CACHE);
|
||||
const httpBackend: angular.IHttpBackendService = injector.get(NG1_HTTP_BACKEND);
|
||||
const $controller: angular.IControllerService = injector.get(NG1_CONTROLLER);
|
||||
const compile: angular.ICompileService = injector.get($COMPILE);
|
||||
const templateCache: angular.ITemplateCacheService = injector.get($TEMPLATE_CACHE);
|
||||
const httpBackend: angular.IHttpBackendService = injector.get($HTTP_BACKEND);
|
||||
const $controller: angular.IControllerService = injector.get($CONTROLLER);
|
||||
for (const name in exportedComponents) {
|
||||
if ((<any>exportedComponents).hasOwnProperty(name)) {
|
||||
const exportedComponent = exportedComponents[name];
|
|
@ -6,7 +6,7 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import * as angular from '../angular_js';
|
||||
import * as angular from '../common/angular1';
|
||||
|
||||
// We have to do a little dance to get the ng1 injector into the module injector.
|
||||
// We store the ng1 injector so that the provider in the module injector can access it
|
|
@ -8,9 +8,9 @@
|
|||
|
||||
import {ComponentFactory, ComponentFactoryResolver, Injector, Type} from '@angular/core';
|
||||
|
||||
import * as angular from '../angular_js';
|
||||
import * as angular from '../common/angular1';
|
||||
import {$INJECTOR, $PARSE, INJECTOR_KEY, REQUIRE_NG_MODEL} from '../common/constants';
|
||||
|
||||
import {$INJECTOR, $PARSE, INJECTOR_KEY, REQUIRE_NG1_MODEL} from './constants';
|
||||
import {DowngradeComponentAdapter} from './downgrade_component_adapter';
|
||||
|
||||
let downgradeCount = 0;
|
||||
|
@ -77,7 +77,7 @@ export function downgradeComponent(info: /* ComponentInfo */ {
|
|||
|
||||
return {
|
||||
restrict: 'E',
|
||||
require: ['?^' + INJECTOR_KEY, REQUIRE_NG1_MODEL],
|
||||
require: ['?^' + INJECTOR_KEY, REQUIRE_NG_MODEL],
|
||||
link: (scope: angular.IScope, element: angular.IAugmentedJQuery, attrs: angular.IAttributes,
|
||||
required: any[], transclude: angular.ITranscludeFunction) => {
|
||||
|
||||
|
@ -87,6 +87,7 @@ export function downgradeComponent(info: /* ComponentInfo */ {
|
|||
}
|
||||
|
||||
const ngModel: angular.INgModelController = required[1];
|
||||
|
||||
const componentFactoryResolver: ComponentFactoryResolver =
|
||||
parentInjector.get(ComponentFactoryResolver);
|
||||
const componentFactory: ComponentFactory<any> =
|
||||
|
@ -110,4 +111,4 @@ export function downgradeComponent(info: /* ComponentInfo */ {
|
|||
|
||||
directiveFactory.$inject = [$INJECTOR, $PARSE];
|
||||
return directiveFactory;
|
||||
}
|
||||
}
|
|
@ -8,11 +8,11 @@
|
|||
|
||||
import {ChangeDetectorRef, ComponentFactory, ComponentRef, EventEmitter, Injector, OnChanges, ReflectiveInjector, SimpleChange, SimpleChanges, Type} from '@angular/core';
|
||||
|
||||
import * as angular from '../angular_js';
|
||||
import {hookupNgModel} from '../util';
|
||||
import * as angular from '../common/angular1';
|
||||
import {$SCOPE} from '../common/constants';
|
||||
import {hookupNgModel} from '../common/util';
|
||||
|
||||
import {ComponentInfo, PropertyBinding} from './component_info';
|
||||
import {$SCOPE} from './constants';
|
||||
|
||||
const INITIAL_VALUE = {
|
||||
__UNINITIALIZED__: true
|
|
@ -8,11 +8,10 @@
|
|||
|
||||
import {DoCheck, ElementRef, EventEmitter, Injector, OnChanges, OnDestroy, OnInit, SimpleChanges} from '@angular/core';
|
||||
|
||||
import * as angular from '../angular_js';
|
||||
import * as angular from '../common/angular1';
|
||||
import {$COMPILE, $CONTROLLER, $HTTP_BACKEND, $INJECTOR, $SCOPE, $TEMPLATE_CACHE} from '../common/constants';
|
||||
import {controllerKey} from '../common/util';
|
||||
import {looseIdentical} from '../facade/lang';
|
||||
import {controllerKey} from '../util';
|
||||
|
||||
import {$COMPILE, $CONTROLLER, $HTTP_BACKEND, $INJECTOR, $SCOPE, $TEMPLATE_CACHE} from './constants';
|
||||
|
||||
const REQUIRE_PREFIX_RE = /^(\^\^?)?(\?)?(\^\^?)?/;
|
||||
const NOT_SUPPORTED: any = 'NOT_SUPPORTED';
|
|
@ -8,11 +8,11 @@
|
|||
|
||||
import {Injector, NgModule, NgZone, Testability} from '@angular/core';
|
||||
|
||||
import * as angular from '../angular_js';
|
||||
import {controllerKey} from '../util';
|
||||
import * as angular from '../common/angular1';
|
||||
import {$$TESTABILITY, $DELEGATE, $INJECTOR, $PROVIDE, $ROOT_SCOPE, INJECTOR_KEY, UPGRADE_MODULE_NAME} from '../common/constants';
|
||||
import {controllerKey} from '../common/util';
|
||||
|
||||
import {angular1Providers, setTempInjectorRef} from './angular1_providers';
|
||||
import {$$TESTABILITY, $DELEGATE, $INJECTOR, $PROVIDE, $ROOT_SCOPE, INJECTOR_KEY, UPGRADE_MODULE_NAME} from './constants';
|
||||
|
||||
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/**
|
||||
* @module
|
||||
* @description
|
||||
* Adapter allowing AngularJS v1 and Angular v2 to run side by side in the same application.
|
||||
*/
|
||||
export {UpgradeAdapter, UpgradeAdapterRef} from './upgrade_adapter';
|
||||
export {VERSION} from './version';
|
|
@ -6,8 +6,15 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
export {downgradeComponent} from './src/aot/downgrade_component';
|
||||
export {downgradeInjectable} from './src/aot/downgrade_injectable';
|
||||
export {UpgradeComponent} from './src/aot/upgrade_component';
|
||||
export {UpgradeModule} from './src/aot/upgrade_module';
|
||||
// This file only reexports content of the `src` folder. Keep it that way.
|
||||
/**
|
||||
* @module
|
||||
* @description
|
||||
* Entry point for all public APIs of the upgrade/static package, allowing
|
||||
* Angular 1 and Angular 2+ to run side by side in the same application.
|
||||
*/
|
||||
export {downgradeInjectable} from './src/common/downgrade_injectable';
|
||||
export {downgradeComponent} from './src/static/downgrade_component';
|
||||
export {UpgradeComponent} from './src/static/upgrade_component';
|
||||
export {UpgradeModule} from './src/static/upgrade_module';
|
||||
|
||||
// This file only re-exports content of the `src` folder. Keep it that way.
|
||||
|
|
|
@ -6,17 +6,18 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {INJECTOR_KEY} from '@angular/upgrade/src/aot/constants';
|
||||
import {downgradeInjectable} from '@angular/upgrade/src/aot/downgrade_injectable';
|
||||
import {INJECTOR_KEY} from '@angular/upgrade/src/common/constants';
|
||||
import {downgradeInjectable} from '@angular/upgrade/src/common/downgrade_injectable';
|
||||
|
||||
export function main() {
|
||||
describe('downgradeInjectable', () => {
|
||||
it('should return an AngularJS annotated factory for the token', () => {
|
||||
const factory = downgradeInjectable('someToken');
|
||||
expect(factory[0]).toEqual(INJECTOR_KEY);
|
||||
expect(factory[1]).toEqual(jasmine.any(Function));
|
||||
expect(factory).toEqual(jasmine.any(Function));
|
||||
expect((factory as any).$inject).toEqual([INJECTOR_KEY]);
|
||||
|
||||
const injector = {get: jasmine.createSpy('get').and.returnValue('service value')};
|
||||
const value = (factory as any)[1](injector);
|
||||
const value = factory(injector);
|
||||
expect(injector.get).toHaveBeenCalledWith('someToken');
|
||||
expect(value).toEqual('service value');
|
||||
});
|
|
@ -0,0 +1,25 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
export function html(html: string): Element {
|
||||
// Don't return `body` itself, because using it as a `$rootElement` for ng1
|
||||
// will attach `$injector` to it and that will affect subsequent tests.
|
||||
const body = document.body;
|
||||
body.innerHTML = `<div>${html.trim()}</div>`;
|
||||
const div = document.body.firstChild as Element;
|
||||
|
||||
if (div.childNodes.length === 1 && div.firstChild instanceof HTMLElement) {
|
||||
return div.firstChild;
|
||||
}
|
||||
|
||||
return div;
|
||||
}
|
||||
|
||||
export function multiTrim(text: string): string {
|
||||
return text.replace(/\n/g, '').replace(/\s\s+/g, ' ').trim();
|
||||
}
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
import {Component} from '@angular/core';
|
||||
import {describe, expect, it} from '@angular/core/testing/testing_internal';
|
||||
import {getComponentInfo, parseFields} from '@angular/upgrade/src/metadata';
|
||||
import {getComponentInfo, parseFields} from '@angular/upgrade/src/dynamic/metadata';
|
||||
|
||||
export function main() {
|
||||
describe('upgrade metadata', () => {
|
|
@ -0,0 +1,9 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
export * from '../common/test_helpers';
|
|
@ -10,8 +10,9 @@ import {ChangeDetectorRef, Class, Component, EventEmitter, Input, NO_ERRORS_SCHE
|
|||
import {async, fakeAsync, flushMicrotasks, tick} from '@angular/core/testing';
|
||||
import {BrowserModule} from '@angular/platform-browser';
|
||||
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
|
||||
import * as angular from '@angular/upgrade/src/angular_js';
|
||||
import {UpgradeAdapter, UpgradeAdapterRef, sortProjectableNodes} from '@angular/upgrade/src/upgrade_adapter';
|
||||
import * as angular from '@angular/upgrade/src/common/angular1';
|
||||
import {UpgradeAdapter, UpgradeAdapterRef, sortProjectableNodes} from '@angular/upgrade/src/dynamic/upgrade_adapter';
|
||||
import {html, multiTrim} from './test_helpers';
|
||||
|
||||
export function main() {
|
||||
describe('adapter: ng1 to ng2', () => {
|
||||
|
@ -1923,23 +1924,7 @@ export function main() {
|
|||
});
|
||||
}
|
||||
|
||||
function multiTrim(text: string): string {
|
||||
return text.replace(/\n/g, '').replace(/\s{2,}/g, ' ').trim();
|
||||
}
|
||||
|
||||
function html(html: string): Element {
|
||||
const body = document.body;
|
||||
body.innerHTML = html;
|
||||
|
||||
if (body.childNodes.length == 1 && body.firstChild instanceof HTMLElement) {
|
||||
return <Element>body.firstChild;
|
||||
}
|
||||
|
||||
return body;
|
||||
}
|
||||
|
||||
function nodes(html: string) {
|
||||
const element = document.createElement('div');
|
||||
element.innerHTML = html;
|
||||
return Array.prototype.slice.call(element.childNodes);
|
||||
}
|
||||
return Array.prototype.slice.call(element.childNodes);
|
|
@ -6,8 +6,8 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {Ng1Token} from '@angular/upgrade/src/angular_js';
|
||||
import {compileFactory, injectorFactory, parseFactory, rootScopeFactory, setTempInjectorRef} from '@angular/upgrade/src/aot/angular1_providers';
|
||||
import {Ng1Token} from '@angular/upgrade/src/common/angular1';
|
||||
import {compileFactory, injectorFactory, parseFactory, rootScopeFactory, setTempInjectorRef} from '@angular/upgrade/src/static/angular1_providers';
|
||||
|
||||
export function main() {
|
||||
describe('upgrade angular1_providers', () => {
|
||||
|
@ -55,4 +55,4 @@ export function main() {
|
|||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
|
@ -10,7 +10,7 @@ import {Component, Directive, ElementRef, Injector, Input, NgModule, NgZone, Sim
|
|||
import {async} from '@angular/core/testing';
|
||||
import {BrowserModule} from '@angular/platform-browser';
|
||||
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
|
||||
import * as angular from '@angular/upgrade/src/angular_js';
|
||||
import * as angular from '@angular/upgrade/src/common/angular1';
|
||||
import {UpgradeComponent, UpgradeModule, downgradeComponent} from '@angular/upgrade/static';
|
||||
|
||||
import {bootstrap, html} from '../test_helpers';
|
|
@ -10,7 +10,7 @@ import {Component, Directive, ElementRef, Injector, NgModule, destroyPlatform} f
|
|||
import {async} from '@angular/core/testing';
|
||||
import {BrowserModule} from '@angular/platform-browser';
|
||||
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
|
||||
import * as angular from '@angular/upgrade/src/angular_js';
|
||||
import * as angular from '@angular/upgrade/src/common/angular1';
|
||||
import {UpgradeComponent, UpgradeModule, downgradeComponent} from '@angular/upgrade/static';
|
||||
|
||||
import {bootstrap, html} from '../test_helpers';
|
|
@ -10,7 +10,7 @@ import {Component, EventEmitter, NgModule, OnChanges, OnDestroy, SimpleChanges,
|
|||
import {async} from '@angular/core/testing';
|
||||
import {BrowserModule} from '@angular/platform-browser';
|
||||
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
|
||||
import * as angular from '@angular/upgrade/src/angular_js';
|
||||
import * as angular from '@angular/upgrade/src/common/angular1';
|
||||
import {UpgradeModule, downgradeComponent} from '@angular/upgrade/static';
|
||||
|
||||
import {bootstrap, html, multiTrim} from '../test_helpers';
|
|
@ -10,7 +10,7 @@ import {Component, Directive, ElementRef, Injector, Input, NgModule, destroyPlat
|
|||
import {async} from '@angular/core/testing';
|
||||
import {BrowserModule} from '@angular/platform-browser';
|
||||
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
|
||||
import * as angular from '@angular/upgrade/src/angular_js';
|
||||
import * as angular from '@angular/upgrade/src/common/angular1';
|
||||
import {UpgradeComponent, UpgradeModule, downgradeComponent} from '@angular/upgrade/static';
|
||||
|
||||
import {bootstrap, html, multiTrim} from '../test_helpers';
|
|
@ -10,8 +10,8 @@ import {InjectionToken, Injector, NgModule, destroyPlatform} from '@angular/core
|
|||
import {async} from '@angular/core/testing';
|
||||
import {BrowserModule} from '@angular/platform-browser';
|
||||
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
|
||||
import * as angular from '@angular/upgrade/src/angular_js';
|
||||
import {$INJECTOR, INJECTOR_KEY} from '@angular/upgrade/src/aot/constants';
|
||||
import * as angular from '@angular/upgrade/src/common/angular1';
|
||||
import {$INJECTOR, INJECTOR_KEY} from '@angular/upgrade/src/common/constants';
|
||||
import {UpgradeModule, downgradeInjectable} from '@angular/upgrade/static';
|
||||
|
||||
import {bootstrap, html} from '../test_helpers';
|
|
@ -11,7 +11,7 @@ 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';
|
||||
import * as angular from '@angular/upgrade/src/angular_js';
|
||||
import * as angular from '@angular/upgrade/src/common/angular1';
|
||||
import {UpgradeModule} from '@angular/upgrade/static';
|
||||
|
||||
import {bootstrap, html} from '../test_helpers';
|
|
@ -10,7 +10,7 @@ import {Component, Directive, ElementRef, EventEmitter, Injector, Input, NO_ERRO
|
|||
import {async, fakeAsync, tick} from '@angular/core/testing';
|
||||
import {BrowserModule} from '@angular/platform-browser';
|
||||
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
|
||||
import * as angular from '@angular/upgrade/src/angular_js';
|
||||
import * as angular from '@angular/upgrade/src/common/angular1';
|
||||
import {UpgradeComponent, UpgradeModule, downgradeComponent} from '@angular/upgrade/static';
|
||||
|
||||
import {bootstrap, digest, html, multiTrim} from '../test_helpers';
|
|
@ -5,11 +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 {PlatformRef, Type} from '@angular/core';
|
||||
import * as angular from '@angular/upgrade/src/angular_js';
|
||||
import {$ROOT_SCOPE} from '@angular/upgrade/src/aot/constants';
|
||||
import * as angular from '@angular/upgrade/src/common/angular1';
|
||||
import {$ROOT_SCOPE} from '@angular/upgrade/src/common/constants';
|
||||
import {UpgradeModule} from '@angular/upgrade/static';
|
||||
|
||||
export * from '../common/test_helpers';
|
||||
|
||||
export function bootstrap(
|
||||
platform: PlatformRef, Ng2Module: Type<{}>, element: Element, ng1Module: angular.IModule) {
|
||||
// We bootstrap the Angular module first; then when it is ready (async)
|
||||
|
@ -25,21 +28,3 @@ export function digest(adapter: UpgradeModule) {
|
|||
const $rootScope = adapter.$injector.get($ROOT_SCOPE) as angular.IRootScopeService;
|
||||
$rootScope.$digest();
|
||||
}
|
||||
|
||||
export function html(html: string): Element {
|
||||
// Don't return `body` itself, because using it as a `$rootElement` for ng1
|
||||
// will attach `$injector` to it and that will affect subsequent tests.
|
||||
const body = document.body;
|
||||
body.innerHTML = `<div>${html.trim()}</div>`;
|
||||
const div = document.body.firstChild as Element;
|
||||
|
||||
if (div.childNodes.length === 1 && div.firstChild instanceof HTMLElement) {
|
||||
return div.firstChild;
|
||||
}
|
||||
|
||||
return div;
|
||||
}
|
||||
|
||||
export function multiTrim(text: string): string {
|
||||
return text.replace(/\n/g, '').replace(/\s\s+/g, ' ').trim();
|
||||
}
|
|
@ -6,7 +6,7 @@ export declare function downgradeComponent(info: {
|
|||
}): any;
|
||||
|
||||
/** @experimental */
|
||||
export declare function downgradeInjectable(token: any): (string | ((i: Injector) => any))[];
|
||||
export declare function downgradeInjectable(token: any): Function;
|
||||
|
||||
/** @experimental */
|
||||
export declare class UpgradeComponent implements OnInit, OnChanges, DoCheck, OnDestroy {
|
||||
|
|
Loading…
Reference in New Issue