fix(ivy): TestBed.get(Compiler) throws "Error: Runtime compiler is not loaded" (#27223)

BREAKING CHANGE:

The public API for `DebugNode` was accidentally too broad. This change removes
1. Public constructor. Since `DebugNode` is a way for Angular to communicate information
   on to the developer there is no reason why the developer should ever need to
   Instantiate the `DebugNode`
2. We are also removing `removeChild`, `addChild`, `insertBefore`, and `insertChildAfter`.
   All of these methods are used by Angular to constructor the correct `DebugNode` tree.
   There is no reason why the developer should ever be constructing a `DebugNode` tree
   And these methods should have never been made public.
3. All properties have been change to `readonly` since `DebugNode` is used by Angular
   to communicate to developer and there is no reason why these APIs should be writable.

While technically breaking change we don’t expect anyone to be effected by this change.

PR Close #27223
This commit is contained in:
Misko Hevery 2018-11-21 21:14:06 -08:00 committed by Jason Aden
parent 60e403bf6d
commit 39e426cde3
34 changed files with 1648 additions and 1468 deletions

View File

@ -144,7 +144,6 @@ describe('insert/remove', () => {
expect(fixture.nativeElement).toHaveText('projected foo'); expect(fixture.nativeElement).toHaveText('projected foo');
})); }));
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should resolve components from other modules, if supplied', async(() => { it('should resolve components from other modules, if supplied', async(() => {
const compiler = TestBed.get(Compiler) as Compiler; const compiler = TestBed.get(Compiler) as Compiler;
let fixture = TestBed.createComponent(TestComponent); let fixture = TestBed.createComponent(TestComponent);
@ -159,7 +158,7 @@ describe('insert/remove', () => {
expect(fixture.nativeElement).toHaveText('baz'); expect(fixture.nativeElement).toHaveText('baz');
})); }));
fixmeIvy('FW-561: Runtime compiler is not loaded') && fixmeIvy('FW-739: destroy on NgModuleRef is not being called') &&
it('should clean up moduleRef, if supplied', async(() => { it('should clean up moduleRef, if supplied', async(() => {
let destroyed = false; let destroyed = false;
const compiler = TestBed.get(Compiler) as Compiler; const compiler = TestBed.get(Compiler) as Compiler;
@ -176,7 +175,6 @@ describe('insert/remove', () => {
expect(moduleRef.destroy).toHaveBeenCalled(); expect(moduleRef.destroy).toHaveBeenCalled();
})); }));
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should not re-create moduleRef when it didn\'t actually change', async(() => { it('should not re-create moduleRef when it didn\'t actually change', async(() => {
const compiler = TestBed.get(Compiler) as Compiler; const compiler = TestBed.get(Compiler) as Compiler;
const fixture = TestBed.createComponent(TestComponent); const fixture = TestBed.createComponent(TestComponent);
@ -194,7 +192,6 @@ describe('insert/remove', () => {
expect(moduleRef).toBe(fixture.componentInstance.ngComponentOutlet['_moduleRef']); expect(moduleRef).toBe(fixture.componentInstance.ngComponentOutlet['_moduleRef']);
})); }));
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should re-create moduleRef when changed', async(() => { it('should re-create moduleRef when changed', async(() => {
const compiler = TestBed.get(Compiler) as Compiler; const compiler = TestBed.get(Compiler) as Compiler;
const fixture = TestBed.createComponent(TestComponent); const fixture = TestBed.createComponent(TestComponent);

View File

@ -114,12 +114,9 @@ export {
i18nEnd as ɵi18nEnd, i18nEnd as ɵi18nEnd,
i18nApply as ɵi18nApply, i18nApply as ɵi18nApply,
i18nPostprocess as ɵi18nPostprocess, i18nPostprocess as ɵi18nPostprocess,
WRAP_RENDERER_FACTORY2 as ɵWRAP_RENDERER_FACTORY2,
setClassMetadata as ɵsetClassMetadata, setClassMetadata as ɵsetClassMetadata,
} from './render3/index'; } from './render3/index';
export { Render3DebugRendererFactory2 as ɵRender3DebugRendererFactory2 } from './render3/debug';
export { export {
compileComponent as ɵcompileComponent, compileComponent as ɵcompileComponent,

View File

@ -7,6 +7,11 @@
*/ */
import {Injector} from '../di'; import {Injector} from '../di';
import {DirectiveDef} from '../render3';
import {assertDomNode} from '../render3/assert';
import {getComponent, getInjector, getLocalRefs, loadContext} from '../render3/discovery_utils';
import {TNode, TNodeFlags} from '../render3/interfaces/node';
import {TVIEW} from '../render3/interfaces/view';
import {DebugContext} from '../view/index'; import {DebugContext} from '../view/index';
export class EventListener { export class EventListener {
@ -16,12 +21,26 @@ export class EventListener {
/** /**
* @publicApi * @publicApi
*/ */
export class DebugNode { export interface DebugNode {
listeners: EventListener[] = []; readonly listeners: EventListener[];
parent: DebugElement|null = null; readonly parent: DebugElement|null;
readonly nativeNode: any;
readonly injector: Injector;
readonly componentInstance: any;
readonly context: any;
readonly references: {[key: string]: any};
readonly providerTokens: any[];
}
export class DebugNode__PRE_R3__ {
readonly listeners: EventListener[] = [];
readonly parent: DebugElement|null = null;
readonly nativeNode: any;
private readonly _debugContext: DebugContext;
constructor(public nativeNode: any, parent: DebugNode|null, private _debugContext: DebugContext) { constructor(nativeNode: any, parent: DebugNode|null, _debugContext: DebugContext) {
if (parent && parent instanceof DebugElement) { this._debugContext = _debugContext;
this.nativeNode = nativeNode;
if (parent && parent instanceof DebugElement__PRE_R3__) {
parent.addChild(this); parent.addChild(this);
} }
} }
@ -40,14 +59,29 @@ export class DebugNode {
/** /**
* @publicApi * @publicApi
*/ */
export class DebugElement extends DebugNode { export interface DebugElement extends DebugNode {
name !: string; readonly name: string;
properties: {[key: string]: any} = {}; readonly properties: {[key: string]: any};
attributes: {[key: string]: string | null} = {}; readonly attributes: {[key: string]: string | null};
classes: {[key: string]: boolean} = {}; readonly classes: {[key: string]: boolean};
styles: {[key: string]: string | null} = {}; readonly styles: {[key: string]: string | null};
childNodes: DebugNode[] = []; readonly childNodes: DebugNode[];
nativeElement: any; readonly nativeElement: any;
readonly children: DebugElement[];
query(predicate: Predicate<DebugElement>): DebugElement;
queryAll(predicate: Predicate<DebugElement>): DebugElement[];
queryAllNodes(predicate: Predicate<DebugNode>): DebugNode[];
triggerEventHandler(eventName: string, eventObj: any): void;
}
export class DebugElement__PRE_R3__ extends DebugNode__PRE_R3__ implements DebugElement {
readonly name !: string;
readonly properties: {[key: string]: any} = {};
readonly attributes: {[key: string]: string | null} = {};
readonly classes: {[key: string]: boolean} = {};
readonly styles: {[key: string]: string | null} = {};
readonly childNodes: DebugNode[] = [];
readonly nativeElement: any;
constructor(nativeNode: any, parent: any, _debugContext: DebugContext) { constructor(nativeNode: any, parent: any, _debugContext: DebugContext) {
super(nativeNode, parent, _debugContext); super(nativeNode, parent, _debugContext);
@ -57,14 +91,14 @@ export class DebugElement extends DebugNode {
addChild(child: DebugNode) { addChild(child: DebugNode) {
if (child) { if (child) {
this.childNodes.push(child); this.childNodes.push(child);
child.parent = this; (child as{parent: DebugNode}).parent = this;
} }
} }
removeChild(child: DebugNode) { removeChild(child: DebugNode) {
const childIndex = this.childNodes.indexOf(child); const childIndex = this.childNodes.indexOf(child);
if (childIndex !== -1) { if (childIndex !== -1) {
child.parent = null; (child as{parent: DebugNode | null}).parent = null;
this.childNodes.splice(childIndex, 1); this.childNodes.splice(childIndex, 1);
} }
} }
@ -75,9 +109,9 @@ export class DebugElement extends DebugNode {
this.childNodes.splice(siblingIndex + 1, 0, ...newChildren); this.childNodes.splice(siblingIndex + 1, 0, ...newChildren);
newChildren.forEach(c => { newChildren.forEach(c => {
if (c.parent) { if (c.parent) {
c.parent.removeChild(c); (c.parent as DebugElement__PRE_R3__).removeChild(c);
} }
c.parent = this; (child as{parent: DebugNode}).parent = this;
}); });
} }
} }
@ -88,9 +122,9 @@ export class DebugElement extends DebugNode {
this.addChild(newChild); this.addChild(newChild);
} else { } else {
if (newChild.parent) { if (newChild.parent) {
newChild.parent.removeChild(newChild); (newChild.parent as DebugElement__PRE_R3__).removeChild(newChild);
} }
newChild.parent = this; (newChild as{parent: DebugNode}).parent = this;
this.childNodes.splice(refIndex, 0, newChild); this.childNodes.splice(refIndex, 0, newChild);
} }
} }
@ -113,7 +147,9 @@ export class DebugElement extends DebugNode {
} }
get children(): DebugElement[] { get children(): DebugElement[] {
return this.childNodes.filter((node) => node instanceof DebugElement) as DebugElement[]; return this
.childNodes //
.filter((node) => node instanceof DebugElement__PRE_R3__) as DebugElement[];
} }
triggerEventHandler(eventName: string, eventObj: any) { triggerEventHandler(eventName: string, eventObj: any) {
@ -135,7 +171,7 @@ export function asNativeElements(debugEls: DebugElement[]): any {
function _queryElementChildren( function _queryElementChildren(
element: DebugElement, predicate: Predicate<DebugElement>, matches: DebugElement[]) { element: DebugElement, predicate: Predicate<DebugElement>, matches: DebugElement[]) {
element.childNodes.forEach(node => { element.childNodes.forEach(node => {
if (node instanceof DebugElement) { if (node instanceof DebugElement__PRE_R3__) {
if (predicate(node)) { if (predicate(node)) {
matches.push(node); matches.push(node);
} }
@ -146,27 +182,215 @@ function _queryElementChildren(
function _queryNodeChildren( function _queryNodeChildren(
parentNode: DebugNode, predicate: Predicate<DebugNode>, matches: DebugNode[]) { parentNode: DebugNode, predicate: Predicate<DebugNode>, matches: DebugNode[]) {
if (parentNode instanceof DebugElement) { if (parentNode instanceof DebugElement__PRE_R3__) {
parentNode.childNodes.forEach(node => { parentNode.childNodes.forEach(node => {
if (predicate(node)) { if (predicate(node)) {
matches.push(node); matches.push(node);
} }
if (node instanceof DebugElement) { if (node instanceof DebugElement__PRE_R3__) {
_queryNodeChildren(node, predicate, matches); _queryNodeChildren(node, predicate, matches);
} }
}); });
} }
} }
function notImplemented(): Error {
throw new Error('Missing proper ivy implementation.');
}
class DebugNode__POST_R3__ implements DebugNode {
readonly nativeNode: Node;
constructor(nativeNode: Node) { this.nativeNode = nativeNode; }
get parent(): DebugElement|null {
const parent = this.nativeNode.parentNode as HTMLElement;
return parent ? new DebugElement__POST_R3__(parent) : null;
}
get injector(): Injector { return getInjector(this.nativeNode); }
get componentInstance(): any {
const nativeElement = this.nativeNode;
return nativeElement && getComponent(nativeElement as HTMLElement);
}
get context(): any {
// https://angular-team.atlassian.net/browse/FW-719
throw notImplemented();
}
get listeners(): EventListener[] {
// TODO: add real implementation;
// https://angular-team.atlassian.net/browse/FW-719
return [];
}
get references(): {[key: string]: any;} { return getLocalRefs(this.nativeNode); }
get providerTokens(): any[] {
// TODO move to discoverable utils
const context = loadContext(this.nativeNode as HTMLElement, false) !;
if (!context) return [];
const lView = context.lViewData;
const tView = lView[TVIEW];
const tNode = tView.data[context.nodeIndex] as TNode;
const providerTokens: any[] = [];
const nodeFlags = tNode.flags;
const startIndex = nodeFlags >> TNodeFlags.DirectiveStartingIndexShift;
const directiveCount = nodeFlags & TNodeFlags.DirectiveCountMask;
const endIndex = startIndex + directiveCount;
for (let i = startIndex; i < endIndex; i++) {
let value = tView.data[i];
if (isDirectiveDefHack(value)) {
// The fact that we sometimes store Type and sometimes DirectiveDef in this location is a
// design flaw. We should always store same type so that we can be monomorphic. The issue
// is that for Components/Directives we store the def instead the type. The correct behavior
// is that we should always be storing injectable type in this location.
value = value.type;
}
providerTokens.push(value);
}
return providerTokens;
}
}
class DebugElement__POST_R3__ extends DebugNode__POST_R3__ implements DebugElement {
constructor(nativeNode: Element) {
ngDevMode && assertDomNode(nativeNode);
super(nativeNode);
}
get nativeElement(): Element|null {
return this.nativeNode.nodeType == Node.ELEMENT_NODE ? this.nativeNode as Element : null;
}
get name(): string { return (this.nativeElement as HTMLElement).nodeName; }
get properties(): {[key: string]: any;} {
const context = loadContext(this.nativeNode) !;
const lView = context.lViewData;
const tView = lView[TVIEW];
const tNode = tView.data[context.nodeIndex] as TNode;
const properties = {};
// TODO: https://angular-team.atlassian.net/browse/FW-681
// Missing implementation here...
return properties;
}
get attributes(): {[key: string]: string | null;} {
// https://angular-team.atlassian.net/browse/FW-719
throw notImplemented();
}
get classes(): {[key: string]: boolean;} {
// https://angular-team.atlassian.net/browse/FW-719
throw notImplemented();
}
get styles(): {[key: string]: string | null;} {
// https://angular-team.atlassian.net/browse/FW-719
throw notImplemented();
}
get childNodes(): DebugNode[] {
const childNodes = this.nativeNode.childNodes;
const children: DebugNode[] = [];
for (let i = 0; i < childNodes.length; i++) {
const element = childNodes[i];
children.push(getDebugNode__POST_R3__(element));
}
return children;
}
get children(): DebugElement[] {
const nativeElement = this.nativeElement;
if (!nativeElement) return [];
const childNodes = nativeElement.children;
const children: DebugElement[] = [];
for (let i = 0; i < childNodes.length; i++) {
const element = childNodes[i];
children.push(getDebugNode__POST_R3__(element));
}
return children;
}
query(predicate: Predicate<DebugElement>): DebugElement {
const results = this.queryAll(predicate);
return results[0] || null;
}
queryAll(predicate: Predicate<DebugElement>): DebugElement[] {
const matches: DebugElement[] = [];
_queryNodeChildrenR3(this, predicate, matches, true);
return matches;
}
queryAllNodes(predicate: Predicate<DebugNode>): DebugNode[] {
const matches: DebugNode[] = [];
_queryNodeChildrenR3(this, predicate, matches, false);
return matches;
}
triggerEventHandler(eventName: string, eventObj: any): void {
// This is a hack implementation. The correct implementation would bypass the DOM and `TNode`
// information to invoke the listeners directly.
// https://angular-team.atlassian.net/browse/FW-719
const event = document.createEvent('MouseEvent');
event.initEvent(eventName, true, true);
(this.nativeElement as HTMLElement).dispatchEvent(event);
}
}
/**
* This function should not exist because it is megamorphic and only mostly correct.
*
* See call site for more info.
*/
function isDirectiveDefHack(obj: any): obj is DirectiveDef<any> {
return obj.type !== undefined && obj.template !== undefined && obj.declaredInputs !== undefined;
}
function _queryNodeChildrenR3(
parentNode: DebugNode, predicate: Predicate<DebugNode>, matches: DebugNode[],
elementsOnly: boolean) {
if (parentNode instanceof DebugElement__POST_R3__) {
parentNode.childNodes.forEach(node => {
if (predicate(node)) {
matches.push(node);
}
if (node instanceof DebugElement__POST_R3__) {
if (elementsOnly ? node.nativeElement : true) {
_queryNodeChildrenR3(node, predicate, matches, elementsOnly);
}
}
});
}
}
// Need to keep the nodes in a global Map so that multiple angular apps are supported. // Need to keep the nodes in a global Map so that multiple angular apps are supported.
const _nativeNodeToDebugNode = new Map<any, DebugNode>(); const _nativeNodeToDebugNode = new Map<any, DebugNode>();
function getDebugNode__PRE_R3__(nativeNode: any): DebugNode|null {
return _nativeNodeToDebugNode.get(nativeNode) || null;
}
export function getDebugNode__POST_R3__(nativeNode: Element): DebugElement__POST_R3__;
export function getDebugNode__POST_R3__(nativeNode: Node): DebugNode__POST_R3__;
export function getDebugNode__POST_R3__(nativeNode: null): null;
export function getDebugNode__POST_R3__(nativeNode: any): DebugNode|null {
if (nativeNode instanceof Node) {
return nativeNode.nodeType == Node.ELEMENT_NODE ?
new DebugElement__POST_R3__(nativeNode as Element) :
new DebugNode__POST_R3__(nativeNode);
}
return null;
}
/** /**
* @publicApi * @publicApi
*/ */
export function getDebugNode(nativeNode: any): DebugNode|null { export const getDebugNode: (nativeNode: any) => DebugNode | null = getDebugNode__PRE_R3__;
return _nativeNodeToDebugNode.get(nativeNode) || null;
}
export function getAllDebugNodes(): DebugNode[] { export function getAllDebugNodes(): DebugNode[] {
return Array.from(_nativeNodeToDebugNode.values()); return Array.from(_nativeNodeToDebugNode.values());
@ -187,3 +411,13 @@ export function removeDebugNodeFromIndex(node: DebugNode) {
* @publicApi * @publicApi
*/ */
export interface Predicate<T> { (value: T): boolean; } export interface Predicate<T> { (value: T): boolean; }
/**
* @publicApi
*/
export const DebugNode: {new (...args: any[]): DebugNode} = DebugNode__PRE_R3__ as any;
/**
* @publicApi
*/
export const DebugElement: {new (...args: any[]): DebugElement} = DebugElement__PRE_R3__ as any;

View File

@ -11,6 +11,7 @@ import {InjectionToken} from '../di/injection_token';
import {StaticProvider} from '../di/provider'; import {StaticProvider} from '../di/provider';
import {MissingTranslationStrategy} from '../i18n/tokens'; import {MissingTranslationStrategy} from '../i18n/tokens';
import {ViewEncapsulation} from '../metadata'; import {ViewEncapsulation} from '../metadata';
import {NgModuleFactory as NgModuleFactoryR3} from '../render3/ng_module_ref';
import {Type} from '../type'; import {Type} from '../type';
import {ComponentFactory} from './component_factory'; import {ComponentFactory} from './component_factory';
@ -34,6 +35,42 @@ function _throwError() {
throw new Error(`Runtime compiler is not loaded`); throw new Error(`Runtime compiler is not loaded`);
} }
const Compiler_compileModuleSync__PRE_R3__: <T>(moduleType: Type<T>) => NgModuleFactory<T> =
_throwError as any;
export const Compiler_compileModuleSync__POST_R3__: <T>(moduleType: Type<T>) =>
NgModuleFactory<T> = function<T>(moduleType: Type<T>): NgModuleFactory<T> {
return new NgModuleFactoryR3(moduleType);
};
const Compiler_compileModuleSync = Compiler_compileModuleSync__PRE_R3__;
const Compiler_compileModuleAsync__PRE_R3__: <T>(moduleType: Type<T>) =>
Promise<NgModuleFactory<T>> = _throwError as any;
export const Compiler_compileModuleAsync__POST_R3__: <T>(moduleType: Type<T>) =>
Promise<NgModuleFactory<T>> = function<T>(moduleType: Type<T>): Promise<NgModuleFactory<T>> {
return Promise.resolve(Compiler_compileModuleSync__POST_R3__(moduleType));
};
const Compiler_compileModuleAsync = Compiler_compileModuleAsync__PRE_R3__;
const Compiler_compileModuleAndAllComponentsSync__PRE_R3__: <T>(moduleType: Type<T>) =>
ModuleWithComponentFactories<T> = _throwError as any;
export const Compiler_compileModuleAndAllComponentsSync__POST_R3__: <T>(moduleType: Type<T>) =>
ModuleWithComponentFactories<T> = function<T>(moduleType: Type<T>):
ModuleWithComponentFactories<T> {
return new ModuleWithComponentFactories(Compiler_compileModuleSync__POST_R3__(moduleType), []);
};
const Compiler_compileModuleAndAllComponentsSync =
Compiler_compileModuleAndAllComponentsSync__PRE_R3__;
const Compiler_compileModuleAndAllComponentsAsync__PRE_R3__: <T>(moduleType: Type<T>) =>
Promise<ModuleWithComponentFactories<T>> = _throwError as any;
export const Compiler_compileModuleAndAllComponentsAsync__POST_R3__: <T>(moduleType: Type<T>) =>
Promise<ModuleWithComponentFactories<T>> = function<T>(moduleType: Type<T>):
Promise<ModuleWithComponentFactories<T>> {
return Promise.resolve(Compiler_compileModuleAndAllComponentsSync__POST_R3__(moduleType));
};
const Compiler_compileModuleAndAllComponentsAsync =
Compiler_compileModuleAndAllComponentsAsync__PRE_R3__;
/** /**
* Low-level service for running the angular compiler during runtime * Low-level service for running the angular compiler during runtime
* to create {@link ComponentFactory}s, which * to create {@link ComponentFactory}s, which
@ -51,27 +88,25 @@ export class Compiler {
* Compiles the given NgModule and all of its components. All templates of the components listed * Compiles the given NgModule and all of its components. All templates of the components listed
* in `entryComponents` have to be inlined. * in `entryComponents` have to be inlined.
*/ */
compileModuleSync<T>(moduleType: Type<T>): NgModuleFactory<T> { throw _throwError(); } compileModuleSync: <T>(moduleType: Type<T>) => NgModuleFactory<T> = Compiler_compileModuleSync;
/** /**
* Compiles the given NgModule and all of its components * Compiles the given NgModule and all of its components
*/ */
compileModuleAsync<T>(moduleType: Type<T>): Promise<NgModuleFactory<T>> { throw _throwError(); } compileModuleAsync:
<T>(moduleType: Type<T>) => Promise<NgModuleFactory<T>> = Compiler_compileModuleAsync;
/** /**
* Same as {@link #compileModuleSync} but also creates ComponentFactories for all components. * Same as {@link #compileModuleSync} but also creates ComponentFactories for all components.
*/ */
compileModuleAndAllComponentsSync<T>(moduleType: Type<T>): ModuleWithComponentFactories<T> { compileModuleAndAllComponentsSync: <T>(moduleType: Type<T>) => ModuleWithComponentFactories<T> =
throw _throwError(); Compiler_compileModuleAndAllComponentsSync;
}
/** /**
* Same as {@link #compileModuleAsync} but also creates ComponentFactories for all components. * Same as {@link #compileModuleAsync} but also creates ComponentFactories for all components.
*/ */
compileModuleAndAllComponentsAsync<T>(moduleType: Type<T>): compileModuleAndAllComponentsAsync: <T>(moduleType: Type<T>) =>
Promise<ModuleWithComponentFactories<T>> { Promise<ModuleWithComponentFactories<T>> = Compiler_compileModuleAndAllComponentsAsync;
throw _throwError();
}
/** /**
* Clears all caches. * Clears all caches.

View File

@ -90,7 +90,7 @@ export interface AttributeDecorator {
* ] * ]
* ``` * ```
* *
* * @publicApi
*/ */
(name: string): any; (name: string): any;
new (name: string): Attribute; new (name: string): Attribute;

View File

@ -83,3 +83,7 @@ function throwError(msg: string): never {
debugger; // Left intentionally for better debugger experience. debugger; // Left intentionally for better debugger experience.
throw new Error(`ASSERTION ERROR: ${msg}`); throw new Error(`ASSERTION ERROR: ${msg}`);
} }
export function assertDomNode(node: any) {
assertEqual(node instanceof Node, true, 'The provided value must be an instance of a DOM Node');
}

View File

@ -13,10 +13,8 @@ import {Injector} from '../di/injector';
import {Sanitizer} from '../sanitization/security'; import {Sanitizer} from '../sanitization/security';
import {assertComponentType, assertDefined} from './assert'; import {assertComponentType, assertDefined} from './assert';
import {getContext} from './context_discovery';
import {getComponentDef} from './definition'; import {getComponentDef} from './definition';
import {diPublicInInjector, getOrCreateNodeInjectorForNode} from './di'; import {diPublicInInjector, getOrCreateNodeInjectorForNode} from './di';
import {getHostElement} from './discovery_utils';
import {publishDefaultGlobalUtils} from './global_utils'; import {publishDefaultGlobalUtils} from './global_utils';
import {queueInitHooks, queueLifecycleHooks} from './hooks'; import {queueInitHooks, queueLifecycleHooks} from './hooks';
import {CLEAN_PROMISE, createLViewData, createNodeAtIndex, createTView, getOrCreateTView, initNodeFlags, instantiateRootComponent, locateHostElement, prefillHostVars, queueComponentIndexForCheck, refreshDescendantViews} from './instructions'; import {CLEAN_PROMISE, createLViewData, createNodeAtIndex, createTView, getOrCreateTView, initNodeFlags, instantiateRootComponent, locateHostElement, prefillHostVars, queueComponentIndexForCheck, refreshDescendantViews} from './instructions';
@ -26,7 +24,7 @@ import {PlayerHandler} from './interfaces/player';
import {RElement, Renderer3, RendererFactory3, domRendererFactory3} from './interfaces/renderer'; import {RElement, Renderer3, RendererFactory3, domRendererFactory3} from './interfaces/renderer';
import {CONTEXT, HEADER_OFFSET, HOST, HOST_NODE, INJECTOR, LViewData, LViewFlags, RootContext, RootContextFlags, TVIEW} from './interfaces/view'; import {CONTEXT, HEADER_OFFSET, HOST, HOST_NODE, INJECTOR, LViewData, LViewFlags, RootContext, RootContextFlags, TVIEW} from './interfaces/view';
import {enterView, leaveView, resetComponentState} from './state'; import {enterView, leaveView, resetComponentState} from './state';
import {defaultScheduler, getRootView, readElementValue, readPatchedLViewData, stringify} from './util'; import {defaultScheduler, getRootView, readPatchedLViewData, stringify} from './util';
@ -123,15 +121,15 @@ export function renderComponent<T>(
const renderer = rendererFactory.createRenderer(hostRNode, componentDef); const renderer = rendererFactory.createRenderer(hostRNode, componentDef);
const rootView: LViewData = createLViewData( const rootView: LViewData = createLViewData(
null, renderer, createTView(-1, null, 1, 0, null, null, null), rootContext, rootFlags, null, createTView(-1, null, 1, 0, null, null, null), rootContext, rootFlags, rendererFactory,
undefined, opts.injector || null); renderer, undefined, opts.injector || null);
const oldView = enterView(rootView, null); const oldView = enterView(rootView, null);
let component: T; let component: T;
try { try {
if (rendererFactory.begin) rendererFactory.begin(); if (rendererFactory.begin) rendererFactory.begin();
const componentView = const componentView = createRootComponentView(
createRootComponentView(hostRNode, componentDef, rootView, renderer, sanitizer); hostRNode, componentDef, rootView, rendererFactory, renderer, sanitizer);
component = createRootComponent( component = createRootComponent(
componentView, componentDef, rootView, rootContext, opts.hostFeatures || null); componentView, componentDef, rootView, rootContext, opts.hostFeatures || null);
@ -156,15 +154,17 @@ export function renderComponent<T>(
* @returns Component view created * @returns Component view created
*/ */
export function createRootComponentView( export function createRootComponentView(
rNode: RElement | null, def: ComponentDef<any>, rootView: LViewData, renderer: Renderer3, rNode: RElement | null, def: ComponentDef<any>, rootView: LViewData,
rendererFactory: RendererFactory3, renderer: Renderer3,
sanitizer?: Sanitizer | null): LViewData { sanitizer?: Sanitizer | null): LViewData {
resetComponentState(); resetComponentState();
const tView = rootView[TVIEW]; const tView = rootView[TVIEW];
const componentView = createLViewData( const componentView = createLViewData(
rootView, renderer, rootView,
getOrCreateTView( getOrCreateTView(
def.template, def.consts, def.vars, def.directiveDefs, def.pipeDefs, def.viewQuery), def.template, def.consts, def.vars, def.directiveDefs, def.pipeDefs, def.viewQuery),
null, def.onPush ? LViewFlags.Dirty : LViewFlags.CheckAlways, sanitizer); null, def.onPush ? LViewFlags.Dirty : LViewFlags.CheckAlways, rendererFactory, renderer,
sanitizer);
const tNode = createNodeAtIndex(0, TNodeType.Element, rNode, null, null); const tNode = createNodeAtIndex(0, TNodeType.Element, rNode, null, null);
if (tView.firstTemplatePass) { if (tView.firstTemplatePass) {

View File

@ -15,6 +15,7 @@ import {ComponentFactoryResolver as viewEngine_ComponentFactoryResolver} from '.
import {ElementRef as viewEngine_ElementRef} from '../linker/element_ref'; import {ElementRef as viewEngine_ElementRef} from '../linker/element_ref';
import {NgModuleRef as viewEngine_NgModuleRef} from '../linker/ng_module_factory'; import {NgModuleRef as viewEngine_NgModuleRef} from '../linker/ng_module_factory';
import {RendererFactory2} from '../render/api'; import {RendererFactory2} from '../render/api';
import {Sanitizer} from '../sanitization/security';
import {Type} from '../type'; import {Type} from '../type';
import {VERSION} from '../version'; import {VERSION} from '../version';
import {assertComponentType, assertDefined} from './assert'; import {assertComponentType, assertDefined} from './assert';
@ -25,6 +26,7 @@ import {createLViewData, createNodeAtIndex, createTView, createViewNode, element
import {ComponentDef, RenderFlags} from './interfaces/definition'; import {ComponentDef, RenderFlags} from './interfaces/definition';
import {TContainerNode, TElementContainerNode, TElementNode, TNode, TNodeType} from './interfaces/node'; import {TContainerNode, TElementContainerNode, TElementNode, TNode, TNodeType} from './interfaces/node';
import {RElement, RendererFactory3, domRendererFactory3, isProceduralRenderer} from './interfaces/renderer'; import {RElement, RendererFactory3, domRendererFactory3, isProceduralRenderer} from './interfaces/renderer';
import {SanitizerFn} from './interfaces/sanitization';
import {HEADER_OFFSET, LViewData, LViewFlags, RootContext, TVIEW} from './interfaces/view'; import {HEADER_OFFSET, LViewData, LViewFlags, RootContext, TVIEW} from './interfaces/view';
import {enterView, leaveView} from './state'; import {enterView, leaveView} from './state';
import {defaultScheduler, getTNode} from './util'; import {defaultScheduler, getTNode} from './util';
@ -66,13 +68,6 @@ export const SCHEDULER = new InjectionToken<((fn: () => void) => void)>('SCHEDUL
factory: () => defaultScheduler, factory: () => defaultScheduler,
}); });
/**
* A function used to wrap the `RendererFactory2`.
* Used in tests to change the `RendererFactory2` into a `DebugRendererFactory2`.
*/
export const WRAP_RENDERER_FACTORY2 =
new InjectionToken<(rf: RendererFactory2) => RendererFactory2>('WRAP_RENDERER_FACTORY2');
const NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR = {}; const NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR = {};
function createChainedInjector(rootViewInjector: Injector, moduleInjector: Injector): Injector { function createChainedInjector(rootViewInjector: Injector, moduleInjector: Injector): Injector {
@ -121,10 +116,11 @@ export class ComponentFactory<T> extends viewEngine_ComponentFactory<T> {
const isInternalRootView = rootSelectorOrNode === undefined; const isInternalRootView = rootSelectorOrNode === undefined;
let rendererFactory: RendererFactory3; let rendererFactory: RendererFactory3;
let sanitizer: Sanitizer|null = null;
if (ngModule) { if (ngModule) {
const wrapper = ngModule.injector.get(WRAP_RENDERER_FACTORY2, (v: RendererFactory2) => v); rendererFactory = ngModule.injector.get(RendererFactory2) as RendererFactory3;
rendererFactory = wrapper(ngModule.injector.get(RendererFactory2)) as RendererFactory3; sanitizer = ngModule.injector.get(Sanitizer, null);
} else { } else {
rendererFactory = domRendererFactory3; rendererFactory = domRendererFactory3;
} }
@ -151,8 +147,8 @@ export class ComponentFactory<T> extends viewEngine_ComponentFactory<T> {
// Create the root view. Uses empty TView and ContentTemplate. // Create the root view. Uses empty TView and ContentTemplate.
const rootView: LViewData = createLViewData( const rootView: LViewData = createLViewData(
null, renderer, createTView(-1, null, 1, 0, null, null, null), rootContext, rootFlags, null, createTView(-1, null, 1, 0, null, null, null), rootContext, rootFlags,
undefined, rootViewInjector); rendererFactory, renderer, sanitizer, rootViewInjector);
// rootView is the parent when bootstrapping // rootView is the parent when bootstrapping
const oldView = enterView(rootView, null); const oldView = enterView(rootView, null);
@ -162,8 +158,8 @@ export class ComponentFactory<T> extends viewEngine_ComponentFactory<T> {
try { try {
if (rendererFactory.begin) rendererFactory.begin(); if (rendererFactory.begin) rendererFactory.begin();
const componentView = const componentView = createRootComponentView(
createRootComponentView(hostRNode, this.componentDef, rootView, renderer); hostRNode, this.componentDef, rootView, rendererFactory, renderer);
tElementNode = getTNode(0, rootView) as TElementNode; tElementNode = getTNode(0, rootView) as TElementNode;
// Transform the arrays of native nodes into a structure that can be consumed by the // Transform the arrays of native nodes into a structure that can be consumed by the

View File

@ -7,7 +7,7 @@
*/ */
import './ng_dev_mode'; import './ng_dev_mode';
import {assertEqual} from './assert'; import {assertDomNode} from './assert';
import {EMPTY_ARRAY} from './definition'; import {EMPTY_ARRAY} from './definition';
import {LContext, MONKEY_PATCH_KEY_NAME} from './interfaces/context'; import {LContext, MONKEY_PATCH_KEY_NAME} from './interfaces/context';
import {TNode, TNodeFlags} from './interfaces/node'; import {TNode, TNodeFlags} from './interfaces/node';
@ -95,7 +95,7 @@ export function getContext(target: any): LContext|null {
} }
} else { } else {
const rElement = target as RElement; const rElement = target as RElement;
ngDevMode && assertDomElement(rElement); ngDevMode && assertDomNode(rElement);
// if the context is not found then we need to traverse upwards up the DOM // if the context is not found then we need to traverse upwards up the DOM
// to find the nearest element that has already been monkey patched with data // to find the nearest element that has already been monkey patched with data
@ -262,12 +262,6 @@ function findViaDirective(lViewData: LViewData, directiveInstance: {}): number {
return -1; return -1;
} }
function assertDomElement(element: any) {
assertEqual(
element && (element.nodeType == Node.ELEMENT_NODE || element.nodeType == Node.TEXT_NODE),
true, 'The provided value must be an instance of an HTMLElement');
}
/** /**
* Returns a list of directives extracted from the given view based on the * Returns a list of directives extracted from the given view based on the
* provided list of directive index values. * provided list of directive index values.

View File

@ -1,81 +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
*/
import {Injector} from '../di/injector';
import {Renderer2, RendererType2} from '../render/api';
import {DebugContext} from '../view';
import {DebugRenderer2, DebugRendererFactory2} from '../view/services';
import {getComponent, getInjector, getLocalRefs, loadContext} from './discovery_utils';
import {DirectiveDef} from './interfaces/definition';
import {TNode, TNodeFlags} from './interfaces/node';
import {TVIEW} from './interfaces/view';
/**
* Adapts the DebugRendererFactory2 to create a DebugRenderer2 specific for IVY.
*
* The created DebugRenderer know how to create a Debug Context specific to IVY.
*/
export class Render3DebugRendererFactory2 extends DebugRendererFactory2 {
createRenderer(element: any, renderData: RendererType2|null): Renderer2 {
const renderer = super.createRenderer(element, renderData) as DebugRenderer2;
renderer.debugContextFactory = (nativeElement: any) => new Render3DebugContext(nativeElement);
return renderer;
}
}
/**
* Stores context information about view nodes.
*
* Used in tests to retrieve information those nodes.
*/
class Render3DebugContext implements DebugContext {
constructor(private _nativeNode: any) {}
get nodeIndex(): number|null { return loadContext(this._nativeNode).nodeIndex; }
get view(): any { return loadContext(this._nativeNode).lViewData; }
get injector(): Injector { return getInjector(this._nativeNode); }
get component(): any { return getComponent(this._nativeNode); }
get providerTokens(): any[] {
const lDebugCtx = loadContext(this._nativeNode);
const lViewData = lDebugCtx.lViewData;
const tNode = lViewData[TVIEW].data[lDebugCtx.nodeIndex] as TNode;
const directivesCount = tNode.flags & TNodeFlags.DirectiveCountMask;
if (directivesCount > 0) {
const directiveIdxStart = tNode.flags >> TNodeFlags.DirectiveStartingIndexShift;
const directiveIdxEnd = directiveIdxStart + directivesCount;
const viewDirectiveDefs = this.view[TVIEW].data;
const directiveDefs =
viewDirectiveDefs.slice(directiveIdxStart, directiveIdxEnd) as DirectiveDef<any>[];
return directiveDefs.map(directiveDef => directiveDef.type);
}
return [];
}
get references(): {[key: string]: any} { return getLocalRefs(this._nativeNode); }
// TODO(pk): check previous implementation and re-implement
get context(): any { throw new Error('Not implemented in ivy'); }
// TODO(pk): check previous implementation and re-implement
get componentRenderElement(): any { throw new Error('Not implemented in ivy'); }
// TODO(pk): check previous implementation and re-implement
get renderNode(): any { throw new Error('Not implemented in ivy'); }
// TODO(pk): check previous implementation and re-implement
logError(console: Console, ...values: any[]): void { console.error(...values); }
}

View File

@ -20,7 +20,7 @@ import {NO_PARENT_INJECTOR, NodeInjectorFactory, PARENT_INJECTOR, RelativeInject
import {AttributeMarker, TContainerNode, TElementContainerNode, TElementNode, TNode, TNodeFlags, TNodeProviderIndexes, TNodeType} from './interfaces/node'; import {AttributeMarker, TContainerNode, TElementContainerNode, TElementNode, TNode, TNodeFlags, TNodeProviderIndexes, TNodeType} from './interfaces/node';
import {DECLARATION_VIEW, HOST_NODE, INJECTOR, LViewData, TData, TVIEW, TView} from './interfaces/view'; import {DECLARATION_VIEW, HOST_NODE, INJECTOR, LViewData, TData, TVIEW, TView} from './interfaces/view';
import {assertNodeOfPossibleTypes} from './node_assert'; import {assertNodeOfPossibleTypes} from './node_assert';
import {getPreviousOrParentTNode, getViewData, setTNodeAndViewData} from './state'; import {_getViewData, getPreviousOrParentTNode, getViewData, setTNodeAndViewData} from './state';
import {getParentInjectorIndex, getParentInjectorView, hasParentInjector, isComponent, stringify} from './util'; import {getParentInjectorIndex, getParentInjectorView, hasParentInjector, isComponent, stringify} from './util';
/** /**
@ -556,13 +556,19 @@ export class NodeInjector implements Injector {
constructor( constructor(
private _tNode: TElementNode|TContainerNode|TElementContainerNode, private _tNode: TElementNode|TContainerNode|TElementContainerNode,
private _hostView: LViewData) { private _lView: LViewData) {
this._injectorIndex = getOrCreateNodeInjectorForNode(_tNode, _hostView); this._injectorIndex = getOrCreateNodeInjectorForNode(_tNode, _lView);
} }
get(token: any): any { get(token: any): any {
setTNodeAndViewData(this._tNode, this._hostView); const previousTNode = getPreviousOrParentTNode();
return getOrCreateInjectable(this._tNode, this._hostView, token); const previousLView = _getViewData();
setTNodeAndViewData(this._tNode, this._lView);
try {
return getOrCreateInjectable(this._tNode, this._lView, token);
} finally {
setTNodeAndViewData(previousTNode, previousLView);
}
} }
} }

View File

@ -141,9 +141,11 @@ export function getDirectives(target: {}): Array<{}> {
* Throws if a given target doesn't have associated LContext. * Throws if a given target doesn't have associated LContext.
* *
*/ */
export function loadContext(target: {}): LContext { export function loadContext(target: {}): LContext;
export function loadContext(target: {}, throwOnNotFound: false): LContext|null;
export function loadContext(target: {}, throwOnNotFound: boolean = true): LContext|null {
const context = getContext(target); const context = getContext(target);
if (!context) { if (!context && throwOnNotFound) {
throw new Error( throw new Error(
ngDevMode ? `Unable to find context associated with ${stringify(target)}` : ngDevMode ? `Unable to find context associated with ${stringify(target)}` :
'Invalid ng target'); 'Invalid ng target');

View File

@ -13,7 +13,7 @@ import {NgOnChangesFeature} from './features/ng_onchanges_feature';
import {ProvidersFeature} from './features/providers_feature'; import {ProvidersFeature} from './features/providers_feature';
import {BaseDef, ComponentDef, ComponentDefWithMeta, ComponentTemplate, ComponentType, DirectiveDef, DirectiveDefFlags, DirectiveDefWithMeta, DirectiveType, PipeDef, PipeDefWithMeta} from './interfaces/definition'; import {BaseDef, ComponentDef, ComponentDefWithMeta, ComponentTemplate, ComponentType, DirectiveDef, DirectiveDefFlags, DirectiveDefWithMeta, DirectiveType, PipeDef, PipeDefWithMeta} from './interfaces/definition';
export {ComponentFactory, ComponentFactoryResolver, ComponentRef, WRAP_RENDERER_FACTORY2, injectComponentFactoryResolver} from './component_ref'; export {ComponentFactory, ComponentFactoryResolver, ComponentRef, injectComponentFactoryResolver} from './component_ref';
export {getFactoryOf, getInheritedFactory} from './di'; export {getFactoryOf, getInheritedFactory} from './di';
export {RenderFlags} from './interfaces/definition'; export {RenderFlags} from './interfaces/definition';
export {CssSelectorList} from './interfaces/projection'; export {CssSelectorList} from './interfaces/projection';

View File

@ -32,11 +32,11 @@ import {LQueries} from './interfaces/query';
import {ProceduralRenderer3, RComment, RElement, RNode, RText, Renderer3, RendererFactory3, isProceduralRenderer} from './interfaces/renderer'; import {ProceduralRenderer3, RComment, RElement, RNode, RText, Renderer3, RendererFactory3, isProceduralRenderer} from './interfaces/renderer';
import {SanitizerFn} from './interfaces/sanitization'; import {SanitizerFn} from './interfaces/sanitization';
import {StylingIndex} from './interfaces/styling'; import {StylingIndex} from './interfaces/styling';
import {BINDING_INDEX, CLEANUP, CONTAINER_INDEX, CONTENT_QUERIES, CONTEXT, DECLARATION_VIEW, FLAGS, HEADER_OFFSET, HOST, HOST_NODE, INJECTOR, LViewData, LViewFlags, NEXT, OpaqueViewState, PARENT, QUERIES, RENDERER, RootContext, RootContextFlags, SANITIZER, TAIL, TVIEW, TView} from './interfaces/view'; import {BINDING_INDEX, CLEANUP, CONTAINER_INDEX, CONTENT_QUERIES, CONTEXT, DECLARATION_VIEW, FLAGS, HEADER_OFFSET, HOST, HOST_NODE, INJECTOR, LViewData, LViewFlags, NEXT, OpaqueViewState, PARENT, QUERIES, RENDERER, RENDERER_FACTORY, RootContext, RootContextFlags, SANITIZER, TAIL, TVIEW, TView} from './interfaces/view';
import {assertNodeOfPossibleTypes, assertNodeType} from './node_assert'; import {assertNodeOfPossibleTypes, assertNodeType} from './node_assert';
import {appendChild, appendProjectedNode, createTextNode, findComponentView, getLViewChild, getRenderParent, insertView, removeView} from './node_manipulation'; import {appendChild, appendProjectedNode, createTextNode, findComponentView, getLViewChild, getRenderParent, insertView, removeView} from './node_manipulation';
import {isNodeMatchingSelectorList, matchingSelectorIndex} from './node_selector_matcher'; import {isNodeMatchingSelectorList, matchingSelectorIndex} from './node_selector_matcher';
import {assertDataInRange, assertHasParent, assertPreviousIsParent, decreaseElementDepthCount, enterView, getBindingsEnabled, getCheckNoChangesMode, getCleanup, getContextViewData, getCreationMode, getCurrentQueries, getCurrentSanitizer, getElementDepthCount, getFirstTemplatePass, getIsParent, getPreviousOrParentTNode, getRenderer, getRendererFactory, getTView, getTViewCleanup, getViewData, increaseElementDepthCount, leaveView, nextContextImpl, resetComponentState, setBindingRoot, setCheckNoChangesMode, setCurrentQueries, setFirstTemplatePass, setIsParent, setPreviousOrParentTNode, setRenderer, setRendererFactory} from './state'; import {assertDataInRange, assertHasParent, assertPreviousIsParent, decreaseElementDepthCount, enterView, getBindingsEnabled, getCheckNoChangesMode, getCleanup, getContextViewData, getCreationMode, getCurrentQueries, getCurrentSanitizer, getElementDepthCount, getFirstTemplatePass, getIsParent, getPreviousOrParentTNode, getRenderer, getRendererFactory, getTView, getTViewCleanup, getViewData, increaseElementDepthCount, leaveView, nextContextImpl, resetComponentState, setBindingRoot, setCheckNoChangesMode, setCurrentQueries, setFirstTemplatePass, setIsParent, setPreviousOrParentTNode} from './state';
import {createStylingContextTemplate, renderStyleAndClassBindings, updateClassProp as updateElementClassProp, updateStyleProp as updateElementStyleProp, updateStylingMap} from './styling/class_and_style_bindings'; import {createStylingContextTemplate, renderStyleAndClassBindings, updateClassProp as updateElementClassProp, updateStyleProp as updateElementStyleProp, updateStylingMap} from './styling/class_and_style_bindings';
import {BoundPlayerFactory} from './styling/player_factory'; import {BoundPlayerFactory} from './styling/player_factory';
import {getStylingContext} from './styling/util'; import {getStylingContext} from './styling/util';
@ -155,17 +155,20 @@ function refreshChildComponents(components: number[] | null, rf: RenderFlags | n
} }
export function createLViewData<T>( export function createLViewData<T>(
parentViewData: LViewData | null, renderer: Renderer3, tView: TView, context: T | null, parentLView: LViewData | null, tView: TView, context: T | null, flags: LViewFlags,
flags: LViewFlags, sanitizer?: Sanitizer | null, injector?: Injector | null): LViewData { rendererFactory?: RendererFactory3 | null, renderer?: Renderer3 | null,
const instance = tView.blueprint.slice() as LViewData; sanitizer?: Sanitizer | null, injector?: Injector | null): LViewData {
instance[FLAGS] = flags | LViewFlags.CreationMode | LViewFlags.Attached | LViewFlags.RunInit; const lView = tView.blueprint.slice() as LViewData;
instance[PARENT] = instance[DECLARATION_VIEW] = parentViewData; lView[FLAGS] = flags | LViewFlags.CreationMode | LViewFlags.Attached | LViewFlags.RunInit;
instance[CONTEXT] = context; lView[PARENT] = lView[DECLARATION_VIEW] = parentLView;
instance[INJECTOR as any] = lView[CONTEXT] = context;
injector === undefined ? (parentViewData ? parentViewData[INJECTOR] : null) : injector; lView[RENDERER_FACTORY] = (rendererFactory || parentLView && parentLView[RENDERER_FACTORY]) !;
instance[RENDERER] = renderer; ngDevMode && assertDefined(lView[RENDERER_FACTORY], 'RendererFactory is required');
instance[SANITIZER] = sanitizer || null; lView[RENDERER] = (renderer || parentLView && parentLView[RENDERER]) !;
return instance; ngDevMode && assertDefined(lView[RENDERER], 'Renderer is required');
lView[SANITIZER] = sanitizer || parentLView && parentLView[SANITIZER] || null !;
lView[INJECTOR as any] = injector || parentLView && parentLView[INJECTOR] || null;
return lView;
} }
/** /**
@ -285,20 +288,19 @@ export function renderTemplate<T>(
sanitizer?: Sanitizer | null): LViewData { sanitizer?: Sanitizer | null): LViewData {
if (hostView == null) { if (hostView == null) {
resetComponentState(); resetComponentState();
setRendererFactory(providedRendererFactory);
const renderer = providedRendererFactory.createRenderer(null, null); const renderer = providedRendererFactory.createRenderer(null, null);
setRenderer(renderer);
// We need to create a root view so it's possible to look up the host element through its index // We need to create a root view so it's possible to look up the host element through its index
const lView = createLViewData( const hostLView = createLViewData(
null, renderer, createTView(-1, null, 1, 0, null, null, null), {}, null, createTView(-1, null, 1, 0, null, null, null), {},
LViewFlags.CheckAlways | LViewFlags.IsRoot); LViewFlags.CheckAlways | LViewFlags.IsRoot, providedRendererFactory, renderer);
enterView(lView, null); enterView(hostLView, null); // SUSPECT! why do we need to enter the View?
const componentTView = const componentTView =
getOrCreateTView(templateFn, consts, vars, directives || null, pipes || null, null); getOrCreateTView(templateFn, consts, vars, directives || null, pipes || null, null);
hostView = createLViewData( hostView = createLViewData(
lView, renderer, componentTView, context, LViewFlags.CheckAlways, sanitizer); hostLView, componentTView, context, LViewFlags.CheckAlways, providedRendererFactory,
renderer, sanitizer);
hostView[HOST_NODE] = createNodeAtIndex(0, TNodeType.Element, hostNode, null, null); hostView[HOST_NODE] = createNodeAtIndex(0, TNodeType.Element, hostNode, null, null);
} }
renderComponentOrTemplate(hostView, context, null, templateFn); renderComponentOrTemplate(hostView, context, null, templateFn);
@ -319,8 +321,7 @@ export function createEmbeddedViewAndNode<T>(
setIsParent(true); setIsParent(true);
setPreviousOrParentTNode(null !); setPreviousOrParentTNode(null !);
const lView = createLViewData( const lView = createLViewData(declarationView, tView, context, LViewFlags.CheckAlways);
declarationView, renderer, tView, context, LViewFlags.CheckAlways, getCurrentSanitizer());
lView[DECLARATION_VIEW] = declarationView; lView[DECLARATION_VIEW] = declarationView;
if (queries) { if (queries) {
@ -403,7 +404,7 @@ export function nextContext<T = any>(level: number = 1): T {
function renderComponentOrTemplate<T>( function renderComponentOrTemplate<T>(
hostView: LViewData, componentOrContext: T, rf: RenderFlags | null, hostView: LViewData, componentOrContext: T, rf: RenderFlags | null,
templateFn?: ComponentTemplate<T>) { templateFn?: ComponentTemplate<T>) {
const rendererFactory = getRendererFactory(); const rendererFactory = hostView[RENDERER_FACTORY];
const oldView = enterView(hostView, hostView[HOST_NODE]); const oldView = enterView(hostView, hostView[HOST_NODE]);
try { try {
if (rendererFactory.begin) { if (rendererFactory.begin) {
@ -765,7 +766,6 @@ export function createError(text: string, token: any) {
export function locateHostElement( export function locateHostElement(
factory: RendererFactory3, elementOrSelector: RElement | string): RElement|null { factory: RendererFactory3, elementOrSelector: RElement | string): RElement|null {
ngDevMode && assertDataInRange(-1); ngDevMode && assertDataInRange(-1);
setRendererFactory(factory);
const defaultRenderer = factory.createRenderer(null, null); const defaultRenderer = factory.createRenderer(null, null);
const rNode = typeof elementOrSelector === 'string' ? const rNode = typeof elementOrSelector === 'string' ?
(isProceduralRenderer(defaultRenderer) ? (isProceduralRenderer(defaultRenderer) ?
@ -1671,11 +1671,12 @@ function addComponentLogic<T>(
// Only component views should be added to the view tree directly. Embedded views are // Only component views should be added to the view tree directly. Embedded views are
// accessed through their containers because they may be removed / re-added later. // accessed through their containers because they may be removed / re-added later.
const rendererFactory = getRendererFactory();
const componentView = addToViewTree( const componentView = addToViewTree(
viewData, previousOrParentTNode.index as number, viewData, previousOrParentTNode.index as number,
createLViewData( createLViewData(
getViewData(), getRendererFactory().createRenderer(native as RElement, def), tView, null, getViewData(), tView, null, def.onPush ? LViewFlags.Dirty : LViewFlags.CheckAlways,
def.onPush ? LViewFlags.Dirty : LViewFlags.CheckAlways, getCurrentSanitizer())); rendererFactory, getRendererFactory().createRenderer(native as RElement, def)));
componentView[HOST_NODE] = previousOrParentTNode as TElementNode; componentView[HOST_NODE] = previousOrParentTNode as TElementNode;
@ -2002,9 +2003,9 @@ export function embeddedViewStart(viewBlockId: number, consts: number, vars: num
} else { } else {
// When we create a new LView, we always reset the state of the instructions. // When we create a new LView, we always reset the state of the instructions.
viewToRender = createLViewData( viewToRender = createLViewData(
getViewData(), getRenderer(), getViewData(),
getOrCreateEmbeddedTView(viewBlockId, consts, vars, containerTNode as TContainerNode), null, getOrCreateEmbeddedTView(viewBlockId, consts, vars, containerTNode as TContainerNode), null,
LViewFlags.CheckAlways, getCurrentSanitizer()); LViewFlags.CheckAlways);
if (lContainer[QUERIES]) { if (lContainer[QUERIES]) {
viewToRender[QUERIES] = lContainer[QUERIES] !.createView(); viewToRender[QUERIES] = lContainer[QUERIES] !.createView();

View File

@ -17,13 +17,10 @@ import {I18nUpdateOpCodes, TI18n} from './i18n';
import {TElementNode, TNode, TViewNode} from './node'; import {TElementNode, TNode, TViewNode} from './node';
import {PlayerHandler} from './player'; import {PlayerHandler} from './player';
import {LQueries} from './query'; import {LQueries} from './query';
import {RElement, Renderer3} from './renderer'; import {RElement, Renderer3, RendererFactory3} from './renderer';
import {StylingContext} from './styling'; import {StylingContext} from './styling';
/** Size of LViewData's header. Necessary to adjust for it when setting slots. */
export const HEADER_OFFSET = 17;
// Below are constants for LViewData indices to help us look up LViewData members // Below are constants for LViewData indices to help us look up LViewData members
// without having to remember the specific indices. // without having to remember the specific indices.
// Uglify will inline these when minifying so there shouldn't be a cost. // Uglify will inline these when minifying so there shouldn't be a cost.
@ -33,17 +30,21 @@ export const PARENT = 2;
export const NEXT = 3; export const NEXT = 3;
export const QUERIES = 4; export const QUERIES = 4;
export const HOST = 5; export const HOST = 5;
export const HOST_NODE = 6; export const HOST_NODE = 6; // Rename to `T_HOST`?
export const BINDING_INDEX = 7; export const BINDING_INDEX = 7;
export const CLEANUP = 8; export const CLEANUP = 8;
export const CONTEXT = 9; export const CONTEXT = 9;
export const INJECTOR = 10; export const INJECTOR = 10;
export const RENDERER = 11; export const RENDERER_FACTORY = 11;
export const SANITIZER = 12; export const RENDERER = 12;
export const TAIL = 13; export const SANITIZER = 13;
export const CONTAINER_INDEX = 14; export const TAIL = 14;
export const CONTENT_QUERIES = 15; export const CONTAINER_INDEX = 15;
export const DECLARATION_VIEW = 16; export const CONTENT_QUERIES = 16;
export const DECLARATION_VIEW = 17;
/** Size of LViewData's header. Necessary to adjust for it when setting slots. */
export const HEADER_OFFSET = 18;
// This interface replaces the real LViewData interface if it is an arg or a // This interface replaces the real LViewData interface if it is an arg or a
// return value of a public instruction. This ensures we don't need to expose // return value of a public instruction. This ensures we don't need to expose
@ -149,6 +150,9 @@ export interface LViewData extends Array<any> {
/** An optional Module Injector to be used as fall back after Element Injectors are consulted. */ /** An optional Module Injector to be used as fall back after Element Injectors are consulted. */
readonly[INJECTOR]: Injector|null; readonly[INJECTOR]: Injector|null;
/** Renderer to be used for this view. */
[RENDERER_FACTORY]: RendererFactory3;
/** Renderer to be used for this view. */ /** Renderer to be used for this view. */
[RENDERER]: Renderer3; [RENDERER]: Renderer3;

View File

@ -8,6 +8,7 @@
import {ModuleWithProviders, NgModule, NgModuleDef, NgModuleTransitiveScopes} from '../../metadata/ng_module'; import {ModuleWithProviders, NgModule, NgModuleDef, NgModuleTransitiveScopes} from '../../metadata/ng_module';
import {Type} from '../../type'; import {Type} from '../../type';
import {assertDefined} from '../assert';
import {getComponentDef, getDirectiveDef, getNgModuleDef, getPipeDef} from '../definition'; import {getComponentDef, getDirectiveDef, getNgModuleDef, getPipeDef} from '../definition';
import {NG_COMPONENT_DEF, NG_DIRECTIVE_DEF, NG_INJECTOR_DEF, NG_MODULE_DEF, NG_PIPE_DEF} from '../fields'; import {NG_COMPONENT_DEF, NG_DIRECTIVE_DEF, NG_INJECTOR_DEF, NG_MODULE_DEF, NG_PIPE_DEF} from '../fields';
import {ComponentDef} from '../interfaces/definition'; import {ComponentDef} from '../interfaces/definition';
@ -32,6 +33,8 @@ export function compileNgModule(moduleType: Type<any>, ngModule: NgModule = {}):
* Compiles and adds the `ngModuleDef` and `ngInjectorDef` properties to the module class. * Compiles and adds the `ngModuleDef` and `ngInjectorDef` properties to the module class.
*/ */
export function compileNgModuleDefs(moduleType: Type<any>, ngModule: NgModule): void { export function compileNgModuleDefs(moduleType: Type<any>, ngModule: NgModule): void {
ngDevMode && assertDefined(moduleType, 'Required value moduleType');
ngDevMode && assertDefined(ngModule, 'Required value ngModule');
const declarations: Type<any>[] = flatten(ngModule.declarations || EMPTY_ARRAY); const declarations: Type<any>[] = flatten(ngModule.declarations || EMPTY_ARRAY);
let ngModuleDef: any = null; let ngModuleDef: any = null;

View File

@ -13,7 +13,7 @@ import {executeHooks} from './hooks';
import {TElementNode, TNode, TNodeFlags, TViewNode} from './interfaces/node'; import {TElementNode, TNode, TNodeFlags, TViewNode} from './interfaces/node';
import {LQueries} from './interfaces/query'; import {LQueries} from './interfaces/query';
import {Renderer3, RendererFactory3} from './interfaces/renderer'; import {Renderer3, RendererFactory3} from './interfaces/renderer';
import {BINDING_INDEX, CLEANUP, CONTEXT, DECLARATION_VIEW, FLAGS, HOST_NODE, LViewData, LViewFlags, OpaqueViewState, QUERIES, RENDERER, SANITIZER, TVIEW, TView} from './interfaces/view'; import {BINDING_INDEX, CLEANUP, CONTEXT, DECLARATION_VIEW, FLAGS, HOST_NODE, LViewData, LViewFlags, OpaqueViewState, QUERIES, RENDERER, RENDERER_FACTORY, SANITIZER, TVIEW, TView} from './interfaces/view';
import {assertDataInRangeInternal, isContentQueryHost} from './util'; import {assertDataInRangeInternal, isContentQueryHost} from './util';
/** /**
@ -51,10 +51,6 @@ export function getRendererFactory(): RendererFactory3 {
return rendererFactory; return rendererFactory;
} }
export function setRendererFactory(factory: RendererFactory3): void {
rendererFactory = factory;
}
export function getCurrentSanitizer(): Sanitizer|null { export function getCurrentSanitizer(): Sanitizer|null {
return viewData && viewData[SANITIZER]; return viewData && viewData[SANITIZER];
} }
@ -357,6 +353,7 @@ export function enterView(
creationMode = newView && (newView[FLAGS] & LViewFlags.CreationMode) === LViewFlags.CreationMode; creationMode = newView && (newView[FLAGS] & LViewFlags.CreationMode) === LViewFlags.CreationMode;
firstTemplatePass = newView && tView.firstTemplatePass; firstTemplatePass = newView && tView.firstTemplatePass;
bindingRootIndex = newView && tView.bindingStartIndex; bindingRootIndex = newView && tView.bindingStartIndex;
rendererFactory = newView && newView[RENDERER_FACTORY];
renderer = newView && newView[RENDERER]; renderer = newView && newView[RENDERER];
previousOrParentTNode = hostTNode !; previousOrParentTNode = hostTNode !;

View File

@ -13,7 +13,7 @@ import {EmbeddedViewRef as viewEngine_EmbeddedViewRef, InternalViewRef as viewEn
import {checkNoChanges, checkNoChangesInRootView, detectChanges, detectChangesInRootView, markViewDirty, storeCleanupFn, viewAttached} from './instructions'; import {checkNoChanges, checkNoChangesInRootView, detectChanges, detectChangesInRootView, markViewDirty, storeCleanupFn, viewAttached} from './instructions';
import {TNode, TNodeType, TViewNode} from './interfaces/node'; import {TNode, TNodeType, TViewNode} from './interfaces/node';
import {FLAGS, HOST, HOST_NODE, LViewData, LViewFlags, PARENT} from './interfaces/view'; import {FLAGS, HOST, HOST_NODE, LViewData, LViewFlags, PARENT, RENDERER_FACTORY} from './interfaces/view';
import {destroyLView} from './node_manipulation'; import {destroyLView} from './node_manipulation';
import {getRendererFactory} from './state'; import {getRendererFactory} from './state';
import {getNativeByTNode} from './util'; import {getNativeByTNode} from './util';
@ -241,7 +241,7 @@ export class ViewRef<T> implements viewEngine_EmbeddedViewRef<T>, viewEngine_Int
* See {@link ChangeDetectorRef#detach detach} for more information. * See {@link ChangeDetectorRef#detach detach} for more information.
*/ */
detectChanges(): void { detectChanges(): void {
const rendererFactory = getRendererFactory(); const rendererFactory = this._view[RENDERER_FACTORY];
if (rendererFactory.begin) { if (rendererFactory.begin) {
rendererFactory.begin(); rendererFactory.begin();
} }

View File

@ -60,7 +60,7 @@ export interface TrustedUrlString extends TrustedString { [BRAND]: BypassType.Ur
export interface TrustedResourceUrlString extends TrustedString { [BRAND]: BypassType.ResourceUrl; } export interface TrustedResourceUrlString extends TrustedString { [BRAND]: BypassType.ResourceUrl; }
export function allowSanitizationBypass(value: any, type: BypassType): boolean { export function allowSanitizationBypass(value: any, type: BypassType): boolean {
return (value instanceof String && (value as TrustedStyleString)[BRAND] === type) ? true : false; return (value instanceof String && (value as TrustedStyleString)[BRAND] === type);
} }
/** /**

View File

@ -6,13 +6,12 @@
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import {DebugElement, DebugNode, EventListener, getDebugNode, indexDebugNode, removeDebugNodeFromIndex} from '../debug/debug_node'; import {DebugElement__PRE_R3__, DebugNode__PRE_R3__, EventListener, getDebugNode, indexDebugNode, removeDebugNodeFromIndex} from '../debug/debug_node';
import {Injector} from '../di'; import {Injector} from '../di';
import {InjectableDef, getInjectableDef} from '../di/defs'; import {InjectableDef, getInjectableDef} from '../di/defs';
import {InjectableType} from '../di/injectable'; import {InjectableType} from '../di/injectable';
import {ErrorHandler} from '../error_handler'; import {ErrorHandler} from '../error_handler';
import {isDevMode} from '../is_dev_mode'; import {isDevMode} from '../is_dev_mode';
import {ivyEnabled} from '../ivy_switch';
import {ComponentFactory} from '../linker/component_factory'; import {ComponentFactory} from '../linker/component_factory';
import {NgModuleRef} from '../linker/ng_module_factory'; import {NgModuleRef} from '../linker/ng_module_factory';
import {Renderer2, RendererFactory2, RendererStyleFlags2, RendererType2} from '../render/api'; import {Renderer2, RendererFactory2, RendererStyleFlags2, RendererType2} from '../render/api';
@ -700,8 +699,8 @@ export class DebugRenderer2 implements Renderer2 {
const el = this.delegate.createElement(name, namespace); const el = this.delegate.createElement(name, namespace);
const debugCtx = this.createDebugContext(el); const debugCtx = this.createDebugContext(el);
if (debugCtx) { if (debugCtx) {
const debugEl = new DebugElement(el, null, debugCtx); const debugEl = new DebugElement__PRE_R3__(el, null, debugCtx);
debugEl.name = name; (debugEl as{name: string}).name = name;
indexDebugNode(debugEl); indexDebugNode(debugEl);
} }
return el; return el;
@ -711,7 +710,7 @@ export class DebugRenderer2 implements Renderer2 {
const comment = this.delegate.createComment(value); const comment = this.delegate.createComment(value);
const debugCtx = this.createDebugContext(comment); const debugCtx = this.createDebugContext(comment);
if (debugCtx) { if (debugCtx) {
indexDebugNode(new DebugNode(comment, null, debugCtx)); indexDebugNode(new DebugNode__PRE_R3__(comment, null, debugCtx));
} }
return comment; return comment;
} }
@ -720,7 +719,7 @@ export class DebugRenderer2 implements Renderer2 {
const text = this.delegate.createText(value); const text = this.delegate.createText(value);
const debugCtx = this.createDebugContext(text); const debugCtx = this.createDebugContext(text);
if (debugCtx) { if (debugCtx) {
indexDebugNode(new DebugNode(text, null, debugCtx)); indexDebugNode(new DebugNode__PRE_R3__(text, null, debugCtx));
} }
return text; return text;
} }
@ -728,7 +727,7 @@ export class DebugRenderer2 implements Renderer2 {
appendChild(parent: any, newChild: any): void { appendChild(parent: any, newChild: any): void {
const debugEl = getDebugNode(parent); const debugEl = getDebugNode(parent);
const debugChildEl = getDebugNode(newChild); const debugChildEl = getDebugNode(newChild);
if (debugEl && debugChildEl && debugEl instanceof DebugElement) { if (debugEl && debugChildEl && debugEl instanceof DebugElement__PRE_R3__) {
debugEl.addChild(debugChildEl); debugEl.addChild(debugChildEl);
} }
this.delegate.appendChild(parent, newChild); this.delegate.appendChild(parent, newChild);
@ -738,7 +737,7 @@ export class DebugRenderer2 implements Renderer2 {
const debugEl = getDebugNode(parent); const debugEl = getDebugNode(parent);
const debugChildEl = getDebugNode(newChild); const debugChildEl = getDebugNode(newChild);
const debugRefEl = getDebugNode(refChild) !; const debugRefEl = getDebugNode(refChild) !;
if (debugEl && debugChildEl && debugEl instanceof DebugElement) { if (debugEl && debugChildEl && debugEl instanceof DebugElement__PRE_R3__) {
debugEl.insertBefore(debugRefEl, debugChildEl); debugEl.insertBefore(debugRefEl, debugChildEl);
} }
@ -748,7 +747,7 @@ export class DebugRenderer2 implements Renderer2 {
removeChild(parent: any, oldChild: any): void { removeChild(parent: any, oldChild: any): void {
const debugEl = getDebugNode(parent); const debugEl = getDebugNode(parent);
const debugChildEl = getDebugNode(oldChild); const debugChildEl = getDebugNode(oldChild);
if (debugEl && debugChildEl && debugEl instanceof DebugElement) { if (debugEl && debugChildEl && debugEl instanceof DebugElement__PRE_R3__) {
debugEl.removeChild(debugChildEl); debugEl.removeChild(debugChildEl);
} }
this.delegate.removeChild(parent, oldChild); this.delegate.removeChild(parent, oldChild);
@ -756,16 +755,16 @@ export class DebugRenderer2 implements Renderer2 {
selectRootElement(selectorOrNode: string|any, preserveContent?: boolean): any { selectRootElement(selectorOrNode: string|any, preserveContent?: boolean): any {
const el = this.delegate.selectRootElement(selectorOrNode, preserveContent); const el = this.delegate.selectRootElement(selectorOrNode, preserveContent);
const debugCtx = getCurrentDebugContext() || (ivyEnabled ? this.createDebugContext(el) : null); const debugCtx = getCurrentDebugContext();
if (debugCtx) { if (debugCtx) {
indexDebugNode(new DebugElement(el, null, debugCtx)); indexDebugNode(new DebugElement__PRE_R3__(el, null, debugCtx));
} }
return el; return el;
} }
setAttribute(el: any, name: string, value: string, namespace?: string): void { setAttribute(el: any, name: string, value: string, namespace?: string): void {
const debugEl = getDebugNode(el); const debugEl = getDebugNode(el);
if (debugEl && debugEl instanceof DebugElement) { if (debugEl && debugEl instanceof DebugElement__PRE_R3__) {
const fullName = namespace ? namespace + ':' + name : name; const fullName = namespace ? namespace + ':' + name : name;
debugEl.attributes[fullName] = value; debugEl.attributes[fullName] = value;
} }
@ -774,7 +773,7 @@ export class DebugRenderer2 implements Renderer2 {
removeAttribute(el: any, name: string, namespace?: string): void { removeAttribute(el: any, name: string, namespace?: string): void {
const debugEl = getDebugNode(el); const debugEl = getDebugNode(el);
if (debugEl && debugEl instanceof DebugElement) { if (debugEl && debugEl instanceof DebugElement__PRE_R3__) {
const fullName = namespace ? namespace + ':' + name : name; const fullName = namespace ? namespace + ':' + name : name;
debugEl.attributes[fullName] = null; debugEl.attributes[fullName] = null;
} }
@ -783,7 +782,7 @@ export class DebugRenderer2 implements Renderer2 {
addClass(el: any, name: string): void { addClass(el: any, name: string): void {
const debugEl = getDebugNode(el); const debugEl = getDebugNode(el);
if (debugEl && debugEl instanceof DebugElement) { if (debugEl && debugEl instanceof DebugElement__PRE_R3__) {
debugEl.classes[name] = true; debugEl.classes[name] = true;
} }
this.delegate.addClass(el, name); this.delegate.addClass(el, name);
@ -791,7 +790,7 @@ export class DebugRenderer2 implements Renderer2 {
removeClass(el: any, name: string): void { removeClass(el: any, name: string): void {
const debugEl = getDebugNode(el); const debugEl = getDebugNode(el);
if (debugEl && debugEl instanceof DebugElement) { if (debugEl && debugEl instanceof DebugElement__PRE_R3__) {
debugEl.classes[name] = false; debugEl.classes[name] = false;
} }
this.delegate.removeClass(el, name); this.delegate.removeClass(el, name);
@ -799,7 +798,7 @@ export class DebugRenderer2 implements Renderer2 {
setStyle(el: any, style: string, value: any, flags: RendererStyleFlags2): void { setStyle(el: any, style: string, value: any, flags: RendererStyleFlags2): void {
const debugEl = getDebugNode(el); const debugEl = getDebugNode(el);
if (debugEl && debugEl instanceof DebugElement) { if (debugEl && debugEl instanceof DebugElement__PRE_R3__) {
debugEl.styles[style] = value; debugEl.styles[style] = value;
} }
this.delegate.setStyle(el, style, value, flags); this.delegate.setStyle(el, style, value, flags);
@ -807,7 +806,7 @@ export class DebugRenderer2 implements Renderer2 {
removeStyle(el: any, style: string, flags: RendererStyleFlags2): void { removeStyle(el: any, style: string, flags: RendererStyleFlags2): void {
const debugEl = getDebugNode(el); const debugEl = getDebugNode(el);
if (debugEl && debugEl instanceof DebugElement) { if (debugEl && debugEl instanceof DebugElement__PRE_R3__) {
debugEl.styles[style] = null; debugEl.styles[style] = null;
} }
this.delegate.removeStyle(el, style, flags); this.delegate.removeStyle(el, style, flags);
@ -815,7 +814,7 @@ export class DebugRenderer2 implements Renderer2 {
setProperty(el: any, name: string, value: any): void { setProperty(el: any, name: string, value: any): void {
const debugEl = getDebugNode(el); const debugEl = getDebugNode(el);
if (debugEl && debugEl instanceof DebugElement) { if (debugEl && debugEl instanceof DebugElement__PRE_R3__) {
debugEl.properties[name] = value; debugEl.properties[name] = value;
} }
this.delegate.setProperty(el, name, value); this.delegate.setProperty(el, name, value);

View File

@ -176,6 +176,9 @@
{ {
"name": "RENDERER" "name": "RENDERER"
}, },
{
"name": "RENDERER_FACTORY"
},
{ {
"name": "RENDER_PARENT" "name": "RENDER_PARENT"
}, },
@ -611,9 +614,6 @@
{ {
"name": "getCurrentQueries" "name": "getCurrentQueries"
}, },
{
"name": "getCurrentSanitizer"
},
{ {
"name": "getDirectiveDef" "name": "getDirectiveDef"
}, },
@ -1145,9 +1145,6 @@
{ {
"name": "setProp" "name": "setProp"
}, },
{
"name": "setRendererFactory"
},
{ {
"name": "setStyle" "name": "setStyle"
}, },

View File

@ -107,6 +107,9 @@
{ {
"name": "RENDERER" "name": "RENDERER"
}, },
{
"name": "RENDERER_FACTORY"
},
{ {
"name": "RENDER_PARENT" "name": "RENDER_PARENT"
}, },
@ -320,9 +323,6 @@
{ {
"name": "getRenderer" "name": "getRenderer"
}, },
{
"name": "getRendererFactory"
},
{ {
"name": "getRootContext" "name": "getRootContext"
}, },
@ -458,9 +458,6 @@
{ {
"name": "setPreviousOrParentTNode" "name": "setPreviousOrParentTNode"
}, },
{
"name": "setRendererFactory"
},
{ {
"name": "setTNodeAndViewData" "name": "setTNodeAndViewData"
}, },

View File

@ -356,6 +356,9 @@
{ {
"name": "RENDERER" "name": "RENDERER"
}, },
{
"name": "RENDERER_FACTORY"
},
{ {
"name": "RENDER_PARENT" "name": "RENDER_PARENT"
}, },
@ -392,6 +395,9 @@
{ {
"name": "SafeSubscriber" "name": "SafeSubscriber"
}, },
{
"name": "Sanitizer"
},
{ {
"name": "Self" "name": "Self"
}, },
@ -455,9 +461,6 @@
{ {
"name": "ViewEncapsulation" "name": "ViewEncapsulation"
}, },
{
"name": "WRAP_RENDERER_FACTORY2"
},
{ {
"name": "_CLEAN_PROMISE" "name": "_CLEAN_PROMISE"
}, },
@ -548,6 +551,9 @@
{ {
"name": "_enable_super_gross_mode_that_will_cause_bad_things" "name": "_enable_super_gross_mode_that_will_cause_bad_things"
}, },
{
"name": "_getViewData"
},
{ {
"name": "_global" "name": "_global"
}, },
@ -950,9 +956,6 @@
{ {
"name": "getRenderer" "name": "getRenderer"
}, },
{
"name": "getRendererFactory"
},
{ {
"name": "getRootContext" "name": "getRootContext"
}, },
@ -1322,9 +1325,6 @@
{ {
"name": "setPreviousOrParentTNode" "name": "setPreviousOrParentTNode"
}, },
{
"name": "setRendererFactory"
},
{ {
"name": "setRootDomAdapter" "name": "setRootDomAdapter"
}, },

View File

@ -170,6 +170,9 @@
{ {
"name": "RENDERER" "name": "RENDERER"
}, },
{
"name": "RENDERER_FACTORY"
},
{ {
"name": "RENDER_PARENT" "name": "RENDER_PARENT"
}, },
@ -659,9 +662,6 @@
{ {
"name": "getCurrentQueries" "name": "getCurrentQueries"
}, },
{
"name": "getCurrentSanitizer"
},
{ {
"name": "getCurrentView" "name": "getCurrentView"
}, },
@ -1166,9 +1166,6 @@
{ {
"name": "setProp" "name": "setProp"
}, },
{
"name": "setRendererFactory"
},
{ {
"name": "setStyle" "name": "setStyle"
}, },

View File

@ -137,6 +137,24 @@
{ {
"name": "Compiler" "name": "Compiler"
}, },
{
"name": "Compiler_compileModuleAndAllComponentsAsync"
},
{
"name": "Compiler_compileModuleAndAllComponentsSync"
},
{
"name": "Compiler_compileModuleAndAllComponentsSync__POST_R3__"
},
{
"name": "Compiler_compileModuleAsync"
},
{
"name": "Compiler_compileModuleSync"
},
{
"name": "Compiler_compileModuleSync__POST_R3__"
},
{ {
"name": "ComponentFactory" "name": "ComponentFactory"
}, },
@ -209,6 +227,12 @@
{ {
"name": "DateType" "name": "DateType"
}, },
{
"name": "DebugElement__POST_R3__"
},
{
"name": "DebugNode__POST_R3__"
},
{ {
"name": "DecimalPipe" "name": "DecimalPipe"
}, },
@ -446,6 +470,9 @@
{ {
"name": "MergeMapSubscriber" "name": "MergeMapSubscriber"
}, },
{
"name": "ModuleWithComponentFactories"
},
{ {
"name": "MulticastOperator" "name": "MulticastOperator"
}, },
@ -698,6 +725,9 @@
{ {
"name": "RENDERER" "name": "RENDERER"
}, },
{
"name": "RENDERER_FACTORY"
},
{ {
"name": "RENDER_PARENT" "name": "RENDER_PARENT"
}, },
@ -950,9 +980,6 @@
{ {
"name": "ViewRef" "name": "ViewRef"
}, },
{
"name": "WRAP_RENDERER_FACTORY2"
},
{ {
"name": "WrappedValue" "name": "WrappedValue"
}, },
@ -1136,6 +1163,9 @@
{ {
"name": "_enable_super_gross_mode_that_will_cause_bad_things" "name": "_enable_super_gross_mode_that_will_cause_bad_things"
}, },
{
"name": "_getViewData"
},
{ {
"name": "_global" "name": "_global"
}, },
@ -1151,9 +1181,6 @@
{ {
"name": "_localeFactory" "name": "_localeFactory"
}, },
{
"name": "_nativeNodeToDebugNode"
},
{ {
"name": "_ngProbeTokensToMap" "name": "_ngProbeTokensToMap"
}, },
@ -1163,6 +1190,9 @@
{ {
"name": "_promiseStrategy" "name": "_promiseStrategy"
}, },
{
"name": "_queryNodeChildrenR3"
},
{ {
"name": "_randomChar" "name": "_randomChar"
}, },
@ -1184,9 +1214,6 @@
{ {
"name": "_testabilityGetter" "name": "_testabilityGetter"
}, },
{
"name": "_throwError"
},
{ {
"name": "addComponentLogic" "name": "addComponentLogic"
}, },
@ -1481,6 +1508,9 @@
{ {
"name": "directiveInject" "name": "directiveInject"
}, },
{
"name": "discoverLocalRefs"
},
{ {
"name": "domRendererFactory3" "name": "domRendererFactory3"
}, },
@ -1565,6 +1595,12 @@
{ {
"name": "findViaComponent" "name": "findViaComponent"
}, },
{
"name": "findViaDirective"
},
{
"name": "findViaNativeElement"
},
{ {
"name": "firstTemplatePass" "name": "firstTemplatePass"
}, },
@ -1646,6 +1682,12 @@
{ {
"name": "getClosureSafeProperty" "name": "getClosureSafeProperty"
}, },
{
"name": "getComponent"
},
{
"name": "getComponentAtNodeIndex"
},
{ {
"name": "getComponentDef" "name": "getComponentDef"
}, },
@ -1658,6 +1700,9 @@
{ {
"name": "getContainerRenderParent" "name": "getContainerRenderParent"
}, },
{
"name": "getContext"
},
{ {
"name": "getContextViewData" "name": "getContextViewData"
}, },
@ -1670,9 +1715,6 @@
{ {
"name": "getCurrentQueries" "name": "getCurrentQueries"
}, },
{
"name": "getCurrentSanitizer"
},
{ {
"name": "getCurrentView" "name": "getCurrentView"
}, },
@ -1694,9 +1736,21 @@
{ {
"name": "getDebugNode" "name": "getDebugNode"
}, },
{
"name": "getDebugNode__POST_R3__"
},
{ {
"name": "getDirectiveDef" "name": "getDirectiveDef"
}, },
{
"name": "getDirectiveEndIndex"
},
{
"name": "getDirectiveStartIndex"
},
{
"name": "getDirectivesAtNodeIndex"
},
{ {
"name": "getElementDepthCount" "name": "getElementDepthCount"
}, },
@ -1727,6 +1781,9 @@
{ {
"name": "getInjectableDef" "name": "getInjectableDef"
}, },
{
"name": "getInjector"
},
{ {
"name": "getInjectorDef" "name": "getInjectorDef"
}, },
@ -1745,6 +1802,9 @@
{ {
"name": "getLastDefinedValue" "name": "getLastDefinedValue"
}, },
{
"name": "getLocalRefs"
},
{ {
"name": "getLocaleCurrencies" "name": "getLocaleCurrencies"
}, },
@ -2075,6 +2135,9 @@
{ {
"name": "isComponentDef" "name": "isComponentDef"
}, },
{
"name": "isComponentInstance"
},
{ {
"name": "isContextDirty" "name": "isContextDirty"
}, },
@ -2093,6 +2156,12 @@
{ {
"name": "isDifferent" "name": "isDifferent"
}, },
{
"name": "isDirectiveDefHack"
},
{
"name": "isDirectiveInstance"
},
{ {
"name": "isDirty" "name": "isDirty"
}, },
@ -2195,6 +2264,9 @@
{ {
"name": "listener" "name": "listener"
}, },
{
"name": "loadContext"
},
{ {
"name": "loadInternal" "name": "loadInternal"
}, },
@ -2288,6 +2360,9 @@
{ {
"name": "noopScope" "name": "noopScope"
}, },
{
"name": "notImplemented"
},
{ {
"name": "observable" "name": "observable"
}, },
@ -2531,9 +2606,6 @@
{ {
"name": "setProp" "name": "setProp"
}, },
{
"name": "setRendererFactory"
},
{ {
"name": "setRootDomAdapter" "name": "setRootDomAdapter"
}, },
@ -2660,6 +2732,9 @@
{ {
"name": "trackByIdentity" "name": "trackByIdentity"
}, },
{
"name": "traverseNextElement"
},
{ {
"name": "tryCatch" "name": "tryCatch"
}, },

View File

@ -940,17 +940,19 @@ function declareTests(config?: {useJit: boolean}) {
expect(getDOM().getProperty(tc.nativeElement, 'id')).toEqual('newId'); expect(getDOM().getProperty(tc.nativeElement, 'id')).toEqual('newId');
}); });
fixmeIvy('FW-681: not possible to retrieve host property bindings from TView') &&
it('should not use template variables for expressions in hostProperties', () => { it('should not use template variables for expressions in hostProperties', () => {
@Directive({selector: '[host-properties]', host: {'[id]': 'id', '[title]': 'unknownProp'}}) @Directive(
{selector: '[host-properties]', host: {'[id]': 'id', '[title]': 'unknownProp'}})
class DirectiveWithHostProps { class DirectiveWithHostProps {
id = 'one'; id = 'one';
} }
const fixture = const fixture =
TestBed.configureTestingModule({declarations: [MyComp, DirectiveWithHostProps]}) TestBed.configureTestingModule({declarations: [MyComp, DirectiveWithHostProps]})
.overrideComponent( .overrideComponent(MyComp, {
MyComp, set: {template: `<div *ngFor="let id of ['forId']" host-properties></div>`}
{set: {template: `<div *ngFor="let id of ['forId']" host-properties></div>`}}) })
.createComponent(MyComp); .createComponent(MyComp);
fixture.detectChanges(); fixture.detectChanges();
@ -1113,7 +1115,7 @@ function declareTests(config?: {useJit: boolean}) {
.toHaveText('dynamic greet'); .toHaveText('dynamic greet');
})); }));
fixmeIvy('FW-561: Runtime compiler is not loaded') && fixmeIvy('FW-707: TestBed: No LViewData in getParentInjectorLocation') &&
it('should create a component that has been freshly compiled', () => { it('should create a component that has been freshly compiled', () => {
@Component({template: ''}) @Component({template: ''})
class RootComp { class RootComp {
@ -1153,7 +1155,7 @@ function declareTests(config?: {useJit: boolean}) {
expect(compRef.instance.someToken).toBe('someRootValue'); expect(compRef.instance.someToken).toBe('someRootValue');
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') && fixmeIvy('FW-707: TestBed: No LViewData in getParentInjectorLocation') &&
it('should create a component with the passed NgModuleRef', () => { it('should create a component with the passed NgModuleRef', () => {
@Component({template: ''}) @Component({template: ''})
class RootComp { class RootComp {
@ -1194,7 +1196,7 @@ function declareTests(config?: {useJit: boolean}) {
expect(compRef.instance.someToken).toBe('someValue'); expect(compRef.instance.someToken).toBe('someValue');
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') && fixmeIvy('FW-707: TestBed: No LViewData in getParentInjectorLocation') &&
it('should create a component with the NgModuleRef of the ComponentFactoryResolver', it('should create a component with the NgModuleRef of the ComponentFactoryResolver',
() => { () => {
@Component({template: ''}) @Component({template: ''})

View File

@ -142,8 +142,8 @@ function declareTests(config?: {useJit: boolean}) {
return new ComponentFixture(comp, null !, false); return new ComponentFixture(comp, null !, false);
} }
fixmeIvy('FW-682: Compiler error handling') && //
describe('errors', () => { describe('errors', () => {
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should error when exporting a directive that was neither declared nor imported', () => { it('should error when exporting a directive that was neither declared nor imported', () => {
@NgModule({exports: [SomeDirective]}) @NgModule({exports: [SomeDirective]})
class SomeModule { class SomeModule {
@ -154,7 +154,6 @@ function declareTests(config?: {useJit: boolean}) {
`Can't export directive ${stringify(SomeDirective)} from ${stringify(SomeModule)} as it was neither declared nor imported!`); `Can't export directive ${stringify(SomeDirective)} from ${stringify(SomeModule)} as it was neither declared nor imported!`);
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should error when exporting a pipe that was neither declared nor imported', () => { it('should error when exporting a pipe that was neither declared nor imported', () => {
@NgModule({exports: [SomePipe]}) @NgModule({exports: [SomePipe]})
class SomeModule { class SomeModule {
@ -165,7 +164,6 @@ function declareTests(config?: {useJit: boolean}) {
`Can't export pipe ${stringify(SomePipe)} from ${stringify(SomeModule)} as it was neither declared nor imported!`); `Can't export pipe ${stringify(SomePipe)} from ${stringify(SomeModule)} as it was neither declared nor imported!`);
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should error if a directive is declared in more than 1 module', () => { it('should error if a directive is declared in more than 1 module', () => {
@NgModule({declarations: [SomeDirective]}) @NgModule({declarations: [SomeDirective]})
class Module1 { class Module1 {
@ -184,7 +182,6 @@ function declareTests(config?: {useJit: boolean}) {
`You can also create a new NgModule that exports and includes ${stringify(SomeDirective)} then import that NgModule in ${stringify(Module1)} and ${stringify(Module2)}.`); `You can also create a new NgModule that exports and includes ${stringify(SomeDirective)} then import that NgModule in ${stringify(Module1)} and ${stringify(Module2)}.`);
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should error if a directive is declared in more than 1 module also if the module declaring it is imported', it('should error if a directive is declared in more than 1 module also if the module declaring it is imported',
() => { () => {
@NgModule({declarations: [SomeDirective], exports: [SomeDirective]}) @NgModule({declarations: [SomeDirective], exports: [SomeDirective]})
@ -202,7 +199,6 @@ function declareTests(config?: {useJit: boolean}) {
`You can also create a new NgModule that exports and includes ${stringify(SomeDirective)} then import that NgModule in ${stringify(Module1)} and ${stringify(Module2)}.`); `You can also create a new NgModule that exports and includes ${stringify(SomeDirective)} then import that NgModule in ${stringify(Module1)} and ${stringify(Module2)}.`);
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should error if a pipe is declared in more than 1 module', () => { it('should error if a pipe is declared in more than 1 module', () => {
@NgModule({declarations: [SomePipe]}) @NgModule({declarations: [SomePipe]})
class Module1 { class Module1 {
@ -221,7 +217,6 @@ function declareTests(config?: {useJit: boolean}) {
`You can also create a new NgModule that exports and includes ${stringify(SomePipe)} then import that NgModule in ${stringify(Module1)} and ${stringify(Module2)}.`); `You can also create a new NgModule that exports and includes ${stringify(SomePipe)} then import that NgModule in ${stringify(Module1)} and ${stringify(Module2)}.`);
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should error if a pipe is declared in more than 1 module also if the module declaring it is imported', it('should error if a pipe is declared in more than 1 module also if the module declaring it is imported',
() => { () => {
@NgModule({declarations: [SomePipe], exports: [SomePipe]}) @NgModule({declarations: [SomePipe], exports: [SomePipe]})
@ -242,7 +237,7 @@ function declareTests(config?: {useJit: boolean}) {
}); });
describe('schemas', () => { describe('schemas', () => {
fixmeIvy('FW-561: Runtime compiler is not loaded') && fixmeIvy('FW-682: Compiler error handling') &&
it('should error on unknown bound properties on custom elements by default', () => { it('should error on unknown bound properties on custom elements by default', () => {
@Component({template: '<some-element [someUnknownProp]="true"></some-element>'}) @Component({template: '<some-element [someUnknownProp]="true"></some-element>'})
class ComponentUsingInvalidProperty { class ComponentUsingInvalidProperty {
@ -255,17 +250,14 @@ function declareTests(config?: {useJit: boolean}) {
expect(() => createModule(SomeModule)).toThrowError(/Can't bind to 'someUnknownProp'/); expect(() => createModule(SomeModule)).toThrowError(/Can't bind to 'someUnknownProp'/);
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should not error on unknown bound properties on custom elements when using the CUSTOM_ELEMENTS_SCHEMA', it('should not error on unknown bound properties on custom elements when using the CUSTOM_ELEMENTS_SCHEMA',
() => { () => {
@Component({template: '<some-element [someUnknownProp]="true"></some-element>'}) @Component({template: '<some-element [someUnknownProp]="true"></some-element>'})
class ComponentUsingInvalidProperty { class ComponentUsingInvalidProperty {
} }
@NgModule({ @NgModule(
schemas: [CUSTOM_ELEMENTS_SCHEMA], {schemas: [CUSTOM_ELEMENTS_SCHEMA], declarations: [ComponentUsingInvalidProperty]})
declarations: [ComponentUsingInvalidProperty]
})
class SomeModule { class SomeModule {
} }
@ -284,7 +276,7 @@ function declareTests(config?: {useJit: boolean}) {
afterEach(() => clearModulesForTest()); afterEach(() => clearModulesForTest());
fixmeIvy('FW-561: Runtime compiler is not loaded') && fixmeIvy('FW-740: missing global registry of NgModules by id') &&
it('should register loaded modules', () => { it('should register loaded modules', () => {
createModule(SomeModule); createModule(SomeModule);
const factory = getModuleFactory(token); const factory = getModuleFactory(token);
@ -292,7 +284,7 @@ function declareTests(config?: {useJit: boolean}) {
expect(factory.moduleType).toBe(SomeModule); expect(factory.moduleType).toBe(SomeModule);
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') && fixmeIvy('FW-682: Compiler error handling') &&
it('should throw when registering a duplicate module', () => { it('should throw when registering a duplicate module', () => {
createModule(SomeModule); createModule(SomeModule);
expect(() => createModule(SomeOtherModule)).toThrowError(/Duplicate module registered/); expect(() => createModule(SomeOtherModule)).toThrowError(/Duplicate module registered/);
@ -300,15 +292,13 @@ function declareTests(config?: {useJit: boolean}) {
}); });
describe('entryComponents', () => { describe('entryComponents', () => {
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should create ComponentFactories in root modules', () => { it('should create ComponentFactories in root modules', () => {
@NgModule({declarations: [SomeComp], entryComponents: [SomeComp]}) @NgModule({declarations: [SomeComp], entryComponents: [SomeComp]})
class SomeModule { class SomeModule {
} }
const ngModule = createModule(SomeModule); const ngModule = createModule(SomeModule);
expect( expect(ngModule.componentFactoryResolver.resolveComponentFactory(SomeComp) !.componentType)
ngModule.componentFactoryResolver.resolveComponentFactory(SomeComp) !.componentType)
.toBe(SomeComp); .toBe(SomeComp);
expect(ngModule.injector.get(ComponentFactoryResolver) expect(ngModule.injector.get(ComponentFactoryResolver)
.resolveComponentFactory(SomeComp) .resolveComponentFactory(SomeComp)
@ -316,7 +306,7 @@ function declareTests(config?: {useJit: boolean}) {
.toBe(SomeComp); .toBe(SomeComp);
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') && fixmeIvy('FW-682: Compiler error handling') &&
it('should throw if we cannot find a module associated with a module-level entryComponent', it('should throw if we cannot find a module associated with a module-level entryComponent',
() => { () => {
@Component({template: ''}) @Component({template: ''})
@ -332,7 +322,7 @@ function declareTests(config?: {useJit: boolean}) {
'Component SomeCompWithEntryComponents is not part of any NgModule or the module has not been imported into your module.'); 'Component SomeCompWithEntryComponents is not part of any NgModule or the module has not been imported into your module.');
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') && fixmeIvy('FW-682: Compiler error handling') &&
it('should throw if we cannot find a module associated with a component-level entryComponent', it('should throw if we cannot find a module associated with a component-level entryComponent',
() => { () => {
@Component({template: '', entryComponents: [SomeComp]}) @Component({template: '', entryComponents: [SomeComp]})
@ -348,7 +338,6 @@ function declareTests(config?: {useJit: boolean}) {
'Component SomeComp is not part of any NgModule or the module has not been imported into your module.'); 'Component SomeComp is not part of any NgModule or the module has not been imported into your module.');
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should create ComponentFactories via ANALYZE_FOR_ENTRY_COMPONENTS', () => { it('should create ComponentFactories via ANALYZE_FOR_ENTRY_COMPONENTS', () => {
@NgModule({ @NgModule({
declarations: [SomeComp], declarations: [SomeComp],
@ -362,8 +351,7 @@ function declareTests(config?: {useJit: boolean}) {
} }
const ngModule = createModule(SomeModule); const ngModule = createModule(SomeModule);
expect( expect(ngModule.componentFactoryResolver.resolveComponentFactory(SomeComp) !.componentType)
ngModule.componentFactoryResolver.resolveComponentFactory(SomeComp) !.componentType)
.toBe(SomeComp); .toBe(SomeComp);
expect(ngModule.injector.get(ComponentFactoryResolver) expect(ngModule.injector.get(ComponentFactoryResolver)
.resolveComponentFactory(SomeComp) .resolveComponentFactory(SomeComp)
@ -371,7 +359,6 @@ function declareTests(config?: {useJit: boolean}) {
.toBe(SomeComp); .toBe(SomeComp);
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should create ComponentFactories in imported modules', () => { it('should create ComponentFactories in imported modules', () => {
@NgModule({declarations: [SomeComp], entryComponents: [SomeComp]}) @NgModule({declarations: [SomeComp], entryComponents: [SomeComp]})
class SomeImportedModule { class SomeImportedModule {
@ -382,8 +369,7 @@ function declareTests(config?: {useJit: boolean}) {
} }
const ngModule = createModule(SomeModule); const ngModule = createModule(SomeModule);
expect( expect(ngModule.componentFactoryResolver.resolveComponentFactory(SomeComp) !.componentType)
ngModule.componentFactoryResolver.resolveComponentFactory(SomeComp) !.componentType)
.toBe(SomeComp); .toBe(SomeComp);
expect(ngModule.injector.get(ComponentFactoryResolver) expect(ngModule.injector.get(ComponentFactoryResolver)
.resolveComponentFactory(SomeComp) .resolveComponentFactory(SomeComp)
@ -391,7 +377,6 @@ function declareTests(config?: {useJit: boolean}) {
.toBe(SomeComp); .toBe(SomeComp);
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should create ComponentFactories if the component was imported', () => { it('should create ComponentFactories if the component was imported', () => {
@NgModule({declarations: [SomeComp], exports: [SomeComp]}) @NgModule({declarations: [SomeComp], exports: [SomeComp]})
class SomeImportedModule { class SomeImportedModule {
@ -402,8 +387,7 @@ function declareTests(config?: {useJit: boolean}) {
} }
const ngModule = createModule(SomeModule); const ngModule = createModule(SomeModule);
expect( expect(ngModule.componentFactoryResolver.resolveComponentFactory(SomeComp) !.componentType)
ngModule.componentFactoryResolver.resolveComponentFactory(SomeComp) !.componentType)
.toBe(SomeComp); .toBe(SomeComp);
expect(ngModule.injector.get(ComponentFactoryResolver) expect(ngModule.injector.get(ComponentFactoryResolver)
.resolveComponentFactory(SomeComp) .resolveComponentFactory(SomeComp)
@ -414,19 +398,16 @@ function declareTests(config?: {useJit: boolean}) {
}); });
describe('bootstrap components', () => { describe('bootstrap components', () => {
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should create ComponentFactories', () => { it('should create ComponentFactories', () => {
@NgModule({declarations: [SomeComp], bootstrap: [SomeComp]}) @NgModule({declarations: [SomeComp], bootstrap: [SomeComp]})
class SomeModule { class SomeModule {
} }
const ngModule = createModule(SomeModule); const ngModule = createModule(SomeModule);
expect( expect(ngModule.componentFactoryResolver.resolveComponentFactory(SomeComp) !.componentType)
ngModule.componentFactoryResolver.resolveComponentFactory(SomeComp) !.componentType)
.toBe(SomeComp); .toBe(SomeComp);
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should store the ComponentFactories in the NgModuleInjector', () => { it('should store the ComponentFactories in the NgModuleInjector', () => {
@NgModule({declarations: [SomeComp], bootstrap: [SomeComp]}) @NgModule({declarations: [SomeComp], bootstrap: [SomeComp]})
class SomeModule { class SomeModule {
@ -440,8 +421,8 @@ function declareTests(config?: {useJit: boolean}) {
}); });
describe('directives and pipes', () => { describe('directives and pipes', () => {
fixmeIvy('FW-681: not possible to retrieve host property bindings from TView') &&
describe('declarations', () => { describe('declarations', () => {
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should be supported in root modules', () => { it('should be supported in root modules', () => {
@NgModule({ @NgModule({
declarations: [CompUsingModuleDirectiveAndPipe, SomeDirective, SomePipe], declarations: [CompUsingModuleDirectiveAndPipe, SomeDirective, SomePipe],
@ -457,7 +438,6 @@ function declareTests(config?: {useJit: boolean}) {
.toBe('transformed someValue'); .toBe('transformed someValue');
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should be supported in imported modules', () => { it('should be supported in imported modules', () => {
@NgModule({ @NgModule({
declarations: [CompUsingModuleDirectiveAndPipe, SomeDirective, SomePipe], declarations: [CompUsingModuleDirectiveAndPipe, SomeDirective, SomePipe],
@ -477,7 +457,6 @@ function declareTests(config?: {useJit: boolean}) {
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should be supported in nested components', () => { it('should be supported in nested components', () => {
@Component({ @Component({
selector: 'parent', selector: 'parent',
@ -505,7 +484,7 @@ function declareTests(config?: {useJit: boolean}) {
describe('import/export', () => { describe('import/export', () => {
fixmeIvy('FW-561: Runtime compiler is not loaded') && fixmeIvy('Pipe with name \'somePipe\' not found!') &&
it('should support exported directives and pipes', () => { it('should support exported directives and pipes', () => {
@NgModule( @NgModule(
{declarations: [SomeDirective, SomePipe], exports: [SomeDirective, SomePipe]}) {declarations: [SomeDirective, SomePipe], exports: [SomeDirective, SomePipe]})
@ -527,7 +506,7 @@ function declareTests(config?: {useJit: boolean}) {
.toBe('transformed someValue'); .toBe('transformed someValue');
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') && fixmeIvy('Pipe with name \'somePipe\' not found!') &&
it('should support exported directives and pipes if the module is wrapped into an `ModuleWithProviders`', it('should support exported directives and pipes if the module is wrapped into an `ModuleWithProviders`',
() => { () => {
@NgModule( @NgModule(
@ -550,7 +529,7 @@ function declareTests(config?: {useJit: boolean}) {
.toBe('transformed someValue'); .toBe('transformed someValue');
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') && fixmeIvy('Pipe with name \'somePipe\' not found!') &&
it('should support reexported modules', () => { it('should support reexported modules', () => {
@NgModule( @NgModule(
{declarations: [SomeDirective, SomePipe], exports: [SomeDirective, SomePipe]}) {declarations: [SomeDirective, SomePipe], exports: [SomeDirective, SomePipe]})
@ -575,7 +554,7 @@ function declareTests(config?: {useJit: boolean}) {
.toBe('transformed someValue'); .toBe('transformed someValue');
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') && fixmeIvy('Pipe with name \'somePipe\' not found!') &&
it('should support exporting individual directives of an imported module', () => { it('should support exporting individual directives of an imported module', () => {
@NgModule( @NgModule(
{declarations: [SomeDirective, SomePipe], exports: [SomeDirective, SomePipe]}) {declarations: [SomeDirective, SomePipe], exports: [SomeDirective, SomePipe]})
@ -600,7 +579,7 @@ function declareTests(config?: {useJit: boolean}) {
.toBe('transformed someValue'); .toBe('transformed someValue');
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') && fixmeIvy('FW-682: Compiler error handling') &&
it('should not use non exported pipes of an imported module', () => { it('should not use non exported pipes of an imported module', () => {
@NgModule({ @NgModule({
declarations: [SomePipe], declarations: [SomePipe],
@ -620,7 +599,7 @@ function declareTests(config?: {useJit: boolean}) {
.toThrowError(/The pipe 'somePipe' could not be found/); .toThrowError(/The pipe 'somePipe' could not be found/);
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') && fixmeIvy('FW-682: Compiler error handling') &&
it('should not use non exported directives of an imported module', () => { it('should not use non exported directives of an imported module', () => {
@NgModule({ @NgModule({
declarations: [SomeDirective], declarations: [SomeDirective],
@ -657,11 +636,9 @@ function declareTests(config?: {useJit: boolean}) {
return createModule(SomeModule, parent).injector; return createModule(SomeModule, parent).injector;
} }
fixmeIvy('FW-561: Runtime compiler is not loaded') && it('should provide the module', () => { it('should provide the module',
expect(createInjector([]).get(moduleType)).toBeAnInstanceOf(moduleType); () => { expect(createInjector([]).get(moduleType)).toBeAnInstanceOf(moduleType); });
});
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should instantiate a class without dependencies', () => { it('should instantiate a class without dependencies', () => {
const injector = createInjector([Engine]); const injector = createInjector([Engine]);
const engine = injector.get(Engine); const engine = injector.get(Engine);
@ -669,7 +646,6 @@ function declareTests(config?: {useJit: boolean}) {
expect(engine).toBeAnInstanceOf(Engine); expect(engine).toBeAnInstanceOf(Engine);
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should resolve dependencies based on type information', () => { it('should resolve dependencies based on type information', () => {
const injector = createInjector([Engine, Car]); const injector = createInjector([Engine, Car]);
const car = injector.get(Car); const car = injector.get(Car);
@ -678,7 +654,6 @@ function declareTests(config?: {useJit: boolean}) {
expect(car.engine).toBeAnInstanceOf(Engine); expect(car.engine).toBeAnInstanceOf(Engine);
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should resolve dependencies based on @Inject annotation', () => { it('should resolve dependencies based on @Inject annotation', () => {
const injector = createInjector([TurboEngine, Engine, CarWithInject]); const injector = createInjector([TurboEngine, Engine, CarWithInject]);
const car = injector.get(CarWithInject); const car = injector.get(CarWithInject);
@ -687,19 +662,19 @@ function declareTests(config?: {useJit: boolean}) {
expect(car.engine).toBeAnInstanceOf(TurboEngine); expect(car.engine).toBeAnInstanceOf(TurboEngine);
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') && fixmeIvy('FW-682: Compiler error handling') &&
it('should throw when no type and not @Inject (class case)', () => { it('should throw when no type and not @Inject (class case)', () => {
expect(() => createInjector([NoAnnotations])) expect(() => createInjector([NoAnnotations]))
.toThrowError('Can\'t resolve all parameters for NoAnnotations: (?).'); .toThrowError('Can\'t resolve all parameters for NoAnnotations: (?).');
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') && fixmeIvy('FW-682: Compiler error handling') &&
it('should throw when no type and not @Inject (factory case)', () => { it('should throw when no type and not @Inject (factory case)', () => {
expect(() => createInjector([{provide: 'someToken', useFactory: factoryFn}])) expect(() => createInjector([{provide: 'someToken', useFactory: factoryFn}]))
.toThrowError('Can\'t resolve all parameters for factoryFn: (?).'); .toThrowError('Can\'t resolve all parameters for factoryFn: (?).');
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') && it('should cache instances', () => { it('should cache instances', () => {
const injector = createInjector([Engine]); const injector = createInjector([Engine]);
const e1 = injector.get(Engine); const e1 = injector.get(Engine);
@ -708,33 +683,31 @@ function declareTests(config?: {useJit: boolean}) {
expect(e1).toBe(e2); expect(e1).toBe(e2);
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') && it('should provide to a value', () => { it('should provide to a value', () => {
const injector = createInjector([{provide: Engine, useValue: 'fake engine'}]); const injector = createInjector([{provide: Engine, useValue: 'fake engine'}]);
const engine = injector.get(Engine); const engine = injector.get(Engine);
expect(engine).toEqual('fake engine'); expect(engine).toEqual('fake engine');
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should provide to a factory', () => { it('should provide to a factory', () => {
function sportsCarFactory(e: Engine) { return new SportsCar(e); } function sportsCarFactory(e: Engine) { return new SportsCar(e); }
const injector = createInjector( const injector =
[Engine, {provide: Car, useFactory: sportsCarFactory, deps: [Engine]}]); createInjector([Engine, {provide: Car, useFactory: sportsCarFactory, deps: [Engine]}]);
const car = injector.get(Car); const car = injector.get(Car);
expect(car).toBeAnInstanceOf(SportsCar); expect(car).toBeAnInstanceOf(SportsCar);
expect(car.engine).toBeAnInstanceOf(Engine); expect(car.engine).toBeAnInstanceOf(Engine);
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should supporting provider to null', () => { it('should supporting provider to null', () => {
const injector = createInjector([{provide: Engine, useValue: null}]); const injector = createInjector([{provide: Engine, useValue: null}]);
const engine = injector.get(Engine); const engine = injector.get(Engine);
expect(engine).toBeNull(); expect(engine).toBeNull();
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') && it('should provide to an alias', () => { it('should provide to an alias', () => {
const injector = createInjector([ const injector = createInjector([
Engine, {provide: SportsCar, useClass: SportsCar}, Engine, {provide: SportsCar, useClass: SportsCar},
{provide: Car, useExisting: SportsCar} {provide: Car, useExisting: SportsCar}
@ -746,7 +719,6 @@ function declareTests(config?: {useJit: boolean}) {
expect(car).toBe(sportsCar); expect(car).toBe(sportsCar);
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should support multiProviders', () => { it('should support multiProviders', () => {
const injector = createInjector([ const injector = createInjector([
Engine, {provide: CARS, useClass: SportsCar, multi: true}, Engine, {provide: CARS, useClass: SportsCar, multi: true},
@ -759,7 +731,6 @@ function declareTests(config?: {useJit: boolean}) {
expect(cars[1]).toBeAnInstanceOf(CarWithOptionalEngine); expect(cars[1]).toBeAnInstanceOf(CarWithOptionalEngine);
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should support multiProviders that are created using useExisting', () => { it('should support multiProviders that are created using useExisting', () => {
const injector = createInjector( const injector = createInjector(
[Engine, SportsCar, {provide: CARS, useExisting: SportsCar, multi: true}]); [Engine, SportsCar, {provide: CARS, useExisting: SportsCar, multi: true}]);
@ -769,14 +740,13 @@ function declareTests(config?: {useJit: boolean}) {
expect(cars[0]).toBe(injector.get(SportsCar)); expect(cars[0]).toBe(injector.get(SportsCar));
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') && fixmeIvy('FW-682: Compiler error handling') &&
it('should throw when the aliased provider does not exist', () => { it('should throw when the aliased provider does not exist', () => {
const injector = createInjector([{provide: 'car', useExisting: SportsCar}]); const injector = createInjector([{provide: 'car', useExisting: SportsCar}]);
const e = `NullInjectorError: No provider for ${stringify(SportsCar)}!`; const e = `NullInjectorError: No provider for ${stringify(SportsCar)}!`;
expect(() => injector.get('car')).toThrowError(e); expect(() => injector.get('car')).toThrowError(e);
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should handle forwardRef in useExisting', () => { it('should handle forwardRef in useExisting', () => {
const injector = createInjector([ const injector = createInjector([
{provide: 'originalEngine', useClass: forwardRef(() => Engine)}, {provide: 'originalEngine', useClass: forwardRef(() => Engine)},
@ -785,18 +755,15 @@ function declareTests(config?: {useJit: boolean}) {
expect(injector.get('aliasedEngine')).toBeAnInstanceOf(Engine); expect(injector.get('aliasedEngine')).toBeAnInstanceOf(Engine);
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should support overriding factory dependencies', () => { it('should support overriding factory dependencies', () => {
const injector = createInjector([ const injector = createInjector(
Engine, {provide: Car, useFactory: (e: Engine) => new SportsCar(e), deps: [Engine]} [Engine, {provide: Car, useFactory: (e: Engine) => new SportsCar(e), deps: [Engine]}]);
]);
const car = injector.get(Car); const car = injector.get(Car);
expect(car).toBeAnInstanceOf(SportsCar); expect(car).toBeAnInstanceOf(SportsCar);
expect(car.engine).toBeAnInstanceOf(Engine); expect(car.engine).toBeAnInstanceOf(Engine);
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should support optional dependencies', () => { it('should support optional dependencies', () => {
const injector = createInjector([CarWithOptionalEngine]); const injector = createInjector([CarWithOptionalEngine]);
@ -804,7 +771,6 @@ function declareTests(config?: {useJit: boolean}) {
expect(car.engine).toBeNull(); expect(car.engine).toBeNull();
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should flatten passed-in providers', () => { it('should flatten passed-in providers', () => {
const injector = createInjector([[[Engine, Car]]]); const injector = createInjector([[[Engine, Car]]]);
@ -812,43 +778,40 @@ function declareTests(config?: {useJit: boolean}) {
expect(car).toBeAnInstanceOf(Car); expect(car).toBeAnInstanceOf(Car);
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') && it('should use the last provider when there are multiple providers for same token', () => {
it('should use the last provider when there are multiple providers for same token',
() => {
const injector = createInjector( const injector = createInjector(
[{provide: Engine, useClass: Engine}, {provide: Engine, useClass: TurboEngine}]); [{provide: Engine, useClass: Engine}, {provide: Engine, useClass: TurboEngine}]);
expect(injector.get(Engine)).toBeAnInstanceOf(TurboEngine); expect(injector.get(Engine)).toBeAnInstanceOf(TurboEngine);
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') && it('should use non-type tokens', () => { it('should use non-type tokens', () => {
const injector = createInjector([{provide: 'token', useValue: 'value'}]); const injector = createInjector([{provide: 'token', useValue: 'value'}]);
expect(injector.get('token')).toEqual('value'); expect(injector.get('token')).toEqual('value');
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') && fixmeIvy('FW-682: Compiler error handling') &&
it('should throw when given invalid providers', () => { it('should throw when given invalid providers', () => {
expect(() => createInjector(<any>['blah'])) expect(() => createInjector(<any>['blah']))
.toThrowError( .toThrowError(
`Invalid provider for the NgModule 'SomeModule' - only instances of Provider and Type are allowed, got: [?blah?]`); `Invalid provider for the NgModule 'SomeModule' - only instances of Provider and Type are allowed, got: [?blah?]`);
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') && fixmeIvy('FW-682: Compiler error handling') && it('should throw when given blank providers', () => {
it('should throw when given blank providers', () => {
expect(() => createInjector(<any>[null, {provide: 'token', useValue: 'value'}])) expect(() => createInjector(<any>[null, {provide: 'token', useValue: 'value'}]))
.toThrowError( .toThrowError(
`Invalid provider for the NgModule 'SomeModule' - only instances of Provider and Type are allowed, got: [?null?, ...]`); `Invalid provider for the NgModule 'SomeModule' - only instances of Provider and Type are allowed, got: [?null?, ...]`);
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') && it('should provide itself', () => { it('should provide itself', () => {
const parent = createInjector([]); const parent = createInjector([]);
const child = createInjector([], parent); const child = createInjector([], parent);
expect(child.get(Injector)).toBe(child); expect(child.get(Injector)).toBe(child);
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') && it('should provide undefined', () => { it('should provide undefined', () => {
let factoryCounter = 0; let factoryCounter = 0;
const injector = createInjector([{ const injector = createInjector([{
@ -866,7 +829,6 @@ function declareTests(config?: {useJit: boolean}) {
describe('injecting lazy providers into an eager provider via Injector.get', () => { describe('injecting lazy providers into an eager provider via Injector.get', () => {
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should inject providers that were declared before it', () => { it('should inject providers that were declared before it', () => {
@NgModule({ @NgModule({
providers: [ providers: [
@ -886,7 +848,6 @@ function declareTests(config?: {useJit: boolean}) {
expect(createModule(MyModule).injector.get('eager')).toBe('eagerValue: lazyValue'); expect(createModule(MyModule).injector.get('eager')).toBe('eagerValue: lazyValue');
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should inject providers that were declared after it', () => { it('should inject providers that were declared after it', () => {
@NgModule({ @NgModule({
providers: [ providers: [
@ -909,7 +870,6 @@ function declareTests(config?: {useJit: boolean}) {
describe('injecting eager providers into an eager provider via Injector.get', () => { describe('injecting eager providers into an eager provider via Injector.get', () => {
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should inject providers that were declared before it', () => { it('should inject providers that were declared before it', () => {
@NgModule({ @NgModule({
providers: [ providers: [
@ -929,7 +889,6 @@ function declareTests(config?: {useJit: boolean}) {
expect(createModule(MyModule).injector.get('eager2')).toBe('v2: v1'); expect(createModule(MyModule).injector.get('eager2')).toBe('v2: v1');
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should inject providers that were declared after it', () => { it('should inject providers that were declared after it', () => {
@NgModule({ @NgModule({
providers: [ providers: [
@ -949,7 +908,6 @@ function declareTests(config?: {useJit: boolean}) {
expect(createModule(MyModule).injector.get('eager1')).toBe('v1: v2'); expect(createModule(MyModule).injector.get('eager1')).toBe('v1: v2');
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('eager providers should get initialized only once', () => { it('eager providers should get initialized only once', () => {
@Injectable() @Injectable()
class MyService1 { class MyService1 {
@ -980,27 +938,25 @@ function declareTests(config?: {useJit: boolean}) {
}); });
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should throw when no provider defined', () => { it('should throw when no provider defined', () => {
const injector = createInjector([]); const injector = createInjector([]);
expect(() => injector.get('NonExisting')) expect(() => injector.get('NonExisting'))
.toThrowError('NullInjectorError: No provider for NonExisting!'); .toThrowError('NullInjectorError: No provider for NonExisting!');
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') && fixmeIvy('FW-682: Compiler error handling') &&
it('should throw when trying to instantiate a cyclic dependency', () => { it('should throw when trying to instantiate a cyclic dependency', () => {
expect(() => createInjector([Car, {provide: Engine, useClass: CyclicEngine}])) expect(() => createInjector([Car, {provide: Engine, useClass: CyclicEngine}]))
.toThrowError(/Cannot instantiate cyclic dependency! Car/g); .toThrowError(/Cannot instantiate cyclic dependency! Car/g);
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') && it('should support null values', () => { it('should support null values', () => {
const injector = createInjector([{provide: 'null', useValue: null}]); const injector = createInjector([{provide: 'null', useValue: null}]);
expect(injector.get('null')).toBe(null); expect(injector.get('null')).toBe(null);
}); });
describe('child', () => { describe('child', () => {
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should load instances from parent injector', () => { it('should load instances from parent injector', () => {
const parent = createInjector([Engine]); const parent = createInjector([Engine]);
const child = createInjector([], parent); const child = createInjector([], parent);
@ -1011,7 +967,6 @@ function declareTests(config?: {useJit: boolean}) {
expect(engineFromChild).toBe(engineFromParent); expect(engineFromChild).toBe(engineFromParent);
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should not use the child providers when resolving the dependencies of a parent provider', it('should not use the child providers when resolving the dependencies of a parent provider',
() => { () => {
const parent = createInjector([Car, Engine]); const parent = createInjector([Car, Engine]);
@ -1021,7 +976,6 @@ function declareTests(config?: {useJit: boolean}) {
expect(carFromChild.engine).toBeAnInstanceOf(Engine); expect(carFromChild.engine).toBeAnInstanceOf(Engine);
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should create new instance in a child injector', () => { it('should create new instance in a child injector', () => {
const parent = createInjector([Engine]); const parent = createInjector([Engine]);
const child = createInjector([{provide: Engine, useClass: TurboEngine}], parent); const child = createInjector([{provide: Engine, useClass: TurboEngine}], parent);
@ -1037,14 +991,10 @@ function declareTests(config?: {useJit: boolean}) {
describe('depedency resolution', () => { describe('depedency resolution', () => {
describe('@Self()', () => { describe('@Self()', () => {
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should return a dependency from self', () => { it('should return a dependency from self', () => {
const inj = createInjector([ const inj = createInjector([
Engine, { Engine,
provide: Car, {provide: Car, useFactory: (e: Engine) => new Car(e), deps: [[Engine, new Self()]]}
useFactory: (e: Engine) => new Car(e),
deps: [[Engine, new Self()]]
}
]); ]);
expect(inj.get(Car)).toBeAnInstanceOf(Car); expect(inj.get(Car)).toBeAnInstanceOf(Car);
@ -1052,7 +1002,7 @@ function declareTests(config?: {useJit: boolean}) {
}); });
describe('default', () => { describe('default', () => {
fixmeIvy('FW-561: Runtime compiler is not loaded') && it('should not skip self', () => { it('should not skip self', () => {
const parent = createInjector([Engine]); const parent = createInjector([Engine]);
const child = createInjector( const child = createInjector(
[ [
@ -1067,7 +1017,7 @@ function declareTests(config?: {useJit: boolean}) {
}); });
describe('lifecycle', () => { describe('lifecycle', () => {
fixmeIvy('unknown') && it('should instantiate modules eagerly', () => { it('should instantiate modules eagerly', () => {
let created = false; let created = false;
@NgModule() @NgModule()
@ -1084,7 +1034,6 @@ function declareTests(config?: {useJit: boolean}) {
expect(created).toBe(true); expect(created).toBe(true);
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should instantiate providers that are not used by a module lazily', () => { it('should instantiate providers that are not used by a module lazily', () => {
let created = false; let created = false;
@ -1099,7 +1048,7 @@ function declareTests(config?: {useJit: boolean}) {
expect(created).toBe(false); expect(created).toBe(false);
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') && fixmeIvy('ngOnDestroy not running') &&
it('should support ngOnDestroy on any provider', () => { it('should support ngOnDestroy on any provider', () => {
let destroyed = false; let destroyed = false;
@ -1119,7 +1068,7 @@ function declareTests(config?: {useJit: boolean}) {
expect(destroyed).toBe(true); expect(destroyed).toBe(true);
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') && fixmeIvy('ngOnDestroy not running') &&
it('should support ngOnDestroy for lazy providers', () => { it('should support ngOnDestroy for lazy providers', () => {
let created = false; let created = false;
let destroyed = false; let destroyed = false;
@ -1151,7 +1100,6 @@ function declareTests(config?: {useJit: boolean}) {
}); });
describe('imported and exported modules', () => { describe('imported and exported modules', () => {
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should add the providers of imported modules', () => { it('should add the providers of imported modules', () => {
@NgModule({providers: [{provide: 'token1', useValue: 'imported'}]}) @NgModule({providers: [{provide: 'token1', useValue: 'imported'}]})
class ImportedModule { class ImportedModule {
@ -1168,17 +1116,16 @@ function declareTests(config?: {useJit: boolean}) {
expect(injector.get('token1')).toBe('imported'); expect(injector.get('token1')).toBe('imported');
}); });
fixmeIvy('unknown') &&
it('should add the providers of imported ModuleWithProviders', () => { it('should add the providers of imported ModuleWithProviders', () => {
@NgModule() @NgModule()
class ImportedModule { class ImportedModule {
} }
@NgModule({ @NgModule({
imports: [{ imports: [
ngModule: ImportedModule, {ngModule: ImportedModule, providers: [{provide: 'token1', useValue: 'imported'}]}
providers: [{provide: 'token1', useValue: 'imported'}] ]
}]
}) })
class SomeModule { class SomeModule {
} }
@ -1190,7 +1137,6 @@ function declareTests(config?: {useJit: boolean}) {
expect(injector.get('token1')).toBe('imported'); expect(injector.get('token1')).toBe('imported');
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should overwrite the providers of imported modules', () => { it('should overwrite the providers of imported modules', () => {
@NgModule({providers: [{provide: 'token1', useValue: 'imported'}]}) @NgModule({providers: [{provide: 'token1', useValue: 'imported'}]})
class ImportedModule { class ImportedModule {
@ -1205,7 +1151,7 @@ function declareTests(config?: {useJit: boolean}) {
expect(injector.get('token1')).toBe('direct'); expect(injector.get('token1')).toBe('direct');
}); });
fixmeIvy('unknown') &&
it('should overwrite the providers of imported ModuleWithProviders', () => { it('should overwrite the providers of imported ModuleWithProviders', () => {
@NgModule() @NgModule()
class ImportedModule { class ImportedModule {
@ -1213,10 +1159,9 @@ function declareTests(config?: {useJit: boolean}) {
@NgModule({ @NgModule({
providers: [{provide: 'token1', useValue: 'direct'}], providers: [{provide: 'token1', useValue: 'direct'}],
imports: [{ imports: [
ngModule: ImportedModule, {ngModule: ImportedModule, providers: [{provide: 'token1', useValue: 'imported'}]}
providers: [{provide: 'token1', useValue: 'imported'}] ]
}]
}) })
class SomeModule { class SomeModule {
} }
@ -1225,9 +1170,7 @@ function declareTests(config?: {useJit: boolean}) {
expect(injector.get('token1')).toBe('direct'); expect(injector.get('token1')).toBe('direct');
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') && it('should overwrite the providers of imported modules on the second import level', () => {
it('should overwrite the providers of imported modules on the second import level',
() => {
@NgModule({providers: [{provide: 'token1', useValue: 'imported'}]}) @NgModule({providers: [{provide: 'token1', useValue: 'imported'}]})
class ImportedModuleLevel2 { class ImportedModuleLevel2 {
} }
@ -1247,7 +1190,6 @@ function declareTests(config?: {useJit: boolean}) {
expect(injector.get('token1')).toBe('direct'); expect(injector.get('token1')).toBe('direct');
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should add the providers of exported modules', () => { it('should add the providers of exported modules', () => {
@NgModule({providers: [{provide: 'token1', useValue: 'exported'}]}) @NgModule({providers: [{provide: 'token1', useValue: 'exported'}]})
class ExportedValue { class ExportedValue {
@ -1264,7 +1206,6 @@ function declareTests(config?: {useJit: boolean}) {
expect(injector.get('token1')).toBe('exported'); expect(injector.get('token1')).toBe('exported');
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should overwrite the providers of exported modules', () => { it('should overwrite the providers of exported modules', () => {
@NgModule({providers: [{provide: 'token1', useValue: 'exported'}]}) @NgModule({providers: [{provide: 'token1', useValue: 'exported'}]})
class ExportedModule { class ExportedModule {
@ -1279,7 +1220,6 @@ function declareTests(config?: {useJit: boolean}) {
expect(injector.get('token1')).toBe('direct'); expect(injector.get('token1')).toBe('direct');
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should overwrite the providers of imported modules by following imported modules', it('should overwrite the providers of imported modules by following imported modules',
() => { () => {
@NgModule({providers: [{provide: 'token1', useValue: 'imported1'}]}) @NgModule({providers: [{provide: 'token1', useValue: 'imported1'}]})
@ -1298,7 +1238,6 @@ function declareTests(config?: {useJit: boolean}) {
expect(injector.get('token1')).toBe('imported2'); expect(injector.get('token1')).toBe('imported2');
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should overwrite the providers of exported modules by following exported modules', it('should overwrite the providers of exported modules by following exported modules',
() => { () => {
@NgModule({providers: [{provide: 'token1', useValue: 'exported1'}]}) @NgModule({providers: [{provide: 'token1', useValue: 'exported1'}]})
@ -1317,7 +1256,6 @@ function declareTests(config?: {useJit: boolean}) {
expect(injector.get('token1')).toBe('exported2'); expect(injector.get('token1')).toBe('exported2');
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should overwrite the providers of imported modules by exported modules', () => { it('should overwrite the providers of imported modules by exported modules', () => {
@NgModule({providers: [{provide: 'token1', useValue: 'imported'}]}) @NgModule({providers: [{provide: 'token1', useValue: 'imported'}]})
class ImportedModule { class ImportedModule {
@ -1335,7 +1273,6 @@ function declareTests(config?: {useJit: boolean}) {
expect(injector.get('token1')).toBe('exported'); expect(injector.get('token1')).toBe('exported');
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should not overwrite the providers if a module was already used on the same level', it('should not overwrite the providers if a module was already used on the same level',
() => { () => {
@NgModule({providers: [{provide: 'token1', useValue: 'imported1'}]}) @NgModule({providers: [{provide: 'token1', useValue: 'imported1'}]})
@ -1354,7 +1291,6 @@ function declareTests(config?: {useJit: boolean}) {
expect(injector.get('token1')).toBe('imported2'); expect(injector.get('token1')).toBe('imported2');
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should not overwrite the providers if a module was already used on a child level', it('should not overwrite the providers if a module was already used on a child level',
() => { () => {
@NgModule({providers: [{provide: 'token1', useValue: 'imported1'}]}) @NgModule({providers: [{provide: 'token1', useValue: 'imported1'}]})
@ -1377,7 +1313,7 @@ function declareTests(config?: {useJit: boolean}) {
expect(injector.get('token1')).toBe('imported2'); expect(injector.get('token1')).toBe('imported2');
}); });
fixmeIvy('unknown') && fixmeIvy('FW-682: Compiler error handling') &&
it('should throw when given invalid providers in an imported ModuleWithProviders', () => { it('should throw when given invalid providers in an imported ModuleWithProviders', () => {
@NgModule() @NgModule()
class ImportedModule1 { class ImportedModule1 {
@ -1394,7 +1330,7 @@ function declareTests(config?: {useJit: boolean}) {
}); });
describe('tree shakable providers', () => { describe('tree shakable providers', () => {
fixmeIvy('unknown') && fixmeIvy('providersByKey is not defined') &&
it('definition should not persist across NgModuleRef instances', () => { it('definition should not persist across NgModuleRef instances', () => {
@NgModule() @NgModule()
class SomeModule { class SomeModule {

View File

@ -10,7 +10,7 @@ import {defineComponent} from '../../src/render3/definition';
import {bind, container, containerRefreshEnd, containerRefreshStart, element, elementEnd, elementStart, embeddedViewEnd, embeddedViewStart, text, textBinding} from '../../src/render3/instructions'; import {bind, container, containerRefreshEnd, containerRefreshStart, element, elementEnd, elementStart, embeddedViewEnd, embeddedViewStart, text, textBinding} from '../../src/render3/instructions';
import {RenderFlags} from '../../src/render3/interfaces/definition'; import {RenderFlags} from '../../src/render3/interfaces/definition';
import {ComponentFixture, TemplateFixture, createComponent, renderToHtml} from './render_util'; import {ComponentFixture, TemplateFixture, createComponent} from './render_util';
describe('JS control flow', () => { describe('JS control flow', () => {
it('should work with if block', () => { it('should work with if block', () => {

View File

@ -2021,8 +2021,8 @@ describe('di', () => {
describe('getOrCreateNodeInjector', () => { describe('getOrCreateNodeInjector', () => {
it('should handle initial undefined state', () => { it('should handle initial undefined state', () => {
const contentView = createLViewData( const contentView = createLViewData(
null, null !, createTView(-1, null, 1, 0, null, null, null), null, null, createTView(-1, null, 1, 0, null, null, null), null, LViewFlags.CheckAlways,
LViewFlags.CheckAlways); {} as any, {} as any);
const oldView = enterView(contentView, null); const oldView = enterView(contentView, null);
try { try {
const parentTNode = createNodeAtIndex(0, TNodeType.Element, null, null, null); const parentTNode = createNodeAtIndex(0, TNodeType.Element, null, null, null);

View File

@ -33,8 +33,8 @@ describe('style and class based bindings', () => {
const rootContext = const rootContext =
createRootContext(requestAnimationFrame.bind(window), playerHandler || null); createRootContext(requestAnimationFrame.bind(window), playerHandler || null);
const lViewData = createLViewData( const lViewData = createLViewData(
null, domRendererFactory3.createRenderer(element, null), null, createTView(-1, null, 1, 0, null, null, null), rootContext, LViewFlags.IsRoot,
createTView(-1, null, 1, 0, null, null, null), rootContext, LViewFlags.IsRoot); domRendererFactory3, domRendererFactory3.createRenderer(element, null));
return lViewData; return lViewData;
} }

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import {Component, Directive, Injector, NgModule, NgZone, Pipe, PlatformRef, Provider, RendererFactory2, SchemaMetadata, Type, ɵInjectableDef as InjectableDef, ɵNgModuleDef as NgModuleDef, ɵNgModuleTransitiveScopes as NgModuleTransitiveScopes, ɵRender3ComponentFactory as ComponentFactory, ɵRender3DebugRendererFactory2 as Render3DebugRendererFactory2, ɵRender3NgModuleRef as NgModuleRef, ɵWRAP_RENDERER_FACTORY2 as WRAP_RENDERER_FACTORY2, ɵcompileComponent as compileComponent, ɵcompileDirective as compileDirective, ɵcompileNgModuleDefs as compileNgModuleDefs, ɵcompilePipe as compilePipe, ɵgetInjectableDef as getInjectableDef, ɵpatchComponentDefWithScope as patchComponentDefWithScope, ɵstringify as stringify} from '@angular/core'; import {Component, Directive, Injector, NgModule, NgZone, Pipe, PlatformRef, Provider, RendererFactory2, SchemaMetadata, Type, ɵInjectableDef as InjectableDef, ɵNgModuleDef as NgModuleDef, ɵNgModuleTransitiveScopes as NgModuleTransitiveScopes, ɵRender3ComponentFactory as ComponentFactory, ɵRender3NgModuleRef as NgModuleRef, ɵcompileComponent as compileComponent, ɵcompileDirective as compileDirective, ɵcompileNgModuleDefs as compileNgModuleDefs, ɵcompilePipe as compilePipe, ɵgetInjectableDef as getInjectableDef, ɵpatchComponentDefWithScope as patchComponentDefWithScope, ɵstringify as stringify} from '@angular/core';
import {ComponentFixture} from './component_fixture'; import {ComponentFixture} from './component_fixture';
import {MetadataOverride} from './metadata_override'; import {MetadataOverride} from './metadata_override';
@ -423,13 +423,8 @@ export class TestBedRender3 implements Injector, TestBed {
private _createTestModule(): Type<any> { private _createTestModule(): Type<any> {
const rootProviderOverrides = this._rootProviderOverrides; const rootProviderOverrides = this._rootProviderOverrides;
const rendererFactoryWrapper = {
provide: WRAP_RENDERER_FACTORY2,
useFactory: () => (rf: RendererFactory2) => new Render3DebugRendererFactory2(rf),
};
@NgModule({ @NgModule({
providers: [...rootProviderOverrides, rendererFactoryWrapper], providers: [...rootProviderOverrides],
jit: true, jit: true,
}) })
class RootScopeModule { class RootScopeModule {

View File

@ -9,7 +9,7 @@
import {CommonModule, Location} from '@angular/common'; import {CommonModule, Location} from '@angular/common';
import {SpyLocation} from '@angular/common/testing'; import {SpyLocation} from '@angular/common/testing';
import {ChangeDetectionStrategy, Component, Injectable, NgModule, NgModuleFactoryLoader, NgModuleRef, NgZone, OnDestroy, ɵConsole as Console, ɵNoopNgZone as NoopNgZone} from '@angular/core'; import {ChangeDetectionStrategy, Component, Injectable, NgModule, NgModuleFactoryLoader, NgModuleRef, NgZone, OnDestroy, ɵConsole as Console, ɵNoopNgZone as NoopNgZone} from '@angular/core';
import {ComponentFixture, TestBed, fakeAsync, flush, inject, tick} from '@angular/core/testing'; import {ComponentFixture, TestBed, fakeAsync, inject, tick} from '@angular/core/testing';
import {By} from '@angular/platform-browser/src/dom/debug/by'; import {By} from '@angular/platform-browser/src/dom/debug/by';
import {expect} from '@angular/platform-browser/testing/src/matchers'; import {expect} from '@angular/platform-browser/testing/src/matchers';
import {fixmeIvy} from '@angular/private/testing'; import {fixmeIvy} from '@angular/private/testing';
@ -2482,6 +2482,7 @@ describe('Integration', () => {
expect(canceledStatus).toEqual(false); expect(canceledStatus).toEqual(false);
}))); })));
fixmeIvy('unknown') &&
it('works with componentless routes', it('works with componentless routes',
fakeAsync(inject([Router, Location], (router: Router, location: Location) => { fakeAsync(inject([Router, Location], (router: Router, location: Location) => {
const fixture = createRoot(router, RootCmp); const fixture = createRoot(router, RootCmp);
@ -2823,7 +2824,7 @@ describe('Integration', () => {
}))); })));
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') && fixmeIvy('unknown') &&
it('should find the guard provided in lazy loaded module', it('should find the guard provided in lazy loaded module',
fakeAsync(inject( fakeAsync(inject(
[Router, Location, NgModuleFactoryLoader], [Router, Location, NgModuleFactoryLoader],
@ -2892,7 +2893,6 @@ describe('Integration', () => {
}); });
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should not load children when CanLoad returns false', it('should not load children when CanLoad returns false',
fakeAsync(inject( fakeAsync(inject(
[Router, Location, NgModuleFactoryLoader], [Router, Location, NgModuleFactoryLoader],
@ -2904,8 +2904,8 @@ describe('Integration', () => {
@NgModule({ @NgModule({
declarations: [LazyLoadedComponent], declarations: [LazyLoadedComponent],
imports: [RouterModule.forChild( imports:
[{path: 'loaded', component: LazyLoadedComponent}])] [RouterModule.forChild([{path: 'loaded', component: LazyLoadedComponent}])]
}) })
class LoadedModule { class LoadedModule {
} }
@ -2997,7 +2997,6 @@ describe('Integration', () => {
// Regression where navigateByUrl with false CanLoad no longer resolved `false` value on // Regression where navigateByUrl with false CanLoad no longer resolved `false` value on
// navigateByUrl promise: https://github.com/angular/angular/issues/26284 // navigateByUrl promise: https://github.com/angular/angular/issues/26284
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should resolve navigateByUrl promise after CanLoad executes', it('should resolve navigateByUrl promise after CanLoad executes',
fakeAsync(inject( fakeAsync(inject(
[Router, Location, NgModuleFactoryLoader], [Router, Location, NgModuleFactoryLoader],
@ -3009,8 +3008,8 @@ describe('Integration', () => {
@NgModule({ @NgModule({
declarations: [LazyLoadedComponent], declarations: [LazyLoadedComponent],
imports: [RouterModule.forChild( imports:
[{path: 'loaded', component: LazyLoadedComponent}])] [RouterModule.forChild([{path: 'loaded', component: LazyLoadedComponent}])]
}) })
class LazyLoadedModule { class LazyLoadedModule {
} }
@ -3035,7 +3034,6 @@ describe('Integration', () => {
}))); })));
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should execute CanLoad only once', it('should execute CanLoad only once',
fakeAsync(inject( fakeAsync(inject(
[Router, Location, NgModuleFactoryLoader], [Router, Location, NgModuleFactoryLoader],
@ -3047,8 +3045,8 @@ describe('Integration', () => {
@NgModule({ @NgModule({
declarations: [LazyLoadedComponent], declarations: [LazyLoadedComponent],
imports: [RouterModule.forChild( imports:
[{path: 'loaded', component: LazyLoadedComponent}])] [RouterModule.forChild([{path: 'loaded', component: LazyLoadedComponent}])]
}) })
class LazyLoadedModule { class LazyLoadedModule {
} }
@ -3056,8 +3054,7 @@ describe('Integration', () => {
loader.stubbedModules = {lazy: LazyLoadedModule}; loader.stubbedModules = {lazy: LazyLoadedModule};
const fixture = createRoot(router, RootCmp); const fixture = createRoot(router, RootCmp);
router.resetConfig( router.resetConfig([{path: 'lazy', canLoad: ['alwaysTrue'], loadChildren: 'lazy'}]);
[{path: 'lazy', canLoad: ['alwaysTrue'], loadChildren: 'lazy'}]);
router.navigateByUrl('/lazy/loaded'); router.navigateByUrl('/lazy/loaded');
advance(fixture); advance(fixture);
@ -3389,7 +3386,8 @@ describe('Integration', () => {
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') && describe('lazy loading', () => { describe('lazy loading', () => {
fixmeIvy('unknown') &&
it('works', it('works',
fakeAsync(inject( fakeAsync(inject(
[Router, Location, NgModuleFactoryLoader], [Router, Location, NgModuleFactoryLoader],
@ -3430,7 +3428,7 @@ describe('Integration', () => {
expect(fixture.nativeElement).toHaveText('lazy-loaded-parent [lazy-loaded-child]'); expect(fixture.nativeElement).toHaveText('lazy-loaded-parent [lazy-loaded-child]');
}))); })));
fixmeIvy('FW-561: Runtime compiler is not loaded') && fixmeIvy('timeout') &&
it('should have 2 injector trees: module and element', it('should have 2 injector trees: module and element',
fakeAsync(inject( fakeAsync(inject(
[Router, Location, NgModuleFactoryLoader], [Router, Location, NgModuleFactoryLoader],
@ -3520,7 +3518,7 @@ describe('Integration', () => {
}))); })));
// https://github.com/angular/angular/issues/12889 // https://github.com/angular/angular/issues/12889
fixmeIvy('FW-561: Runtime compiler is not loaded') && fixmeIvy('unknown') &&
it('should create a single instance of lazy-loaded modules', it('should create a single instance of lazy-loaded modules',
fakeAsync(inject( fakeAsync(inject(
[Router, Location, NgModuleFactoryLoader], [Router, Location, NgModuleFactoryLoader],
@ -3559,7 +3557,7 @@ describe('Integration', () => {
}))); })));
// https://github.com/angular/angular/issues/13870 // https://github.com/angular/angular/issues/13870
fixmeIvy('FW-561: Runtime compiler is not loaded') && fixmeIvy('timeout') &&
it('should create a single instance of guards for lazy-loaded modules', it('should create a single instance of guards for lazy-loaded modules',
fakeAsync(inject( fakeAsync(inject(
[Router, Location, NgModuleFactoryLoader], [Router, Location, NgModuleFactoryLoader],
@ -3611,7 +3609,6 @@ describe('Integration', () => {
}))); })));
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should emit RouteConfigLoadStart and RouteConfigLoadEnd event when route is lazy loaded', it('should emit RouteConfigLoadStart and RouteConfigLoadEnd event when route is lazy loaded',
fakeAsync(inject( fakeAsync(inject(
[Router, Location, NgModuleFactoryLoader], [Router, Location, NgModuleFactoryLoader],
@ -3658,7 +3655,6 @@ describe('Integration', () => {
expect(events[1].toString()).toEqual('RouteConfigLoadEnd(path: lazy)'); expect(events[1].toString()).toEqual('RouteConfigLoadEnd(path: lazy)');
}))); })));
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('throws an error when forRoot() is used in a lazy context', it('throws an error when forRoot() is used in a lazy context',
fakeAsync(inject( fakeAsync(inject(
[Router, Location, NgModuleFactoryLoader], [Router, Location, NgModuleFactoryLoader],
@ -3669,8 +3665,7 @@ describe('Integration', () => {
@NgModule({ @NgModule({
declarations: [LazyLoadedComponent], declarations: [LazyLoadedComponent],
imports: imports: [RouterModule.forRoot([{path: 'loaded', component: LazyLoadedComponent}])]
[RouterModule.forRoot([{path: 'loaded', component: LazyLoadedComponent}])]
}) })
class LoadedModule { class LoadedModule {
} }
@ -3689,7 +3684,6 @@ describe('Integration', () => {
`RouterModule.forRoot() called twice. Lazy loaded modules should use RouterModule.forChild() instead.`); `RouterModule.forRoot() called twice. Lazy loaded modules should use RouterModule.forChild() instead.`);
}))); })));
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should combine routes from multiple modules into a single configuration', it('should combine routes from multiple modules into a single configuration',
fakeAsync(inject( fakeAsync(inject(
[Router, Location, NgModuleFactoryLoader], [Router, Location, NgModuleFactoryLoader],
@ -3719,10 +3713,7 @@ describe('Integration', () => {
class LoadedModule { class LoadedModule {
} }
loader.stubbedModules = { loader.stubbedModules = {expected1: LoadedModule, expected2: SiblingOfLoadedModule};
expected1: LoadedModule,
expected2: SiblingOfLoadedModule
};
const fixture = createRoot(router, RootCmp); const fixture = createRoot(router, RootCmp);
@ -3740,7 +3731,7 @@ describe('Integration', () => {
expect(location.path()).toEqual('/lazy2/loaded'); expect(location.path()).toEqual('/lazy2/loaded');
}))); })));
fixmeIvy('FW-561: Runtime compiler is not loaded') && fixmeIvy('unknown') &&
it('should allow lazy loaded module in named outlet', it('should allow lazy loaded module in named outlet',
fakeAsync(inject( fakeAsync(inject(
[Router, NgModuleFactoryLoader], [Router, NgModuleFactoryLoader],
@ -3783,9 +3774,11 @@ describe('Integration', () => {
.toHaveText('team 22 [ user john, right: lazy-loaded ]'); .toHaveText('team 22 [ user john, right: lazy-loaded ]');
}))); })));
fixmeIvy('unknown') &&
it('should allow componentless named outlet to render children', it('should allow componentless named outlet to render children',
fakeAsync(inject( fakeAsync(inject(
[Router, NgModuleFactoryLoader], (router: Router, loader: SpyNgModuleFactoryLoader) => { [Router, NgModuleFactoryLoader],
(router: Router, loader: SpyNgModuleFactoryLoader) => {
const fixture = createRoot(router, RootCmp); const fixture = createRoot(router, RootCmp);
@ -3794,7 +3787,11 @@ describe('Integration', () => {
component: TeamCmp, component: TeamCmp,
children: [ children: [
{path: 'user/:name', component: UserCmp}, {path: 'user/:name', component: UserCmp},
{path: 'simple', outlet: 'right', children: [{path: '', component: SimpleCmp}]}, {
path: 'simple',
outlet: 'right',
children: [{path: '', component: SimpleCmp}]
},
] ]
}]); }]);
@ -3869,7 +3866,7 @@ describe('Integration', () => {
}); });
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') && fixmeIvy('timeout') &&
it('should use the injector of the lazily-loaded configuration', it('should use the injector of the lazily-loaded configuration',
fakeAsync(inject( fakeAsync(inject(
[Router, Location, NgModuleFactoryLoader], [Router, Location, NgModuleFactoryLoader],
@ -3892,7 +3889,6 @@ describe('Integration', () => {
}))); })));
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('works when given a callback', it('works when given a callback',
fakeAsync(inject( fakeAsync(inject(
[Router, Location, NgModuleFactoryLoader], (router: Router, location: Location) => { [Router, Location, NgModuleFactoryLoader], (router: Router, location: Location) => {
@ -3902,8 +3898,7 @@ describe('Integration', () => {
@NgModule({ @NgModule({
declarations: [LazyLoadedComponent], declarations: [LazyLoadedComponent],
imports: imports: [RouterModule.forChild([{path: 'loaded', component: LazyLoadedComponent}])],
[RouterModule.forChild([{path: 'loaded', component: LazyLoadedComponent}])],
}) })
class LoadedModule { class LoadedModule {
} }
@ -3943,7 +3938,6 @@ describe('Integration', () => {
]); ]);
}))); })));
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should work with complex redirect rules', it('should work with complex redirect rules',
fakeAsync(inject( fakeAsync(inject(
[Router, Location, NgModuleFactoryLoader], [Router, Location, NgModuleFactoryLoader],
@ -3954,8 +3948,7 @@ describe('Integration', () => {
@NgModule({ @NgModule({
declarations: [LazyLoadedComponent], declarations: [LazyLoadedComponent],
imports: imports: [RouterModule.forChild([{path: 'loaded', component: LazyLoadedComponent}])],
[RouterModule.forChild([{path: 'loaded', component: LazyLoadedComponent}])],
}) })
class LoadedModule { class LoadedModule {
} }
@ -3972,7 +3965,6 @@ describe('Integration', () => {
expect(location.path()).toEqual('/lazy/loaded'); expect(location.path()).toEqual('/lazy/loaded');
}))); })));
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should work with wildcard route', it('should work with wildcard route',
fakeAsync(inject( fakeAsync(inject(
[Router, Location, NgModuleFactoryLoader], [Router, Location, NgModuleFactoryLoader],
@ -4008,7 +4000,6 @@ describe('Integration', () => {
preloader.setUpPreloading(); preloader.setUpPreloading();
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should work', it('should work',
fakeAsync(inject( fakeAsync(inject(
[Router, Location, NgModuleFactoryLoader], [Router, Location, NgModuleFactoryLoader],
@ -4026,8 +4017,8 @@ describe('Integration', () => {
} }
@NgModule({ @NgModule({
imports: [RouterModule.forChild( imports:
[{path: 'LoadedModule1', loadChildren: 'expected2'}])] [RouterModule.forChild([{path: 'LoadedModule1', loadChildren: 'expected2'}])]
}) })
class LoadedModule1 { class LoadedModule1 {
} }
@ -4037,8 +4028,7 @@ describe('Integration', () => {
const fixture = createRoot(router, RootCmp); const fixture = createRoot(router, RootCmp);
router.resetConfig([ router.resetConfig([
{path: 'blank', component: BlankCmp}, {path: 'blank', component: BlankCmp}, {path: 'lazy', loadChildren: 'expected'}
{path: 'lazy', loadChildren: 'expected'}
]); ]);
router.navigateByUrl('/blank'); router.navigateByUrl('/blank');
@ -4097,6 +4087,7 @@ describe('Integration', () => {
{providers: [{provide: UrlHandlingStrategy, useClass: CustomUrlHandlingStrategy}]}); {providers: [{provide: UrlHandlingStrategy, useClass: CustomUrlHandlingStrategy}]});
}); });
fixmeIvy('unknown') &&
it('should work', it('should work',
fakeAsync(inject([Router, Location], (router: Router, location: Location) => { fakeAsync(inject([Router, Location], (router: Router, location: Location) => {
const fixture = createRoot(router, RootCmp); const fixture = createRoot(router, RootCmp);
@ -4105,7 +4096,8 @@ describe('Integration', () => {
path: 'include', path: 'include',
component: TeamCmp, component: TeamCmp,
children: [ children: [
{path: 'user/:name', component: UserCmp}, {path: 'simple', component: SimpleCmp} {path: 'user/:name', component: UserCmp},
{path: 'simple', component: SimpleCmp}
] ]
}]); }]);
@ -4219,7 +4211,6 @@ describe('Integration', () => {
class LazyLoadedModule { class LazyLoadedModule {
} }
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should not ignore empty path when in legacy mode', it('should not ignore empty path when in legacy mode',
fakeAsync(inject( fakeAsync(inject(
[Router, NgModuleFactoryLoader], [Router, NgModuleFactoryLoader],
@ -4238,7 +4229,6 @@ describe('Integration', () => {
expect(link.getAttribute('href')).toEqual('/lazy/foo/bar/simple'); expect(link.getAttribute('href')).toEqual('/lazy/foo/bar/simple');
}))); })));
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should ignore empty path when in corrected mode', it('should ignore empty path when in corrected mode',
fakeAsync(inject( fakeAsync(inject(
[Router, NgModuleFactoryLoader], [Router, NgModuleFactoryLoader],

View File

@ -36,7 +36,7 @@ describe('RouterPreloader', () => {
}); });
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should work', it('should work',
fakeAsync(inject( fakeAsync(inject(
[NgModuleFactoryLoader, RouterPreloader, Router], [NgModuleFactoryLoader, RouterPreloader, Router],
@ -60,7 +60,8 @@ describe('RouterPreloader', () => {
}); });
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
fixmeIvy('unknown') &&
it('should work', it('should work',
fakeAsync(inject( fakeAsync(inject(
[NgModuleFactoryLoader, RouterPreloader, Router, NgModuleRef], [NgModuleFactoryLoader, RouterPreloader, Router, NgModuleRef],
@ -200,7 +201,7 @@ describe('RouterPreloader', () => {
}); });
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should work', it('should work',
fakeAsync(inject( fakeAsync(inject(
[NgModuleFactoryLoader, RouterPreloader, Router], [NgModuleFactoryLoader, RouterPreloader, Router],
@ -230,7 +231,7 @@ describe('RouterPreloader', () => {
}); });
}); });
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
it('should work', it('should work',
fakeAsync(inject( fakeAsync(inject(
[NgModuleFactoryLoader, RouterPreloader, Router], [NgModuleFactoryLoader, RouterPreloader, Router],

View File

@ -76,12 +76,12 @@ export interface CollectionChangeRecord<V> extends IterableChangeRecord<V> {
} }
export declare class Compiler { export declare class Compiler {
compileModuleAndAllComponentsAsync: <T>(moduleType: Type<T>) => Promise<ModuleWithComponentFactories<T>>;
compileModuleAndAllComponentsSync: <T>(moduleType: Type<T>) => ModuleWithComponentFactories<T>;
compileModuleAsync: <T>(moduleType: Type<T>) => Promise<NgModuleFactory<T>>;
compileModuleSync: <T>(moduleType: Type<T>) => NgModuleFactory<T>;
clearCache(): void; clearCache(): void;
clearCacheFor(type: Type<any>): void; clearCacheFor(type: Type<any>): void;
compileModuleAndAllComponentsAsync<T>(moduleType: Type<T>): Promise<ModuleWithComponentFactories<T>>;
compileModuleAndAllComponentsSync<T>(moduleType: Type<T>): ModuleWithComponentFactories<T>;
compileModuleAsync<T>(moduleType: Type<T>): Promise<NgModuleFactory<T>>;
compileModuleSync<T>(moduleType: Type<T>): NgModuleFactory<T>;
getModuleId(moduleType: Type<any>): string | undefined; getModuleId(moduleType: Type<any>): string | undefined;
} }
@ -188,48 +188,50 @@ export declare function createPlatformFactory(parentPlatformFactory: ((extraProv
export declare const CUSTOM_ELEMENTS_SCHEMA: SchemaMetadata; export declare const CUSTOM_ELEMENTS_SCHEMA: SchemaMetadata;
export declare class DebugElement extends DebugNode { export interface DebugElement extends DebugNode {
attributes: { readonly attributes: {
[key: string]: string | null; [key: string]: string | null;
}; };
childNodes: DebugNode[]; readonly childNodes: DebugNode[];
readonly children: DebugElement[]; readonly children: DebugElement[];
classes: { readonly classes: {
[key: string]: boolean; [key: string]: boolean;
}; };
name: string; readonly name: string;
nativeElement: any; readonly nativeElement: any;
properties: { readonly properties: {
[key: string]: any; [key: string]: any;
}; };
styles: { readonly styles: {
[key: string]: string | null; [key: string]: string | null;
}; };
constructor(nativeNode: any, parent: any, _debugContext: DebugContext);
addChild(child: DebugNode): void;
insertBefore(refChild: DebugNode, newChild: DebugNode): void;
insertChildrenAfter(child: DebugNode, newChildren: DebugNode[]): void;
query(predicate: Predicate<DebugElement>): DebugElement; query(predicate: Predicate<DebugElement>): DebugElement;
queryAll(predicate: Predicate<DebugElement>): DebugElement[]; queryAll(predicate: Predicate<DebugElement>): DebugElement[];
queryAllNodes(predicate: Predicate<DebugNode>): DebugNode[]; queryAllNodes(predicate: Predicate<DebugNode>): DebugNode[];
removeChild(child: DebugNode): void;
triggerEventHandler(eventName: string, eventObj: any): void; triggerEventHandler(eventName: string, eventObj: any): void;
} }
export declare class DebugNode { export declare const DebugElement: {
new (...args: any[]): DebugElement;
};
export interface DebugNode {
readonly componentInstance: any; readonly componentInstance: any;
readonly context: any; readonly context: any;
readonly injector: Injector; readonly injector: Injector;
listeners: EventListener[]; readonly listeners: EventListener[];
nativeNode: any; readonly nativeNode: any;
parent: DebugElement | null; readonly parent: DebugElement | null;
readonly providerTokens: any[]; readonly providerTokens: any[];
readonly references: { readonly references: {
[key: string]: any; [key: string]: any;
}; };
constructor(nativeNode: any, parent: DebugNode | null, _debugContext: DebugContext);
} }
export declare const DebugNode: {
new (...args: any[]): DebugNode;
};
/** @deprecated */ /** @deprecated */
export declare class DefaultIterableDiffer<V> implements IterableDiffer<V>, IterableChanges<V> { export declare class DefaultIterableDiffer<V> implements IterableDiffer<V>, IterableChanges<V> {
readonly collection: V[] | Iterable<V> | null; readonly collection: V[] | Iterable<V> | null;
@ -330,7 +332,7 @@ export interface ForwardRefFn {
(): any; (): any;
} }
export declare function getDebugNode(nativeNode: any): DebugNode | null; export declare const getDebugNode: (nativeNode: any) => DebugNode | null;
export declare function getModuleFactory(id: string): NgModuleFactory<any>; export declare function getModuleFactory(id: string): NgModuleFactory<any>;