refactor(ivy): treate LView as the primary global state (#27282)

- rename `LViewData` to `LView` (to be consistent with `TView`)
- Remove `getRenderer`, `getRendererFactory`, `getTview`, `getCurrentQueries`,

PR Close #27282
This commit is contained in:
Misko Hevery 2018-11-21 21:14:06 -08:00 committed by Igor Minar
parent 4354fce2bb
commit 816ec0b1c3
56 changed files with 1217 additions and 1326 deletions

View File

@ -231,7 +231,7 @@ class DebugNode__POST_R3__ implements DebugNode {
// TODO move to discoverable utils // TODO move to discoverable utils
const context = loadContext(this.nativeNode as HTMLElement, false) !; const context = loadContext(this.nativeNode as HTMLElement, false) !;
if (!context) return []; if (!context) return [];
const lView = context.lViewData; const lView = context.lView;
const tView = lView[TVIEW]; const tView = lView[TVIEW];
const tNode = tView.data[context.nodeIndex] as TNode; const tNode = tView.data[context.nodeIndex] as TNode;
const providerTokens: any[] = []; const providerTokens: any[] = [];
@ -268,7 +268,7 @@ class DebugElement__POST_R3__ extends DebugNode__POST_R3__ implements DebugEleme
get properties(): {[key: string]: any;} { get properties(): {[key: string]: any;} {
const context = loadContext(this.nativeNode) !; const context = loadContext(this.nativeNode) !;
const lView = context.lViewData; const lView = context.lView;
const tView = lView[TVIEW]; const tView = lView[TVIEW];
const tNode = tView.data[context.nodeIndex] as TNode; const tNode = tView.data[context.nodeIndex] as TNode;
const properties = {}; const properties = {};

View File

@ -1,17 +1,17 @@
# View Data Explanation # View Data Explanation
`LViewData` and `TView.data` are how the Ivy renderer keeps track of the internal data needed to render the template. `LView` and `TView.data` are how the Ivy renderer keeps track of the internal data needed to render the template.
`LViewData` is designed so that a single array can contain all of the necessary data for the template rendering in a compact form. `LView` is designed so that a single array can contain all of the necessary data for the template rendering in a compact form.
`TView.data` is a corollary to the `LViewData` and contains information which can be shared across the template instances. `TView.data` is a corollary to the `LView` and contains information which can be shared across the template instances.
## `LViewData` / `TView.data` layout. ## `LView` / `TView.data` layout.
Both `LViewData` and `TView.data` are arrays whose indices refer to the same item. Both `LView` and `TView.data` are arrays whose indices refer to the same item.
For example index `123` may point to a component instance in the `LViewData` but a component type in `TView.data`. For example index `123` may point to a component instance in the `LView` but a component type in `TView.data`.
The layout is as such: The layout is as such:
| Section | `LViewData` | `TView.data` | Section | `LView` | `TView.data`
| ---------- | ------------------------------------------------------------ | -------------------------------------------------- | ---------- | ------------------------------------------------------------ | --------------------------------------------------
| `HEADER` | contextual data | mostly `null` | `HEADER` | contextual data | mostly `null`
| `CONSTS` | DOM, pipe, and local ref instances | | `CONSTS` | DOM, pipe, and local ref instances |
@ -22,7 +22,7 @@ The layout is as such:
## `HEADER` ## `HEADER`
`HEADER` is a fixed array size which contains contextual information about the template. `HEADER` is a fixed array size which contains contextual information about the template.
Mostly information such as parent `LViewData`, `Sanitizer`, `TView`, and many more bits of information needed for template rendering. Mostly information such as parent `LView`, `Sanitizer`, `TView`, and many more bits of information needed for template rendering.
## `CONSTS` ## `CONSTS`
@ -57,7 +57,7 @@ class MyApp {
The above will create following layout: The above will create following layout:
| Index | `LViewData` | `TView.data` | Index | `LView` | `TView.data`
| ----: | ----------- | ------------ | ----: | ----------- | ------------
| `HEADER` | `HEADER`
| `CONSTS` | `CONSTS`
@ -70,9 +70,9 @@ The above will create following layout:
NOTE: NOTE:
- The `10` is not the actual size of `HEADER` but it is left here for simplification. - The `10` is not the actual size of `HEADER` but it is left here for simplification.
- `LViewData` contains DOM instances only - `LView` contains DOM instances only
- `TView.data` contains information on relationships such as where the parent is. - `TView.data` contains information on relationships such as where the parent is.
You need the `TView.data` information to make sense of the `LViewData` information. You need the `TView.data` information to make sense of the `LView` information.
## `VARS` ## `VARS`
@ -109,7 +109,7 @@ class MyApp {
The above will create following layout: The above will create following layout:
| Index | `LViewData` | `TView.data` | Index | `LView` | `TView.data`
| ----: | ----------- | ------------ | ----: | ----------- | ------------
| `HEADER` | `HEADER`
| `CONSTS` | `CONSTS`
@ -121,7 +121,7 @@ The above will create following layout:
| ... | ... | ... | ... | ... | ...
NOTE: NOTE:
- `LViewData` contain DOM instances and previous binding values only - `LView` contain DOM instances and previous binding values only
- `TView.data` contains information on relationships and property labels. - `TView.data` contains information on relationships and property labels.
@ -182,7 +182,7 @@ class Tooltip {
The above will create the following layout: The above will create the following layout:
| Index | `LViewData` | `TView.data` | Index | `LView` | `TView.data`
| ----: | ----------- | ------------ | ----: | ----------- | ------------
| `HEADER` | `HEADER`
| `CONSTS` | `CONSTS`
@ -256,10 +256,10 @@ This is because at the time of compilation we don't know about all of the inject
Injection needs to store three things: Injection needs to store three things:
- The injection token stored in `TView.data` - The injection token stored in `TView.data`
- The token factory stored in `LProtoViewData` and subsequently in `LViewData` - The token factory stored in `LProtoViewData` and subsequently in `LView`
- The value for the injection token stored in `LViewData`. (Replacing token factory upon creation). - The value for the injection token stored in `LView`. (Replacing token factory upon creation).
To save time when creating `LViewData` we use an array clone operation to copy data from `LProtoViewdata` to `LViewData`. To save time when creating `LView` we use an array clone operation to copy data from `LProtoViewdata` to `LView`.
The `LProtoViewData` is initialized by the `ProvidesFeature`. The `LProtoViewData` is initialized by the `ProvidesFeature`.
Injection tokens are sorted into three sections: Injection tokens are sorted into three sections:
@ -321,7 +321,7 @@ class Child {
The above will create the following layout: The above will create the following layout:
| Index | `LViewData` | `TView.data` | Index | `LView` | `TView.data`
| ----: | ------------ | ------------- | ----: | ------------ | -------------
| `HEADER` | `HEADER`
| `CONSTS` | `CONSTS`
@ -366,9 +366,9 @@ function isFactory(obj: any): obj is Factory {
Pseudo code: Pseudo code:
1. Check if bloom filter has the value of the token. (If not exit) 1. Check if bloom filter has the value of the token. (If not exit)
2. Locate the token in the expando honoring `directives`, `providers` and `viewProvider` rules by limiting the search scope. 2. Locate the token in the expando honoring `directives`, `providers` and `viewProvider` rules by limiting the search scope.
3. Read the value of `lViewData[index]` at that location. 3. Read the value of `lView[index]` at that location.
- if `isFactory(lViewData[index])` then mark it as resolving and invoke it. Replace `lViewData[index]` with the value returned from factory (caching mechanism). - if `isFactory(lView[index])` then mark it as resolving and invoke it. Replace `lView[index]` with the value returned from factory (caching mechanism).
- if `!isFactory(lViewData[index])` then return the cached value as is. - if `!isFactory(lView[index])` then return the cached value as is.
# `EXPANDO` and Injecting Special Objects. # `EXPANDO` and Injecting Special Objects.
@ -437,6 +437,6 @@ function inject(token: any): any {
TODO TODO
## Combining `LContainer` with `LViewData` ## Combining `LContainer` with `LView`
TODO TODO

View File

@ -7,6 +7,8 @@
*/ */
import {getComponentDef, getNgModuleDef} from './definition'; import {getComponentDef, getNgModuleDef} from './definition';
import {TNode} from './interfaces/node';
import {LView} from './interfaces/view';
// The functions in this file verify that the assumptions we are making // The functions in this file verify that the assumptions we are making
// about state in an instruction are correct before implementing any logic. // about state in an instruction are correct before implementing any logic.
@ -87,3 +89,22 @@ function throwError(msg: string): never {
export function assertDomNode(node: any) { export function assertDomNode(node: any) {
assertEqual(node instanceof Node, true, 'The provided value must be an instance of a DOM Node'); assertEqual(node instanceof Node, true, 'The provided value must be an instance of a DOM Node');
} }
export function assertPreviousIsParent(isParent: boolean) {
assertEqual(isParent, true, 'previousOrParentTNode should be a parent');
}
export function assertHasParent(tNode: TNode) {
assertDefined(tNode.parent, 'previousOrParentTNode should have a parent');
}
export function assertDataNext(lView: LView, index: number, arr?: any[]) {
if (arr == null) arr = lView;
assertEqual(
arr.length, index, `index ${index} expected to be at the end of arr (length ${arr.length})`);
}
export function assertDataInRange(arr: any[], index: number) {
assertLessThan(index, arr ? arr.length : 0, 'index expected to be a valid data index');
}

View File

@ -0,0 +1,75 @@
/**
* @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 {devModeEqual} from '../change_detection/change_detection_util';
import {assertDataInRange, assertLessThan, assertNotEqual} from './assert';
import {throwErrorIfNoChangesMode} from './errors';
import {BINDING_INDEX, LView} from './interfaces/view';
import {getCheckNoChangesMode, getCreationMode} from './state';
import {NO_CHANGE} from './tokens';
import {isDifferent} from './util';
// TODO(misko): consider inlining
/** Updates binding and returns the value. */
export function updateBinding(lView: LView, bindingIndex: number, value: any): any {
return lView[bindingIndex] = value;
}
/** Gets the current binding value. */
export function getBinding(lView: LView, bindingIndex: number): any {
ngDevMode && assertDataInRange(lView, lView[bindingIndex]);
ngDevMode &&
assertNotEqual(lView[bindingIndex], NO_CHANGE, 'Stored value should never be NO_CHANGE.');
return lView[bindingIndex];
}
/** Updates binding if changed, then returns whether it was updated. */
export function bindingUpdated(lView: LView, bindingIndex: number, value: any): boolean {
ngDevMode && assertNotEqual(value, NO_CHANGE, 'Incoming value should never be NO_CHANGE.');
ngDevMode &&
assertLessThan(bindingIndex, lView.length, `Slot should have been initialized to NO_CHANGE`);
if (lView[bindingIndex] === NO_CHANGE) {
// initial pass
lView[bindingIndex] = value;
} else if (isDifferent(lView[bindingIndex], value)) {
if (ngDevMode && getCheckNoChangesMode()) {
if (!devModeEqual(lView[bindingIndex], value)) {
throwErrorIfNoChangesMode(getCreationMode(), lView[bindingIndex], value);
}
}
lView[bindingIndex] = value;
} else {
return false;
}
return true;
}
/** Updates 2 bindings if changed, then returns whether either was updated. */
export function bindingUpdated2(lView: LView, bindingIndex: number, exp1: any, exp2: any): boolean {
const different = bindingUpdated(lView, bindingIndex, exp1);
return bindingUpdated(lView, bindingIndex + 1, exp2) || different;
}
/** Updates 3 bindings if changed, then returns whether any was updated. */
export function bindingUpdated3(
lView: LView, bindingIndex: number, exp1: any, exp2: any, exp3: any): boolean {
const different = bindingUpdated2(lView, bindingIndex, exp1, exp2);
return bindingUpdated(lView, bindingIndex + 2, exp3) || different;
}
/** Updates 4 bindings if changed, then returns whether any was updated. */
export function bindingUpdated4(
lView: LView, bindingIndex: number, exp1: any, exp2: any, exp3: any, exp4: any): boolean {
const different = bindingUpdated2(lView, bindingIndex, exp1, exp2);
return bindingUpdated2(lView, bindingIndex + 2, exp3, exp4) || different;
}

View File

@ -17,14 +17,14 @@ import {getComponentDef} from './definition';
import {diPublicInInjector, getOrCreateNodeInjectorForNode} from './di'; import {diPublicInInjector, getOrCreateNodeInjectorForNode} from './di';
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, createLView, createNodeAtIndex, createTView, getOrCreateTView, initNodeFlags, instantiateRootComponent, locateHostElement, prefillHostVars, queueComponentIndexForCheck, refreshDescendantViews} from './instructions';
import {ComponentDef, ComponentType} from './interfaces/definition'; import {ComponentDef, ComponentType} from './interfaces/definition';
import {TElementNode, TNodeFlags, TNodeType} from './interfaces/node'; import {TElementNode, TNodeFlags, TNodeType} from './interfaces/node';
import {PlayerHandler} from './interfaces/player'; 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, LView, LViewFlags, RootContext, RootContextFlags, TVIEW} from './interfaces/view';
import {enterView, leaveView, resetComponentState} from './state'; import {enterView, leaveView, resetComponentState} from './state';
import {defaultScheduler, getRootView, readPatchedLViewData, stringify} from './util'; import {defaultScheduler, getRootView, readPatchedLView, stringify} from './util';
@ -120,7 +120,7 @@ export function renderComponent<T>(
const rootContext = createRootContext(opts.scheduler, opts.playerHandler); const rootContext = createRootContext(opts.scheduler, opts.playerHandler);
const renderer = rendererFactory.createRenderer(hostRNode, componentDef); const renderer = rendererFactory.createRenderer(hostRNode, componentDef);
const rootView: LViewData = createLViewData( const rootView: LView = createLView(
null, createTView(-1, null, 1, 0, null, null, null), rootContext, rootFlags, rendererFactory, null, createTView(-1, null, 1, 0, null, null, null), rootContext, rootFlags, rendererFactory,
renderer, undefined, opts.injector || null); renderer, undefined, opts.injector || null);
@ -154,12 +154,11 @@ 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, rNode: RElement | null, def: ComponentDef<any>, rootView: LView,
rendererFactory: RendererFactory3, renderer: Renderer3, rendererFactory: RendererFactory3, renderer: Renderer3, sanitizer?: Sanitizer | null): LView {
sanitizer?: Sanitizer | null): LViewData {
resetComponentState(); resetComponentState();
const tView = rootView[TVIEW]; const tView = rootView[TVIEW];
const componentView = createLViewData( const componentView = createLView(
rootView, 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),
@ -185,8 +184,8 @@ export function createRootComponentView(
* renderComponent() and ViewContainerRef.createComponent(). * renderComponent() and ViewContainerRef.createComponent().
*/ */
export function createRootComponent<T>( export function createRootComponent<T>(
componentView: LViewData, componentDef: ComponentDef<T>, rootView: LViewData, componentView: LView, componentDef: ComponentDef<T>, rootView: LView, rootContext: RootContext,
rootContext: RootContext, hostFeatures: HostFeature[] | null): any { hostFeatures: HostFeature[] | null): any {
const tView = rootView[TVIEW]; const tView = rootView[TVIEW];
// Create directive instance with factory() and store at next index in viewData // Create directive instance with factory() and store at next index in viewData
const component = instantiateRootComponent(tView, rootView, componentDef); const component = instantiateRootComponent(tView, rootView, componentDef);
@ -226,7 +225,7 @@ export function createRootContext(
* ``` * ```
*/ */
export function LifecycleHooksFeature(component: any, def: ComponentDef<any>): void { export function LifecycleHooksFeature(component: any, def: ComponentDef<any>): void {
const rootTView = readPatchedLViewData(component) ![TVIEW]; const rootTView = readPatchedLView(component) ![TVIEW];
const dirIndex = rootTView.data.length - 1; const dirIndex = rootTView.data.length - 1;
queueInitHooks(dirIndex, def.onInit, def.doCheck, rootTView); queueInitHooks(dirIndex, def.onInit, def.doCheck, rootTView);

View File

@ -22,12 +22,12 @@ import {assertComponentType, assertDefined} from './assert';
import {LifecycleHooksFeature, createRootComponent, createRootComponentView, createRootContext} from './component'; import {LifecycleHooksFeature, createRootComponent, createRootComponentView, createRootContext} from './component';
import {getComponentDef} from './definition'; import {getComponentDef} from './definition';
import {NodeInjector} from './di'; import {NodeInjector} from './di';
import {createLViewData, createNodeAtIndex, createTView, createViewNode, elementCreate, locateHostElement, refreshDescendantViews} from './instructions'; import {createLView, createNodeAtIndex, createTView, createViewNode, elementCreate, locateHostElement, refreshDescendantViews} from './instructions';
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 {SanitizerFn} from './interfaces/sanitization';
import {HEADER_OFFSET, LViewData, LViewFlags, RootContext, TVIEW} from './interfaces/view'; import {HEADER_OFFSET, LView, 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';
import {createElementRef} from './view_engine_compatibility'; import {createElementRef} from './view_engine_compatibility';
@ -146,12 +146,12 @@ 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 rootLView = createLView(
null, createTView(-1, null, 1, 0, null, null, null), rootContext, rootFlags, null, createTView(-1, null, 1, 0, null, null, null), rootContext, rootFlags,
rendererFactory, renderer, sanitizer, rootViewInjector); rendererFactory, renderer, sanitizer, rootViewInjector);
// rootView is the parent when bootstrapping // rootView is the parent when bootstrapping
const oldView = enterView(rootView, null); const oldLView = enterView(rootLView, null);
let component: T; let component: T;
let tElementNode: TElementNode; let tElementNode: TElementNode;
@ -159,14 +159,14 @@ export class ComponentFactory<T> extends viewEngine_ComponentFactory<T> {
if (rendererFactory.begin) rendererFactory.begin(); if (rendererFactory.begin) rendererFactory.begin();
const componentView = createRootComponentView( const componentView = createRootComponentView(
hostRNode, this.componentDef, rootView, rendererFactory, renderer); hostRNode, this.componentDef, rootLView, rendererFactory, renderer);
tElementNode = getTNode(0, rootView) as TElementNode; tElementNode = getTNode(0, rootLView) 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
// projection instruction. This is needed to support the reprojection of these nodes. // projection instruction. This is needed to support the reprojection of these nodes.
if (projectableNodes) { if (projectableNodes) {
let index = 0; let index = 0;
const tView = rootView[TVIEW]; const tView = rootLView[TVIEW];
const projection: TNode[] = tElementNode.projection = []; const projection: TNode[] = tElementNode.projection = [];
for (let i = 0; i < projectableNodes.length; i++) { for (let i = 0; i < projectableNodes.length; i++) {
const nodeList = projectableNodes[i]; const nodeList = projectableNodes[i];
@ -181,7 +181,7 @@ export class ComponentFactory<T> extends viewEngine_ComponentFactory<T> {
tView.expandoStartIndex++; tView.expandoStartIndex++;
tView.blueprint.splice(++index + HEADER_OFFSET, 0, null); tView.blueprint.splice(++index + HEADER_OFFSET, 0, null);
tView.data.splice(index + HEADER_OFFSET, 0, null); tView.data.splice(index + HEADER_OFFSET, 0, null);
rootView.splice(index + HEADER_OFFSET, 0, null); rootLView.splice(index + HEADER_OFFSET, 0, null);
} }
const tNode = const tNode =
createNodeAtIndex(index, TNodeType.Element, nodeList[j] as RElement, null, null); createNodeAtIndex(index, TNodeType.Element, nodeList[j] as RElement, null, null);
@ -196,17 +196,17 @@ export class ComponentFactory<T> extends viewEngine_ComponentFactory<T> {
// executed here? // executed here?
// Angular 5 reference: https://stackblitz.com/edit/lifecycle-hooks-vcref // Angular 5 reference: https://stackblitz.com/edit/lifecycle-hooks-vcref
component = createRootComponent( component = createRootComponent(
componentView, this.componentDef, rootView, rootContext, [LifecycleHooksFeature]); componentView, this.componentDef, rootLView, rootContext, [LifecycleHooksFeature]);
refreshDescendantViews(rootView, RenderFlags.Create); refreshDescendantViews(rootLView, RenderFlags.Create);
} finally { } finally {
leaveView(oldView, true); leaveView(oldLView, true);
if (rendererFactory.end) rendererFactory.end(); if (rendererFactory.end) rendererFactory.end();
} }
const componentRef = new ComponentRef( const componentRef = new ComponentRef(
this.componentType, component, this.componentType, component,
createElementRef(viewEngine_ElementRef, tElementNode, rootView), rootView, tElementNode); createElementRef(viewEngine_ElementRef, tElementNode, rootLView), rootLView, tElementNode);
if (isInternalRootView) { if (isInternalRootView) {
// The host element of the internal root view is attached to the component's host view node // The host element of the internal root view is attached to the component's host view node
@ -246,16 +246,16 @@ export class ComponentRef<T> extends viewEngine_ComponentRef<T> {
constructor( constructor(
componentType: Type<T>, instance: T, public location: viewEngine_ElementRef, componentType: Type<T>, instance: T, public location: viewEngine_ElementRef,
private _rootView: LViewData, private _rootLView: LView,
private _tNode: TElementNode|TContainerNode|TElementContainerNode) { private _tNode: TElementNode|TContainerNode|TElementContainerNode) {
super(); super();
this.instance = instance; this.instance = instance;
this.hostView = this.changeDetectorRef = new RootViewRef<T>(_rootView); this.hostView = this.changeDetectorRef = new RootViewRef<T>(_rootLView);
this.hostView._tViewNode = createViewNode(-1, _rootView); this.hostView._tViewNode = createViewNode(-1, _rootLView);
this.componentType = componentType; this.componentType = componentType;
} }
get injector(): Injector { return new NodeInjector(this._tNode, this._rootView); } get injector(): Injector { return new NodeInjector(this._tNode, this._rootLView); }
destroy(): void { destroy(): void {
ngDevMode && assertDefined(this.destroyCbs, 'NgModule already destroyed'); ngDevMode && assertDefined(this.destroyCbs, 'NgModule already destroyed');

View File

@ -12,7 +12,7 @@ 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';
import {RElement} from './interfaces/renderer'; import {RElement} from './interfaces/renderer';
import {CONTEXT, HEADER_OFFSET, HOST, LViewData, TVIEW} from './interfaces/view'; import {CONTEXT, HEADER_OFFSET, HOST, LView, TVIEW} from './interfaces/view';
import {getComponentViewByIndex, getNativeByTNode, readElementValue, readPatchedData} from './util'; import {getComponentViewByIndex, getNativeByTNode, readElementValue, readPatchedData} from './util';
@ -23,7 +23,7 @@ import {getComponentViewByIndex, getNativeByTNode, readElementValue, readPatched
* monkey-patched property to derive the `LContext` data. Once called then the monkey-patched * monkey-patched property to derive the `LContext` data. Once called then the monkey-patched
* value will be that of the newly created `LContext`. * value will be that of the newly created `LContext`.
* *
* If the monkey-patched value is the `LViewData` instance then the context value for that * If the monkey-patched value is the `LView` instance then the context value for that
* target will be created and the monkey-patch reference will be updated. Therefore when this * target will be created and the monkey-patch reference will be updated. Therefore when this
* function is called it may mutate the provided element\'s, component\'s or any of the associated * function is called it may mutate the provided element\'s, component\'s or any of the associated
* directive\'s monkey-patch values. * directive\'s monkey-patch values.
@ -39,28 +39,28 @@ import {getComponentViewByIndex, getNativeByTNode, readElementValue, readPatched
export function getContext(target: any): LContext|null { export function getContext(target: any): LContext|null {
let mpValue = readPatchedData(target); let mpValue = readPatchedData(target);
if (mpValue) { if (mpValue) {
// only when it's an array is it considered an LViewData instance // only when it's an array is it considered an LView instance
// ... otherwise it's an already constructed LContext instance // ... otherwise it's an already constructed LContext instance
if (Array.isArray(mpValue)) { if (Array.isArray(mpValue)) {
const lViewData: LViewData = mpValue !; const lView: LView = mpValue !;
let nodeIndex: number; let nodeIndex: number;
let component: any = undefined; let component: any = undefined;
let directives: any[]|null|undefined = undefined; let directives: any[]|null|undefined = undefined;
if (isComponentInstance(target)) { if (isComponentInstance(target)) {
nodeIndex = findViaComponent(lViewData, target); nodeIndex = findViaComponent(lView, target);
if (nodeIndex == -1) { if (nodeIndex == -1) {
throw new Error('The provided component was not found in the application'); throw new Error('The provided component was not found in the application');
} }
component = target; component = target;
} else if (isDirectiveInstance(target)) { } else if (isDirectiveInstance(target)) {
nodeIndex = findViaDirective(lViewData, target); nodeIndex = findViaDirective(lView, target);
if (nodeIndex == -1) { if (nodeIndex == -1) {
throw new Error('The provided directive was not found in the application'); throw new Error('The provided directive was not found in the application');
} }
directives = getDirectivesAtNodeIndex(nodeIndex, lViewData, false); directives = getDirectivesAtNodeIndex(nodeIndex, lView, false);
} else { } else {
nodeIndex = findViaNativeElement(lViewData, target as RElement); nodeIndex = findViaNativeElement(lView, target as RElement);
if (nodeIndex == -1) { if (nodeIndex == -1) {
return null; return null;
} }
@ -70,11 +70,11 @@ export function getContext(target: any): LContext|null {
// are expensive. Instead, only the target data (the element, compontent or // are expensive. Instead, only the target data (the element, compontent or
// directive details) are filled into the context. If called multiple times // directive details) are filled into the context. If called multiple times
// with different target values then the missing target data will be filled in. // with different target values then the missing target data will be filled in.
const native = readElementValue(lViewData[nodeIndex]); const native = readElementValue(lView[nodeIndex]);
const existingCtx = readPatchedData(native); const existingCtx = readPatchedData(native);
const context: LContext = (existingCtx && !Array.isArray(existingCtx)) ? const context: LContext = (existingCtx && !Array.isArray(existingCtx)) ?
existingCtx : existingCtx :
createLContext(lViewData, nodeIndex, native); createLContext(lView, nodeIndex, native);
// only when the component has been discovered then update the monkey-patch // only when the component has been discovered then update the monkey-patch
if (component && context.component === undefined) { if (component && context.component === undefined) {
@ -103,23 +103,23 @@ export function getContext(target: any): LContext|null {
while (parent = parent.parentNode) { while (parent = parent.parentNode) {
const parentContext = readPatchedData(parent); const parentContext = readPatchedData(parent);
if (parentContext) { if (parentContext) {
let lViewData: LViewData|null; let lView: LView|null;
if (Array.isArray(parentContext)) { if (Array.isArray(parentContext)) {
lViewData = parentContext as LViewData; lView = parentContext as LView;
} else { } else {
lViewData = parentContext.lViewData; lView = parentContext.lView;
} }
// the edge of the app was also reached here through another means // the edge of the app was also reached here through another means
// (maybe because the DOM was changed manually). // (maybe because the DOM was changed manually).
if (!lViewData) { if (!lView) {
return null; return null;
} }
const index = findViaNativeElement(lViewData, rElement); const index = findViaNativeElement(lView, rElement);
if (index >= 0) { if (index >= 0) {
const native = readElementValue(lViewData[index]); const native = readElementValue(lView[index]);
const context = createLContext(lViewData, index, native); const context = createLContext(lView, index, native);
attachPatchData(native, context); attachPatchData(native, context);
mpValue = context; mpValue = context;
break; break;
@ -133,9 +133,9 @@ export function getContext(target: any): LContext|null {
/** /**
* Creates an empty instance of a `LContext` context * Creates an empty instance of a `LContext` context
*/ */
function createLContext(lViewData: LViewData, nodeIndex: number, native: RElement): LContext { function createLContext(lView: LView, nodeIndex: number, native: RElement): LContext {
return { return {
lViewData, lView,
nodeIndex, nodeIndex,
native, native,
component: undefined, component: undefined,
@ -150,20 +150,20 @@ function createLContext(lViewData: LViewData, nodeIndex: number, native: RElemen
* @param componentInstance * @param componentInstance
* @returns The component's view * @returns The component's view
*/ */
export function getComponentViewByInstance(componentInstance: {}): LViewData { export function getComponentViewByInstance(componentInstance: {}): LView {
let lViewData = readPatchedData(componentInstance); let lView = readPatchedData(componentInstance);
let view: LViewData; let view: LView;
if (Array.isArray(lViewData)) { if (Array.isArray(lView)) {
const nodeIndex = findViaComponent(lViewData, componentInstance); const nodeIndex = findViaComponent(lView, componentInstance);
view = getComponentViewByIndex(nodeIndex, lViewData); view = getComponentViewByIndex(nodeIndex, lView);
const context = createLContext(lViewData, nodeIndex, view[HOST] as RElement); const context = createLContext(lView, nodeIndex, view[HOST] as RElement);
context.component = componentInstance; context.component = componentInstance;
attachPatchData(componentInstance, context); attachPatchData(componentInstance, context);
attachPatchData(context.native, context); attachPatchData(context.native, context);
} else { } else {
const context = lViewData as any as LContext; const context = lView as any as LContext;
view = getComponentViewByIndex(context.nodeIndex, context.lViewData); view = getComponentViewByIndex(context.nodeIndex, context.lView);
} }
return view; return view;
} }
@ -172,7 +172,7 @@ export function getComponentViewByInstance(componentInstance: {}): LViewData {
* Assigns the given data to the given target (which could be a component, * Assigns the given data to the given target (which could be a component,
* directive or DOM node instance) using monkey-patching. * directive or DOM node instance) using monkey-patching.
*/ */
export function attachPatchData(target: any, data: LViewData | LContext) { export function attachPatchData(target: any, data: LView | LContext) {
target[MONKEY_PATCH_KEY_NAME] = data; target[MONKEY_PATCH_KEY_NAME] = data;
} }
@ -185,12 +185,12 @@ export function isDirectiveInstance(instance: any): boolean {
} }
/** /**
* Locates the element within the given LViewData and returns the matching index * Locates the element within the given LView and returns the matching index
*/ */
function findViaNativeElement(lViewData: LViewData, target: RElement): number { function findViaNativeElement(lView: LView, target: RElement): number {
let tNode = lViewData[TVIEW].firstChild; let tNode = lView[TVIEW].firstChild;
while (tNode) { while (tNode) {
const native = getNativeByTNode(tNode, lViewData) !; const native = getNativeByTNode(tNode, lView) !;
if (native === target) { if (native === target) {
return tNode.index; return tNode.index;
} }
@ -215,20 +215,20 @@ function traverseNextElement(tNode: TNode): TNode|null {
} }
/** /**
* Locates the component within the given LViewData and returns the matching index * Locates the component within the given LView and returns the matching index
*/ */
function findViaComponent(lViewData: LViewData, componentInstance: {}): number { function findViaComponent(lView: LView, componentInstance: {}): number {
const componentIndices = lViewData[TVIEW].components; const componentIndices = lView[TVIEW].components;
if (componentIndices) { if (componentIndices) {
for (let i = 0; i < componentIndices.length; i++) { for (let i = 0; i < componentIndices.length; i++) {
const elementComponentIndex = componentIndices[i]; const elementComponentIndex = componentIndices[i];
const componentView = getComponentViewByIndex(elementComponentIndex, lViewData); const componentView = getComponentViewByIndex(elementComponentIndex, lView);
if (componentView[CONTEXT] === componentInstance) { if (componentView[CONTEXT] === componentInstance) {
return elementComponentIndex; return elementComponentIndex;
} }
} }
} else { } else {
const rootComponentView = getComponentViewByIndex(HEADER_OFFSET, lViewData); const rootComponentView = getComponentViewByIndex(HEADER_OFFSET, lView);
const rootComponent = rootComponentView[CONTEXT]; const rootComponent = rootComponentView[CONTEXT];
if (rootComponent === componentInstance) { if (rootComponent === componentInstance) {
// we are dealing with the root element here therefore we know that the // we are dealing with the root element here therefore we know that the
@ -240,20 +240,20 @@ function findViaComponent(lViewData: LViewData, componentInstance: {}): number {
} }
/** /**
* Locates the directive within the given LViewData and returns the matching index * Locates the directive within the given LView and returns the matching index
*/ */
function findViaDirective(lViewData: LViewData, directiveInstance: {}): number { function findViaDirective(lView: LView, directiveInstance: {}): number {
// if a directive is monkey patched then it will (by default) // if a directive is monkey patched then it will (by default)
// have a reference to the LViewData of the current view. The // have a reference to the LView of the current view. The
// element bound to the directive being search lives somewhere // element bound to the directive being search lives somewhere
// in the view data. We loop through the nodes and check their // in the view data. We loop through the nodes and check their
// list of directives for the instance. // list of directives for the instance.
let tNode = lViewData[TVIEW].firstChild; let tNode = lView[TVIEW].firstChild;
while (tNode) { while (tNode) {
const directiveIndexStart = getDirectiveStartIndex(tNode); const directiveIndexStart = getDirectiveStartIndex(tNode);
const directiveIndexEnd = getDirectiveEndIndex(tNode, directiveIndexStart); const directiveIndexEnd = getDirectiveEndIndex(tNode, directiveIndexStart);
for (let i = directiveIndexStart; i < directiveIndexEnd; i++) { for (let i = directiveIndexStart; i < directiveIndexEnd; i++) {
if (lViewData[i] === directiveInstance) { if (lView[i] === directiveInstance) {
return tNode.index; return tNode.index;
} }
} }
@ -267,39 +267,38 @@ function findViaDirective(lViewData: LViewData, directiveInstance: {}): number {
* provided list of directive index values. * provided list of directive index values.
* *
* @param nodeIndex The node index * @param nodeIndex The node index
* @param lViewData The target view data * @param lView The target view data
* @param includeComponents Whether or not to include components in returned directives * @param includeComponents Whether or not to include components in returned directives
*/ */
export function getDirectivesAtNodeIndex( export function getDirectivesAtNodeIndex(
nodeIndex: number, lViewData: LViewData, includeComponents: boolean): any[]|null { nodeIndex: number, lView: LView, includeComponents: boolean): any[]|null {
const tNode = lViewData[TVIEW].data[nodeIndex] as TNode; const tNode = lView[TVIEW].data[nodeIndex] as TNode;
let directiveStartIndex = getDirectiveStartIndex(tNode); let directiveStartIndex = getDirectiveStartIndex(tNode);
if (directiveStartIndex == 0) return EMPTY_ARRAY; if (directiveStartIndex == 0) return EMPTY_ARRAY;
const directiveEndIndex = getDirectiveEndIndex(tNode, directiveStartIndex); const directiveEndIndex = getDirectiveEndIndex(tNode, directiveStartIndex);
if (!includeComponents && tNode.flags & TNodeFlags.isComponent) directiveStartIndex++; if (!includeComponents && tNode.flags & TNodeFlags.isComponent) directiveStartIndex++;
return lViewData.slice(directiveStartIndex, directiveEndIndex); return lView.slice(directiveStartIndex, directiveEndIndex);
} }
export function getComponentAtNodeIndex(nodeIndex: number, lViewData: LViewData): {}|null { export function getComponentAtNodeIndex(nodeIndex: number, lView: LView): {}|null {
const tNode = lViewData[TVIEW].data[nodeIndex] as TNode; const tNode = lView[TVIEW].data[nodeIndex] as TNode;
let directiveStartIndex = getDirectiveStartIndex(tNode); let directiveStartIndex = getDirectiveStartIndex(tNode);
return tNode.flags & TNodeFlags.isComponent ? lViewData[directiveStartIndex] : null; return tNode.flags & TNodeFlags.isComponent ? lView[directiveStartIndex] : null;
} }
/** /**
* Returns a map of local references (local reference name => element or directive instance) that * Returns a map of local references (local reference name => element or directive instance) that
* exist on a given element. * exist on a given element.
*/ */
export function discoverLocalRefs(lViewData: LViewData, nodeIndex: number): {[key: string]: any}| export function discoverLocalRefs(lView: LView, nodeIndex: number): {[key: string]: any}|null {
null { const tNode = lView[TVIEW].data[nodeIndex] as TNode;
const tNode = lViewData[TVIEW].data[nodeIndex] as TNode;
if (tNode && tNode.localNames) { if (tNode && tNode.localNames) {
const result: {[key: string]: any} = {}; const result: {[key: string]: any} = {};
for (let i = 0; i < tNode.localNames.length; i += 2) { for (let i = 0; i < tNode.localNames.length; i += 2) {
const localRefName = tNode.localNames[i]; const localRefName = tNode.localNames[i];
const directiveIndex = tNode.localNames[i + 1] as number; const directiveIndex = tNode.localNames[i + 1] as number;
result[localRefName] = result[localRefName] =
directiveIndex === -1 ? getNativeByTNode(tNode, lViewData) ! : lViewData[directiveIndex]; directiveIndex === -1 ? getNativeByTNode(tNode, lView) ! : lView[directiveIndex];
} }
return result; return result;
} }

View File

@ -59,7 +59,7 @@ export function defineComponent<T>(componentDefinition: {
/** /**
* The number of nodes, local refs, and pipes in this component template. * The number of nodes, local refs, and pipes in this component template.
* *
* Used to calculate the length of this component's LViewData array, so we * Used to calculate the length of this component's LView array, so we
* can pre-fill the array and set the binding start index. * can pre-fill the array and set the binding start index.
*/ */
// TODO(kara): remove queries from this count // TODO(kara): remove queries from this count
@ -68,7 +68,7 @@ export function defineComponent<T>(componentDefinition: {
/** /**
* The number of bindings in this component template (including pure fn bindings). * The number of bindings in this component template (including pure fn bindings).
* *
* Used to calculate the length of this component's LViewData array, so we * Used to calculate the length of this component's LView array, so we
* can pre-fill the array and set the host binding start index. * can pre-fill the array and set the host binding start index.
*/ */
vars: number; vars: number;
@ -76,7 +76,7 @@ export function defineComponent<T>(componentDefinition: {
/** /**
* The number of host bindings (including pure fn bindings) in this component. * The number of host bindings (including pure fn bindings) in this component.
* *
* Used to calculate the length of the LViewData array for the *parent* component * Used to calculate the length of the LView array for the *parent* component
* of this component. * of this component.
*/ */
hostVars?: number; hostVars?: number;
@ -589,7 +589,7 @@ export const defineDirective = defineComponent as any as<T>(directiveDefinition:
/** /**
* The number of host bindings (including pure fn bindings) in this directive. * The number of host bindings (including pure fn bindings) in this directive.
* *
* Used to calculate the length of the LViewData array for the *parent* component * Used to calculate the length of the LView array for the *parent* component
* of this directive. * of this directive.
*/ */
hostVars?: number; hostVars?: number;

View File

@ -18,9 +18,9 @@ import {NG_ELEMENT_ID} from './fields';
import {DirectiveDef} from './interfaces/definition'; import {DirectiveDef} from './interfaces/definition';
import {NO_PARENT_INJECTOR, NodeInjectorFactory, PARENT_INJECTOR, RelativeInjectorLocation, RelativeInjectorLocationFlags, TNODE, isFactory} from './interfaces/injector'; import {NO_PARENT_INJECTOR, NodeInjectorFactory, PARENT_INJECTOR, RelativeInjectorLocation, RelativeInjectorLocationFlags, TNODE, isFactory} from './interfaces/injector';
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, LView, TData, TVIEW, TView} from './interfaces/view';
import {assertNodeOfPossibleTypes} from './node_assert'; import {assertNodeOfPossibleTypes} from './node_assert';
import {_getViewData, getPreviousOrParentTNode, getViewData, setTNodeAndViewData} from './state'; import {getLView, getPreviousOrParentTNode, setTNodeAndViewData} from './state';
import {getParentInjectorIndex, getParentInjectorView, hasParentInjector, isComponent, stringify} from './util'; import {getParentInjectorIndex, getParentInjectorView, hasParentInjector, isComponent, stringify} from './util';
/** /**
@ -130,7 +130,7 @@ export function bloomAdd(
* @returns Node injector * @returns Node injector
*/ */
export function getOrCreateNodeInjectorForNode( export function getOrCreateNodeInjectorForNode(
tNode: TElementNode | TContainerNode | TElementContainerNode, hostView: LViewData): number { tNode: TElementNode | TContainerNode | TElementContainerNode, hostView: LView): number {
const existingInjectorIndex = getInjectorIndex(tNode, hostView); const existingInjectorIndex = getInjectorIndex(tNode, hostView);
if (existingInjectorIndex !== -1) { if (existingInjectorIndex !== -1) {
return existingInjectorIndex; return existingInjectorIndex;
@ -150,18 +150,18 @@ export function getOrCreateNodeInjectorForNode(
const parentLoc = getParentInjectorLocation(tNode, hostView); const parentLoc = getParentInjectorLocation(tNode, hostView);
const parentIndex = getParentInjectorIndex(parentLoc); const parentIndex = getParentInjectorIndex(parentLoc);
const parentView: LViewData = getParentInjectorView(parentLoc, hostView); const parentLView = getParentInjectorView(parentLoc, hostView);
const injectorIndex = tNode.injectorIndex; const injectorIndex = tNode.injectorIndex;
// If a parent injector can't be found, its location is set to -1. // If a parent injector can't be found, its location is set to -1.
// In that case, we don't need to set up a cumulative bloom // In that case, we don't need to set up a cumulative bloom
if (hasParentInjector(parentLoc)) { if (hasParentInjector(parentLoc)) {
const parentData = parentView[TVIEW].data as any; const parentData = parentLView[TVIEW].data as any;
// Creates a cumulative bloom filter that merges the parent's bloom filter // Creates a cumulative bloom filter that merges the parent's bloom filter
// and its own cumulative bloom (which contains tokens for all ancestors) // and its own cumulative bloom (which contains tokens for all ancestors)
for (let i = 0; i < 8; i++) { for (let i = 0; i < 8; i++) {
hostView[injectorIndex + i] = parentView[parentIndex + i] | parentData[parentIndex + i]; hostView[injectorIndex + i] = parentLView[parentIndex + i] | parentData[parentIndex + i];
} }
} }
@ -174,7 +174,7 @@ function insertBloom(arr: any[], footer: TNode | null): void {
} }
export function getInjectorIndex(tNode: TNode, hostView: LViewData): number { export function getInjectorIndex(tNode: TNode, hostView: LView): number {
if (tNode.injectorIndex === -1 || if (tNode.injectorIndex === -1 ||
// If the injector index is the same as its parent's injector index, then the index has been // If the injector index is the same as its parent's injector index, then the index has been
// copied down from the parent node. No injector has been created yet on this node. // copied down from the parent node. No injector has been created yet on this node.
@ -194,7 +194,7 @@ export function getInjectorIndex(tNode: TNode, hostView: LViewData): number {
* *
* Returns a combination of number of `ViewData` we have to go up and index in that `Viewdata` * Returns a combination of number of `ViewData` we have to go up and index in that `Viewdata`
*/ */
export function getParentInjectorLocation(tNode: TNode, view: LViewData): RelativeInjectorLocation { export function getParentInjectorLocation(tNode: TNode, view: LView): RelativeInjectorLocation {
if (tNode.parent && tNode.parent.injectorIndex !== -1) { if (tNode.parent && tNode.parent.injectorIndex !== -1) {
return tNode.parent.injectorIndex as any; // ViewOffset is 0, AcrossHostBoundary is 0 return tNode.parent.injectorIndex as any; // ViewOffset is 0, AcrossHostBoundary is 0
} }
@ -227,7 +227,7 @@ export function getParentInjectorLocation(tNode: TNode, view: LViewData): Relati
* @param token The type or the injection token to be made public * @param token The type or the injection token to be made public
*/ */
export function diPublicInInjector( export function diPublicInInjector(
injectorIndex: number, view: LViewData, token: InjectionToken<any>| Type<any>): void { injectorIndex: number, view: LView, token: InjectionToken<any>| Type<any>): void {
bloomAdd(injectorIndex, view[TVIEW], token); bloomAdd(injectorIndex, view[TVIEW], token);
} }
@ -292,7 +292,7 @@ export function injectAttributeImpl(tNode: TNode, attrNameToInject: string): str
* @returns the value from the injector or `null` when not found * @returns the value from the injector or `null` when not found
*/ */
export function getOrCreateInjectable<T>( export function getOrCreateInjectable<T>(
tNode: TElementNode | TContainerNode | TElementContainerNode, lViewData: LViewData, tNode: TElementNode | TContainerNode | TElementContainerNode, lView: LView,
token: Type<T>| InjectionToken<T>, flags: InjectFlags = InjectFlags.Default, token: Type<T>| InjectionToken<T>, flags: InjectFlags = InjectFlags.Default,
notFoundValue?: any): T|null { notFoundValue?: any): T|null {
const bloomHash = bloomHashBitOrFactory(token); const bloomHash = bloomHashBitOrFactory(token);
@ -300,8 +300,8 @@ export function getOrCreateInjectable<T>(
// so just call the factory function to create it. // so just call the factory function to create it.
if (typeof bloomHash === 'function') { if (typeof bloomHash === 'function') {
const savePreviousOrParentTNode = getPreviousOrParentTNode(); const savePreviousOrParentTNode = getPreviousOrParentTNode();
const saveViewData = getViewData(); const saveLView = getLView();
setTNodeAndViewData(tNode, lViewData); setTNodeAndViewData(tNode, lView);
try { try {
const value = bloomHash(); const value = bloomHash();
if (value == null && !(flags & InjectFlags.Optional)) { if (value == null && !(flags & InjectFlags.Optional)) {
@ -310,7 +310,7 @@ export function getOrCreateInjectable<T>(
return value; return value;
} }
} finally { } finally {
setTNodeAndViewData(savePreviousOrParentTNode, saveViewData); setTNodeAndViewData(savePreviousOrParentTNode, saveLView);
} }
} else if (typeof bloomHash == 'number') { } else if (typeof bloomHash == 'number') {
// If the token has a bloom hash, then it is a token which could be in NodeInjector. // If the token has a bloom hash, then it is a token which could be in NodeInjector.
@ -318,48 +318,48 @@ export function getOrCreateInjectable<T>(
// A reference to the previous injector TView that was found while climbing the element injector // A reference to the previous injector TView that was found while climbing the element injector
// tree. This is used to know if viewProviders can be accessed on the current injector. // tree. This is used to know if viewProviders can be accessed on the current injector.
let previousTView: TView|null = null; let previousTView: TView|null = null;
let injectorIndex = getInjectorIndex(tNode, lViewData); let injectorIndex = getInjectorIndex(tNode, lView);
let parentLocation: RelativeInjectorLocation = NO_PARENT_INJECTOR; let parentLocation: RelativeInjectorLocation = NO_PARENT_INJECTOR;
// If we should skip this injector, or if there is no injector on this node, start by searching // If we should skip this injector, or if there is no injector on this node, start by searching
// the parent injector. // the parent injector.
if (injectorIndex === -1 || flags & InjectFlags.SkipSelf) { if (injectorIndex === -1 || flags & InjectFlags.SkipSelf) {
parentLocation = injectorIndex === -1 ? getParentInjectorLocation(tNode, lViewData) : parentLocation = injectorIndex === -1 ? getParentInjectorLocation(tNode, lView) :
lViewData[injectorIndex + PARENT_INJECTOR]; lView[injectorIndex + PARENT_INJECTOR];
if (!shouldSearchParent(flags, parentLocation)) { if (!shouldSearchParent(flags, parentLocation)) {
injectorIndex = -1; injectorIndex = -1;
} else { } else {
previousTView = lViewData[TVIEW]; previousTView = lView[TVIEW];
injectorIndex = getParentInjectorIndex(parentLocation); injectorIndex = getParentInjectorIndex(parentLocation);
lViewData = getParentInjectorView(parentLocation, lViewData); lView = getParentInjectorView(parentLocation, lView);
} }
} }
// Traverse up the injector tree until we find a potential match or until we know there // Traverse up the injector tree until we find a potential match or until we know there
// *isn't* a match. // *isn't* a match.
while (injectorIndex !== -1) { while (injectorIndex !== -1) {
parentLocation = lViewData[injectorIndex + PARENT_INJECTOR]; parentLocation = lView[injectorIndex + PARENT_INJECTOR];
// Check the current injector. If it matches, see if it contains token. // Check the current injector. If it matches, see if it contains token.
const tView = lViewData[TVIEW]; const tView = lView[TVIEW];
if (bloomHasToken(bloomHash, injectorIndex, tView.data)) { if (bloomHasToken(bloomHash, injectorIndex, tView.data)) {
// At this point, we have an injector which *may* contain the token, so we step through // At this point, we have an injector which *may* contain the token, so we step through
// the providers and directives associated with the injector's corresponding node to get // the providers and directives associated with the injector's corresponding node to get
// the instance. // the instance.
const instance: T|null = const instance: T|null =
searchTokensOnInjector<T>(injectorIndex, lViewData, token, previousTView); searchTokensOnInjector<T>(injectorIndex, lView, token, previousTView);
if (instance !== NOT_FOUND) { if (instance !== NOT_FOUND) {
return instance; return instance;
} }
} }
if (shouldSearchParent(flags, parentLocation) && if (shouldSearchParent(flags, parentLocation) &&
bloomHasToken(bloomHash, injectorIndex, lViewData)) { bloomHasToken(bloomHash, injectorIndex, lView)) {
// The def wasn't found anywhere on this node, so it was a false positive. // The def wasn't found anywhere on this node, so it was a false positive.
// Traverse up the tree and continue searching. // Traverse up the tree and continue searching.
previousTView = tView; previousTView = tView;
injectorIndex = getParentInjectorIndex(parentLocation); injectorIndex = getParentInjectorIndex(parentLocation);
lViewData = getParentInjectorView(parentLocation, lViewData); lView = getParentInjectorView(parentLocation, lView);
} else { } else {
// If we should not search parent OR If the ancestor bloom filter value does not have the // If we should not search parent OR If the ancestor bloom filter value does not have the
// bit corresponding to the directive we can give up on traversing up to find the specific // bit corresponding to the directive we can give up on traversing up to find the specific
@ -375,7 +375,7 @@ export function getOrCreateInjectable<T>(
} }
if ((flags & (InjectFlags.Self | InjectFlags.Host)) === 0) { if ((flags & (InjectFlags.Self | InjectFlags.Host)) === 0) {
const moduleInjector = lViewData[INJECTOR]; const moduleInjector = lView[INJECTOR];
if (moduleInjector) { if (moduleInjector) {
return moduleInjector.get(token, notFoundValue, flags & InjectFlags.Optional); return moduleInjector.get(token, notFoundValue, flags & InjectFlags.Optional);
} else { } else {
@ -392,7 +392,7 @@ export function getOrCreateInjectable<T>(
const NOT_FOUND = {}; const NOT_FOUND = {};
function searchTokensOnInjector<T>( function searchTokensOnInjector<T>(
injectorIndex: number, injectorView: LViewData, token: Type<T>| InjectionToken<T>, injectorIndex: number, injectorView: LView, token: Type<T>| InjectionToken<T>,
previousTView: TView | null) { previousTView: TView | null) {
const currentTView = injectorView[TVIEW]; const currentTView = injectorView[TVIEW];
const tNode = currentTView.data[injectorIndex + TNODE] as TNode; const tNode = currentTView.data[injectorIndex + TNODE] as TNode;
@ -425,15 +425,15 @@ function searchTokensOnInjector<T>(
* Searches for the given token among the node's directives and providers. * Searches for the given token among the node's directives and providers.
* *
* @param tNode TNode on which directives are present. * @param tNode TNode on which directives are present.
* @param view The view we are currently processing * @param lView The view we are currently processing
* @param token Provider token or type of a directive to look for. * @param token Provider token or type of a directive to look for.
* @param canAccessViewProviders Whether view providers should be considered. * @param canAccessViewProviders Whether view providers should be considered.
* @returns Index of a found directive or provider, or null when none found. * @returns Index of a found directive or provider, or null when none found.
*/ */
export function locateDirectiveOrProvider<T>( export function locateDirectiveOrProvider<T>(
tNode: TNode, view: LViewData, token: Type<T>| InjectionToken<T>, tNode: TNode, lView: LView, token: Type<T>| InjectionToken<T>,
canAccessViewProviders: boolean): number|null { canAccessViewProviders: boolean): number|null {
const tView = view[TVIEW]; const tView = lView[TVIEW];
const nodeFlags = tNode.flags; const nodeFlags = tNode.flags;
const nodeProviderIndexes = tNode.providerIndexes; const nodeProviderIndexes = tNode.providerIndexes;
const tInjectables = tView.data; const tInjectables = tView.data;
@ -463,7 +463,7 @@ export function locateDirectiveOrProvider<T>(
* instantiates the `injectable` and caches the value. * instantiates the `injectable` and caches the value.
*/ */
export function getNodeInjectable( export function getNodeInjectable(
tData: TData, lData: LViewData, index: number, tNode: TElementNode): any { tData: TData, lData: LView, index: number, tNode: TElementNode): any {
let value = lData[index]; let value = lData[index];
if (isFactory(value)) { if (isFactory(value)) {
const factory: NodeInjectorFactory = value; const factory: NodeInjectorFactory = value;
@ -477,7 +477,7 @@ export function getNodeInjectable(
previousInjectImplementation = setInjectImplementation(factory.injectImpl); previousInjectImplementation = setInjectImplementation(factory.injectImpl);
} }
const savePreviousOrParentTNode = getPreviousOrParentTNode(); const savePreviousOrParentTNode = getPreviousOrParentTNode();
const saveViewData = getViewData(); const saveLView = getLView();
setTNodeAndViewData(tNode, lData); setTNodeAndViewData(tNode, lData);
try { try {
value = lData[index] = factory.factory(null, tData, lData, tNode); value = lData[index] = factory.factory(null, tData, lData, tNode);
@ -485,7 +485,7 @@ export function getNodeInjectable(
if (factory.injectImpl) setInjectImplementation(previousInjectImplementation); if (factory.injectImpl) setInjectImplementation(previousInjectImplementation);
setIncludeViewProviders(previousIncludeViewProviders); setIncludeViewProviders(previousIncludeViewProviders);
factory.resolving = false; factory.resolving = false;
setTNodeAndViewData(savePreviousOrParentTNode, saveViewData); setTNodeAndViewData(savePreviousOrParentTNode, saveLView);
} }
} }
return value; return value;
@ -510,7 +510,7 @@ export function bloomHashBitOrFactory(token: Type<any>| InjectionToken<any>): nu
} }
export function bloomHasToken( export function bloomHasToken(
bloomHash: number, injectorIndex: number, injectorView: LViewData | TData) { bloomHash: number, injectorIndex: number, injectorView: LView | TData) {
// Create a mask that targets the specific bit associated with the directive we're looking for. // Create a mask that targets the specific bit associated with the directive we're looking for.
// JS bit operations are 32 bits, so this will be a number between 2^0 and 2^31, corresponding // JS bit operations are 32 bits, so this will be a number between 2^0 and 2^31, corresponding
// to bit positions 0 - 31 in a 32 bit integer. // to bit positions 0 - 31 in a 32 bit integer.
@ -548,21 +548,20 @@ function shouldSearchParent(flags: InjectFlags, parentLocation: RelativeInjector
export function injectInjector() { export function injectInjector() {
const tNode = getPreviousOrParentTNode() as TElementNode | TContainerNode | TElementContainerNode; const tNode = getPreviousOrParentTNode() as TElementNode | TContainerNode | TElementContainerNode;
return new NodeInjector(tNode, getViewData()); return new NodeInjector(tNode, getLView());
} }
export class NodeInjector implements Injector { export class NodeInjector implements Injector {
private _injectorIndex: number; private _injectorIndex: number;
constructor( constructor(
private _tNode: TElementNode|TContainerNode|TElementContainerNode, private _tNode: TElementNode|TContainerNode|TElementContainerNode, private _lView: LView) {
private _lView: LViewData) {
this._injectorIndex = getOrCreateNodeInjectorForNode(_tNode, _lView); this._injectorIndex = getOrCreateNodeInjectorForNode(_tNode, _lView);
} }
get(token: any): any { get(token: any): any {
const previousTNode = getPreviousOrParentTNode(); const previousTNode = getPreviousOrParentTNode();
const previousLView = _getViewData(); const previousLView = getLView();
setTNodeAndViewData(this._tNode, this._lView); setTNodeAndViewData(this._tNode, this._lView);
try { try {
return getOrCreateInjectable(this._tNode, this._lView, token); return getOrCreateInjectable(this._tNode, this._lView, token);

View File

@ -16,8 +16,8 @@ import {diPublicInInjector, getNodeInjectable, getOrCreateNodeInjectorForNode} f
import {directiveInject} from './instructions'; import {directiveInject} from './instructions';
import {NodeInjectorFactory} from './interfaces/injector'; import {NodeInjectorFactory} from './interfaces/injector';
import {TContainerNode, TElementContainerNode, TElementNode, TNodeFlags, TNodeProviderIndexes} from './interfaces/node'; import {TContainerNode, TElementContainerNode, TElementNode, TNodeFlags, TNodeProviderIndexes} from './interfaces/node';
import {LViewData, TData, TVIEW, TView} from './interfaces/view'; import {LView, TData, TVIEW, TView} from './interfaces/view';
import {getPreviousOrParentTNode, getViewData} from './state'; import {getLView, getPreviousOrParentTNode} from './state';
import {isComponentDef} from './util'; import {isComponentDef} from './util';
@ -42,8 +42,8 @@ import {isComponentDef} from './util';
*/ */
export function providersResolver<T>( export function providersResolver<T>(
def: DirectiveDef<T>, providers: Provider[], viewProviders: Provider[]): void { def: DirectiveDef<T>, providers: Provider[], viewProviders: Provider[]): void {
const viewData = getViewData(); const lView = getLView();
const tView: TView = viewData[TVIEW]; const tView: TView = lView[TVIEW];
if (tView.firstTemplatePass) { if (tView.firstTemplatePass) {
const isComponent = isComponentDef(def); const isComponent = isComponentDef(def);
@ -71,7 +71,7 @@ function resolveProvider(
provider[i], tInjectables, lInjectablesBlueprint, isComponent, isViewProvider); provider[i], tInjectables, lInjectablesBlueprint, isComponent, isViewProvider);
} }
} else { } else {
const viewData = getViewData(); const lView = getLView();
let token: any = isTypeProvider(provider) ? provider : resolveForwardRef(provider.provide); let token: any = isTypeProvider(provider) ? provider : resolveForwardRef(provider.provide);
let providerFactory: () => any = providerToFactory(provider); let providerFactory: () => any = providerToFactory(provider);
@ -92,8 +92,8 @@ function resolveProvider(
diPublicInInjector( diPublicInInjector(
getOrCreateNodeInjectorForNode( getOrCreateNodeInjectorForNode(
previousOrParentTNode as TElementNode | TContainerNode | TElementContainerNode, previousOrParentTNode as TElementNode | TContainerNode | TElementContainerNode,
viewData), lView),
viewData, token); lView, token);
tInjectables.push(token); tInjectables.push(token);
previousOrParentTNode.flags += 1 << TNodeFlags.DirectiveStartingIndexShift; previousOrParentTNode.flags += 1 << TNodeFlags.DirectiveStartingIndexShift;
if (isViewProvider) { if (isViewProvider) {
@ -101,10 +101,10 @@ function resolveProvider(
TNodeProviderIndexes.CptViewProvidersCountShifter; TNodeProviderIndexes.CptViewProvidersCountShifter;
} }
lInjectablesBlueprint.push(factory); lInjectablesBlueprint.push(factory);
viewData.push(factory); lView.push(factory);
} else { } else {
lInjectablesBlueprint[existingFactoryIndex] = factory; lInjectablesBlueprint[existingFactoryIndex] = factory;
viewData[existingFactoryIndex] = factory; lView[existingFactoryIndex] = factory;
} }
} else { } else {
// Multi provider case: // Multi provider case:
@ -143,8 +143,8 @@ function resolveProvider(
diPublicInInjector( diPublicInInjector(
getOrCreateNodeInjectorForNode( getOrCreateNodeInjectorForNode(
previousOrParentTNode as TElementNode | TContainerNode | TElementContainerNode, previousOrParentTNode as TElementNode | TContainerNode | TElementContainerNode,
viewData), lView),
viewData, token); lView, token);
const factory = multiFactory( const factory = multiFactory(
isViewProvider ? multiViewProvidersFactoryResolver : multiProvidersFactoryResolver, isViewProvider ? multiViewProvidersFactoryResolver : multiProvidersFactoryResolver,
lInjectablesBlueprint.length, isViewProvider, isComponent, providerFactory); lInjectablesBlueprint.length, isViewProvider, isComponent, providerFactory);
@ -158,7 +158,7 @@ function resolveProvider(
TNodeProviderIndexes.CptViewProvidersCountShifter; TNodeProviderIndexes.CptViewProvidersCountShifter;
} }
lInjectablesBlueprint.push(factory); lInjectablesBlueprint.push(factory);
viewData.push(factory); lView.push(factory);
} else { } else {
// Cases 1.b and 2.b // Cases 1.b and 2.b
multiFactoryAdd( multiFactoryAdd(
@ -197,8 +197,7 @@ function indexOf(item: any, arr: any[], begin: number, end: number) {
* Use this with `multi` `providers`. * Use this with `multi` `providers`.
*/ */
function multiProvidersFactoryResolver( function multiProvidersFactoryResolver(
this: NodeInjectorFactory, _: null, tData: TData, lData: LViewData, this: NodeInjectorFactory, _: null, tData: TData, lData: LView, tNode: TElementNode): any[] {
tNode: TElementNode): any[] {
return multiResolve(this.multi !, []); return multiResolve(this.multi !, []);
} }
@ -208,8 +207,7 @@ function multiProvidersFactoryResolver(
* This factory knows how to concatenate itself with the existing `multi` `providers`. * This factory knows how to concatenate itself with the existing `multi` `providers`.
*/ */
function multiViewProvidersFactoryResolver( function multiViewProvidersFactoryResolver(
this: NodeInjectorFactory, _: null, tData: TData, lData: LViewData, this: NodeInjectorFactory, _: null, tData: TData, lData: LView, tNode: TElementNode): any[] {
tNode: TElementNode): any[] {
const factories = this.multi !; const factories = this.multi !;
let result: any[]; let result: any[];
if (this.providerFactory) { if (this.providerFactory) {
@ -246,9 +244,8 @@ function multiResolve(factories: Array<() => any>, result: any[]): any[] {
* Creates a multi factory. * Creates a multi factory.
*/ */
function multiFactory( function multiFactory(
factoryFn: factoryFn: (
(this: NodeInjectorFactory, _: null, tData: TData, lData: LViewData, tNode: TElementNode) => this: NodeInjectorFactory, _: null, tData: TData, lData: LView, tNode: TElementNode) => any,
any,
index: number, isViewProvider: boolean, isComponent: boolean, index: number, isViewProvider: boolean, isComponent: boolean,
f: () => any): NodeInjectorFactory { f: () => any): NodeInjectorFactory {
const factory = new NodeInjectorFactory(factoryFn, isViewProvider, directiveInject); const factory = new NodeInjectorFactory(factoryFn, isViewProvider, directiveInject);

View File

@ -11,8 +11,8 @@ import {assertDefined} from './assert';
import {discoverLocalRefs, getComponentAtNodeIndex, getContext, getDirectivesAtNodeIndex} from './context_discovery'; import {discoverLocalRefs, getComponentAtNodeIndex, getContext, getDirectivesAtNodeIndex} from './context_discovery';
import {LContext} from './interfaces/context'; import {LContext} from './interfaces/context';
import {TElementNode} from './interfaces/node'; import {TElementNode} from './interfaces/node';
import {CONTEXT, FLAGS, HOST, LViewData, LViewFlags, PARENT, RootContext, TVIEW} from './interfaces/view'; import {CONTEXT, FLAGS, HOST, LView, LViewFlags, PARENT, RootContext, TVIEW} from './interfaces/view';
import {readPatchedLViewData, stringify} from './util'; import {readPatchedLView, stringify} from './util';
import {NodeInjector} from './view_engine_compatibility'; import {NodeInjector} from './view_engine_compatibility';
@ -42,7 +42,7 @@ export function getComponent<T = {}>(element: Element): T|null {
const context = loadContext(element) !; const context = loadContext(element) !;
if (context.component === undefined) { if (context.component === undefined) {
context.component = getComponentAtNodeIndex(context.nodeIndex, context.lViewData); context.component = getComponentAtNodeIndex(context.nodeIndex, context.lView);
} }
return context.component as T; return context.component as T;
@ -70,7 +70,7 @@ export function getComponent<T = {}>(element: Element): T|null {
*/ */
export function getViewComponent<T = {}>(element: Element | {}): T|null { export function getViewComponent<T = {}>(element: Element | {}): T|null {
const context = loadContext(element) !; const context = loadContext(element) !;
let lView: LViewData = context.lViewData; let lView: LView = context.lView;
while (lView[PARENT] && lView[HOST] === null) { while (lView[PARENT] && lView[HOST] === null) {
// As long as lView[HOST] is null we know we are part of sub-template such as `*ngIf` // As long as lView[HOST] is null we know we are part of sub-template such as `*ngIf`
lView = lView[PARENT] !; lView = lView[PARENT] !;
@ -86,10 +86,10 @@ export function getViewComponent<T = {}>(element: Element | {}): T|null {
* the application where the target is situated. * the application where the target is situated.
* *
*/ */
export function getRootContext(target: LViewData | {}): RootContext { export function getRootContext(target: LView | {}): RootContext {
const lViewData = Array.isArray(target) ? target : loadContext(target) !.lViewData; const lView = Array.isArray(target) ? target : loadContext(target) !.lView;
const rootLViewData = getRootView(lViewData); const rootLView = getRootView(lView);
return rootLViewData[CONTEXT] as RootContext; return rootLView[CONTEXT] as RootContext;
} }
/** /**
@ -114,9 +114,9 @@ export function getRootComponents(target: {}): any[] {
*/ */
export function getInjector(target: {}): Injector { export function getInjector(target: {}): Injector {
const context = loadContext(target); const context = loadContext(target);
const tNode = context.lViewData[TVIEW].data[context.nodeIndex] as TElementNode; const tNode = context.lView[TVIEW].data[context.nodeIndex] as TElementNode;
return new NodeInjector(tNode, context.lViewData); return new NodeInjector(tNode, context.lView);
} }
/** /**
@ -130,7 +130,7 @@ export function getDirectives(target: {}): Array<{}> {
const context = loadContext(target) !; const context = loadContext(target) !;
if (context.directives === undefined) { if (context.directives === undefined) {
context.directives = getDirectivesAtNodeIndex(context.nodeIndex, context.lViewData, false); context.directives = getDirectivesAtNodeIndex(context.nodeIndex, context.lView, false);
} }
return context.directives || []; return context.directives || [];
@ -154,25 +154,25 @@ export function loadContext(target: {}, throwOnNotFound: boolean = true): LConte
} }
/** /**
* Retrieve the root view from any component by walking the parent `LViewData` until * Retrieve the root view from any component by walking the parent `LView` until
* reaching the root `LViewData`. * reaching the root `LView`.
* *
* @param componentOrView any component or view * @param componentOrView any component or view
* *
*/ */
export function getRootView(componentOrView: LViewData | {}): LViewData { export function getRootView(componentOrView: LView | {}): LView {
let lViewData: LViewData; let lView: LView;
if (Array.isArray(componentOrView)) { if (Array.isArray(componentOrView)) {
ngDevMode && assertDefined(componentOrView, 'lViewData'); ngDevMode && assertDefined(componentOrView, 'lView');
lViewData = componentOrView as LViewData; lView = componentOrView as LView;
} else { } else {
ngDevMode && assertDefined(componentOrView, 'component'); ngDevMode && assertDefined(componentOrView, 'component');
lViewData = readPatchedLViewData(componentOrView) !; lView = readPatchedLView(componentOrView) !;
} }
while (lViewData && !(lViewData[FLAGS] & LViewFlags.IsRoot)) { while (lView && !(lView[FLAGS] & LViewFlags.IsRoot)) {
lViewData = lViewData[PARENT] !; lView = lView[PARENT] !;
} }
return lViewData; return lView;
} }
/** /**
@ -188,7 +188,7 @@ export function getLocalRefs(target: {}): {[key: string]: any} {
const context = loadContext(target) !; const context = loadContext(target) !;
if (context.localRefs === undefined) { if (context.localRefs === undefined) {
context.localRefs = discoverLocalRefs(context.lViewData, context.nodeIndex); context.localRefs = discoverLocalRefs(context.lView, context.nodeIndex);
} }
return context.localRefs || {}; return context.localRefs || {};

View File

@ -20,16 +20,14 @@ export function throwMultipleComponentError(tNode: TNode): never {
/** Throws an ExpressionChangedAfterChecked error if checkNoChanges mode is on. */ /** Throws an ExpressionChangedAfterChecked error if checkNoChanges mode is on. */
export function throwErrorIfNoChangesMode( export function throwErrorIfNoChangesMode(
creationMode: boolean, checkNoChangesMode: boolean, oldValue: any, currValue: any): never|void { creationMode: boolean, oldValue: any, currValue: any): never|void {
if (checkNoChangesMode) { let msg =
let msg = `ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: '${oldValue}'. Current value: '${currValue}'.`;
`ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: '${oldValue}'. Current value: '${currValue}'.`; if (creationMode) {
if (creationMode) { msg +=
msg += ` It seems like the view has been created after its parent and its children have been dirty checked.` +
` It seems like the view has been created after its parent and its children have been dirty checked.` + ` Has it been created in a change detection hook ?`;
` Has it been created in a change detection hook ?`;
}
// TODO: include debug context
throw new Error(msg);
} }
// TODO: include debug context
throw new Error(msg);
} }

View File

@ -9,7 +9,7 @@
import {assertEqual} from './assert'; import {assertEqual} from './assert';
import {DirectiveDef} from './interfaces/definition'; import {DirectiveDef} from './interfaces/definition';
import {TNodeFlags} from './interfaces/node'; import {TNodeFlags} from './interfaces/node';
import {FLAGS, HookData, LViewData, LViewFlags, TView} from './interfaces/view'; import {FLAGS, HookData, LView, LViewFlags, TView} from './interfaces/view';
/** /**
@ -20,7 +20,7 @@ import {FLAGS, HookData, LViewData, LViewFlags, TView} from './interfaces/view';
* directive index), then saved in the even indices of the initHooks array. The odd indices * directive index), then saved in the even indices of the initHooks array. The odd indices
* hold the hook functions themselves. * hold the hook functions themselves.
* *
* @param index The index of the directive in LViewData * @param index The index of the directive in LView
* @param hooks The static hooks map on the directive def * @param hooks The static hooks map on the directive def
* @param tView The current TView * @param tView The current TView
*/ */
@ -96,8 +96,7 @@ function queueDestroyHooks(def: DirectiveDef<any>, tView: TView, i: number): voi
* *
* @param currentView The current view * @param currentView The current view
*/ */
export function executeInitHooks( export function executeInitHooks(currentView: LView, tView: TView, creationMode: boolean): void {
currentView: LViewData, tView: TView, creationMode: boolean): void {
if (currentView[FLAGS] & LViewFlags.RunInit) { if (currentView[FLAGS] & LViewFlags.RunInit) {
executeHooks(currentView, tView.initHooks, tView.checkHooks, creationMode); executeHooks(currentView, tView.initHooks, tView.checkHooks, creationMode);
currentView[FLAGS] &= ~LViewFlags.RunInit; currentView[FLAGS] &= ~LViewFlags.RunInit;
@ -110,7 +109,7 @@ export function executeInitHooks(
* @param currentView The current view * @param currentView The current view
*/ */
export function executeHooks( export function executeHooks(
data: LViewData, allHooks: HookData | null, checkHooks: HookData | null, data: LView, allHooks: HookData | null, checkHooks: HookData | null,
creationMode: boolean): void { creationMode: boolean): void {
const hooksToCall = creationMode ? allHooks : checkHooks; const hooksToCall = creationMode ? allHooks : checkHooks;
if (hooksToCall) { if (hooksToCall) {

View File

@ -166,7 +166,7 @@ const i18nUpdateOpCodes = <I18nUpdateOpCodes>[
// has changed then execute update OpCodes. // has changed then execute update OpCodes.
// has NOT changed then skip `7` values and start processing next OpCodes. // has NOT changed then skip `7` values and start processing next OpCodes.
0b1, 7, 0b1, 7,
// Concatenate `newValue = 'Hello ' + lViewData[bindIndex-1] + '!';`. // Concatenate `newValue = 'Hello ' + lView[bindIndex-1] + '!';`.
'Hello ', // accumulate('Hello '); 'Hello ', // accumulate('Hello ');
-1, // accumulate(-1); -1, // accumulate(-1);
'!', // accumulate('!'); '!', // accumulate('!');
@ -305,13 +305,13 @@ const tI18n = <TI18n>{
create: <I18nMutateOpCodes>[ // Processed by `i18nEnd` create: <I18nMutateOpCodes>[ // Processed by `i18nEnd`
// Equivalent to: // Equivalent to:
// // Assume expandoIndex = 100; // // Assume expandoIndex = 100;
// const node = lViewData[expandoIndex++] = document.createTextNode(''); // const node = lView[expandoIndex++] = document.createTextNode('');
// lViewData[2].insertBefore(node, lViewData[3]); // lView[2].insertBefore(node, lView[3]);
"", 2 << SHIFT_PARENT | 3 << SHIFT_REF | InsertBefore, "", 2 << SHIFT_PARENT | 3 << SHIFT_REF | InsertBefore,
// Equivalent to: // Equivalent to:
// // Assume expandoIndex = 101; // // Assume expandoIndex = 101;
// const node = lViewData[expandoIndex++] = document.createTextNode('.'); // const node = lView[expandoIndex++] = document.createTextNode('.');
// lViewData[0].appendChild(node); // lView[0].appendChild(node);
'.', 2 << SHIFT_PARENT | AppendChild, '.', 2 << SHIFT_PARENT | AppendChild,
], ],
update: <I18nUpdateOpCodes>[ // Processed by `i18nApply` update: <I18nUpdateOpCodes>[ // Processed by `i18nApply`
@ -323,7 +323,7 @@ const tI18n = <TI18n>{
-1, // accumulate(-1); -1, // accumulate(-1);
'is rendered as: ', // accumulate('is rendered as: '); 'is rendered as: ', // accumulate('is rendered as: ');
// Flush the concatenated string to text node at position 100. // Flush the concatenated string to text node at position 100.
100 << SHIFT_REF | Text, // lViewData[100].textContent = accumulatorFlush(); 100 << SHIFT_REF | Text, // lView[100].textContent = accumulatorFlush();
], ],
icus: null, icus: null,
} }
@ -369,8 +369,8 @@ const tI18n = <TI18n>{
create: <I18nMutateOpCodes>[ create: <I18nMutateOpCodes>[
// Equivalent to: // Equivalent to:
// // Assume expandoIndex = 200; // // Assume expandoIndex = 200;
// const node = lViewData[expandoIndex++] = document.createComment(''); // const node = lView[expandoIndex++] = document.createComment('');
// lViewData[1].appendChild(node); // lView[1].appendChild(node);
COMMENT_MARKER, '', 1 << SHIFT_PARENT | AppendChild, COMMENT_MARKER, '', 1 << SHIFT_PARENT | AppendChild,
], ],
update: <I18nUpdateOpCodes>[ update: <I18nUpdateOpCodes>[
@ -380,12 +380,12 @@ const tI18n = <TI18n>{
// has NOT changed then skip `2` values and start processing next OpCodes. // has NOT changed then skip `2` values and start processing next OpCodes.
0b1, 2, 0b1, 2,
-1, // accumulate(-1); -1, // accumulate(-1);
// Switch ICU: `icuSwitchCase(lViewData[200 /*SHIFT_REF*/], 0 /*SHIFT_ICU*/, accumulatorFlush());` // Switch ICU: `icuSwitchCase(lView[200 /*SHIFT_REF*/], 0 /*SHIFT_ICU*/, accumulatorFlush());`
200 << SHIFT_REF | 0 << SHIFT_ICU | IcuSwitch, 200 << SHIFT_REF | 0 << SHIFT_ICU | IcuSwitch,
// NOTE: the bit mask here is the logical OR of all of the masks in the ICU. // NOTE: the bit mask here is the logical OR of all of the masks in the ICU.
0b1, 1, 0b1, 1,
// Update ICU: `icuUpdateCase(lViewData[200 /*SHIFT_REF*/], 0 /*SHIFT_ICU*/);` // Update ICU: `icuUpdateCase(lView[200 /*SHIFT_REF*/], 0 /*SHIFT_ICU*/);`
// SHIFT_REF: points to: `i18nStart(0, MSG_div, 1);` // SHIFT_REF: points to: `i18nStart(0, MSG_div, 1);`
// SHIFT_ICU: is an index into which ICU is being updated. In our example we only have // SHIFT_ICU: is an index into which ICU is being updated. In our example we only have
// one ICU so it is 0-th ICU to update. // one ICU so it is 0-th ICU to update.
@ -401,75 +401,75 @@ const tI18n = <TI18n>{
// Case: `0`: `{no <b title="none">emails</b>!}` // Case: `0`: `{no <b title="none">emails</b>!}`
<I18nMutateOpCodes>[ <I18nMutateOpCodes>[
// // assume expandoIndex == 203 // // assume expandoIndex == 203
// const node = lViewData[expandoIndex++] = document.createTextNode('no '); // const node = lView[expandoIndex++] = document.createTextNode('no ');
// lViewData[1].appendChild(node); // lView[1].appendChild(node);
'no ', 1 << SHIFT_PARENT | AppendChild, 'no ', 1 << SHIFT_PARENT | AppendChild,
// Equivalent to: // Equivalent to:
// // assume expandoIndex == 204 // // assume expandoIndex == 204
// const node = lViewData[expandoIndex++] = document.createElement('b'); // const node = lView[expandoIndex++] = document.createElement('b');
// lViewData[1].appendChild(node); // lView[1].appendChild(node);
ELEMENT_MARKER, 'b', 1 << SHIFT_PARENT | AppendChild, ELEMENT_MARKER, 'b', 1 << SHIFT_PARENT | AppendChild,
// const node = lViewData[204]; // const node = lView[204];
// node.setAttribute('title', 'none'); // node.setAttribute('title', 'none');
204 << SHIFT_REF | Select, 'title', 'none' 204 << SHIFT_REF | Select, 'title', 'none'
// // assume expandoIndex == 205 // // assume expandoIndex == 205
// const node = lViewData[expandoIndex++] = document.createTextNode('email'); // const node = lView[expandoIndex++] = document.createTextNode('email');
// lViewData[1].appendChild(node); // lView[1].appendChild(node);
'email', 204 << SHIFT_PARENT | AppendChild, 'email', 204 << SHIFT_PARENT | AppendChild,
] ]
// Case: `1`: `{one <i>email</i>}` // Case: `1`: `{one <i>email</i>}`
<I18nMutateOpCodes>[ <I18nMutateOpCodes>[
// // assume expandoIndex == 203 // // assume expandoIndex == 203
// const node = lViewData[expandoIndex++] = document.createTextNode('no '); // const node = lView[expandoIndex++] = document.createTextNode('no ');
// lViewData[1].appendChild(node, lViewData[2]); // lView[1].appendChild(node, lView[2]);
'one ', 1 << SHIFT_PARENT | AppendChild, 'one ', 1 << SHIFT_PARENT | AppendChild,
// Equivalent to: // Equivalent to:
// // assume expandoIndex == 204 // // assume expandoIndex == 204
// const node = lViewData[expandoIndex++] = document.createElement('b'); // const node = lView[expandoIndex++] = document.createElement('b');
// lViewData[1].appendChild(node); // lView[1].appendChild(node);
ELEMENT_MARKER, 'i', 1 << SHIFT_PARENT | AppendChild, ELEMENT_MARKER, 'i', 1 << SHIFT_PARENT | AppendChild,
// // assume expandoIndex == 205 // // assume expandoIndex == 205
// const node = lViewData[expandoIndex++] = document.createTextNode('email'); // const node = lView[expandoIndex++] = document.createTextNode('email');
// lViewData[1].appendChild(node); // lView[1].appendChild(node);
'email', 204 << SHIFT_PARENT | AppendChild, 'email', 204 << SHIFT_PARENT | AppendChild,
] ]
// Case: `"other"`: `{<7B>0<EFBFBD> <span title="<22>0<EFBFBD>">emails</span>}` // Case: `"other"`: `{<7B>0<EFBFBD> <span title="<22>0<EFBFBD>">emails</span>}`
<I18nMutateOpCodes>[ <I18nMutateOpCodes>[
// // assume expandoIndex == 203 // // assume expandoIndex == 203
// const node = lViewData[expandoIndex++] = document.createTextNode(''); // const node = lView[expandoIndex++] = document.createTextNode('');
// lViewData[1].appendChild(node); // lView[1].appendChild(node);
'', 1 << SHIFT_PARENT | AppendChild, '', 1 << SHIFT_PARENT | AppendChild,
// Equivalent to: // Equivalent to:
// // assume expandoIndex == 204 // // assume expandoIndex == 204
// const node = lViewData[expandoIndex++] = document.createComment('span'); // const node = lView[expandoIndex++] = document.createComment('span');
// lViewData[1].appendChild(node); // lView[1].appendChild(node);
ELEMENT_MARKER, 'span', 1 << SHIFT_PARENT | AppendChild, ELEMENT_MARKER, 'span', 1 << SHIFT_PARENT | AppendChild,
// // assume expandoIndex == 205 // // assume expandoIndex == 205
// const node = lViewData[expandoIndex++] = document.createTextNode('emails'); // const node = lView[expandoIndex++] = document.createTextNode('emails');
// lViewData[1].appendChild(node); // lView[1].appendChild(node);
'emails', 204 << SHIFT_PARENT | AppendChild, 'emails', 204 << SHIFT_PARENT | AppendChild,
] ]
], ],
remove: [ remove: [
// Case: `0`: `{no <b title="none">emails</b>!}` // Case: `0`: `{no <b title="none">emails</b>!}`
<I18nMutateOpCodes>[ <I18nMutateOpCodes>[
// lViewData[1].remove(lViewData[203]); // lView[1].remove(lView[203]);
1 << SHIFT_PARENT | 203 << SHIFT_REF | Remove, 1 << SHIFT_PARENT | 203 << SHIFT_REF | Remove,
// lViewData[1].remove(lViewData[204]); // lView[1].remove(lView[204]);
1 << SHIFT_PARENT | 204 << SHIFT_REF | Remove, 1 << SHIFT_PARENT | 204 << SHIFT_REF | Remove,
] ]
// Case: `1`: `{one <i>email</i>}` // Case: `1`: `{one <i>email</i>}`
<I18nMutateOpCodes>[ <I18nMutateOpCodes>[
// lViewData[1].remove(lViewData[203]); // lView[1].remove(lView[203]);
1 << SHIFT_PARENT | 203 << SHIFT_REF | Remove, 1 << SHIFT_PARENT | 203 << SHIFT_REF | Remove,
// lViewData[1].remove(lViewData[204]); // lView[1].remove(lView[204]);
1 << SHIFT_PARENT | 204 << SHIFT_REF | Remove, 1 << SHIFT_PARENT | 204 << SHIFT_REF | Remove,
] ]
// Case: `"other"`: `{<7B>0<EFBFBD> <span title="<22>0<EFBFBD>">emails</span>}` // Case: `"other"`: `{<7B>0<EFBFBD> <span title="<22>0<EFBFBD>">emails</span>}`
<I18nMutateOpCodes>[ <I18nMutateOpCodes>[
// lViewData[1].remove(lViewData[203]); // lView[1].remove(lView[203]);
1 << SHIFT_PARENT | 203 << SHIFT_REF | Remove, 1 << SHIFT_PARENT | 203 << SHIFT_REF | Remove,
// lViewData[1].remove(lViewData[204]); // lView[1].remove(lView[204]);
1 << SHIFT_PARENT | 204 << SHIFT_REF | Remove, 1 << SHIFT_PARENT | 204 << SHIFT_REF | Remove,
] ]
], ],
@ -496,9 +496,9 @@ const tI18n = <TI18n>{
// has changed then execute update OpCodes. // has changed then execute update OpCodes.
// has NOT changed then skip `4` values and start processing next OpCodes. // has NOT changed then skip `4` values and start processing next OpCodes.
0b1, 4, 0b1, 4,
// Concatenate `newValue = '' + lViewData[bindIndex -1];`. // Concatenate `newValue = '' + lView[bindIndex -1];`.
-1, // accumulate(-1); -1, // accumulate(-1);
// Update attribute: `lViewData[204].setAttribute(204, 'title', 0b1, 2,(null));` // Update attribute: `lView[204].setAttribute(204, 'title', 0b1, 2,(null));`
// NOTE: `null` implies no sanitization. // NOTE: `null` implies no sanitization.
204 << SHIFT_REF | Attr, 'title', null 204 << SHIFT_REF | Attr, 'title', null
] ]
@ -555,12 +555,12 @@ const tI18n = <TI18n>{
// if (first_execution_for_tview) { // if (first_execution_for_tview) {
// ngDevMode && assertEquals(tView.blueprint.length, expandoIndex); // ngDevMode && assertEquals(tView.blueprint.length, expandoIndex);
// tView.blueprint.push(null); // tView.blueprint.push(null);
// ngDevMode && assertEquals(lViewData.length, expandoIndex); // ngDevMode && assertEquals(lView.length, expandoIndex);
// lViewData.push(node); // lView.push(node);
// } else { // } else {
// lViewData[expandoIndex] = node; // save expandoIndex == 100; // lView[expandoIndex] = node; // save expandoIndex == 100;
// } // }
// lViewData[0].appendChild(node); // lView[0].appendChild(node);
// expandoIndex++; // expandoIndex++;
"", 0 << SHIFT_PARENT | AppendChild, "", 0 << SHIFT_PARENT | AppendChild,
], ],
@ -636,14 +636,14 @@ const tI18n = <TI18n>{
// has NOT changed then skip `2` values and start processing next OpCodes. // has NOT changed then skip `2` values and start processing next OpCodes.
0b1, 2, 0b1, 2,
-1, // accumulate(-1) -1, // accumulate(-1)
// Switch ICU: `icuSwitchCase(lViewData[200 /*SHIFT_REF*/], 0 /*SHIFT_ICU*/, accumulatorFlush());` // Switch ICU: `icuSwitchCase(lView[200 /*SHIFT_REF*/], 0 /*SHIFT_ICU*/, accumulatorFlush());`
200 << SHIFT_REF | 0 << SHIFT_ICU | IcuSwitch, 200 << SHIFT_REF | 0 << SHIFT_ICU | IcuSwitch,
// NOTE: the bit mask here is the logical OR of all of the masks in the ICU. // NOTE: the bit mask here is the logical OR of all of the masks in the ICU.
0b1, 4, 0b1, 4,
'You have ', // accumulate('You have '); 'You have ', // accumulate('You have ');
// Update ICU: `icuUpdateCase(lViewData[200 /*SHIFT_REF*/], 0 /*SHIFT_ICU*/);` // Update ICU: `icuUpdateCase(lView[200 /*SHIFT_REF*/], 0 /*SHIFT_ICU*/);`
// SHIFT_REF: points to: `i18nStart(0, MSG_div, 1);` // SHIFT_REF: points to: `i18nStart(0, MSG_div, 1);`
// SHIFT_ICU: is an index into which ICU is being updated. In our example we only have // SHIFT_ICU: is an index into which ICU is being updated. In our example we only have
// one ICU so it is 0-th ICU to update. // one ICU so it is 0-th ICU to update.
@ -700,7 +700,7 @@ const tI18n = <TI18n>{
// has changed then execute update OpCodes. // has changed then execute update OpCodes.
// has NOT changed then skip `1` values and start processing next OpCodes. // has NOT changed then skip `1` values and start processing next OpCodes.
-1, 2, -1, 2,
-1, // accumulate(lViewData[bindIndex-1]); -1, // accumulate(lView[bindIndex-1]);
'emails', // accumulate('no emails'); 'emails', // accumulate('no emails');
] ]
] ]
@ -789,8 +789,8 @@ const tI18n = <TI18n>{
expandoStartIndex: 100, // Assume in this example EXPANDO starts at 100 expandoStartIndex: 100, // Assume in this example EXPANDO starts at 100
create: <I18nMutateOpCodes>[ // Processed by `i18nEnd` create: <I18nMutateOpCodes>[ // Processed by `i18nEnd`
// Equivalent to: // Equivalent to:
// const node = lViewData[expandoIndex++] = document.createTextNode(''); // const node = lView[expandoIndex++] = document.createTextNode('');
// lViewData[0].insertBefore(node, lViewData[3]); // lView[0].insertBefore(node, lView[3]);
"Translated text", 0 << SHIFT_PARENT | AppendChild, "Translated text", 0 << SHIFT_PARENT | AppendChild,
], ],
update: <I18nUpdateOpCodes>[ ], update: <I18nUpdateOpCodes>[ ],
@ -799,8 +799,8 @@ const tI18n = <TI18n>{
``` ```
RESOLVE: RESOLVE:
- One way we could solve it is by `i18nStart` would store an object in `LViewData` at its position which would implement `RNode` but which would handle the corner case of inserting into a synthetic parent. - One way we could solve it is by `i18nStart` would store an object in `LView` at its position which would implement `RNode` but which would handle the corner case of inserting into a synthetic parent.
- Another way this could be implemented is for `i18nStore` to leave a marker in the `LViewData` which would tell the OpCode processor that it is dealing with a synthetic parent. - Another way this could be implemented is for `i18nStore` to leave a marker in the `LView` which would tell the OpCode processor that it is dealing with a synthetic parent.
## Nested ICUs ## Nested ICUs
@ -882,12 +882,12 @@ const tI18n = <TI18n>{
// has NOT changed then skip `2` values and start processing next OpCodes. // has NOT changed then skip `2` values and start processing next OpCodes.
0b1, 2, 0b1, 2,
-1, // accumulate(-1); -1, // accumulate(-1);
// Switch ICU: `icuSwitchCase(lViewData[100 /*SHIFT_REF*/], 0 /*SHIFT_ICU*/, accumulatorFlush());` // Switch ICU: `icuSwitchCase(lView[100 /*SHIFT_REF*/], 0 /*SHIFT_ICU*/, accumulatorFlush());`
100 << SHIFT_REF | 0 << SHIFT_ICU | IcuSwitch, 100 << SHIFT_REF | 0 << SHIFT_ICU | IcuSwitch,
// NOTE: the bit mask here is the logical OR of all of the masks in the ICU. // NOTE: the bit mask here is the logical OR of all of the masks in the ICU.
0b1, 1, 0b1, 1,
// Update ICU: `icuUpdateCase(lViewData[100 /*SHIFT_REF*/], 0 /*SHIFT_ICU*/);` // Update ICU: `icuUpdateCase(lView[100 /*SHIFT_REF*/], 0 /*SHIFT_ICU*/);`
// SHIFT_REF: points to: `i18nStart(0, MSG_div, 1);` // SHIFT_REF: points to: `i18nStart(0, MSG_div, 1);`
// SHIFT_ICU: is an index into which ICU is being updated. In our example we only have // SHIFT_ICU: is an index into which ICU is being updated. In our example we only have
// one ICU so it is 0-th ICU to update. // one ICU so it is 0-th ICU to update.
@ -925,12 +925,12 @@ const tI18n = <TI18n>{
-2, ' ', 100 << SHIFT_REF | Text, // Case: `<60>0<EFBFBD> ` -2, ' ', 100 << SHIFT_REF | Text, // Case: `<60>0<EFBFBD> `
0b10, 5, 0b10, 5,
-1, -1,
// Switch ICU: `icuSwitchCase(lViewData[101 /*SHIFT_REF*/], 0 /*SHIFT_ICU*/, accumulatorFlush());` // Switch ICU: `icuSwitchCase(lView[101 /*SHIFT_REF*/], 0 /*SHIFT_ICU*/, accumulatorFlush());`
101 << SHIFT_REF | 0 << SHIFT_ICU | IcuSwitch, 101 << SHIFT_REF | 0 << SHIFT_ICU | IcuSwitch,
// NOTE: the bit mask here is the logical OR of all of the masks int the ICU. // NOTE: the bit mask here is the logical OR of all of the masks int the ICU.
0b10, 1, 0b10, 1,
// Update ICU: `icuUpdateCase(lViewData[101 /*SHIFT_REF*/], 0 /*SHIFT_ICU*/);` // Update ICU: `icuUpdateCase(lView[101 /*SHIFT_REF*/], 0 /*SHIFT_ICU*/);`
101 << SHIFT_REF | 0 << SHIFT_ICU | IcuUpdate, 101 << SHIFT_REF | 0 << SHIFT_ICU | IcuUpdate,
], ],
] ]

View File

@ -9,6 +9,7 @@
import {SRCSET_ATTRS, URI_ATTRS, VALID_ATTRS, VALID_ELEMENTS, getTemplateContent} from '../sanitization/html_sanitizer'; import {SRCSET_ATTRS, URI_ATTRS, VALID_ATTRS, VALID_ELEMENTS, getTemplateContent} from '../sanitization/html_sanitizer';
import {InertBodyHelper} from '../sanitization/inert_body'; import {InertBodyHelper} from '../sanitization/inert_body';
import {_sanitizeUrl, sanitizeSrcset} from '../sanitization/url_sanitizer'; import {_sanitizeUrl, sanitizeSrcset} from '../sanitization/url_sanitizer';
import {assertDefined, assertEqual, assertGreaterThan} from './assert'; import {assertDefined, assertEqual, assertGreaterThan} from './assert';
import {allocExpando, createNodeAtIndex, elementAttribute, load, textBinding} from './instructions'; import {allocExpando, createNodeAtIndex, elementAttribute, load, textBinding} from './instructions';
import {LContainer, NATIVE, RENDER_PARENT} from './interfaces/container'; import {LContainer, NATIVE, RENDER_PARENT} from './interfaces/container';
@ -17,9 +18,9 @@ import {TElementNode, TIcuContainerNode, TNode, TNodeType} from './interfaces/no
import {RComment, RElement} from './interfaces/renderer'; import {RComment, RElement} from './interfaces/renderer';
import {SanitizerFn} from './interfaces/sanitization'; import {SanitizerFn} from './interfaces/sanitization';
import {StylingContext} from './interfaces/styling'; import {StylingContext} from './interfaces/styling';
import {BINDING_INDEX, HEADER_OFFSET, HOST_NODE, LViewData, TVIEW, TView} from './interfaces/view'; import {BINDING_INDEX, HEADER_OFFSET, HOST_NODE, LView, RENDERER, TVIEW, TView} from './interfaces/view';
import {appendChild, createTextNode, removeChild} from './node_manipulation'; import {appendChild, createTextNode, removeChild} from './node_manipulation';
import {_getViewData, getIsParent, getPreviousOrParentTNode, getRenderer, getTView, setIsParent, setPreviousOrParentTNode} from './state'; import {getIsParent, getLView, getPreviousOrParentTNode, setIsParent, setPreviousOrParentTNode} from './state';
import {NO_CHANGE} from './tokens'; import {NO_CHANGE} from './tokens';
import {addAllToArray, getNativeByIndex, getNativeByTNode, getTNode, isLContainer, stringify} from './util'; import {addAllToArray, getNativeByIndex, getNativeByTNode, getTNode, isLContainer, stringify} from './util';
@ -334,7 +335,7 @@ const parentIndexStack: number[] = [];
* @param subTemplateIndex Optional sub-template index in the `message`. * @param subTemplateIndex Optional sub-template index in the `message`.
*/ */
export function i18nStart(index: number, message: string, subTemplateIndex?: number): void { export function i18nStart(index: number, message: string, subTemplateIndex?: number): void {
const tView = getTView(); const tView = getLView()[TVIEW];
ngDevMode && assertDefined(tView, `tView should be defined`); ngDevMode && assertDefined(tView, `tView should be defined`);
ngDevMode && ngDevMode &&
assertEqual( assertEqual(
@ -350,7 +351,7 @@ export function i18nStart(index: number, message: string, subTemplateIndex?: num
function i18nStartFirstPass( function i18nStartFirstPass(
tView: TView, index: number, message: string, subTemplateIndex?: number) { tView: TView, index: number, message: string, subTemplateIndex?: number) {
i18nIndexStack[++i18nIndexStackPointer] = index; i18nIndexStack[++i18nIndexStackPointer] = index;
const viewData = _getViewData(); const viewData = getLView();
const expandoStartIndex = tView.blueprint.length - HEADER_OFFSET; const expandoStartIndex = tView.blueprint.length - HEADER_OFFSET;
const previousOrParentTNode = getPreviousOrParentTNode(); const previousOrParentTNode = getPreviousOrParentTNode();
const parentTNode = getIsParent() ? getPreviousOrParentTNode() : const parentTNode = getIsParent() ? getPreviousOrParentTNode() :
@ -457,7 +458,7 @@ function i18nStartFirstPass(
function appendI18nNode(tNode: TNode, parentTNode: TNode, previousTNode: TNode | null): TNode { function appendI18nNode(tNode: TNode, parentTNode: TNode, previousTNode: TNode | null): TNode {
ngDevMode && ngDevMode.rendererMoveNode++; ngDevMode && ngDevMode.rendererMoveNode++;
const viewData = _getViewData(); const viewData = getLView();
if (!previousTNode) { if (!previousTNode) {
previousTNode = parentTNode; previousTNode = parentTNode;
} }
@ -563,7 +564,7 @@ export function i18nPostprocess(
* into the render tree, moves the placeholder nodes and removes the deleted nodes. * into the render tree, moves the placeholder nodes and removes the deleted nodes.
*/ */
export function i18nEnd(): void { export function i18nEnd(): void {
const tView = getTView(); const tView = getLView()[TVIEW];
ngDevMode && assertDefined(tView, `tView should be defined`); ngDevMode && assertDefined(tView, `tView should be defined`);
ngDevMode && ngDevMode &&
assertEqual( assertEqual(
@ -577,7 +578,7 @@ export function i18nEnd(): void {
* See `i18nEnd` above. * See `i18nEnd` above.
*/ */
function i18nEndFirstPass(tView: TView) { function i18nEndFirstPass(tView: TView) {
const viewData = _getViewData(); const viewData = getLView();
ngDevMode && assertEqual( ngDevMode && assertEqual(
viewData[BINDING_INDEX], viewData[TVIEW].bindingStartIndex, viewData[BINDING_INDEX], viewData[TVIEW].bindingStartIndex,
'i18nEnd should be called before any binding'); 'i18nEnd should be called before any binding');
@ -602,8 +603,8 @@ function i18nEndFirstPass(tView: TView) {
function readCreateOpCodes( function readCreateOpCodes(
index: number, createOpCodes: I18nMutateOpCodes, expandoStartIndex: number, index: number, createOpCodes: I18nMutateOpCodes, expandoStartIndex: number,
viewData: LViewData): number[] { viewData: LView): number[] {
const renderer = getRenderer(); const renderer = getLView()[RENDERER];
let currentTNode: TNode|null = null; let currentTNode: TNode|null = null;
let previousTNode: TNode|null = null; let previousTNode: TNode|null = null;
const visitedPlaceholders: number[] = []; const visitedPlaceholders: number[] = [];
@ -702,7 +703,7 @@ function readCreateOpCodes(
function readUpdateOpCodes( function readUpdateOpCodes(
updateOpCodes: I18nUpdateOpCodes, icus: TIcu[] | null, bindingsStartIndex: number, updateOpCodes: I18nUpdateOpCodes, icus: TIcu[] | null, bindingsStartIndex: number,
changeMask: number, viewData: LViewData, bypassCheckBit = false) { changeMask: number, viewData: LView, bypassCheckBit = false) {
let caseCreated = false; let caseCreated = false;
for (let i = 0; i < updateOpCodes.length; i++) { for (let i = 0; i < updateOpCodes.length; i++) {
// bit code to check if we should apply the next update // bit code to check if we should apply the next update
@ -786,7 +787,7 @@ function readUpdateOpCodes(
} }
} }
function removeNode(index: number, viewData: LViewData) { function removeNode(index: number, viewData: LView) {
const removedPhTNode = getTNode(index, viewData); const removedPhTNode = getTNode(index, viewData);
const removedPhRNode = getNativeByIndex(index, viewData); const removedPhRNode = getNativeByIndex(index, viewData);
removeChild(removedPhTNode, removedPhRNode || null, viewData); removeChild(removedPhTNode, removedPhRNode || null, viewData);
@ -839,7 +840,7 @@ export function i18n(index: number, message: string, subTemplateIndex?: number):
* @param values * @param values
*/ */
export function i18nAttributes(index: number, values: string[]): void { export function i18nAttributes(index: number, values: string[]): void {
const tView = getTView(); const tView = getLView()[TVIEW];
ngDevMode && assertDefined(tView, `tView should be defined`); ngDevMode && assertDefined(tView, `tView should be defined`);
ngDevMode && ngDevMode &&
assertEqual( assertEqual(
@ -906,9 +907,9 @@ export function i18nExp<T>(expression: T | NO_CHANGE): void {
*/ */
export function i18nApply(index: number) { export function i18nApply(index: number) {
if (shiftsCounter) { if (shiftsCounter) {
const tView = getTView(); const lView = getLView();
const tView = lView[TVIEW];
ngDevMode && assertDefined(tView, `tView should be defined`); ngDevMode && assertDefined(tView, `tView should be defined`);
const viewData = _getViewData();
const tI18n = tView.data[index + HEADER_OFFSET]; const tI18n = tView.data[index + HEADER_OFFSET];
let updateOpCodes: I18nUpdateOpCodes; let updateOpCodes: I18nUpdateOpCodes;
let icus: TIcu[]|null = null; let icus: TIcu[]|null = null;
@ -918,8 +919,8 @@ export function i18nApply(index: number) {
updateOpCodes = (tI18n as TI18n).update; updateOpCodes = (tI18n as TI18n).update;
icus = (tI18n as TI18n).icus; icus = (tI18n as TI18n).icus;
} }
const bindingsStartIndex = viewData[BINDING_INDEX] - shiftsCounter - 1; const bindingsStartIndex = lView[BINDING_INDEX] - shiftsCounter - 1;
readUpdateOpCodes(updateOpCodes, icus, bindingsStartIndex, changeMask, viewData); readUpdateOpCodes(updateOpCodes, icus, bindingsStartIndex, changeMask, lView);
// Reset changeMask & maskBit to default for the next update cycle // Reset changeMask & maskBit to default for the next update cycle
changeMask = 0b0; changeMask = 0b0;
@ -1348,10 +1349,10 @@ function icuStart(
update: updateCodes update: updateCodes
}; };
tIcus.push(tIcu); tIcus.push(tIcu);
const lViewData = _getViewData(); const lView = getLView();
const worstCaseSize = Math.max(...vars); const worstCaseSize = Math.max(...vars);
for (let i = 0; i < worstCaseSize; i++) { for (let i = 0; i < worstCaseSize; i++) {
allocExpando(lViewData); allocExpando(lView);
} }
} }

View File

@ -78,10 +78,11 @@ export {
directiveInject, directiveInject,
injectAttribute, injectAttribute,
getCurrentView
} from './instructions'; } from './instructions';
export { export {
getCurrentView,
restoreView, restoreView,
enableBindings, enableBindings,

File diff suppressed because it is too large Load Diff

View File

@ -9,7 +9,7 @@
import {LQueries} from './query'; import {LQueries} from './query';
import {RComment, RElement} from './renderer'; import {RComment, RElement} from './renderer';
import {StylingContext} from './styling'; import {StylingContext} from './styling';
import {HOST, LViewData, NEXT, PARENT, QUERIES} from './view'; import {HOST, LView, NEXT, PARENT, QUERIES} from './view';
/** /**
@ -20,14 +20,14 @@ import {HOST, LViewData, NEXT, PARENT, QUERIES} from './view';
export const ACTIVE_INDEX = 0; export const ACTIVE_INDEX = 0;
export const VIEWS = 1; export const VIEWS = 1;
// PARENT, NEXT, QUERIES, and HOST are indices 2, 3, 4, and 5. // PARENT, NEXT, QUERIES, and HOST are indices 2, 3, 4, and 5.
// As we already have these constants in LViewData, we don't need to re-create them. // As we already have these constants in LView, we don't need to re-create them.
export const NATIVE = 6; export const NATIVE = 6;
export const RENDER_PARENT = 7; export const RENDER_PARENT = 7;
/** /**
* The state associated with a container. * The state associated with a container.
* *
* This is an array so that its structure is closer to LViewData. This helps * This is an array so that its structure is closer to LView. This helps
* when traversing the view tree (which is a mix of containers and component * when traversing the view tree (which is a mix of containers and component
* views), so we can jump to viewOrContainer[NEXT] in the same way regardless * views), so we can jump to viewOrContainer[NEXT] in the same way regardless
* of type. * of type.
@ -49,19 +49,19 @@ export interface LContainer extends Array<any> {
* (and don't need to be re-added) and so we can remove views from the DOM when they * (and don't need to be re-added) and so we can remove views from the DOM when they
* are no longer required. * are no longer required.
*/ */
[VIEWS]: LViewData[]; [VIEWS]: LView[];
/** /**
* Access to the parent view is necessary so we can propagate back * Access to the parent view is necessary so we can propagate back
* up from inside a container to parent[NEXT]. * up from inside a container to parent[NEXT].
*/ */
[PARENT]: LViewData|null; [PARENT]: LView|null;
/** /**
* This allows us to jump from a container to a sibling container or component * This allows us to jump from a container to a sibling container or component
* view with the same parent, so we can remove listeners efficiently. * view with the same parent, so we can remove listeners efficiently.
*/ */
[NEXT]: LViewData|LContainer|null; [NEXT]: LView|LContainer|null;
/** /**
* Queries active for this container - all the views inserted to / removed from * Queries active for this container - all the views inserted to / removed from
@ -72,13 +72,13 @@ export interface LContainer extends Array<any> {
/** /**
* The host element of this LContainer. * The host element of this LContainer.
* *
* The host could be an LViewData if this container is on a component node. * The host could be an LView if this container is on a component node.
* In that case, the component LViewData is its HOST. * In that case, the component LView is its HOST.
* *
* It could also be a styling context if this is a node with a style/class * It could also be a styling context if this is a node with a style/class
* binding. * binding.
*/ */
[HOST]: RElement|RComment|StylingContext|LViewData; [HOST]: RElement|RComment|StylingContext|LView;
/** The comment element that serves as an anchor for this LContainer. */ /** The comment element that serves as an anchor for this LContainer. */
[NATIVE]: RComment; [NATIVE]: RComment;

View File

@ -8,7 +8,7 @@
import {RElement} from './renderer'; import {RElement} from './renderer';
import {LViewData} from './view'; import {LView} from './view';
/** /**
* This property will be monkey-patched on elements, components and directives * This property will be monkey-patched on elements, components and directives
@ -17,7 +17,7 @@ export const MONKEY_PATCH_KEY_NAME = '__ngContext__';
/** /**
* The internal view context which is specific to a given DOM element, directive or * The internal view context which is specific to a given DOM element, directive or
* component instance. Each value in here (besides the LViewData and element node details) * component instance. Each value in here (besides the LView and element node details)
* can be present, null or undefined. If undefined then it implies the value has not been * can be present, null or undefined. If undefined then it implies the value has not been
* looked up yet, otherwise, if null, then a lookup was executed and nothing was found. * looked up yet, otherwise, if null, then a lookup was executed and nothing was found.
* *
@ -29,7 +29,7 @@ export interface LContext {
/** /**
* The component's parent view data. * The component's parent view data.
*/ */
lViewData: LViewData; lView: LView;
/** /**
* The index instance of the node. * The index instance of the node.

View File

@ -139,7 +139,7 @@ export interface DirectiveDef<T> extends BaseDef<T> {
/** /**
* The number of host bindings (including pure fn bindings) in this directive/component. * The number of host bindings (including pure fn bindings) in this directive/component.
* *
* Used to calculate the length of the LViewData array for the *parent* component * Used to calculate the length of the LView array for the *parent* component
* of this directive/component. * of this directive/component.
*/ */
readonly hostVars: number; readonly hostVars: number;
@ -205,7 +205,7 @@ export interface ComponentDef<T> extends DirectiveDef<T> {
/** /**
* The number of nodes, local refs, and pipes in this component template. * The number of nodes, local refs, and pipes in this component template.
* *
* Used to calculate the length of the component's LViewData array, so we * Used to calculate the length of the component's LView array, so we
* can pre-fill the array and set the binding start index. * can pre-fill the array and set the binding start index.
*/ */
// TODO(kara): remove queries from this count // TODO(kara): remove queries from this count
@ -214,7 +214,7 @@ export interface ComponentDef<T> extends DirectiveDef<T> {
/** /**
* The number of bindings in this component template (including pure fn bindings). * The number of bindings in this component template (including pure fn bindings).
* *
* Used to calculate the length of the component's LViewData array, so we * Used to calculate the length of the component's LView array, so we
* can pre-fill the array and set the host binding start index. * can pre-fill the array and set the host binding start index.
*/ */
readonly vars: number; readonly vars: number;

View File

@ -74,60 +74,60 @@ export interface COMMENT_MARKER { marker: 'comment'; }
* // For adding text nodes * // For adding text nodes
* // --------------------- * // ---------------------
* // Equivalent to: * // Equivalent to:
* // const node = lViewData[index++] = document.createTextNode('abc'); * // const node = lView[index++] = document.createTextNode('abc');
* // lViewData[1].insertBefore(node, lViewData[2]); * // lView[1].insertBefore(node, lView[2]);
* 'abc', 1 << SHIFT_PARENT | 2 << SHIFT_REF | InsertBefore, * 'abc', 1 << SHIFT_PARENT | 2 << SHIFT_REF | InsertBefore,
* *
* // Equivalent to: * // Equivalent to:
* // const node = lViewData[index++] = document.createTextNode('xyz'); * // const node = lView[index++] = document.createTextNode('xyz');
* // lViewData[1].appendChild(node); * // lView[1].appendChild(node);
* 'xyz', 1 << SHIFT_PARENT | AppendChild, * 'xyz', 1 << SHIFT_PARENT | AppendChild,
* *
* // For adding element nodes * // For adding element nodes
* // --------------------- * // ---------------------
* // Equivalent to: * // Equivalent to:
* // const node = lViewData[index++] = document.createElement('div'); * // const node = lView[index++] = document.createElement('div');
* // lViewData[1].insertBefore(node, lViewData[2]); * // lView[1].insertBefore(node, lView[2]);
* ELEMENT_MARKER, 'div', 1 << SHIFT_PARENT | 2 << SHIFT_REF | InsertBefore, * ELEMENT_MARKER, 'div', 1 << SHIFT_PARENT | 2 << SHIFT_REF | InsertBefore,
* *
* // Equivalent to: * // Equivalent to:
* // const node = lViewData[index++] = document.createElement('div'); * // const node = lView[index++] = document.createElement('div');
* // lViewData[1].appendChild(node); * // lView[1].appendChild(node);
* ELEMENT_MARKER, 'div', 1 << SHIFT_PARENT | AppendChild, * ELEMENT_MARKER, 'div', 1 << SHIFT_PARENT | AppendChild,
* *
* // For adding comment nodes * // For adding comment nodes
* // --------------------- * // ---------------------
* // Equivalent to: * // Equivalent to:
* // const node = lViewData[index++] = document.createComment(''); * // const node = lView[index++] = document.createComment('');
* // lViewData[1].insertBefore(node, lViewData[2]); * // lView[1].insertBefore(node, lView[2]);
* COMMENT_MARKER, '', 1 << SHIFT_PARENT | 2 << SHIFT_REF | InsertBefore, * COMMENT_MARKER, '', 1 << SHIFT_PARENT | 2 << SHIFT_REF | InsertBefore,
* *
* // Equivalent to: * // Equivalent to:
* // const node = lViewData[index++] = document.createComment(''); * // const node = lView[index++] = document.createComment('');
* // lViewData[1].appendChild(node); * // lView[1].appendChild(node);
* COMMENT_MARKER, '', 1 << SHIFT_PARENT | AppendChild, * COMMENT_MARKER, '', 1 << SHIFT_PARENT | AppendChild,
* *
* // For moving existing nodes to a different location * // For moving existing nodes to a different location
* // -------------------------------------------------- * // --------------------------------------------------
* // Equivalent to: * // Equivalent to:
* // const node = lViewData[1]; * // const node = lView[1];
* // lViewData[2].insertBefore(node, lViewData[3]); * // lView[2].insertBefore(node, lView[3]);
* 1 << SHIFT_REF | Select, 2 << SHIFT_PARENT | 3 << SHIFT_REF | InsertBefore, * 1 << SHIFT_REF | Select, 2 << SHIFT_PARENT | 3 << SHIFT_REF | InsertBefore,
* *
* // Equivalent to: * // Equivalent to:
* // const node = lViewData[1]; * // const node = lView[1];
* // lViewData[2].appendChild(node); * // lView[2].appendChild(node);
* 1 << SHIFT_REF | Select, 2 << SHIFT_PARENT | AppendChild, * 1 << SHIFT_REF | Select, 2 << SHIFT_PARENT | AppendChild,
* *
* // For removing existing nodes * // For removing existing nodes
* // -------------------------------------------------- * // --------------------------------------------------
* // const node = lViewData[1]; * // const node = lView[1];
* // removeChild(tView.data(1), node, lViewData); * // removeChild(tView.data(1), node, lView);
* 1 << SHIFT_REF | Remove, * 1 << SHIFT_REF | Remove,
* *
* // For writing attributes * // For writing attributes
* // -------------------------------------------------- * // --------------------------------------------------
* // const node = lViewData[1]; * // const node = lView[1];
* // node.setAttribute('attr', 'value'); * // node.setAttribute('attr', 'value');
* 1 << SHIFT_REF | Select, 'attr', 'value' * 1 << SHIFT_REF | Select, 'attr', 'value'
* // NOTE: Select followed by two string (vs select followed by OpCode) * // NOTE: Select followed by two string (vs select followed by OpCode)
@ -196,7 +196,7 @@ export const enum I18nUpdateOpCode {
* // has changed then execute update OpCodes. * // has changed then execute update OpCodes.
* // has NOT changed then skip `7` values and start processing next OpCodes. * // has NOT changed then skip `7` values and start processing next OpCodes.
* 0b11, 7, * 0b11, 7,
* // Concatenate `newValue = 'pre'+lViewData[bindIndex-4]+'in'+lViewData[bindIndex-3]+'post';`. * // Concatenate `newValue = 'pre'+lView[bindIndex-4]+'in'+lView[bindIndex-3]+'post';`.
* 'pre', -4, 'in', -3, 'post', * 'pre', -4, 'in', -3, 'post',
* // Update attribute: `elementAttribute(1, 'title', sanitizerFn(newValue));` * // Update attribute: `elementAttribute(1, 'title', sanitizerFn(newValue));`
* 1 << SHIFT_REF | Attr, 'title', sanitizerFn, * 1 << SHIFT_REF | Attr, 'title', sanitizerFn,
@ -206,9 +206,9 @@ export const enum I18nUpdateOpCode {
* // has changed then execute update OpCodes. * // has changed then execute update OpCodes.
* // has NOT changed then skip `4` values and start processing next OpCodes. * // has NOT changed then skip `4` values and start processing next OpCodes.
* 0b100, 4, * 0b100, 4,
* // Concatenate `newValue = 'Hello ' + lViewData[bindIndex -2] + '!';`. * // Concatenate `newValue = 'Hello ' + lView[bindIndex -2] + '!';`.
* 'Hello ', -2, '!', * 'Hello ', -2, '!',
* // Update text: `lViewData[1].textContent = newValue;` * // Update text: `lView[1].textContent = newValue;`
* 1 << SHIFT_REF | Text, * 1 << SHIFT_REF | Text,
* *
* // The following OpCodes represent: `<div i18n>{exp4, plural, ... }">` * // The following OpCodes represent: `<div i18n>{exp4, plural, ... }">`
@ -216,14 +216,14 @@ export const enum I18nUpdateOpCode {
* // has changed then execute update OpCodes. * // has changed then execute update OpCodes.
* // has NOT changed then skip `4` values and start processing next OpCodes. * // has NOT changed then skip `4` values and start processing next OpCodes.
* 0b1000, 4, * 0b1000, 4,
* // Concatenate `newValue = lViewData[bindIndex -1];`. * // Concatenate `newValue = lView[bindIndex -1];`.
* -1, * -1,
* // Switch ICU: `icuSwitchCase(lViewData[1], 0, newValue);` * // Switch ICU: `icuSwitchCase(lView[1], 0, newValue);`
* 0 << SHIFT_ICU | 1 << SHIFT_REF | IcuSwitch, * 0 << SHIFT_ICU | 1 << SHIFT_REF | IcuSwitch,
* *
* // Note `changeMask & -1` is always true, so the IcuUpdate will always execute. * // Note `changeMask & -1` is always true, so the IcuUpdate will always execute.
* -1, 1, * -1, 1,
* // Update ICU: `icuUpdateCase(lViewData[1], 0);` * // Update ICU: `icuUpdateCase(lView[1], 0);`
* 0 << SHIFT_ICU | 1 << SHIFT_REF | IcuUpdate, * 0 << SHIFT_ICU | 1 << SHIFT_REF | IcuUpdate,
* *
* ]; * ];

View File

@ -10,7 +10,7 @@ import {InjectionToken} from '../../di/injection_token';
import {InjectFlags} from '../../di/injector_compatibility'; import {InjectFlags} from '../../di/injector_compatibility';
import {Type} from '../../type'; import {Type} from '../../type';
import {TElementNode} from './node'; import {TElementNode} from './node';
import {LViewData, TData} from './view'; import {LView, TData} from './view';
export const TNODE = 8; export const TNODE = 8;
export const PARENT_INJECTOR = 8; export const PARENT_INJECTOR = 8;
@ -19,7 +19,7 @@ export const INJECTOR_SIZE = 9;
/** /**
* Represents a relative location of parent injector. * Represents a relative location of parent injector.
* *
* The interfaces encodes number of parents `LViewData`s to traverse and index in the `LViewData` * The interfaces encodes number of parents `LView`s to traverse and index in the `LView`
* pointing to the parent injector. * pointing to the parent injector.
*/ */
export interface RelativeInjectorLocation { __brand__: 'RelativeInjectorLocationFlags'; } export interface RelativeInjectorLocation { __brand__: 'RelativeInjectorLocationFlags'; }
@ -34,10 +34,10 @@ export const enum RelativeInjectorLocationFlags {
export const NO_PARENT_INJECTOR: RelativeInjectorLocation = -1 as any; export const NO_PARENT_INJECTOR: RelativeInjectorLocation = -1 as any;
/** /**
* Each injector is saved in 9 contiguous slots in `LViewData` and 9 contiguous slots in * Each injector is saved in 9 contiguous slots in `LView` and 9 contiguous slots in
* `TView.data`. This allows us to store information about the current node's tokens (which * `TView.data`. This allows us to store information about the current node's tokens (which
* can be shared in `TView`) as well as the tokens of its ancestor nodes (which cannot be * can be shared in `TView`) as well as the tokens of its ancestor nodes (which cannot be
* shared, so they live in `LViewData`). * shared, so they live in `LView`).
* *
* Each of these slots (aside from the last slot) contains a bloom filter. This bloom filter * Each of these slots (aside from the last slot) contains a bloom filter. This bloom filter
* determines whether a directive is available on the associated node or not. This prevents us * determines whether a directive is available on the associated node or not. This prevents us
@ -45,7 +45,7 @@ export const NO_PARENT_INJECTOR: RelativeInjectorLocation = -1 as any;
* *
* See: https://en.wikipedia.org/wiki/Bloom_filter for more about bloom filters. * See: https://en.wikipedia.org/wiki/Bloom_filter for more about bloom filters.
* *
* Because all injectors have been flattened into `LViewData` and `TViewData`, they cannot typed * Because all injectors have been flattened into `LView` and `TViewData`, they cannot typed
* using interfaces as they were previously. The start index of each `LInjector` and `TInjector` * using interfaces as they were previously. The start index of each `LInjector` and `TInjector`
* will differ based on where it is flattened into the main array, so it's not possible to know * will differ based on where it is flattened into the main array, so it's not possible to know
* the indices ahead of time and save their types here. The interfaces are still included here * the indices ahead of time and save their types here. The interfaces are still included here
@ -226,7 +226,7 @@ export class NodeInjectorFactory {
* array where existing instances of injectables are stored. This is used in case * array where existing instances of injectables are stored. This is used in case
* of multi shadow is needed. See `multi` field documentation. * of multi shadow is needed. See `multi` field documentation.
*/ */
lData: LViewData, lView: LView,
/** /**
* The TNode of the same element injector. * The TNode of the same element injector.
*/ */

View File

@ -7,7 +7,7 @@
*/ */
import {StylingContext} from './styling'; import {StylingContext} from './styling';
import {LViewData, TView} from './view'; import {LView, TView} from './view';
/** /**
@ -103,7 +103,7 @@ export interface TNode {
type: TNodeType; type: TNodeType;
/** /**
* Index of the TNode in TView.data and corresponding native element in LViewData. * Index of the TNode in TView.data and corresponding native element in LView.
* *
* This is necessary to get from any TNode to its corresponding native element when * This is necessary to get from any TNode to its corresponding native element when
* traversing the node tree. * traversing the node tree.
@ -113,7 +113,7 @@ export interface TNode {
index: number; index: number;
/** /**
* The index of the closest injector in this node's LViewData. * The index of the closest injector in this node's LView.
* *
* If the index === -1, there is no injector on this node or any ancestor node in this view. * If the index === -1, there is no injector on this node or any ancestor node in this view.
* *
@ -361,7 +361,7 @@ export interface TContainerNode extends TNode {
/** Static data for an <ng-container> */ /** Static data for an <ng-container> */
export interface TElementContainerNode extends TNode { export interface TElementContainerNode extends TNode {
/** Index in the LViewData[] array. */ /** Index in the LView[] array. */
index: number; index: number;
child: TElementNode|TTextNode|TContainerNode|TElementContainerNode|TProjectionNode|null; child: TElementNode|TTextNode|TContainerNode|TElementContainerNode|TProjectionNode|null;
parent: TElementNode|TElementContainerNode|null; parent: TElementNode|TElementContainerNode|null;
@ -371,7 +371,7 @@ export interface TElementContainerNode extends TNode {
/** Static data for an ICU expression */ /** Static data for an ICU expression */
export interface TIcuContainerNode extends TNode { export interface TIcuContainerNode extends TNode {
/** Index in the LViewData[] array. */ /** Index in the LView[] array. */
index: number; index: number;
child: TElementNode|TTextNode|null; child: TElementNode|TTextNode|null;
parent: TElementNode|TElementContainerNode|null; parent: TElementNode|TElementContainerNode|null;
@ -481,4 +481,4 @@ export type TNodeWithLocalRefs = TContainerNode | TElementNode | TElementContain
* - `<div #nativeDivEl>` - `nativeDivEl` should point to the native `<div>` element; * - `<div #nativeDivEl>` - `nativeDivEl` should point to the native `<div>` element;
* - `<ng-template #tplRef>` - `tplRef` should point to the `TemplateRef` instance; * - `<ng-template #tplRef>` - `tplRef` should point to the `TemplateRef` instance;
*/ */
export type LocalRefExtractor = (tNode: TNodeWithLocalRefs, currentView: LViewData) => any; export type LocalRefExtractor = (tNode: TNodeWithLocalRefs, currentView: LView) => any;

View File

@ -21,7 +21,7 @@ import {RElement, Renderer3, RendererFactory3} from './renderer';
import {StylingContext} from './styling'; import {StylingContext} from './styling';
// Below are constants for LViewData indices to help us look up LViewData members // Below are constants for LView indices to help us look up LView 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.
export const TVIEW = 0; export const TVIEW = 0;
@ -42,11 +42,11 @@ export const TAIL = 14;
export const CONTAINER_INDEX = 15; export const CONTAINER_INDEX = 15;
export const CONTENT_QUERIES = 16; export const CONTENT_QUERIES = 16;
export const DECLARATION_VIEW = 17; export const DECLARATION_VIEW = 17;
/** Size of LViewData's header. Necessary to adjust for it when setting slots. */ /** Size of LView's header. Necessary to adjust for it when setting slots. */
export const HEADER_OFFSET = 18; export const HEADER_OFFSET = 18;
// This interface replaces the real LViewData interface if it is an arg or a // This interface replaces the real LView 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
// the actual interface, which should be kept private. // the actual interface, which should be kept private.
export interface OpaqueViewState { export interface OpaqueViewState {
@ -55,16 +55,16 @@ export interface OpaqueViewState {
/** /**
* `LViewData` stores all of the information needed to process the instructions as * `LView` stores all of the information needed to process the instructions as
* they are invoked from the template. Each embedded view and component view has its * they are invoked from the template. Each embedded view and component view has its
* own `LViewData`. When processing a particular view, we set the `viewData` to that * own `LView`. When processing a particular view, we set the `viewData` to that
* `LViewData`. When that view is done processing, the `viewData` is set back to * `LView`. When that view is done processing, the `viewData` is set back to
* whatever the original `viewData` was before (the parent `LViewData`). * whatever the original `viewData` was before (the parent `LView`).
* *
* Keeping separate state for each view facilities view insertion / deletion, so we * Keeping separate state for each view facilities view insertion / deletion, so we
* don't have to edit the data array based on which views are present. * don't have to edit the data array based on which views are present.
*/ */
export interface LViewData extends Array<any> { export interface LView extends Array<any> {
/** /**
* The static data for this view. We need a reference to this so we can easily walk up the * The static data for this view. We need a reference to this so we can easily walk up the
* node tree in DI and get the TView.data array associated with a node (where the * node tree in DI and get the TView.data array associated with a node (where the
@ -77,30 +77,30 @@ export interface LViewData extends Array<any> {
/** /**
* The parent view is needed when we exit the view and must restore the previous * The parent view is needed when we exit the view and must restore the previous
* `LViewData`. Without this, the render method would have to keep a stack of * `LView`. Without this, the render method would have to keep a stack of
* views as it is recursively rendering templates. * views as it is recursively rendering templates.
* *
* This is the "insertion" view for embedded views. This allows us to properly * This is the "insertion" view for embedded views. This allows us to properly
* destroy embedded views. * destroy embedded views.
*/ */
[PARENT]: LViewData|null; [PARENT]: LView|null;
/** /**
* *
* The next sibling LViewData or LContainer. * The next sibling LView or LContainer.
* *
* Allows us to propagate between sibling view states that aren't in the same * Allows us to propagate between sibling view states that aren't in the same
* container. Embedded views already have a node.next, but it is only set for * container. Embedded views already have a node.next, but it is only set for
* views in the same container. We need a way to link component views and views * views in the same container. We need a way to link component views and views
* across containers as well. * across containers as well.
*/ */
[NEXT]: LViewData|LContainer|null; [NEXT]: LView|LContainer|null;
/** Queries active for this view - nodes from a view are reported to those queries. */ /** Queries active for this view - nodes from a view are reported to those queries. */
[QUERIES]: LQueries|null; [QUERIES]: LQueries|null;
/** /**
* The host node for this LViewData instance, if this is a component view. * The host node for this LView instance, if this is a component view.
* *
* If this is an embedded view, HOST will be null. * If this is an embedded view, HOST will be null.
*/ */
@ -135,7 +135,7 @@ export interface LViewData extends Array<any> {
* These change per LView instance, so they cannot be stored on TView. Instead, * These change per LView instance, so they cannot be stored on TView. Instead,
* TView.cleanup saves an index to the necessary context in this array. * TView.cleanup saves an index to the necessary context in this array.
*/ */
// TODO: flatten into LViewData[] // TODO: flatten into LView[]
[CLEANUP]: any[]|null; [CLEANUP]: any[]|null;
/** /**
@ -160,12 +160,12 @@ export interface LViewData extends Array<any> {
[SANITIZER]: Sanitizer|null; [SANITIZER]: Sanitizer|null;
/** /**
* The last LViewData or LContainer beneath this LViewData in the hierarchy. * The last LView or LContainer beneath this LView in the hierarchy.
* *
* The tail allows us to quickly add a new state to the end of the view list * The tail allows us to quickly add a new state to the end of the view list
* without having to propagate starting from the first child. * without having to propagate starting from the first child.
*/ */
[TAIL]: LViewData|LContainer|null; [TAIL]: LView|LContainer|null;
/** /**
* The index of the parent container's host node. Applicable only to embedded views that * The index of the parent container's host node. Applicable only to embedded views that
@ -191,7 +191,7 @@ export interface LViewData extends Array<any> {
* *
* The template for a dynamically created view may be declared in a different view than * The template for a dynamically created view may be declared in a different view than
* it is inserted. We already track the "insertion view" (view where the template was * it is inserted. We already track the "insertion view" (view where the template was
* inserted) in LViewData[PARENT], but we also need access to the "declaration view" * inserted) in LView[PARENT], but we also need access to the "declaration view"
* (view where the template was declared). Otherwise, we wouldn't be able to call the * (view where the template was declared). Otherwise, we wouldn't be able to call the
* view's template function with the proper contexts. Context should be inherited from * view's template function with the proper contexts. Context should be inherited from
* the declaration view tree, not the insertion view tree. * the declaration view tree, not the insertion view tree.
@ -208,10 +208,10 @@ export interface LViewData extends Array<any> {
* template function during change detection, we need the declaration view to get inherited * template function during change detection, we need the declaration view to get inherited
* context. * context.
*/ */
[DECLARATION_VIEW]: LViewData|null; [DECLARATION_VIEW]: LView|null;
} }
/** Flags associated with an LView (saved in LViewData[FLAGS]) */ /** Flags associated with an LView (saved in LView[FLAGS]) */
export const enum LViewFlags { export const enum LViewFlags {
/** /**
* Whether or not the view is in creationMode. * Whether or not the view is in creationMode.
@ -265,10 +265,10 @@ export interface TView {
readonly id: number; readonly id: number;
/** /**
* This is a blueprint used to generate LViewData instances for this TView. Copying this * This is a blueprint used to generate LView instances for this TView. Copying this
* blueprint is faster than creating a new LViewData from scratch. * blueprint is faster than creating a new LView from scratch.
*/ */
blueprint: LViewData; blueprint: LView;
/** /**
* The template function used to refresh the view of dynamically created views * The template function used to refresh the view of dynamically created views
@ -313,9 +313,9 @@ export interface TView {
bindingStartIndex: number; bindingStartIndex: number;
/** /**
* The index where the "expando" section of `LViewData` begins. The expando * The index where the "expando" section of `LView` begins. The expando
* section contains injectors, directive instances, and host binding values. * section contains injectors, directive instances, and host binding values.
* Unlike the "consts" and "vars" sections of `LViewData`, the length of this * Unlike the "consts" and "vars" sections of `LView`, the length of this
* section cannot be calculated at compile-time because directives are matched * section cannot be calculated at compile-time because directives are matched
* at runtime to preserve locality. * at runtime to preserve locality.
* *

View File

@ -13,14 +13,14 @@ import {LContainer, NATIVE, RENDER_PARENT, VIEWS, unusedValueExportToPlacateAjd
import {TContainerNode, TElementContainerNode, TElementNode, TNode, TNodeFlags, TNodeType, TViewNode, unusedValueExportToPlacateAjd as unused2} from './interfaces/node'; import {TContainerNode, TElementContainerNode, TElementNode, TNode, TNodeFlags, TNodeType, TViewNode, unusedValueExportToPlacateAjd as unused2} from './interfaces/node';
import {unusedValueExportToPlacateAjd as unused3} from './interfaces/projection'; import {unusedValueExportToPlacateAjd as unused3} from './interfaces/projection';
import {ProceduralRenderer3, RComment, RElement, RNode, RText, Renderer3, isProceduralRenderer, unusedValueExportToPlacateAjd as unused4} from './interfaces/renderer'; import {ProceduralRenderer3, RComment, RElement, RNode, RText, Renderer3, isProceduralRenderer, unusedValueExportToPlacateAjd as unused4} from './interfaces/renderer';
import {CLEANUP, CONTAINER_INDEX, FLAGS, HEADER_OFFSET, HOST_NODE, HookData, LViewData, LViewFlags, NEXT, PARENT, QUERIES, RENDERER, TVIEW, unusedValueExportToPlacateAjd as unused5} from './interfaces/view'; import {CLEANUP, CONTAINER_INDEX, FLAGS, HEADER_OFFSET, HOST_NODE, HookData, LView, LViewFlags, NEXT, PARENT, QUERIES, RENDERER, TVIEW, unusedValueExportToPlacateAjd as unused5} from './interfaces/view';
import {assertNodeType} from './node_assert'; import {assertNodeType} from './node_assert';
import {getNativeByTNode, isLContainer, isRootView, readElementValue, stringify} from './util'; import {getNativeByTNode, isLContainer, isRootView, readElementValue, stringify} from './util';
const unusedValueToPlacateAjd = unused1 + unused2 + unused3 + unused4 + unused5; const unusedValueToPlacateAjd = unused1 + unused2 + unused3 + unused4 + unused5;
/** Retrieves the parent element of a given node. */ /** Retrieves the parent element of a given node. */
export function getParentNative(tNode: TNode, currentView: LViewData): RElement|RComment|null { export function getParentNative(tNode: TNode, currentView: LView): RElement|RComment|null {
if (tNode.parent == null) { if (tNode.parent == null) {
return getHostNative(currentView); return getHostNative(currentView);
} else { } else {
@ -44,14 +44,14 @@ function getFirstParentNative(tNode: TNode): TNode {
* Gets the host element given a view. Will return null if the current view is an embedded view, * Gets the host element given a view. Will return null if the current view is an embedded view,
* which does not have a host element. * which does not have a host element.
*/ */
export function getHostNative(currentView: LViewData): RElement|null { export function getHostNative(currentView: LView): RElement|null {
const hostTNode = currentView[HOST_NODE] as TElementNode; const hostTNode = currentView[HOST_NODE] as TElementNode;
return hostTNode && hostTNode.type !== TNodeType.View ? return hostTNode && hostTNode.type !== TNodeType.View ?
(getNativeByTNode(hostTNode, currentView[PARENT] !) as RElement) : (getNativeByTNode(hostTNode, currentView[PARENT] !) as RElement) :
null; null;
} }
export function getLContainer(tNode: TViewNode, embeddedView: LViewData): LContainer|null { export function getLContainer(tNode: TViewNode, embeddedView: LView): LContainer|null {
if (tNode.index === -1) { if (tNode.index === -1) {
// This is a dynamically created view inside a dynamic container. // This is a dynamically created view inside a dynamic container.
// If the host index is -1, the view has not yet been inserted, so it has no parent. // If the host index is -1, the view has not yet been inserted, so it has no parent.
@ -68,7 +68,7 @@ export function getLContainer(tNode: TViewNode, embeddedView: LViewData): LConta
* Retrieves render parent for a given view. * Retrieves render parent for a given view.
* Might be null if a view is not yet attached to any container. * Might be null if a view is not yet attached to any container.
*/ */
export function getContainerRenderParent(tViewNode: TViewNode, view: LViewData): RElement|null { export function getContainerRenderParent(tViewNode: TViewNode, view: LView): RElement|null {
const container = getLContainer(tViewNode, view); const container = getLContainer(tViewNode, view);
return container ? container[RENDER_PARENT] : null; return container ? container[RENDER_PARENT] : null;
} }
@ -92,7 +92,7 @@ const enum WalkTNodeTreeAction {
* a new array each time the function is called. Instead the array will be * a new array each time the function is called. Instead the array will be
* re-used by each invocation. This works because the function is not reentrant. * re-used by each invocation. This works because the function is not reentrant.
*/ */
const projectionNodeStack: (LViewData | TNode)[] = []; const projectionNodeStack: (LView | TNode)[] = [];
/** /**
* Walks a tree of TNodes, applying a transformation on the element nodes, either only on the first * Walks a tree of TNodes, applying a transformation on the element nodes, either only on the first
@ -107,7 +107,7 @@ const projectionNodeStack: (LViewData | TNode)[] = [];
* Insert. * Insert.
*/ */
function walkTNodeTree( function walkTNodeTree(
viewToWalk: LViewData, action: WalkTNodeTreeAction, renderer: Renderer3, viewToWalk: LView, action: WalkTNodeTreeAction, renderer: Renderer3,
renderParent: RElement | null, beforeNode?: RNode | null) { renderParent: RElement | null, beforeNode?: RNode | null) {
const rootTNode = viewToWalk[TVIEW].node as TViewNode; const rootTNode = viewToWalk[TVIEW].node as TViewNode;
let projectionNodeIndex = -1; let projectionNodeIndex = -1;
@ -159,7 +159,7 @@ function walkTNodeTree(
if (nextTNode === null) { if (nextTNode === null) {
// this last node was projected, we need to get back down to its projection node // this last node was projected, we need to get back down to its projection node
if (tNode.next === null && (tNode.flags & TNodeFlags.isProjected)) { if (tNode.next === null && (tNode.flags & TNodeFlags.isProjected)) {
currentView = projectionNodeStack[projectionNodeIndex--] as LViewData; currentView = projectionNodeStack[projectionNodeIndex--] as LView;
tNode = projectionNodeStack[projectionNodeIndex--] as TNode; tNode = projectionNodeStack[projectionNodeIndex--] as TNode;
} }
nextTNode = tNode.next; nextTNode = tNode.next;
@ -184,7 +184,7 @@ function walkTNodeTree(
} }
if (tNode.type === TNodeType.View && currentView[NEXT]) { if (tNode.type === TNodeType.View && currentView[NEXT]) {
currentView = currentView[NEXT] as LViewData; currentView = currentView[NEXT] as LView;
nextTNode = currentView[TVIEW].node; nextTNode = currentView[TVIEW].node;
} else { } else {
nextTNode = tNode.next; nextTNode = tNode.next;
@ -198,19 +198,19 @@ function walkTNodeTree(
/** /**
* Given a current view, finds the nearest component's host (LElement). * Given a current view, finds the nearest component's host (LElement).
* *
* @param lViewData LViewData for which we want a host element node * @param lView LView for which we want a host element node
* @returns The host node * @returns The host node
*/ */
export function findComponentView(lViewData: LViewData): LViewData { export function findComponentView(lView: LView): LView {
let rootTNode = lViewData[HOST_NODE]; let rootTNode = lView[HOST_NODE];
while (rootTNode && rootTNode.type === TNodeType.View) { while (rootTNode && rootTNode.type === TNodeType.View) {
ngDevMode && assertDefined(lViewData[PARENT], 'viewData.parent'); ngDevMode && assertDefined(lView[PARENT], 'lView.parent');
lViewData = lViewData[PARENT] !; lView = lView[PARENT] !;
rootTNode = lViewData[HOST_NODE]; rootTNode = lView[HOST_NODE];
} }
return lViewData; return lView;
} }
/** /**
@ -251,10 +251,10 @@ export function createTextNode(value: any, renderer: Renderer3): RText {
* @param beforeNode The node before which elements should be added, if insert mode * @param beforeNode The node before which elements should be added, if insert mode
*/ */
export function addRemoveViewFromContainer( export function addRemoveViewFromContainer(
viewToWalk: LViewData, insertMode: true, beforeNode: RNode | null): void; viewToWalk: LView, insertMode: true, beforeNode: RNode | null): void;
export function addRemoveViewFromContainer(viewToWalk: LViewData, insertMode: false): void; export function addRemoveViewFromContainer(viewToWalk: LView, insertMode: false): void;
export function addRemoveViewFromContainer( export function addRemoveViewFromContainer(
viewToWalk: LViewData, insertMode: boolean, beforeNode?: RNode | null): void { viewToWalk: LView, insertMode: boolean, beforeNode?: RNode | null): void {
const renderParent = getContainerRenderParent(viewToWalk[TVIEW].node as TViewNode, viewToWalk); const renderParent = getContainerRenderParent(viewToWalk[TVIEW].node as TViewNode, viewToWalk);
ngDevMode && assertNodeType(viewToWalk[TVIEW].node as TNode, TNodeType.View); ngDevMode && assertNodeType(viewToWalk[TVIEW].node as TNode, TNodeType.View);
if (renderParent) { if (renderParent) {
@ -278,22 +278,22 @@ export function addRemoveViewFromContainer(
* *
* @param rootView The view to destroy * @param rootView The view to destroy
*/ */
export function destroyViewTree(rootView: LViewData): void { export function destroyViewTree(rootView: LView): void {
// If the view has no children, we can clean it up and return early. // If the view has no children, we can clean it up and return early.
if (rootView[TVIEW].childIndex === -1) { if (rootView[TVIEW].childIndex === -1) {
return cleanUpView(rootView); return cleanUpView(rootView);
} }
let viewOrContainer: LViewData|LContainer|null = getLViewChild(rootView); let viewOrContainer: LView|LContainer|null = getLViewChild(rootView);
while (viewOrContainer) { while (viewOrContainer) {
let next: LViewData|LContainer|null = null; let next: LView|LContainer|null = null;
if (viewOrContainer.length >= HEADER_OFFSET) { if (viewOrContainer.length >= HEADER_OFFSET) {
// If LViewData, traverse down to child. // If LView, traverse down to child.
const view = viewOrContainer as LViewData; const view = viewOrContainer as LView;
if (view[TVIEW].childIndex > -1) next = getLViewChild(view); if (view[TVIEW].childIndex > -1) next = getLViewChild(view);
} else { } else {
// If container, traverse down to its first LViewData. // If container, traverse down to its first LView.
const container = viewOrContainer as LContainer; const container = viewOrContainer as LContainer;
if (container[VIEWS].length) next = container[VIEWS][0]; if (container[VIEWS].length) next = container[VIEWS][0];
} }
@ -327,7 +327,7 @@ export function destroyViewTree(rootView: LViewData): void {
* @param containerIndex The index of the container node, if dynamic * @param containerIndex The index of the container node, if dynamic
*/ */
export function insertView( export function insertView(
lView: LViewData, lContainer: LContainer, parentView: LViewData, index: number, lView: LView, lContainer: LContainer, parentView: LView, index: number,
containerIndex: number) { containerIndex: number) {
const views = lContainer[VIEWS]; const views = lContainer[VIEWS];
@ -374,7 +374,7 @@ export function detachView(lContainer: LContainer, removeIndex: number, detached
const views = lContainer[VIEWS]; const views = lContainer[VIEWS];
const viewToDetach = views[removeIndex]; const viewToDetach = views[removeIndex];
if (removeIndex > 0) { if (removeIndex > 0) {
views[removeIndex - 1][NEXT] = viewToDetach[NEXT] as LViewData; views[removeIndex - 1][NEXT] = viewToDetach[NEXT] as LView;
} }
views.splice(removeIndex, 1); views.splice(removeIndex, 1);
if (!detached) { if (!detached) {
@ -405,10 +405,10 @@ export function removeView(
destroyLView(view); destroyLView(view);
} }
/** Gets the child of the given LViewData */ /** Gets the child of the given LView */
export function getLViewChild(viewData: LViewData): LViewData|LContainer|null { export function getLViewChild(lView: LView): LView|LContainer|null {
const childIndex = viewData[TVIEW].childIndex; const childIndex = lView[TVIEW].childIndex;
return childIndex === -1 ? null : viewData[childIndex]; return childIndex === -1 ? null : lView[childIndex];
} }
/** /**
@ -417,7 +417,7 @@ export function getLViewChild(viewData: LViewData): LViewData|LContainer|null {
* *
* @param view The view to be destroyed. * @param view The view to be destroyed.
*/ */
export function destroyLView(view: LViewData) { export function destroyLView(view: LView) {
const renderer = view[RENDERER]; const renderer = view[RENDERER];
if (isProceduralRenderer(renderer) && renderer.destroyNode) { if (isProceduralRenderer(renderer) && renderer.destroyNode) {
walkTNodeTree(view, WalkTNodeTreeAction.Destroy, renderer, null); walkTNodeTree(view, WalkTNodeTreeAction.Destroy, renderer, null);
@ -439,14 +439,13 @@ export function destroyLView(view: LViewData) {
* @param rootView The rootView, so we don't propagate too far up the view tree * @param rootView The rootView, so we don't propagate too far up the view tree
* @returns The correct parent LViewOrLContainer * @returns The correct parent LViewOrLContainer
*/ */
export function getParentState(state: LViewData | LContainer, rootView: LViewData): LViewData| export function getParentState(state: LView | LContainer, rootView: LView): LView|LContainer|null {
LContainer|null {
let tNode; let tNode;
if (state.length >= HEADER_OFFSET && (tNode = (state as LViewData) ![HOST_NODE]) && if (state.length >= HEADER_OFFSET && (tNode = (state as LView) ![HOST_NODE]) &&
tNode.type === TNodeType.View) { tNode.type === TNodeType.View) {
// if it's an embedded view, the state needs to go up to the container, in case the // if it's an embedded view, the state needs to go up to the container, in case the
// container has a next // container has a next
return getLContainer(tNode as TViewNode, state as LViewData) as LContainer; return getLContainer(tNode as TViewNode, state as LView) as LContainer;
} else { } else {
// otherwise, use parent view for containers or component views // otherwise, use parent view for containers or component views
return state[PARENT] === rootView ? null : state[PARENT]; return state[PARENT] === rootView ? null : state[PARENT];
@ -456,11 +455,11 @@ export function getParentState(state: LViewData | LContainer, rootView: LViewDat
/** /**
* Removes all listeners and call all onDestroys in a given view. * Removes all listeners and call all onDestroys in a given view.
* *
* @param view The LViewData to clean up * @param view The LView to clean up
*/ */
function cleanUpView(viewOrContainer: LViewData | LContainer): void { function cleanUpView(viewOrContainer: LView | LContainer): void {
if ((viewOrContainer as LViewData).length >= HEADER_OFFSET) { if ((viewOrContainer as LView).length >= HEADER_OFFSET) {
const view = viewOrContainer as LViewData; const view = viewOrContainer as LView;
removeListeners(view); removeListeners(view);
executeOnDestroys(view); executeOnDestroys(view);
executePipeOnDestroys(view); executePipeOnDestroys(view);
@ -473,32 +472,32 @@ function cleanUpView(viewOrContainer: LViewData | LContainer): void {
} }
/** Removes listeners and unsubscribes from output subscriptions */ /** Removes listeners and unsubscribes from output subscriptions */
function removeListeners(viewData: LViewData): void { function removeListeners(lView: LView): void {
const cleanup = viewData[TVIEW].cleanup !; const cleanup = lView[TVIEW].cleanup !;
if (cleanup != null) { if (cleanup != null) {
for (let i = 0; i < cleanup.length - 1; i += 2) { for (let i = 0; i < cleanup.length - 1; i += 2) {
if (typeof cleanup[i] === 'string') { if (typeof cleanup[i] === 'string') {
// This is a listener with the native renderer // This is a listener with the native renderer
const native = readElementValue(viewData[cleanup[i + 1]]); const native = readElementValue(lView[cleanup[i + 1]]);
const listener = viewData[CLEANUP] ![cleanup[i + 2]]; const listener = lView[CLEANUP] ![cleanup[i + 2]];
native.removeEventListener(cleanup[i], listener, cleanup[i + 3]); native.removeEventListener(cleanup[i], listener, cleanup[i + 3]);
i += 2; i += 2;
} else if (typeof cleanup[i] === 'number') { } else if (typeof cleanup[i] === 'number') {
// This is a listener with renderer2 (cleanup fn can be found by index) // This is a listener with renderer2 (cleanup fn can be found by index)
const cleanupFn = viewData[CLEANUP] ![cleanup[i]]; const cleanupFn = lView[CLEANUP] ![cleanup[i]];
cleanupFn(); cleanupFn();
} else { } else {
// This is a cleanup function that is grouped with the index of its context // This is a cleanup function that is grouped with the index of its context
const context = viewData[CLEANUP] ![cleanup[i + 1]]; const context = lView[CLEANUP] ![cleanup[i + 1]];
cleanup[i].call(context); cleanup[i].call(context);
} }
} }
viewData[CLEANUP] = null; lView[CLEANUP] = null;
} }
} }
/** Calls onDestroy hooks for this view */ /** Calls onDestroy hooks for this view */
function executeOnDestroys(view: LViewData): void { function executeOnDestroys(view: LView): void {
const tView = view[TVIEW]; const tView = view[TVIEW];
let destroyHooks: HookData|null; let destroyHooks: HookData|null;
if (tView != null && (destroyHooks = tView.destroyHooks) != null) { if (tView != null && (destroyHooks = tView.destroyHooks) != null) {
@ -507,14 +506,14 @@ function executeOnDestroys(view: LViewData): void {
} }
/** Calls pipe destroy hooks for this view */ /** Calls pipe destroy hooks for this view */
function executePipeOnDestroys(viewData: LViewData): void { function executePipeOnDestroys(lView: LView): void {
const pipeDestroyHooks = viewData[TVIEW] && viewData[TVIEW].pipeDestroyHooks; const pipeDestroyHooks = lView[TVIEW] && lView[TVIEW].pipeDestroyHooks;
if (pipeDestroyHooks) { if (pipeDestroyHooks) {
callHooks(viewData !, pipeDestroyHooks); callHooks(lView !, pipeDestroyHooks);
} }
} }
export function getRenderParent(tNode: TNode, currentView: LViewData): RElement|null { export function getRenderParent(tNode: TNode, currentView: LView): RElement|null {
if (canInsertNativeNode(tNode, currentView)) { if (canInsertNativeNode(tNode, currentView)) {
// If we are asked for a render parent of the root component we need to do low-level DOM // If we are asked for a render parent of the root component we need to do low-level DOM
// operation as LTree doesn't exist above the topmost host node. We might need to find a render // operation as LTree doesn't exist above the topmost host node. We might need to find a render
@ -565,7 +564,7 @@ function canInsertNativeChildOfElement(tNode: TNode): boolean {
* and * and
* the container itself has its render parent determined. * the container itself has its render parent determined.
*/ */
function canInsertNativeChildOfView(viewTNode: TViewNode, view: LViewData): boolean { function canInsertNativeChildOfView(viewTNode: TViewNode, view: LView): boolean {
// Because we are inserting into a `View` the `View` may be disconnected. // Because we are inserting into a `View` the `View` may be disconnected.
const container = getLContainer(viewTNode, view) !; const container = getLContainer(viewTNode, view) !;
if (container == null || container[RENDER_PARENT] == null) { if (container == null || container[RENDER_PARENT] == null) {
@ -597,7 +596,7 @@ function canInsertNativeChildOfView(viewTNode: TViewNode, view: LViewData): bool
* @param currentView Current LView being processed. * @param currentView Current LView being processed.
* @return boolean Whether the node should be inserted now (or delayed until later). * @return boolean Whether the node should be inserted now (or delayed until later).
*/ */
export function canInsertNativeNode(tNode: TNode, currentView: LViewData): boolean { export function canInsertNativeNode(tNode: TNode, currentView: LView): boolean {
let currentNode = tNode; let currentNode = tNode;
let parent: TNode|null = tNode.parent; let parent: TNode|null = tNode.parent;
@ -659,7 +658,7 @@ export function nativeNextSibling(renderer: Renderer3, node: RNode): RNode|null
* @returns Whether or not the child was appended * @returns Whether or not the child was appended
*/ */
export function appendChild( export function appendChild(
childEl: RNode | null = null, childTNode: TNode, currentView: LViewData): boolean { childEl: RNode | null = null, childTNode: TNode, currentView: LView): boolean {
if (childEl !== null && canInsertNativeNode(childTNode, currentView)) { if (childEl !== null && canInsertNativeNode(childTNode, currentView)) {
const renderer = currentView[RENDERER]; const renderer = currentView[RENDERER];
const parentEl = getParentNative(childTNode, currentView); const parentEl = getParentNative(childTNode, currentView);
@ -700,9 +699,9 @@ function getHighestElementContainer(ngContainer: TNode): TNode {
return ngContainer; return ngContainer;
} }
export function getBeforeNodeForView(index: number, views: LViewData[], containerNative: RComment) { export function getBeforeNodeForView(index: number, views: LView[], containerNative: RComment) {
if (index + 1 < views.length) { if (index + 1 < views.length) {
const view = views[index + 1] as LViewData; const view = views[index + 1] as LView;
const viewTNode = view[HOST_NODE] as TViewNode; const viewTNode = view[HOST_NODE] as TViewNode;
return viewTNode.child ? getNativeByTNode(viewTNode.child, view) : containerNative; return viewTNode.child ? getNativeByTNode(viewTNode.child, view) : containerNative;
} else { } else {
@ -718,8 +717,7 @@ export function getBeforeNodeForView(index: number, views: LViewData[], containe
* @param currentView The current LView * @param currentView The current LView
* @returns Whether or not the child was removed * @returns Whether or not the child was removed
*/ */
export function removeChild( export function removeChild(childTNode: TNode, childEl: RNode | null, currentView: LView): boolean {
childTNode: TNode, childEl: RNode | null, currentView: LViewData): boolean {
// We only remove the element if not in View or not projected. // We only remove the element if not in View or not projected.
if (childEl !== null && canInsertNativeNode(childTNode, currentView)) { if (childEl !== null && canInsertNativeNode(childTNode, currentView)) {
const parentNative = getParentNative(childTNode, currentView) !as RElement; const parentNative = getParentNative(childTNode, currentView) !as RElement;
@ -741,8 +739,8 @@ export function removeChild(
* @param projectionView Projection view (view above current) * @param projectionView Projection view (view above current)
*/ */
export function appendProjectedNode( export function appendProjectedNode(
projectedTNode: TNode, tProjectionNode: TNode, currentView: LViewData, projectedTNode: TNode, tProjectionNode: TNode, currentView: LView,
projectionView: LViewData): void { projectionView: LView): void {
const native = getNativeByTNode(projectedTNode, projectionView); const native = getNativeByTNode(projectedTNode, projectionView);
appendChild(native, tProjectionNode, currentView); appendChild(native, tProjectionNode, currentView);

View File

@ -10,9 +10,9 @@ import {PipeTransform} from '../change_detection/pipe_transform';
import {load, store} from './instructions'; import {load, store} from './instructions';
import {PipeDef, PipeDefList} from './interfaces/definition'; import {PipeDef, PipeDefList} from './interfaces/definition';
import {HEADER_OFFSET} from './interfaces/view'; import {HEADER_OFFSET, TVIEW} from './interfaces/view';
import {pureFunction1, pureFunction2, pureFunction3, pureFunction4, pureFunctionV} from './pure_function'; import {pureFunction1, pureFunction2, pureFunction3, pureFunction4, pureFunctionV} from './pure_function';
import {getTView} from './state'; import {getLView} from './state';
/** /**
* Create a pipe. * Create a pipe.
@ -22,7 +22,7 @@ import {getTView} from './state';
* @returns T the instance of the pipe. * @returns T the instance of the pipe.
*/ */
export function pipe(index: number, pipeName: string): any { export function pipe(index: number, pipeName: string): any {
const tView = getTView(); const tView = getLView()[TVIEW];
let pipeDef: PipeDef<any>; let pipeDef: PipeDef<any>;
const adjustedIndex = index + HEADER_OFFSET; const adjustedIndex = index + HEADER_OFFSET;
@ -152,5 +152,5 @@ export function pipeBindV(index: number, slotOffset: number, values: any[]): any
} }
function isPure(index: number): boolean { function isPure(index: number): boolean {
return (<PipeDef<any>>getTView().data[index + HEADER_OFFSET]).pure; return (<PipeDef<any>>getLView()[TVIEW].data[index + HEADER_OFFSET]).pure;
} }

View File

@ -36,9 +36,9 @@ export function addPlayer(
} }
const element = context.native as HTMLElement; const element = context.native as HTMLElement;
const lViewData = context.lViewData; const lView = context.lView;
const playerContext = getOrCreatePlayerContext(element, context) !; const playerContext = getOrCreatePlayerContext(element, context) !;
const rootContext = getRootContext(lViewData); const rootContext = getRootContext(lView);
addPlayerInternal(playerContext, rootContext, element, player, 0, ref); addPlayerInternal(playerContext, rootContext, element, player, 0, ref);
scheduleTick(rootContext, RootContextFlags.FlushPlayers); scheduleTick(rootContext, RootContextFlags.FlushPlayers);
} }
@ -60,7 +60,7 @@ export function getPlayers(ref: ComponentInstance | DirectiveInstance | HTMLElem
return []; return [];
} }
const stylingContext = getStylingContext(context.nodeIndex - HEADER_OFFSET, context.lViewData); const stylingContext = getStylingContext(context.nodeIndex - HEADER_OFFSET, context.lView);
const playerContext = stylingContext ? getPlayerContext(stylingContext) : null; const playerContext = stylingContext ? getPlayerContext(stylingContext) : null;
return playerContext ? getPlayersInternal(playerContext) : []; return playerContext ? getPlayersInternal(playerContext) : [];
} }

View File

@ -6,8 +6,9 @@
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import {bindingUpdated, bindingUpdated2, bindingUpdated3, bindingUpdated4, getBinding, updateBinding} from './instructions'; import {bindingUpdated, bindingUpdated2, bindingUpdated3, bindingUpdated4, getBinding, updateBinding} from './bindings';
import {getBindingRoot, getCreationMode} from './state'; import {getBindingRoot, getCreationMode, getLView} from './state';
/** /**
@ -40,9 +41,10 @@ import {getBindingRoot, getCreationMode} from './state';
export function pureFunction0<T>(slotOffset: number, pureFn: () => T, thisArg?: any): T { export function pureFunction0<T>(slotOffset: number, pureFn: () => T, thisArg?: any): T {
// TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings // TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings
const bindingIndex = getBindingRoot() + slotOffset; const bindingIndex = getBindingRoot() + slotOffset;
const lView = getLView();
return getCreationMode() ? return getCreationMode() ?
updateBinding(bindingIndex, thisArg ? pureFn.call(thisArg) : pureFn()) : updateBinding(lView, bindingIndex, thisArg ? pureFn.call(thisArg) : pureFn()) :
getBinding(bindingIndex); getBinding(lView, bindingIndex);
} }
/** /**
@ -58,10 +60,11 @@ export function pureFunction0<T>(slotOffset: number, pureFn: () => T, thisArg?:
export function pureFunction1( export function pureFunction1(
slotOffset: number, pureFn: (v: any) => any, exp: any, thisArg?: any): any { slotOffset: number, pureFn: (v: any) => any, exp: any, thisArg?: any): any {
// TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings // TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings
const lView = getLView();
const bindingIndex = getBindingRoot() + slotOffset; const bindingIndex = getBindingRoot() + slotOffset;
return bindingUpdated(bindingIndex, exp) ? return bindingUpdated(lView, bindingIndex, exp) ?
updateBinding(bindingIndex + 1, thisArg ? pureFn.call(thisArg, exp) : pureFn(exp)) : updateBinding(lView, bindingIndex + 1, thisArg ? pureFn.call(thisArg, exp) : pureFn(exp)) :
getBinding(bindingIndex + 1); getBinding(lView, bindingIndex + 1);
} }
/** /**
@ -80,10 +83,12 @@ export function pureFunction2(
thisArg?: any): any { thisArg?: any): any {
// TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings // TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings
const bindingIndex = getBindingRoot() + slotOffset; const bindingIndex = getBindingRoot() + slotOffset;
return bindingUpdated2(bindingIndex, exp1, exp2) ? const lView = getLView();
return bindingUpdated2(lView, bindingIndex, exp1, exp2) ?
updateBinding( updateBinding(
bindingIndex + 2, thisArg ? pureFn.call(thisArg, exp1, exp2) : pureFn(exp1, exp2)) : lView, bindingIndex + 2,
getBinding(bindingIndex + 2); thisArg ? pureFn.call(thisArg, exp1, exp2) : pureFn(exp1, exp2)) :
getBinding(lView, bindingIndex + 2);
} }
/** /**
@ -103,11 +108,12 @@ export function pureFunction3(
thisArg?: any): any { thisArg?: any): any {
// TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings // TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings
const bindingIndex = getBindingRoot() + slotOffset; const bindingIndex = getBindingRoot() + slotOffset;
return bindingUpdated3(bindingIndex, exp1, exp2, exp3) ? const lView = getLView();
return bindingUpdated3(lView, bindingIndex, exp1, exp2, exp3) ?
updateBinding( updateBinding(
bindingIndex + 3, lView, bindingIndex + 3,
thisArg ? pureFn.call(thisArg, exp1, exp2, exp3) : pureFn(exp1, exp2, exp3)) : thisArg ? pureFn.call(thisArg, exp1, exp2, exp3) : pureFn(exp1, exp2, exp3)) :
getBinding(bindingIndex + 3); getBinding(lView, bindingIndex + 3);
} }
/** /**
@ -128,11 +134,12 @@ export function pureFunction4(
exp3: any, exp4: any, thisArg?: any): any { exp3: any, exp4: any, thisArg?: any): any {
// TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings // TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings
const bindingIndex = getBindingRoot() + slotOffset; const bindingIndex = getBindingRoot() + slotOffset;
return bindingUpdated4(bindingIndex, exp1, exp2, exp3, exp4) ? const lView = getLView();
return bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4) ?
updateBinding( updateBinding(
bindingIndex + 4, lView, bindingIndex + 4,
thisArg ? pureFn.call(thisArg, exp1, exp2, exp3, exp4) : pureFn(exp1, exp2, exp3, exp4)) : thisArg ? pureFn.call(thisArg, exp1, exp2, exp3, exp4) : pureFn(exp1, exp2, exp3, exp4)) :
getBinding(bindingIndex + 4); getBinding(lView, bindingIndex + 4);
} }
/** /**
@ -154,12 +161,13 @@ export function pureFunction5(
exp2: any, exp3: any, exp4: any, exp5: any, thisArg?: any): any { exp2: any, exp3: any, exp4: any, exp5: any, thisArg?: any): any {
// TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings // TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings
const bindingIndex = getBindingRoot() + slotOffset; const bindingIndex = getBindingRoot() + slotOffset;
const different = bindingUpdated4(bindingIndex, exp1, exp2, exp3, exp4); const lView = getLView();
return bindingUpdated(bindingIndex + 4, exp5) || different ? const different = bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4);
return bindingUpdated(lView, bindingIndex + 4, exp5) || different ?
updateBinding( updateBinding(
bindingIndex + 5, thisArg ? pureFn.call(thisArg, exp1, exp2, exp3, exp4, exp5) : lView, bindingIndex + 5, thisArg ? pureFn.call(thisArg, exp1, exp2, exp3, exp4, exp5) :
pureFn(exp1, exp2, exp3, exp4, exp5)) : pureFn(exp1, exp2, exp3, exp4, exp5)) :
getBinding(bindingIndex + 5); getBinding(lView, bindingIndex + 5);
} }
/** /**
@ -182,12 +190,14 @@ export function pureFunction6(
exp1: any, exp2: any, exp3: any, exp4: any, exp5: any, exp6: any, thisArg?: any): any { exp1: any, exp2: any, exp3: any, exp4: any, exp5: any, exp6: any, thisArg?: any): any {
// TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings // TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings
const bindingIndex = getBindingRoot() + slotOffset; const bindingIndex = getBindingRoot() + slotOffset;
const different = bindingUpdated4(bindingIndex, exp1, exp2, exp3, exp4); const lView = getLView();
return bindingUpdated2(bindingIndex + 4, exp5, exp6) || different ? const different = bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4);
return bindingUpdated2(lView, bindingIndex + 4, exp5, exp6) || different ?
updateBinding( updateBinding(
bindingIndex + 6, thisArg ? pureFn.call(thisArg, exp1, exp2, exp3, exp4, exp5, exp6) : lView, bindingIndex + 6, thisArg ?
pureFn(exp1, exp2, exp3, exp4, exp5, exp6)) : pureFn.call(thisArg, exp1, exp2, exp3, exp4, exp5, exp6) :
getBinding(bindingIndex + 6); pureFn(exp1, exp2, exp3, exp4, exp5, exp6)) :
getBinding(lView, bindingIndex + 6);
} }
/** /**
@ -212,13 +222,14 @@ export function pureFunction7(
exp2: any, exp3: any, exp4: any, exp5: any, exp6: any, exp7: any, thisArg?: any): any { exp2: any, exp3: any, exp4: any, exp5: any, exp6: any, exp7: any, thisArg?: any): any {
// TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings // TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings
const bindingIndex = getBindingRoot() + slotOffset; const bindingIndex = getBindingRoot() + slotOffset;
let different = bindingUpdated4(bindingIndex, exp1, exp2, exp3, exp4); const lView = getLView();
return bindingUpdated3(bindingIndex + 4, exp5, exp6, exp7) || different ? let different = bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4);
return bindingUpdated3(lView, bindingIndex + 4, exp5, exp6, exp7) || different ?
updateBinding( updateBinding(
bindingIndex + 7, thisArg ? lView, bindingIndex + 7, thisArg ?
pureFn.call(thisArg, exp1, exp2, exp3, exp4, exp5, exp6, exp7) : pureFn.call(thisArg, exp1, exp2, exp3, exp4, exp5, exp6, exp7) :
pureFn(exp1, exp2, exp3, exp4, exp5, exp6, exp7)) : pureFn(exp1, exp2, exp3, exp4, exp5, exp6, exp7)) :
getBinding(bindingIndex + 7); getBinding(lView, bindingIndex + 7);
} }
/** /**
@ -245,13 +256,14 @@ export function pureFunction8(
thisArg?: any): any { thisArg?: any): any {
// TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings // TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings
const bindingIndex = getBindingRoot() + slotOffset; const bindingIndex = getBindingRoot() + slotOffset;
const different = bindingUpdated4(bindingIndex, exp1, exp2, exp3, exp4); const lView = getLView();
return bindingUpdated4(bindingIndex + 4, exp5, exp6, exp7, exp8) || different ? const different = bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4);
return bindingUpdated4(lView, bindingIndex + 4, exp5, exp6, exp7, exp8) || different ?
updateBinding( updateBinding(
bindingIndex + 8, thisArg ? lView, bindingIndex + 8, thisArg ?
pureFn.call(thisArg, exp1, exp2, exp3, exp4, exp5, exp6, exp7, exp8) : pureFn.call(thisArg, exp1, exp2, exp3, exp4, exp5, exp6, exp7, exp8) :
pureFn(exp1, exp2, exp3, exp4, exp5, exp6, exp7, exp8)) : pureFn(exp1, exp2, exp3, exp4, exp5, exp6, exp7, exp8)) :
getBinding(bindingIndex + 8); getBinding(lView, bindingIndex + 8);
} }
/** /**
@ -272,9 +284,10 @@ export function pureFunctionV(
// TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings // TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings
let bindingIndex = getBindingRoot() + slotOffset; let bindingIndex = getBindingRoot() + slotOffset;
let different = false; let different = false;
const lView = getLView();
for (let i = 0; i < exps.length; i++) { for (let i = 0; i < exps.length; i++) {
bindingUpdated(bindingIndex++, exps[i]) && (different = true); bindingUpdated(lView, bindingIndex++, exps[i]) && (different = true);
} }
return different ? updateBinding(bindingIndex, pureFn.apply(thisArg, exps)) : return different ? updateBinding(lView, bindingIndex, pureFn.apply(thisArg, exps)) :
getBinding(bindingIndex); getBinding(lView, bindingIndex);
} }

View File

@ -17,7 +17,7 @@ import {TemplateRef as ViewEngine_TemplateRef} from '../linker/template_ref';
import {Type} from '../type'; import {Type} from '../type';
import {getSymbolIterator} from '../util'; import {getSymbolIterator} from '../util';
import {assertDefined, assertEqual} from './assert'; import {assertDefined, assertEqual, assertPreviousIsParent} from './assert';
import {getNodeInjectable, locateDirectiveOrProvider} from './di'; import {getNodeInjectable, locateDirectiveOrProvider} from './di';
import {NG_ELEMENT_ID} from './fields'; import {NG_ELEMENT_ID} from './fields';
import {store, storeCleanupWithContext} from './instructions'; import {store, storeCleanupWithContext} from './instructions';
@ -25,8 +25,8 @@ import {unusedValueExportToPlacateAjd as unused1} from './interfaces/definition'
import {unusedValueExportToPlacateAjd as unused2} from './interfaces/injector'; import {unusedValueExportToPlacateAjd as unused2} from './interfaces/injector';
import {TContainerNode, TElementContainerNode, TElementNode, TNode, TNodeType, unusedValueExportToPlacateAjd as unused3} from './interfaces/node'; import {TContainerNode, TElementContainerNode, TElementNode, TNode, TNodeType, unusedValueExportToPlacateAjd as unused3} from './interfaces/node';
import {LQueries, unusedValueExportToPlacateAjd as unused4} from './interfaces/query'; import {LQueries, unusedValueExportToPlacateAjd as unused4} from './interfaces/query';
import {LViewData, TVIEW} from './interfaces/view'; import {LView, TVIEW} from './interfaces/view';
import {assertPreviousIsParent, getOrCreateCurrentQueries, getViewData} from './state'; import {getIsParent, getLView, getOrCreateCurrentQueries} from './state';
import {flatten, isContentQueryHost} from './util'; import {flatten, isContentQueryHost} from './util';
import {createElementRef, createTemplateRef} from './view_engine_compatibility'; import {createElementRef, createTemplateRef} from './view_engine_compatibility';
@ -245,7 +245,7 @@ function getIdxOfMatchingSelector(tNode: TNode, selector: string): number|null {
// TODO: "read" should be an AbstractType (FW-486) // TODO: "read" should be an AbstractType (FW-486)
function queryByReadToken(read: any, tNode: TNode, currentView: LViewData): any { function queryByReadToken(read: any, tNode: TNode, currentView: LView): any {
const factoryFn = (read as any)[NG_ELEMENT_ID]; const factoryFn = (read as any)[NG_ELEMENT_ID];
if (typeof factoryFn === 'function') { if (typeof factoryFn === 'function') {
return factoryFn(); return factoryFn();
@ -259,7 +259,7 @@ function queryByReadToken(read: any, tNode: TNode, currentView: LViewData): any
return null; return null;
} }
function queryByTNodeType(tNode: TNode, currentView: LViewData): any { function queryByTNodeType(tNode: TNode, currentView: LView): any {
if (tNode.type === TNodeType.Element || tNode.type === TNodeType.ElementContainer) { if (tNode.type === TNodeType.Element || tNode.type === TNodeType.ElementContainer) {
return createElementRef(ViewEngine_ElementRef, tNode, currentView); return createElementRef(ViewEngine_ElementRef, tNode, currentView);
} }
@ -270,7 +270,7 @@ function queryByTNodeType(tNode: TNode, currentView: LViewData): any {
} }
function queryByTemplateRef( function queryByTemplateRef(
templateRefToken: ViewEngine_TemplateRef<any>, tNode: TNode, currentView: LViewData, templateRefToken: ViewEngine_TemplateRef<any>, tNode: TNode, currentView: LView,
read: any): any { read: any): any {
const templateRefResult = (templateRefToken as any)[NG_ELEMENT_ID](); const templateRefResult = (templateRefToken as any)[NG_ELEMENT_ID]();
if (read) { if (read) {
@ -279,7 +279,7 @@ function queryByTemplateRef(
return templateRefResult; return templateRefResult;
} }
function queryRead(tNode: TNode, currentView: LViewData, read: any, matchingIdx: number): any { function queryRead(tNode: TNode, currentView: LView, read: any, matchingIdx: number): any {
if (read) { if (read) {
return queryByReadToken(read, tNode, currentView); return queryByReadToken(read, tNode, currentView);
} }
@ -294,7 +294,7 @@ function queryRead(tNode: TNode, currentView: LViewData, read: any, matchingIdx:
function add( function add(
query: LQuery<any>| null, tNode: TElementNode | TContainerNode | TElementContainerNode) { query: LQuery<any>| null, tNode: TElementNode | TContainerNode | TElementContainerNode) {
const currentView = getViewData(); const currentView = getLView();
while (query) { while (query) {
const predicate = query.predicate; const predicate = query.predicate;
@ -455,11 +455,11 @@ export function query<T>(
memoryIndex: number | null, predicate: Type<any>| string[], descend?: boolean, memoryIndex: number | null, predicate: Type<any>| string[], descend?: boolean,
// TODO: "read" should be an AbstractType (FW-486) // TODO: "read" should be an AbstractType (FW-486)
read?: any): QueryList<T> { read?: any): QueryList<T> {
ngDevMode && assertPreviousIsParent(); ngDevMode && assertPreviousIsParent(getIsParent());
const queryList = new QueryList<T>(); const queryList = new QueryList<T>();
const queries = getOrCreateCurrentQueries(LQueries_); const queries = getOrCreateCurrentQueries(LQueries_);
queries.track(queryList, predicate, descend, read); queries.track(queryList, predicate, descend, read);
storeCleanupWithContext(null, queryList, queryList.destroy); storeCleanupWithContext(getLView(), queryList, queryList.destroy);
if (memoryIndex != null) { if (memoryIndex != null) {
store(memoryIndex, queryList); store(memoryIndex, queryList);
} }

View File

@ -6,58 +6,18 @@
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import {Sanitizer} from '../sanitization/security'; import {assertDefined} from './assert';
import {assertDefined, assertEqual} from './assert';
import {executeHooks} from './hooks'; 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 {BINDING_INDEX, CONTEXT, DECLARATION_VIEW, FLAGS, HOST_NODE, LView, LViewFlags, OpaqueViewState, QUERIES, 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 {isContentQueryHost} from './util';
import {assertDataInRangeInternal, isContentQueryHost} from './util';
/**
* This property gets set before entering a template.
*
* This renderer can be one of two varieties of Renderer3:
*
* - ObjectedOrientedRenderer3
*
* This is the native browser API style, e.g. operations are methods on individual objects
* like HTMLElement. With this style, no additional code is needed as a facade (reducing payload
* size).
*
* - ProceduralRenderer3
*
* In non-native browser environments (e.g. platforms such as web-workers), this is the facade
* that enables element manipulation. This also facilitates backwards compatibility with
* Renderer2.
*/
let renderer: Renderer3;
export function getRenderer(): Renderer3 {
// top level variables should not be exported for performance reasons (PERF_NOTES.md)
return renderer;
}
export function setRenderer(r: Renderer3): void {
renderer = r;
}
let rendererFactory: RendererFactory3;
export function getRendererFactory(): RendererFactory3 {
// top level variables should not be exported for performance reasons (PERF_NOTES.md)
return rendererFactory;
}
export function getCurrentSanitizer(): Sanitizer|null {
return viewData && viewData[SANITIZER];
}
/** /**
* Store the element depth count. This is used to identify the root elements of the template * Store the element depth count. This is used to identify the root elements of the template
* so that we can than attach `LViewData` to only those elements. * so that we can than attach `LView` to only those elements.
*/ */
let elementDepthCount !: number; let elementDepthCount !: number;
@ -142,19 +102,8 @@ export function disableBindings(): void {
bindingsEnabled = false; bindingsEnabled = false;
} }
/** export function getLView(): LView {
* Returns the current OpaqueViewState instance. return lView;
*
* Used in conjunction with the restoreView() instruction to save a snapshot
* of the current view and restore it when listeners are invoked. This allows
* walking the declaration view tree in listeners to get vars from parent views.
*/
export function getCurrentView(): OpaqueViewState {
return viewData as any as OpaqueViewState;
}
export function _getViewData(): LViewData {
return viewData;
} }
/** /**
@ -167,7 +116,7 @@ export function _getViewData(): LViewData {
* @param viewToRestore The OpaqueViewState instance to restore. * @param viewToRestore The OpaqueViewState instance to restore.
*/ */
export function restoreView(viewToRestore: OpaqueViewState) { export function restoreView(viewToRestore: OpaqueViewState) {
contextViewData = viewToRestore as any as LViewData; contextLView = viewToRestore as any as LView;
} }
/** Used to set the parent property when nodes are created and track query results. */ /** Used to set the parent property when nodes are created and track query results. */
@ -182,9 +131,9 @@ export function setPreviousOrParentTNode(tNode: TNode) {
previousOrParentTNode = tNode; previousOrParentTNode = tNode;
} }
export function setTNodeAndViewData(tNode: TNode, view: LViewData) { export function setTNodeAndViewData(tNode: TNode, view: LView) {
previousOrParentTNode = tNode; previousOrParentTNode = tNode;
viewData = view; lView = view;
} }
/** /**
@ -203,24 +152,6 @@ export function setIsParent(value: boolean): void {
isParent = value; isParent = value;
} }
let tView: TView;
export function getTView(): TView {
// top level variables should not be exported for performance reasons (PERF_NOTES.md)
return tView;
}
let currentQueries: LQueries|null;
export function getCurrentQueries(): LQueries|null {
// top level variables should not be exported for performance reasons (PERF_NOTES.md)
return currentQueries;
}
export function setCurrentQueries(queries: LQueries | null): void {
currentQueries = queries;
}
/** /**
* Query instructions can ask for "current queries" in 2 different cases: * Query instructions can ask for "current queries" in 2 different cases:
* - when creating view queries (at the root of a component view, before any node is created - in * - when creating view queries (at the root of a component view, before any node is created - in
@ -230,15 +161,17 @@ export function setCurrentQueries(queries: LQueries | null): void {
*/ */
export function getOrCreateCurrentQueries( export function getOrCreateCurrentQueries(
QueryType: {new (parent: null, shallow: null, deep: null): LQueries}): LQueries { QueryType: {new (parent: null, shallow: null, deep: null): LQueries}): LQueries {
const lView = getLView();
let currentQueries = lView[QUERIES];
// if this is the first content query on a node, any existing LQueries needs to be cloned // if this is the first content query on a node, any existing LQueries needs to be cloned
// in subsequent template passes, the cloning occurs before directive instantiation. // in subsequent template passes, the cloning occurs before directive instantiation.
if (previousOrParentTNode && previousOrParentTNode !== viewData[HOST_NODE] && if (previousOrParentTNode && previousOrParentTNode !== lView[HOST_NODE] &&
!isContentQueryHost(previousOrParentTNode)) { !isContentQueryHost(previousOrParentTNode)) {
currentQueries && (currentQueries = currentQueries.clone()); currentQueries && (currentQueries = lView[QUERIES] = currentQueries.clone());
previousOrParentTNode.flags |= TNodeFlags.hasContentQuery; previousOrParentTNode.flags |= TNodeFlags.hasContentQuery;
} }
return currentQueries || (currentQueries = new QueryType(null, null, null)); return currentQueries || (lView[QUERIES] = new QueryType(null, null, null));
} }
/** /**
@ -257,17 +190,7 @@ export function getCreationMode(): boolean {
* An array of nodes (text, element, container, etc), pipes, their bindings, and * An array of nodes (text, element, container, etc), pipes, their bindings, and
* any local variables that need to be stored between invocations. * any local variables that need to be stored between invocations.
*/ */
let viewData: LViewData; let lView: LView;
/**
* Internal function that returns the current LViewData instance.
*
* The getCurrentView() instruction should be used for anything public.
*/
export function getViewData(): LViewData {
// top level variables should not be exported for performance reasons (PERF_NOTES.md)
return viewData;
}
/** /**
* The last viewData retrieved by nextContext(). * The last viewData retrieved by nextContext().
@ -275,21 +198,13 @@ export function getViewData(): LViewData {
* *
* e.g. const inner = x().$implicit; const outer = x().$implicit; * e.g. const inner = x().$implicit; const outer = x().$implicit;
*/ */
let contextViewData: LViewData = null !; let contextLView: LView = null !;
export function getContextViewData(): LViewData { export function getContextLView(): LView {
// top level variables should not be exported for performance reasons (PERF_NOTES.md) // top level variables should not be exported for performance reasons (PERF_NOTES.md)
return contextViewData; return contextLView;
} }
export function getCleanup(view: LViewData): any[] {
// top level variables should not be exported for performance reasons (PERF_NOTES.md)
return view[CLEANUP] || (view[CLEANUP] = []);
}
export function getTViewCleanup(view: LViewData): any[] {
return view[TVIEW].cleanup || (view[TVIEW].cleanup = []);
}
/** /**
* In this mode, any changes in bindings will throw an ExpressionChangedAfterChecked error. * In this mode, any changes in bindings will throw an ExpressionChangedAfterChecked error.
* *
@ -345,33 +260,29 @@ export function setBindingRoot(value: number) {
* @param host Element to which the View is a child of * @param host Element to which the View is a child of
* @returns the previous state; * @returns the previous state;
*/ */
export function enterView( export function enterView(newView: LView, hostTNode: TElementNode | TViewNode | null): LView {
newView: LViewData, hostTNode: TElementNode | TViewNode | null): LViewData { const oldView = lView;
const oldView: LViewData = viewData; if (newView) {
tView = newView && newView[TVIEW]; const tView = newView[TVIEW];
creationMode = newView && (newView[FLAGS] & LViewFlags.CreationMode) === LViewFlags.CreationMode; creationMode = (newView[FLAGS] & LViewFlags.CreationMode) === LViewFlags.CreationMode;
firstTemplatePass = newView && tView.firstTemplatePass; firstTemplatePass = tView.firstTemplatePass;
bindingRootIndex = newView && tView.bindingStartIndex; bindingRootIndex = tView.bindingStartIndex;
rendererFactory = newView && newView[RENDERER_FACTORY]; }
renderer = newView && newView[RENDERER];
previousOrParentTNode = hostTNode !; previousOrParentTNode = hostTNode !;
isParent = true; isParent = true;
viewData = contextViewData = newView; lView = contextLView = newView;
oldView && (oldView[QUERIES] = currentQueries);
currentQueries = newView && newView[QUERIES];
return oldView; return oldView;
} }
export function nextContextImpl<T = any>(level: number = 1): T { export function nextContextImpl<T = any>(level: number = 1): T {
contextViewData = walkUpViews(level, contextViewData !); contextLView = walkUpViews(level, contextLView !);
return contextViewData[CONTEXT] as T; return contextLView[CONTEXT] as T;
} }
function walkUpViews(nestingLevel: number, currentView: LViewData): LViewData { function walkUpViews(nestingLevel: number, currentView: LView): LView {
while (nestingLevel > 0) { while (nestingLevel > 0) {
ngDevMode && assertDefined( ngDevMode && assertDefined(
currentView[DECLARATION_VIEW], currentView[DECLARATION_VIEW],
@ -400,34 +311,16 @@ export function resetComponentState() {
* @param creationOnly An optional boolean to indicate that the view was processed in creation mode * @param creationOnly An optional boolean to indicate that the view was processed in creation mode
* only, i.e. the first update will be done later. Only possible for dynamically created views. * only, i.e. the first update will be done later. Only possible for dynamically created views.
*/ */
export function leaveView(newView: LViewData, creationOnly?: boolean): void { export function leaveView(newView: LView, creationOnly?: boolean): void {
const tView = lView[TVIEW];
if (!creationOnly) { if (!creationOnly) {
if (!checkNoChangesMode) { if (!checkNoChangesMode) {
executeHooks(viewData, tView.viewHooks, tView.viewCheckHooks, creationMode); executeHooks(lView, tView.viewHooks, tView.viewCheckHooks, creationMode);
} }
// Views are clean and in update mode after being checked, so these bits are cleared // Views are clean and in update mode after being checked, so these bits are cleared
viewData[FLAGS] &= ~(LViewFlags.CreationMode | LViewFlags.Dirty); lView[FLAGS] &= ~(LViewFlags.CreationMode | LViewFlags.Dirty);
} }
viewData[FLAGS] |= LViewFlags.RunInit; lView[FLAGS] |= LViewFlags.RunInit;
viewData[BINDING_INDEX] = tView.bindingStartIndex; lView[BINDING_INDEX] = tView.bindingStartIndex;
enterView(newView, null); enterView(newView, null);
} }
export function assertPreviousIsParent() {
assertEqual(isParent, true, 'previousOrParentTNode should be a parent');
}
export function assertHasParent() {
assertDefined(previousOrParentTNode.parent, 'previousOrParentTNode should have a parent');
}
export function assertDataInRange(index: number, arr?: any[]) {
if (arr == null) arr = viewData;
assertDataInRangeInternal(index, arr || viewData);
}
export function assertDataNext(index: number, arr?: any[]) {
if (arr == null) arr = viewData;
assertEqual(
arr.length, index, `index ${index} expected to be at the end of arr (length ${arr.length})`);
}

View File

@ -10,7 +10,7 @@ import {InitialStylingFlags} from '../interfaces/definition';
import {BindingStore, BindingType, Player, PlayerBuilder, PlayerFactory, PlayerIndex} from '../interfaces/player'; import {BindingStore, BindingType, Player, PlayerBuilder, PlayerFactory, PlayerIndex} from '../interfaces/player';
import {Renderer3, RendererStyleFlags3, isProceduralRenderer} from '../interfaces/renderer'; import {Renderer3, RendererStyleFlags3, isProceduralRenderer} from '../interfaces/renderer';
import {InitialStyles, StylingContext, StylingFlags, StylingIndex} from '../interfaces/styling'; import {InitialStyles, StylingContext, StylingFlags, StylingIndex} from '../interfaces/styling';
import {LViewData, RootContext} from '../interfaces/view'; import {LView, RootContext} from '../interfaces/view';
import {NO_CHANGE} from '../tokens'; import {NO_CHANGE} from '../tokens';
import {getRootContext} from '../util'; import {getRootContext} from '../util';
@ -479,7 +479,7 @@ export function updateClassProp(
* @returns number the total amount of players that got queued for animation (if any) * @returns number the total amount of players that got queued for animation (if any)
*/ */
export function renderStyleAndClassBindings( export function renderStyleAndClassBindings(
context: StylingContext, renderer: Renderer3, rootOrView: RootContext | LViewData, context: StylingContext, renderer: Renderer3, rootOrView: RootContext | LView,
isFirstRender: boolean, classesStore?: BindingStore | null, isFirstRender: boolean, classesStore?: BindingStore | null,
stylesStore?: BindingStore | null): number { stylesStore?: BindingStore | null): number {
let totalPlayersQueued = 0; let totalPlayersQueued = 0;

View File

@ -14,7 +14,7 @@ import {LContext} from '../interfaces/context';
import {PlayState, Player, PlayerContext, PlayerIndex} from '../interfaces/player'; import {PlayState, Player, PlayerContext, PlayerIndex} from '../interfaces/player';
import {RElement} from '../interfaces/renderer'; import {RElement} from '../interfaces/renderer';
import {InitialStyles, StylingContext, StylingIndex} from '../interfaces/styling'; import {InitialStyles, StylingContext, StylingIndex} from '../interfaces/styling';
import {FLAGS, HEADER_OFFSET, HOST, LViewData, RootContext} from '../interfaces/view'; import {FLAGS, HEADER_OFFSET, HOST, LView, RootContext} from '../interfaces/view';
import {getTNode} from '../util'; import {getTNode} from '../util';
import {CorePlayerHandler} from './core_player_handler'; import {CorePlayerHandler} from './core_player_handler';
@ -59,20 +59,20 @@ export function allocStylingContext(
* @param index Index of the style allocation. See: `elementStyling`. * @param index Index of the style allocation. See: `elementStyling`.
* @param viewData The view to search for the styling context * @param viewData The view to search for the styling context
*/ */
export function getStylingContext(index: number, viewData: LViewData): StylingContext { export function getStylingContext(index: number, viewData: LView): StylingContext {
let storageIndex = index + HEADER_OFFSET; let storageIndex = index + HEADER_OFFSET;
let slotValue: LContainer|LViewData|StylingContext|RElement = viewData[storageIndex]; let slotValue: LContainer|LView|StylingContext|RElement = viewData[storageIndex];
let wrapper: LContainer|LViewData|StylingContext = viewData; let wrapper: LContainer|LView|StylingContext = viewData;
while (Array.isArray(slotValue)) { while (Array.isArray(slotValue)) {
wrapper = slotValue; wrapper = slotValue;
slotValue = slotValue[HOST] as LViewData | StylingContext | RElement; slotValue = slotValue[HOST] as LView | StylingContext | RElement;
} }
if (isStylingContext(wrapper)) { if (isStylingContext(wrapper)) {
return wrapper as StylingContext; return wrapper as StylingContext;
} else { } else {
// This is an LViewData or an LContainer // This is an LView or an LContainer
const stylingTemplate = getTNode(index, viewData).stylingTemplate; const stylingTemplate = getTNode(index, viewData).stylingTemplate;
if (wrapper !== viewData) { if (wrapper !== viewData) {
@ -85,8 +85,8 @@ export function getStylingContext(index: number, viewData: LViewData): StylingCo
} }
} }
function isStylingContext(value: LViewData | LContainer | StylingContext) { function isStylingContext(value: LView | LContainer | StylingContext) {
// Not an LViewData or an LContainer // Not an LView or an LContainer
return typeof value[FLAGS] !== 'number' && typeof value[ACTIVE_INDEX] !== 'number'; return typeof value[FLAGS] !== 'number' && typeof value[ACTIVE_INDEX] !== 'number';
} }
@ -158,8 +158,8 @@ export function getOrCreatePlayerContext(target: {}, context?: LContext | null):
return null; return null;
} }
const {lViewData, nodeIndex} = context; const {lView, nodeIndex} = context;
const stylingContext = getStylingContext(nodeIndex - HEADER_OFFSET, lViewData); const stylingContext = getStylingContext(nodeIndex - HEADER_OFFSET, lView);
return getPlayerContext(stylingContext) || allocPlayerContext(stylingContext); return getPlayerContext(stylingContext) || allocPlayerContext(stylingContext);
} }

View File

@ -6,10 +6,9 @@
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import {devModeEqual} from '../change_detection/change_detection_util';
import {global} from '../util'; import {global} from '../util';
import {assertDefined, assertLessThan} from './assert'; import {assertDataInRange, assertDefined} from './assert';
import {ACTIVE_INDEX, LContainer} from './interfaces/container'; import {ACTIVE_INDEX, LContainer} from './interfaces/container';
import {LContext, MONKEY_PATCH_KEY_NAME} from './interfaces/context'; import {LContext, MONKEY_PATCH_KEY_NAME} from './interfaces/context';
import {ComponentDef, DirectiveDef} from './interfaces/definition'; import {ComponentDef, DirectiveDef} from './interfaces/definition';
@ -17,7 +16,7 @@ import {NO_PARENT_INJECTOR, RelativeInjectorLocation, RelativeInjectorLocationFl
import {TContainerNode, TElementNode, TNode, TNodeFlags} from './interfaces/node'; import {TContainerNode, TElementNode, TNode, TNodeFlags} from './interfaces/node';
import {RComment, RElement, RText} from './interfaces/renderer'; import {RComment, RElement, RText} from './interfaces/renderer';
import {StylingContext} from './interfaces/styling'; import {StylingContext} from './interfaces/styling';
import {CONTEXT, DECLARATION_VIEW, FLAGS, HEADER_OFFSET, HOST, HOST_NODE, LViewData, LViewFlags, PARENT, RootContext, TData, TVIEW} from './interfaces/view'; import {CONTEXT, DECLARATION_VIEW, FLAGS, HEADER_OFFSET, HOST, HOST_NODE, LView, LViewFlags, PARENT, RootContext, TData, TVIEW, TView} from './interfaces/view';
@ -26,10 +25,7 @@ import {CONTEXT, DECLARATION_VIEW, FLAGS, HEADER_OFFSET, HOST, HOST_NODE, LViewD
* *
* Constraints are relaxed in checkNoChanges mode. See `devModeEqual` for details. * Constraints are relaxed in checkNoChanges mode. See `devModeEqual` for details.
*/ */
export function isDifferent(a: any, b: any, checkNoChangesMode: boolean): boolean { export function isDifferent(a: any, b: any): boolean {
if (ngDevMode && checkNoChangesMode) {
return !devModeEqual(a, b);
}
// NaN is the only value that is not equal to itself so the first // NaN is the only value that is not equal to itself so the first
// test checks if both a and b are not NaN // test checks if both a and b are not NaN
return !(a !== a && b !== b) && a !== b; return !(a !== a && b !== b) && a !== b;
@ -67,29 +63,24 @@ export function flatten(list: any[]): any[] {
return result; return result;
} }
/** Retrieves a value from any `LViewData` or `TData`. */ /** Retrieves a value from any `LView` or `TData`. */
export function loadInternal<T>(index: number, arr: LViewData | TData): T { export function loadInternal<T>(view: LView | TData, index: number): T {
ngDevMode && assertDataInRangeInternal(index + HEADER_OFFSET, arr); ngDevMode && assertDataInRange(view, index + HEADER_OFFSET);
return arr[index + HEADER_OFFSET]; return view[index + HEADER_OFFSET];
}
export function assertDataInRangeInternal(index: number, arr: any[]) {
assertLessThan(index, arr ? arr.length : 0, 'index expected to be a valid data index');
} }
/** /**
* Takes the value of a slot in `LViewData` and returns the element node. * Takes the value of a slot in `LView` and returns the element node.
* *
* Normally, element nodes are stored flat, but if the node has styles/classes on it, * Normally, element nodes are stored flat, but if the node has styles/classes on it,
* it might be wrapped in a styling context. Or if that node has a directive that injects * it might be wrapped in a styling context. Or if that node has a directive that injects
* ViewContainerRef, it may be wrapped in an LContainer. Or if that node is a component, * ViewContainerRef, it may be wrapped in an LContainer. Or if that node is a component,
* it will be wrapped in LViewData. It could even have all three, so we keep looping * it will be wrapped in LView. It could even have all three, so we keep looping
* until we find something that isn't an array. * until we find something that isn't an array.
* *
* @param value The initial value in `LViewData` * @param value The initial value in `LView`
*/ */
export function readElementValue(value: RElement | StylingContext | LContainer | LViewData): export function readElementValue(value: RElement | StylingContext | LContainer | LView): RElement {
RElement {
while (Array.isArray(value)) { while (Array.isArray(value)) {
value = value[HOST] as any; value = value[HOST] as any;
} }
@ -100,20 +91,20 @@ export function readElementValue(value: RElement | StylingContext | LContainer |
* Retrieves an element value from the provided `viewData`, by unwrapping * Retrieves an element value from the provided `viewData`, by unwrapping
* from any containers, component views, or style contexts. * from any containers, component views, or style contexts.
*/ */
export function getNativeByIndex(index: number, arr: LViewData): RElement { export function getNativeByIndex(index: number, lView: LView): RElement {
return readElementValue(arr[index + HEADER_OFFSET]); return readElementValue(lView[index + HEADER_OFFSET]);
} }
export function getNativeByTNode(tNode: TNode, hostView: LViewData): RElement|RText|RComment { export function getNativeByTNode(tNode: TNode, hostView: LView): RElement|RText|RComment {
return readElementValue(hostView[tNode.index]); return readElementValue(hostView[tNode.index]);
} }
export function getTNode(index: number, view: LViewData): TNode { export function getTNode(index: number, view: LView): TNode {
return view[TVIEW].data[index + HEADER_OFFSET] as TNode; return view[TVIEW].data[index + HEADER_OFFSET] as TNode;
} }
export function getComponentViewByIndex(nodeIndex: number, hostView: LViewData): LViewData { export function getComponentViewByIndex(nodeIndex: number, hostView: LView): LView {
// Could be an LViewData or an LContainer. If LContainer, unwrap to find LViewData. // Could be an LView or an LContainer. If LContainer, unwrap to find LView.
const slotValue = hostView[nodeIndex]; const slotValue = hostView[nodeIndex];
return slotValue.length >= HEADER_OFFSET ? slotValue : slotValue[HOST]; return slotValue.length >= HEADER_OFFSET ? slotValue : slotValue[HOST];
} }
@ -135,26 +126,26 @@ export function isLContainer(value: RElement | RComment | LContainer | StylingCo
return Array.isArray(value) && typeof value[ACTIVE_INDEX] === 'number'; return Array.isArray(value) && typeof value[ACTIVE_INDEX] === 'number';
} }
export function isRootView(target: LViewData): boolean { export function isRootView(target: LView): boolean {
return (target[FLAGS] & LViewFlags.IsRoot) !== 0; return (target[FLAGS] & LViewFlags.IsRoot) !== 0;
} }
/** /**
* Retrieve the root view from any component by walking the parent `LViewData` until * Retrieve the root view from any component by walking the parent `LView` until
* reaching the root `LViewData`. * reaching the root `LView`.
* *
* @param component any component * @param component any component
*/ */
export function getRootView(target: LViewData | {}): LViewData { export function getRootView(target: LView | {}): LView {
ngDevMode && assertDefined(target, 'component'); ngDevMode && assertDefined(target, 'component');
let lViewData = Array.isArray(target) ? (target as LViewData) : readPatchedLViewData(target) !; let lView = Array.isArray(target) ? (target as LView) : readPatchedLView(target) !;
while (lViewData && !(lViewData[FLAGS] & LViewFlags.IsRoot)) { while (lView && !(lView[FLAGS] & LViewFlags.IsRoot)) {
lViewData = lViewData[PARENT] !; lView = lView[PARENT] !;
} }
return lViewData; return lView;
} }
export function getRootContext(viewOrComponent: LViewData | {}): RootContext { export function getRootContext(viewOrComponent: LView | {}): RootContext {
const rootView = getRootView(viewOrComponent); const rootView = getRootView(viewOrComponent);
ngDevMode && ngDevMode &&
assertDefined(rootView[CONTEXT], 'RootView has no context. Perhaps it is disconnected?'); assertDefined(rootView[CONTEXT], 'RootView has no context. Perhaps it is disconnected?');
@ -165,14 +156,14 @@ export function getRootContext(viewOrComponent: LViewData | {}): RootContext {
* Returns the monkey-patch value data present on the target (which could be * Returns the monkey-patch value data present on the target (which could be
* a component, directive or a DOM node). * a component, directive or a DOM node).
*/ */
export function readPatchedData(target: any): LViewData|LContext|null { export function readPatchedData(target: any): LView|LContext|null {
return target[MONKEY_PATCH_KEY_NAME]; return target[MONKEY_PATCH_KEY_NAME];
} }
export function readPatchedLViewData(target: any): LViewData|null { export function readPatchedLView(target: any): LView|null {
const value = readPatchedData(target); const value = readPatchedData(target);
if (value) { if (value) {
return Array.isArray(value) ? value : (value as LContext).lViewData; return Array.isArray(value) ? value : (value as LContext).lView;
} }
return null; return null;
} }
@ -195,11 +186,10 @@ export function getParentInjectorViewOffset(parentLocation: RelativeInjectorLoca
* injector. * injector.
* *
* @param location The location of the parent injector, which contains the view offset * @param location The location of the parent injector, which contains the view offset
* @param startView The LViewData instance from which to start walking up the view tree * @param startView The LView instance from which to start walking up the view tree
* @returns The LViewData instance that contains the parent injector * @returns The LView instance that contains the parent injector
*/ */
export function getParentInjectorView( export function getParentInjectorView(location: RelativeInjectorLocation, startView: LView): LView {
location: RelativeInjectorLocation, startView: LViewData): LViewData {
let viewOffset = getParentInjectorViewOffset(location); let viewOffset = getParentInjectorViewOffset(location);
let parentView = startView; let parentView = startView;
// For most cases, the parent injector can be found on the host node (e.g. for component // For most cases, the parent injector can be found on the host node (e.g. for component
@ -218,12 +208,12 @@ export function getParentInjectorView(
* then walks up the declaration view tree until the TNode of the parent injector is found. * then walks up the declaration view tree until the TNode of the parent injector is found.
* *
* @param location The location of the parent injector, which contains the view offset * @param location The location of the parent injector, which contains the view offset
* @param startView The LViewData instance from which to start walking up the view tree * @param startView The LView instance from which to start walking up the view tree
* @param startTNode The TNode instance of the starting element * @param startTNode The TNode instance of the starting element
* @returns The TNode of the parent injector * @returns The TNode of the parent injector
*/ */
export function getParentInjectorTNode( export function getParentInjectorTNode(
location: RelativeInjectorLocation, startView: LViewData, startTNode: TNode): TElementNode| location: RelativeInjectorLocation, startView: LView, startTNode: TNode): TElementNode|
TContainerNode|null { TContainerNode|null {
if (startTNode.parent && startTNode.parent.injectorIndex !== -1) { if (startTNode.parent && startTNode.parent.injectorIndex !== -1) {
// view offset is 0 // view offset is 0

View File

@ -25,10 +25,10 @@ import {RenderFlags} from './interfaces/definition';
import {TContainerNode, TElementContainerNode, TElementNode, TNode, TNodeFlags, TNodeType, TViewNode} from './interfaces/node'; import {TContainerNode, TElementContainerNode, TElementNode, TNode, TNodeFlags, TNodeType, TViewNode} from './interfaces/node';
import {LQueries} from './interfaces/query'; import {LQueries} from './interfaces/query';
import {RComment, RElement, Renderer3, isProceduralRenderer} from './interfaces/renderer'; import {RComment, RElement, Renderer3, isProceduralRenderer} from './interfaces/renderer';
import {CONTEXT, HOST_NODE, LViewData, QUERIES, RENDERER, TView} from './interfaces/view'; import {CONTEXT, HOST_NODE, LView, QUERIES, RENDERER, TView} from './interfaces/view';
import {assertNodeOfPossibleTypes, assertNodeType} from './node_assert'; import {assertNodeOfPossibleTypes, assertNodeType} from './node_assert';
import {addRemoveViewFromContainer, appendChild, detachView, findComponentView, getBeforeNodeForView, insertView, nativeInsertBefore, nativeNextSibling, nativeParentNode, removeView} from './node_manipulation'; import {addRemoveViewFromContainer, appendChild, detachView, findComponentView, getBeforeNodeForView, insertView, nativeInsertBefore, nativeNextSibling, nativeParentNode, removeView} from './node_manipulation';
import {getPreviousOrParentTNode, getRenderer, getViewData} from './state'; import {getLView, getPreviousOrParentTNode} from './state';
import {getComponentViewByIndex, getNativeByTNode, getParentInjectorTNode, getParentInjectorView, hasParentInjector, isComponent, isLContainer, isRootView} from './util'; import {getComponentViewByIndex, getNativeByTNode, getParentInjectorTNode, getParentInjectorView, hasParentInjector, isComponent, isLContainer, isRootView} from './util';
import {ViewRef} from './view_ref'; import {ViewRef} from './view_ref';
@ -41,7 +41,7 @@ import {ViewRef} from './view_ref';
*/ */
export function injectElementRef(ElementRefToken: typeof ViewEngine_ElementRef): export function injectElementRef(ElementRefToken: typeof ViewEngine_ElementRef):
ViewEngine_ElementRef { ViewEngine_ElementRef {
return createElementRef(ElementRefToken, getPreviousOrParentTNode(), getViewData()); return createElementRef(ElementRefToken, getPreviousOrParentTNode(), getLView());
} }
let R3ElementRef: {new (native: RElement | RComment): ViewEngine_ElementRef}; let R3ElementRef: {new (native: RElement | RComment): ViewEngine_ElementRef};
@ -56,7 +56,7 @@ let R3ElementRef: {new (native: RElement | RComment): ViewEngine_ElementRef};
*/ */
export function createElementRef( export function createElementRef(
ElementRefToken: typeof ViewEngine_ElementRef, tNode: TNode, ElementRefToken: typeof ViewEngine_ElementRef, tNode: TNode,
view: LViewData): ViewEngine_ElementRef { view: LView): ViewEngine_ElementRef {
if (!R3ElementRef) { if (!R3ElementRef) {
// TODO: Fix class name, should be ElementRef, but there appears to be a rollup bug // TODO: Fix class name, should be ElementRef, but there appears to be a rollup bug
R3ElementRef = class ElementRef_ extends ElementRefToken {}; R3ElementRef = class ElementRef_ extends ElementRefToken {};
@ -66,7 +66,7 @@ export function createElementRef(
let R3TemplateRef: { let R3TemplateRef: {
new ( new (
_declarationParentView: LViewData, elementRef: ViewEngine_ElementRef, _tView: TView, _declarationParentView: LView, elementRef: ViewEngine_ElementRef, _tView: TView,
_renderer: Renderer3, _queries: LQueries | null, _injectorIndex: number): _renderer: Renderer3, _queries: LQueries | null, _injectorIndex: number):
ViewEngine_TemplateRef<any> ViewEngine_TemplateRef<any>
}; };
@ -80,7 +80,7 @@ export function injectTemplateRef<T>(
TemplateRefToken: typeof ViewEngine_TemplateRef, TemplateRefToken: typeof ViewEngine_TemplateRef,
ElementRefToken: typeof ViewEngine_ElementRef): ViewEngine_TemplateRef<T>|null { ElementRefToken: typeof ViewEngine_ElementRef): ViewEngine_TemplateRef<T>|null {
return createTemplateRef<T>( return createTemplateRef<T>(
TemplateRefToken, ElementRefToken, getPreviousOrParentTNode(), getViewData()); TemplateRefToken, ElementRefToken, getPreviousOrParentTNode(), getLView());
} }
/** /**
@ -94,12 +94,12 @@ export function injectTemplateRef<T>(
*/ */
export function createTemplateRef<T>( export function createTemplateRef<T>(
TemplateRefToken: typeof ViewEngine_TemplateRef, ElementRefToken: typeof ViewEngine_ElementRef, TemplateRefToken: typeof ViewEngine_TemplateRef, ElementRefToken: typeof ViewEngine_ElementRef,
hostTNode: TNode, hostView: LViewData): ViewEngine_TemplateRef<T>|null { hostTNode: TNode, hostView: LView): ViewEngine_TemplateRef<T>|null {
if (!R3TemplateRef) { if (!R3TemplateRef) {
// TODO: Fix class name, should be TemplateRef, but there appears to be a rollup bug // TODO: Fix class name, should be TemplateRef, but there appears to be a rollup bug
R3TemplateRef = class TemplateRef_<T> extends TemplateRefToken<T> { R3TemplateRef = class TemplateRef_<T> extends TemplateRefToken<T> {
constructor( constructor(
private _declarationParentView: LViewData, readonly elementRef: ViewEngine_ElementRef, private _declarationParentView: LView, readonly elementRef: ViewEngine_ElementRef,
private _tView: TView, private _renderer: Renderer3, private _queries: LQueries|null, private _tView: TView, private _renderer: Renderer3, private _queries: LQueries|null,
private _injectorIndex: number) { private _injectorIndex: number) {
super(); super();
@ -107,7 +107,7 @@ export function createTemplateRef<T>(
createEmbeddedView( createEmbeddedView(
context: T, container?: LContainer, context: T, container?: LContainer,
hostTNode?: TElementNode|TContainerNode|TElementContainerNode, hostView?: LViewData, hostTNode?: TElementNode|TContainerNode|TElementContainerNode, hostView?: LView,
index?: number): viewEngine_EmbeddedViewRef<T> { index?: number): viewEngine_EmbeddedViewRef<T> {
const lView = createEmbeddedViewAndNode( const lView = createEmbeddedViewAndNode(
this._tView, context, this._declarationParentView, this._renderer, this._queries, this._tView, context, this._declarationParentView, this._renderer, this._queries,
@ -128,7 +128,7 @@ export function createTemplateRef<T>(
ngDevMode && assertDefined(hostTNode.tViews, 'TView must be allocated'); ngDevMode && assertDefined(hostTNode.tViews, 'TView must be allocated');
return new R3TemplateRef( return new R3TemplateRef(
hostView, createElementRef(ElementRefToken, hostTNode, hostView), hostTNode.tViews as TView, hostView, createElementRef(ElementRefToken, hostTNode, hostView), hostTNode.tViews as TView,
getRenderer(), hostContainer[QUERIES], hostTNode.injectorIndex); getLView()[RENDERER], hostContainer[QUERIES], hostTNode.injectorIndex);
} else { } else {
return null; return null;
} }
@ -137,7 +137,7 @@ export function createTemplateRef<T>(
let R3ViewContainerRef: { let R3ViewContainerRef: {
new ( new (
lContainer: LContainer, hostTNode: TElementNode | TContainerNode | TElementContainerNode, lContainer: LContainer, hostTNode: TElementNode | TContainerNode | TElementContainerNode,
hostView: LViewData): ViewEngine_ViewContainerRef hostView: LView): ViewEngine_ViewContainerRef
}; };
/** /**
@ -151,13 +151,13 @@ export function injectViewContainerRef(
ElementRefToken: typeof ViewEngine_ElementRef): ViewEngine_ViewContainerRef { ElementRefToken: typeof ViewEngine_ElementRef): ViewEngine_ViewContainerRef {
const previousTNode = const previousTNode =
getPreviousOrParentTNode() as TElementNode | TElementContainerNode | TContainerNode; getPreviousOrParentTNode() as TElementNode | TElementContainerNode | TContainerNode;
return createContainerRef(ViewContainerRefToken, ElementRefToken, previousTNode, getViewData()); return createContainerRef(ViewContainerRefToken, ElementRefToken, previousTNode, getLView());
} }
export class NodeInjector implements Injector { export class NodeInjector implements Injector {
constructor( constructor(
private _tNode: TElementNode|TContainerNode|TElementContainerNode, private _tNode: TElementNode|TContainerNode|TElementContainerNode, private _hostView: LView) {
private _hostView: LViewData) {} }
get(token: any, notFoundValue?: any): any { get(token: any, notFoundValue?: any): any {
return getOrCreateInjectable( return getOrCreateInjectable(
@ -178,7 +178,7 @@ export function createContainerRef(
ViewContainerRefToken: typeof ViewEngine_ViewContainerRef, ViewContainerRefToken: typeof ViewEngine_ViewContainerRef,
ElementRefToken: typeof ViewEngine_ElementRef, ElementRefToken: typeof ViewEngine_ElementRef,
hostTNode: TElementNode|TContainerNode|TElementContainerNode, hostTNode: TElementNode|TContainerNode|TElementContainerNode,
hostView: LViewData): ViewEngine_ViewContainerRef { hostView: LView): ViewEngine_ViewContainerRef {
if (!R3ViewContainerRef) { if (!R3ViewContainerRef) {
// TODO: Fix class name, should be ViewContainerRef, but there appears to be a rollup bug // TODO: Fix class name, should be ViewContainerRef, but there appears to be a rollup bug
R3ViewContainerRef = class ViewContainerRef_ extends ViewContainerRefToken { R3ViewContainerRef = class ViewContainerRef_ extends ViewContainerRefToken {
@ -187,7 +187,7 @@ export function createContainerRef(
constructor( constructor(
private _lContainer: LContainer, private _lContainer: LContainer,
private _hostTNode: TElementNode|TContainerNode|TElementContainerNode, private _hostTNode: TElementNode|TContainerNode|TElementContainerNode,
private _hostView: LViewData) { private _hostView: LView) {
super(); super();
} }
@ -249,7 +249,7 @@ export function createContainerRef(
if (viewRef.destroyed) { if (viewRef.destroyed) {
throw new Error('Cannot insert a destroyed View in a ViewContainer!'); throw new Error('Cannot insert a destroyed View in a ViewContainer!');
} }
const lView = (viewRef as ViewRef<any>)._view !; const lView = (viewRef as ViewRef<any>)._lView !;
const adjustedIdx = this._adjustIndex(index); const adjustedIdx = this._adjustIndex(index);
insertView(lView, this._lContainer, this._hostView, adjustedIdx, this._hostTNode.index); insertView(lView, this._lContainer, this._hostView, adjustedIdx, this._hostTNode.index);
@ -341,7 +341,7 @@ export function createContainerRef(
/** Returns a ChangeDetectorRef (a.k.a. a ViewRef) */ /** Returns a ChangeDetectorRef (a.k.a. a ViewRef) */
export function injectChangeDetectorRef(): ViewEngine_ChangeDetectorRef { export function injectChangeDetectorRef(): ViewEngine_ChangeDetectorRef {
return createViewRef(getPreviousOrParentTNode(), getViewData(), null); return createViewRef(getPreviousOrParentTNode(), getLView(), null);
} }
/** /**
@ -353,7 +353,7 @@ export function injectChangeDetectorRef(): ViewEngine_ChangeDetectorRef {
* @returns The ChangeDetectorRef to use * @returns The ChangeDetectorRef to use
*/ */
export function createViewRef( export function createViewRef(
hostTNode: TNode, hostView: LViewData, context: any): ViewEngine_ChangeDetectorRef { hostTNode: TNode, hostView: LView, context: any): ViewEngine_ChangeDetectorRef {
if (isComponent(hostTNode)) { if (isComponent(hostTNode)) {
const componentIndex = hostTNode.flags >> TNodeFlags.DirectiveStartingIndexShift; const componentIndex = hostTNode.flags >> TNodeFlags.DirectiveStartingIndexShift;
const componentView = getComponentViewByIndex(hostTNode.index, hostView); const componentView = getComponentViewByIndex(hostTNode.index, hostView);
@ -365,7 +365,7 @@ export function createViewRef(
return null !; return null !;
} }
function getOrCreateRenderer2(view: LViewData): Renderer2 { function getOrCreateRenderer2(view: LView): Renderer2 {
const renderer = view[RENDERER]; const renderer = view[RENDERER];
if (isProceduralRenderer(renderer)) { if (isProceduralRenderer(renderer)) {
return renderer as Renderer2; return renderer as Renderer2;
@ -376,5 +376,5 @@ function getOrCreateRenderer2(view: LViewData): Renderer2 {
/** Returns a Renderer2 (or throws when application was bootstrapped with Renderer3) */ /** Returns a Renderer2 (or throws when application was bootstrapped with Renderer3) */
export function injectRenderer2(): Renderer2 { export function injectRenderer2(): Renderer2 {
return getOrCreateRenderer2(getViewData()); return getOrCreateRenderer2(getLView());
} }

View File

@ -11,7 +11,7 @@ import {ElementRef as ViewEngine_ElementRef} from '../linker/element_ref';
import {TemplateRef as ViewEngine_TemplateRef} from '../linker/template_ref'; import {TemplateRef as ViewEngine_TemplateRef} from '../linker/template_ref';
import {TNode} from './interfaces/node'; import {TNode} from './interfaces/node';
import {LViewData} from './interfaces/view'; import {LView} from './interfaces/view';
import {createTemplateRef} from './view_engine_compatibility'; import {createTemplateRef} from './view_engine_compatibility';
@ -20,6 +20,6 @@ import {createTemplateRef} from './view_engine_compatibility';
* Retrieves `TemplateRef` instance from `Injector` when a local reference is placed on the * Retrieves `TemplateRef` instance from `Injector` when a local reference is placed on the
* `<ng-template>` element. * `<ng-template>` element.
*/ */
export function templateRefExtractor(tNode: TNode, currentView: LViewData) { export function templateRefExtractor(tNode: TNode, currentView: LView) {
return createTemplateRef(ViewEngine_TemplateRef, ViewEngine_ElementRef, tNode, currentView); return createTemplateRef(ViewEngine_TemplateRef, ViewEngine_ElementRef, tNode, currentView);
} }

View File

@ -13,9 +13,8 @@ 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, RENDERER_FACTORY} from './interfaces/view'; import {FLAGS, HOST, HOST_NODE, LView, LViewFlags, PARENT, RENDERER_FACTORY} from './interfaces/view';
import {destroyLView} from './node_manipulation'; import {destroyLView} from './node_manipulation';
import {getRendererFactory} from './state';
import {getNativeByTNode} from './util'; import {getNativeByTNode} from './util';
@ -33,42 +32,42 @@ export class ViewRef<T> implements viewEngine_EmbeddedViewRef<T>, viewEngine_Int
/** /**
* @internal * @internal
*/ */
_view: LViewData; public _tViewNode: TViewNode|null = null;
/** /**
* @internal * @internal
*/ */
_tViewNode: TViewNode|null = null; public _lView: LView;
get rootNodes(): any[] { get rootNodes(): any[] {
if (this._view[HOST] == null) { if (this._lView[HOST] == null) {
const tView = this._view[HOST_NODE] as TViewNode; const tView = this._lView[HOST_NODE] as TViewNode;
return collectNativeNodes(this._view, tView, []); return collectNativeNodes(this._lView, tView, []);
} }
return []; return [];
} }
constructor(_view: LViewData, private _context: T|null, private _componentIndex: number) { constructor(_lView: LView, private _context: T|null, private _componentIndex: number) {
this._view = _view; this._lView = _lView;
} }
get context(): T { return this._context ? this._context : this._lookUpContext(); } get context(): T { return this._context ? this._context : this._lookUpContext(); }
get destroyed(): boolean { get destroyed(): boolean {
return (this._view[FLAGS] & LViewFlags.Destroyed) === LViewFlags.Destroyed; return (this._lView[FLAGS] & LViewFlags.Destroyed) === LViewFlags.Destroyed;
} }
destroy(): void { destroy(): void {
if (this._appRef) { if (this._appRef) {
this._appRef.detachView(this); this._appRef.detachView(this);
} else if (this._viewContainerRef && viewAttached(this._view)) { } else if (this._viewContainerRef && viewAttached(this._lView)) {
this._viewContainerRef.detach(this._viewContainerRef.indexOf(this)); this._viewContainerRef.detach(this._viewContainerRef.indexOf(this));
this._viewContainerRef = null; this._viewContainerRef = null;
} }
destroyLView(this._view); destroyLView(this._lView);
} }
onDestroy(callback: Function) { storeCleanupFn(this._view, callback); } onDestroy(callback: Function) { storeCleanupFn(this._lView, callback); }
/** /**
* Marks a view and all of its ancestors dirty. * Marks a view and all of its ancestors dirty.
@ -104,7 +103,7 @@ export class ViewRef<T> implements viewEngine_EmbeddedViewRef<T>, viewEngine_Int
* } * }
* ``` * ```
*/ */
markForCheck(): void { markViewDirty(this._view); } markForCheck(): void { markViewDirty(this._lView); }
/** /**
* Detaches the view from the change detection tree. * Detaches the view from the change detection tree.
@ -159,7 +158,7 @@ export class ViewRef<T> implements viewEngine_EmbeddedViewRef<T>, viewEngine_Int
* } * }
* ``` * ```
*/ */
detach(): void { this._view[FLAGS] &= ~LViewFlags.Attached; } detach(): void { this._lView[FLAGS] &= ~LViewFlags.Attached; }
/** /**
* Re-attaches a view to the change detection tree. * Re-attaches a view to the change detection tree.
@ -217,7 +216,7 @@ export class ViewRef<T> implements viewEngine_EmbeddedViewRef<T>, viewEngine_Int
* } * }
* ``` * ```
*/ */
reattach(): void { this._view[FLAGS] |= LViewFlags.Attached; } reattach(): void { this._lView[FLAGS] |= LViewFlags.Attached; }
/** /**
* Checks the view and its children. * Checks the view and its children.
@ -241,7 +240,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 = this._view[RENDERER_FACTORY]; const rendererFactory = this._lView[RENDERER_FACTORY];
if (rendererFactory.begin) { if (rendererFactory.begin) {
rendererFactory.begin(); rendererFactory.begin();
} }
@ -266,13 +265,13 @@ export class ViewRef<T> implements viewEngine_EmbeddedViewRef<T>, viewEngine_Int
attachToAppRef(appRef: ApplicationRef) { this._appRef = appRef; } attachToAppRef(appRef: ApplicationRef) { this._appRef = appRef; }
private _lookUpContext(): T { private _lookUpContext(): T {
return this._context = this._view[PARENT] ![this._componentIndex] as T; return this._context = this._lView[PARENT] ![this._componentIndex] as T;
} }
} }
/** @internal */ /** @internal */
export class RootViewRef<T> extends ViewRef<T> { export class RootViewRef<T> extends ViewRef<T> {
constructor(public _view: LViewData) { super(_view, null, -1); } constructor(public _view: LView) { super(_view, null, -1); }
detectChanges(): void { detectChangesInRootView(this._view); } detectChanges(): void { detectChangesInRootView(this._view); }
@ -281,7 +280,7 @@ export class RootViewRef<T> extends ViewRef<T> {
get context(): T { return null !; } get context(): T { return null !; }
} }
function collectNativeNodes(lView: LViewData, parentTNode: TNode, result: any[]): any[] { function collectNativeNodes(lView: LView, parentTNode: TNode, result: any[]): any[] {
let tNodeChild = parentTNode.child; let tNodeChild = parentTNode.child;
while (tNodeChild) { while (tNodeChild) {

View File

@ -6,7 +6,8 @@
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import {getCurrentSanitizer} from '../render3/state'; import {SANITIZER} from '../render3/interfaces/view';
import {getLView} from '../render3/state';
import {stringify} from '../render3/util'; import {stringify} from '../render3/util';
import {BypassType, allowSanitizationBypass} from './bypass'; import {BypassType, allowSanitizationBypass} from './bypass';
@ -31,9 +32,9 @@ import {_sanitizeUrl as _sanitizeUrl} from './url_sanitizer';
* and urls have been removed. * and urls have been removed.
*/ */
export function sanitizeHtml(unsafeHtml: any): string { export function sanitizeHtml(unsafeHtml: any): string {
const s = getCurrentSanitizer(); const sanitizer = getLView()[SANITIZER];
if (s) { if (sanitizer) {
return s.sanitize(SecurityContext.HTML, unsafeHtml) || ''; return sanitizer.sanitize(SecurityContext.HTML, unsafeHtml) || '';
} }
if (allowSanitizationBypass(unsafeHtml, BypassType.Html)) { if (allowSanitizationBypass(unsafeHtml, BypassType.Html)) {
return unsafeHtml.toString(); return unsafeHtml.toString();
@ -55,9 +56,9 @@ export function sanitizeHtml(unsafeHtml: any): string {
* dangerous javascript and urls have been removed. * dangerous javascript and urls have been removed.
*/ */
export function sanitizeStyle(unsafeStyle: any): string { export function sanitizeStyle(unsafeStyle: any): string {
const s = getCurrentSanitizer(); const sanitizer = getLView()[SANITIZER];
if (s) { if (sanitizer) {
return s.sanitize(SecurityContext.STYLE, unsafeStyle) || ''; return sanitizer.sanitize(SecurityContext.STYLE, unsafeStyle) || '';
} }
if (allowSanitizationBypass(unsafeStyle, BypassType.Style)) { if (allowSanitizationBypass(unsafeStyle, BypassType.Style)) {
return unsafeStyle.toString(); return unsafeStyle.toString();
@ -80,9 +81,9 @@ export function sanitizeStyle(unsafeStyle: any): string {
* all of the dangerous javascript has been removed. * all of the dangerous javascript has been removed.
*/ */
export function sanitizeUrl(unsafeUrl: any): string { export function sanitizeUrl(unsafeUrl: any): string {
const s = getCurrentSanitizer(); const sanitizer = getLView()[SANITIZER];
if (s) { if (sanitizer) {
return s.sanitize(SecurityContext.URL, unsafeUrl) || ''; return sanitizer.sanitize(SecurityContext.URL, unsafeUrl) || '';
} }
if (allowSanitizationBypass(unsafeUrl, BypassType.Url)) { if (allowSanitizationBypass(unsafeUrl, BypassType.Url)) {
return unsafeUrl.toString(); return unsafeUrl.toString();
@ -100,9 +101,9 @@ export function sanitizeUrl(unsafeUrl: any): string {
* only trusted `url`s have been allowed to pass. * only trusted `url`s have been allowed to pass.
*/ */
export function sanitizeResourceUrl(unsafeResourceUrl: any): string { export function sanitizeResourceUrl(unsafeResourceUrl: any): string {
const s = getCurrentSanitizer(); const sanitizer = getLView()[SANITIZER];
if (s) { if (sanitizer) {
return s.sanitize(SecurityContext.RESOURCE_URL, unsafeResourceUrl) || ''; return sanitizer.sanitize(SecurityContext.RESOURCE_URL, unsafeResourceUrl) || '';
} }
if (allowSanitizationBypass(unsafeResourceUrl, BypassType.ResourceUrl)) { if (allowSanitizationBypass(unsafeResourceUrl, BypassType.ResourceUrl)) {
return unsafeResourceUrl.toString(); return unsafeResourceUrl.toString();
@ -113,16 +114,17 @@ export function sanitizeResourceUrl(unsafeResourceUrl: any): string {
/** /**
* A `script` sanitizer which only lets trusted javascript through. * A `script` sanitizer which only lets trusted javascript through.
* *
* This passes only `script`s marked trusted by calling {@link bypassSanitizationTrustScript}. * This passes only `script`s marked trusted by calling {@link
* bypassSanitizationTrustScript}.
* *
* @param unsafeScript untrusted `script`, typically from the user. * @param unsafeScript untrusted `script`, typically from the user.
* @returns `url` string which is safe to bind to the `<script>` element such as `<img src>`, * @returns `url` string which is safe to bind to the `<script>` element such as `<img src>`,
* because only trusted `scripts`s have been allowed to pass. * because only trusted `scripts` have been allowed to pass.
*/ */
export function sanitizeScript(unsafeScript: any): string { export function sanitizeScript(unsafeScript: any): string {
const s = getCurrentSanitizer(); const sanitizer = getLView()[SANITIZER];
if (s) { if (sanitizer) {
return s.sanitize(SecurityContext.SCRIPT, unsafeScript) || ''; return sanitizer.sanitize(SecurityContext.SCRIPT, unsafeScript) || '';
} }
if (allowSanitizationBypass(unsafeScript, BypassType.Script)) { if (allowSanitizationBypass(unsafeScript, BypassType.Script)) {
return unsafeScript.toString(); return unsafeScript.toString();

View File

@ -387,7 +387,7 @@
"name": "containerInternal" "name": "containerInternal"
}, },
{ {
"name": "contextViewData" "name": "contextLView"
}, },
{ {
"name": "createContainerRef" "name": "createContainerRef"
@ -411,7 +411,7 @@
"name": "createLContext" "name": "createLContext"
}, },
{ {
"name": "createLViewData" "name": "createLView"
}, },
{ {
"name": "createNodeAtIndex" "name": "createNodeAtIndex"
@ -611,9 +611,6 @@
{ {
"name": "getCreationMode" "name": "getCreationMode"
}, },
{
"name": "getCurrentQueries"
},
{ {
"name": "getDirectiveDef" "name": "getDirectiveDef"
}, },
@ -659,6 +656,9 @@
{ {
"name": "getLContainer" "name": "getLContainer"
}, },
{
"name": "getLView"
},
{ {
"name": "getLViewChild" "name": "getLViewChild"
}, },
@ -740,12 +740,6 @@
{ {
"name": "getRenderParent" "name": "getRenderParent"
}, },
{
"name": "getRenderer"
},
{
"name": "getRendererFactory"
},
{ {
"name": "getRootContext" "name": "getRootContext"
}, },
@ -770,9 +764,6 @@
{ {
"name": "getTNode" "name": "getTNode"
}, },
{
"name": "getTView"
},
{ {
"name": "getTViewCleanup" "name": "getTViewCleanup"
}, },
@ -785,9 +776,6 @@
{ {
"name": "getValue" "name": "getValue"
}, },
{
"name": "getViewData"
},
{ {
"name": "hackImplementationOfElementStyling" "name": "hackImplementationOfElementStyling"
}, },
@ -1032,7 +1020,7 @@
"name": "readPatchedData" "name": "readPatchedData"
}, },
{ {
"name": "readPatchedLViewData" "name": "readPatchedLView"
}, },
{ {
"name": "refreshChildComponents" "name": "refreshChildComponents"
@ -1103,9 +1091,6 @@
{ {
"name": "setContextPlayersDirty" "name": "setContextPlayersDirty"
}, },
{
"name": "setCurrentQueries"
},
{ {
"name": "setDirty" "name": "setDirty"
}, },
@ -1187,9 +1172,6 @@
{ {
"name": "textBinding" "name": "textBinding"
}, },
{
"name": "throwErrorIfNoChangesMode"
},
{ {
"name": "throwMultipleComponentError" "name": "throwMultipleComponentError"
}, },

View File

@ -101,9 +101,6 @@
{ {
"name": "PRIVATE_PREFIX" "name": "PRIVATE_PREFIX"
}, },
{
"name": "QUERIES"
},
{ {
"name": "RENDERER" "name": "RENDERER"
}, },
@ -174,7 +171,7 @@
"name": "componentRefresh" "name": "componentRefresh"
}, },
{ {
"name": "createLViewData" "name": "createLView"
}, },
{ {
"name": "createNodeAtIndex" "name": "createNodeAtIndex"
@ -278,6 +275,9 @@
{ {
"name": "getLContainer" "name": "getLContainer"
}, },
{
"name": "getLView"
},
{ {
"name": "getLViewChild" "name": "getLViewChild"
}, },
@ -320,21 +320,12 @@
{ {
"name": "getRenderParent" "name": "getRenderParent"
}, },
{
"name": "getRenderer"
},
{ {
"name": "getRootContext" "name": "getRootContext"
}, },
{ {
"name": "getRootView" "name": "getRootView"
}, },
{
"name": "getTView"
},
{
"name": "getViewData"
},
{ {
"name": "hasParentInjector" "name": "hasParentInjector"
}, },
@ -411,7 +402,7 @@
"name": "readPatchedData" "name": "readPatchedData"
}, },
{ {
"name": "readPatchedLViewData" "name": "readPatchedLView"
}, },
{ {
"name": "refreshChildComponents" "name": "refreshChildComponents"

View File

@ -347,9 +347,6 @@
{ {
"name": "PlatformRef" "name": "PlatformRef"
}, },
{
"name": "QUERIES"
},
{ {
"name": "R3Injector" "name": "R3Injector"
}, },
@ -551,9 +548,6 @@
{ {
"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"
}, },
@ -663,7 +657,7 @@
"name": "createLContext" "name": "createLContext"
}, },
{ {
"name": "createLViewData" "name": "createLView"
}, },
{ {
"name": "createNodeAtIndex" "name": "createNodeAtIndex"
@ -887,6 +881,9 @@
{ {
"name": "getLContainer" "name": "getLContainer"
}, },
{
"name": "getLView"
},
{ {
"name": "getLViewChild" "name": "getLViewChild"
}, },
@ -953,9 +950,6 @@
{ {
"name": "getRenderParent" "name": "getRenderParent"
}, },
{
"name": "getRenderer"
},
{ {
"name": "getRootContext" "name": "getRootContext"
}, },
@ -968,15 +962,9 @@
{ {
"name": "getTNode" "name": "getTNode"
}, },
{
"name": "getTView"
},
{ {
"name": "getTViewCleanup" "name": "getTViewCleanup"
}, },
{
"name": "getViewData"
},
{ {
"name": "hasDeps" "name": "hasDeps"
}, },
@ -1239,7 +1227,7 @@
"name": "readPatchedData" "name": "readPatchedData"
}, },
{ {
"name": "readPatchedLViewData" "name": "readPatchedLView"
}, },
{ {
"name": "recursivelyProcessProviders" "name": "recursivelyProcessProviders"

View File

@ -444,7 +444,7 @@
"name": "containerInternal" "name": "containerInternal"
}, },
{ {
"name": "contextViewData" "name": "contextLView"
}, },
{ {
"name": "createContainerRef" "name": "createContainerRef"
@ -468,7 +468,7 @@
"name": "createLContext" "name": "createLContext"
}, },
{ {
"name": "createLViewData" "name": "createLView"
}, },
{ {
"name": "createNodeAtIndex" "name": "createNodeAtIndex"
@ -654,14 +654,11 @@
"name": "getContainerRenderParent" "name": "getContainerRenderParent"
}, },
{ {
"name": "getContextViewData" "name": "getContextLView"
}, },
{ {
"name": "getCreationMode" "name": "getCreationMode"
}, },
{
"name": "getCurrentQueries"
},
{ {
"name": "getCurrentView" "name": "getCurrentView"
}, },
@ -701,6 +698,9 @@
{ {
"name": "getLContainer" "name": "getLContainer"
}, },
{
"name": "getLView"
},
{ {
"name": "getLViewChild" "name": "getLViewChild"
}, },
@ -779,12 +779,6 @@
{ {
"name": "getRenderParent" "name": "getRenderParent"
}, },
{
"name": "getRenderer"
},
{
"name": "getRendererFactory"
},
{ {
"name": "getRootContext" "name": "getRootContext"
}, },
@ -803,9 +797,6 @@
{ {
"name": "getTNode" "name": "getTNode"
}, },
{
"name": "getTView"
},
{ {
"name": "getTViewCleanup" "name": "getTViewCleanup"
}, },
@ -818,9 +809,6 @@
{ {
"name": "getValue" "name": "getValue"
}, },
{
"name": "getViewData"
},
{ {
"name": "hackImplementationOfElementClassProp" "name": "hackImplementationOfElementClassProp"
}, },
@ -1050,7 +1038,7 @@
"name": "readPatchedData" "name": "readPatchedData"
}, },
{ {
"name": "readPatchedLViewData" "name": "readPatchedLView"
}, },
{ {
"name": "reference" "name": "reference"
@ -1124,9 +1112,6 @@
{ {
"name": "setContextPlayersDirty" "name": "setContextPlayersDirty"
}, },
{
"name": "setCurrentQueries"
},
{ {
"name": "setDirty" "name": "setDirty"
}, },
@ -1205,9 +1190,6 @@
{ {
"name": "textBinding" "name": "textBinding"
}, },
{
"name": "throwErrorIfNoChangesMode"
},
{ {
"name": "throwMultipleComponentError" "name": "throwMultipleComponentError"
}, },

View File

@ -1163,9 +1163,6 @@
{ {
"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"
}, },
@ -1341,7 +1338,7 @@
"name": "containerInternal" "name": "containerInternal"
}, },
{ {
"name": "contextViewData" "name": "contextLView"
}, },
{ {
"name": "convertTimezoneToLocal" "name": "convertTimezoneToLocal"
@ -1377,7 +1374,7 @@
"name": "createLContext" "name": "createLContext"
}, },
{ {
"name": "createLViewData" "name": "createLView"
}, },
{ {
"name": "createNodeAtIndex" "name": "createNodeAtIndex"
@ -1704,7 +1701,7 @@
"name": "getContext" "name": "getContext"
}, },
{ {
"name": "getContextViewData" "name": "getContextLView"
}, },
{ {
"name": "getCreationMode" "name": "getCreationMode"
@ -1712,9 +1709,6 @@
{ {
"name": "getCurrencySymbol" "name": "getCurrencySymbol"
}, },
{
"name": "getCurrentQueries"
},
{ {
"name": "getCurrentView" "name": "getCurrentView"
}, },
@ -1796,6 +1790,9 @@
{ {
"name": "getLContainer" "name": "getLContainer"
}, },
{
"name": "getLView"
},
{ {
"name": "getLViewChild" "name": "getLViewChild"
}, },
@ -1952,12 +1949,6 @@
{ {
"name": "getRenderParent" "name": "getRenderParent"
}, },
{
"name": "getRenderer"
},
{
"name": "getRendererFactory"
},
{ {
"name": "getRootContext" "name": "getRootContext"
}, },
@ -1979,9 +1970,6 @@
{ {
"name": "getTNode" "name": "getTNode"
}, },
{
"name": "getTView"
},
{ {
"name": "getTViewCleanup" "name": "getTViewCleanup"
}, },
@ -2000,9 +1988,6 @@
{ {
"name": "getValue" "name": "getValue"
}, },
{
"name": "getViewData"
},
{ {
"name": "globalListener" "name": "globalListener"
}, },
@ -2460,7 +2445,7 @@
"name": "readPatchedData" "name": "readPatchedData"
}, },
{ {
"name": "readPatchedLViewData" "name": "readPatchedLView"
}, },
{ {
"name": "recursivelyProcessProviders" "name": "recursivelyProcessProviders"
@ -2564,9 +2549,6 @@
{ {
"name": "setCurrentInjector" "name": "setCurrentInjector"
}, },
{
"name": "setCurrentQueries"
},
{ {
"name": "setDirty" "name": "setDirty"
}, },
@ -2702,9 +2684,6 @@
{ {
"name": "textBinding" "name": "textBinding"
}, },
{
"name": "throwErrorIfNoChangesMode"
},
{ {
"name": "throwMultipleComponentError" "name": "throwMultipleComponentError"
}, },

View File

@ -1116,7 +1116,7 @@ function declareTests(config?: {useJit: boolean}) {
.toHaveText('dynamic greet'); .toHaveText('dynamic greet');
})); }));
fixmeIvy('FW-707: TestBed: No LViewData in getParentInjectorLocation') && fixmeIvy('FW-707: TestBed: No LView 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 {
@ -1156,7 +1156,7 @@ function declareTests(config?: {useJit: boolean}) {
expect(compRef.instance.someToken).toBe('someRootValue'); expect(compRef.instance.someToken).toBe('someRootValue');
}); });
fixmeIvy('FW-707: TestBed: No LViewData in getParentInjectorLocation') && fixmeIvy('FW-707: TestBed: No LView 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 {
@ -1197,7 +1197,7 @@ function declareTests(config?: {useJit: boolean}) {
expect(compRef.instance.someToken).toBe('someValue'); expect(compRef.instance.someToken).toBe('someValue');
}); });
fixmeIvy('FW-707: TestBed: No LViewData in getParentInjectorLocation') && fixmeIvy('FW-707: TestBed: No LView 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

@ -8,10 +8,11 @@
import {NgForOfContext} from '@angular/common'; import {NgForOfContext} from '@angular/common';
import {AttributeMarker, defineComponent, element, templateRefExtractor} from '../../src/render3/index'; import {AttributeMarker, defineComponent, element, getCurrentView, templateRefExtractor} from '../../src/render3/index';
import {bind, template, elementEnd, elementProperty, elementStart, interpolation1, interpolation2, interpolation3, interpolationV, listener, load, nextContext, text, textBinding, elementContainerStart, elementContainerEnd, reference} from '../../src/render3/instructions'; import {bind, template, elementEnd, elementProperty, elementStart, interpolation1, interpolation2, interpolation3, interpolationV, listener, load, nextContext, text, textBinding, elementContainerStart, elementContainerEnd, reference} from '../../src/render3/instructions';
import {RenderFlags} from '../../src/render3/interfaces/definition'; import {RenderFlags} from '../../src/render3/interfaces/definition';
import {getCurrentView, restoreView} from '../../src/render3/state'; import {restoreView} from '../../src/render3/state';
import {NgForOf, NgIf, NgTemplateOutlet} from './common_with_def'; import {NgForOf, NgIf, NgTemplateOutlet} from './common_with_def';
import {ComponentFixture, createDirective, getDirectiveOnNode} from './render_util'; import {ComponentFixture, createDirective, getDirectiveOnNode} from './render_util';

View File

@ -13,12 +13,12 @@ import {defineComponent} from '../../src/render3/definition';
import {bloomAdd, bloomHasToken, bloomHashBitOrFactory as bloomHash, getOrCreateNodeInjectorForNode} from '../../src/render3/di'; import {bloomAdd, bloomHasToken, bloomHashBitOrFactory as bloomHash, getOrCreateNodeInjectorForNode} from '../../src/render3/di';
import {defineDirective, elementProperty, load, templateRefExtractor} from '../../src/render3/index'; import {defineDirective, elementProperty, load, templateRefExtractor} from '../../src/render3/index';
import {bind, container, containerRefreshEnd, containerRefreshStart, createNodeAtIndex, createLViewData, createTView, directiveInject, element, elementEnd, elementStart, embeddedViewEnd, embeddedViewStart, injectAttribute, interpolation2, projection, projectionDef, reference, template, text, textBinding, elementContainerStart, elementContainerEnd} from '../../src/render3/instructions'; import {bind, container, containerRefreshEnd, containerRefreshStart, createNodeAtIndex, createLView, createTView, directiveInject, element, elementEnd, elementStart, embeddedViewEnd, embeddedViewStart, injectAttribute, interpolation2, projection, projectionDef, reference, template, text, textBinding, elementContainerStart, elementContainerEnd} from '../../src/render3/instructions';
import {isProceduralRenderer, RElement} from '../../src/render3/interfaces/renderer'; import {isProceduralRenderer, RElement} from '../../src/render3/interfaces/renderer';
import {AttributeMarker, TNodeType} from '../../src/render3/interfaces/node'; import {AttributeMarker, TNodeType} from '../../src/render3/interfaces/node';
import {getNativeByIndex} from '../../src/render3/util'; import {getNativeByIndex} from '../../src/render3/util';
import {LViewFlags} from '../../src/render3/interfaces/view'; import {LViewFlags} from '../../src/render3/interfaces/view';
import {getViewData, enterView, leaveView} from '../../src/render3/state'; import {enterView, leaveView, getLView} from '../../src/render3/state';
import {ViewRef} from '../../src/render3/view_ref'; import {ViewRef} from '../../src/render3/view_ref';
import {getRendererFactory2} from './imported_renderer2'; import {getRendererFactory2} from './imported_renderer2';
@ -1264,7 +1264,7 @@ describe('di', () => {
if (rf & RenderFlags.Create) { if (rf & RenderFlags.Create) {
elementStart(0, 'div', ['dir', '', 'dirSame', '']); elementStart(0, 'div', ['dir', '', 'dirSame', '']);
elementEnd(); elementEnd();
div = getNativeByIndex(0, getViewData()); div = getNativeByIndex(0, getLView());
} }
}, 1, 0, [Directive, DirectiveSameInstance]); }, 1, 0, [Directive, DirectiveSameInstance]);
@ -2020,7 +2020,7 @@ describe('di', () => {
describe('getOrCreateNodeInjector', () => { describe('getOrCreateNodeInjector', () => {
it('should handle initial undefined state', () => { it('should handle initial undefined state', () => {
const contentView = createLViewData( const contentView = createLView(
null, createTView(-1, null, 1, 0, null, null, null), null, LViewFlags.CheckAlways, null, createTView(-1, null, 1, 0, null, null, null), null, LViewFlags.CheckAlways,
{} as any, {} as any); {} as any, {} as any);
const oldView = enterView(contentView, null); const oldView = enterView(contentView, null);

View File

@ -422,7 +422,7 @@ describe('host bindings', () => {
vars: 0, vars: 0,
hostVars: 8, hostVars: 8,
hostBindings: (rf: RenderFlags, ctx: HostBindingComp, elIndex: number) => { hostBindings: (rf: RenderFlags, ctx: HostBindingComp, elIndex: number) => {
// LViewData: [..., id, dir, title, ctx.id, pf1, ctx.title, ctx.otherTitle, pf2] // LView: [..., id, dir, title, ctx.id, pf1, ctx.title, ctx.otherTitle, pf2]
if (rf & RenderFlags.Update) { if (rf & RenderFlags.Update) {
elementProperty(elIndex, 'id', bind(pureFunction1(3, ff, ctx.id))); elementProperty(elIndex, 'id', bind(pureFunction1(3, ff, ctx.id)));
elementProperty(elIndex, 'dir', bind(ctx.dir)); elementProperty(elIndex, 'dir', bind(ctx.dir));
@ -498,7 +498,7 @@ describe('host bindings', () => {
vars: 0, vars: 0,
hostVars: 3, hostVars: 3,
hostBindings: (rf: RenderFlags, ctx: HostBindingComp, elIndex: number) => { hostBindings: (rf: RenderFlags, ctx: HostBindingComp, elIndex: number) => {
// LViewData: [..., id, ctx.id, pf1] // LView: [..., id, ctx.id, pf1]
if (rf & RenderFlags.Update) { if (rf & RenderFlags.Update) {
elementProperty(elIndex, 'id', bind(pureFunction1(1, ff, ctx.id))); elementProperty(elIndex, 'id', bind(pureFunction1(1, ff, ctx.id)));
} }
@ -527,7 +527,7 @@ describe('host bindings', () => {
factory: () => hostBindingDir = new HostBindingDir(), factory: () => hostBindingDir = new HostBindingDir(),
hostVars: 3, hostVars: 3,
hostBindings: (rf: RenderFlags, ctx: HostBindingDir, elIndex: number) => { hostBindings: (rf: RenderFlags, ctx: HostBindingDir, elIndex: number) => {
// LViewData [..., title, ctx.title, pf1] // LView [..., title, ctx.title, pf1]
if (rf & RenderFlags.Update) { if (rf & RenderFlags.Update) {
elementProperty(elIndex, 'title', bind(pureFunction1(1, ff1, ctx.title))); elementProperty(elIndex, 'title', bind(pureFunction1(1, ff1, ctx.title)));
} }
@ -589,7 +589,7 @@ describe('host bindings', () => {
vars: 0, vars: 0,
hostVars: 6, hostVars: 6,
hostBindings: (rf: RenderFlags, ctx: HostBindingComp, elIndex: number) => { hostBindings: (rf: RenderFlags, ctx: HostBindingComp, elIndex: number) => {
// LViewData: [..., id, title, ctx.id, pf1, ctx.title, pf1] // LView: [..., id, title, ctx.id, pf1, ctx.title, pf1]
if (rf & RenderFlags.Update) { if (rf & RenderFlags.Update) {
elementProperty( elementProperty(
elIndex, 'id', bind(ctx.condition ? pureFunction1(2, ff, ctx.id) : 'green')); elIndex, 'id', bind(ctx.condition ? pureFunction1(2, ff, ctx.id) : 'green'));

View File

@ -17,7 +17,7 @@ import {NgIf} from './common_with_def';
import {element, elementEnd, elementStart, template, text, bind, elementProperty, projectionDef, projection} from '../../src/render3/instructions'; import {element, elementEnd, elementStart, template, text, bind, elementProperty, projectionDef, projection} from '../../src/render3/instructions';
import {COMMENT_MARKER, ELEMENT_MARKER, I18nMutateOpCode, I18nUpdateOpCode, I18nUpdateOpCodes, TI18n} from '../../src/render3/interfaces/i18n'; import {COMMENT_MARKER, ELEMENT_MARKER, I18nMutateOpCode, I18nUpdateOpCode, I18nUpdateOpCodes, TI18n} from '../../src/render3/interfaces/i18n';
import {HEADER_OFFSET, LViewData, TVIEW} from '../../src/render3/interfaces/view'; import {HEADER_OFFSET, LView, TVIEW} from '../../src/render3/interfaces/view';
import {ComponentFixture, TemplateFixture} from './render_util'; import {ComponentFixture, TemplateFixture} from './render_util';
const Component: typeof _Component = function(...args: any[]): any { const Component: typeof _Component = function(...args: any[]): any {
@ -691,8 +691,8 @@ describe('Runtime i18n', () => {
const opCodes = tView.data[index + HEADER_OFFSET] as I18nUpdateOpCodes; const opCodes = tView.data[index + HEADER_OFFSET] as I18nUpdateOpCodes;
expect(opCodes).toEqual([]); expect(opCodes).toEqual([]);
expect((getNativeByIndex(0, fixture.hostView as LViewData) as any as Element) expect(
.getAttribute('title')) (getNativeByIndex(0, fixture.hostView as LView) as any as Element).getAttribute('title'))
.toEqual(MSG_title); .toEqual(MSG_title);
}); });

View File

@ -2034,14 +2034,14 @@ describe('render3 integration test', () => {
const section = fixture.hostElement.querySelector('section') !; const section = fixture.hostElement.querySelector('section') !;
const sectionContext = getContext(section) !; const sectionContext = getContext(section) !;
const sectionLView = sectionContext.lViewData !; const sectionLView = sectionContext.lView !;
expect(sectionContext.nodeIndex).toEqual(HEADER_OFFSET); expect(sectionContext.nodeIndex).toEqual(HEADER_OFFSET);
expect(sectionLView.length).toBeGreaterThan(HEADER_OFFSET); expect(sectionLView.length).toBeGreaterThan(HEADER_OFFSET);
expect(sectionContext.native).toBe(section); expect(sectionContext.native).toBe(section);
const div = fixture.hostElement.querySelector('div') !; const div = fixture.hostElement.querySelector('div') !;
const divContext = getContext(div) !; const divContext = getContext(div) !;
const divLView = divContext.lViewData !; const divLView = divContext.lView !;
expect(divContext.nodeIndex).toEqual(HEADER_OFFSET + 1); expect(divContext.nodeIndex).toEqual(HEADER_OFFSET + 1);
expect(divLView.length).toBeGreaterThan(HEADER_OFFSET); expect(divLView.length).toBeGreaterThan(HEADER_OFFSET);
expect(divContext.native).toBe(div); expect(divContext.native).toBe(div);
@ -2077,7 +2077,7 @@ describe('render3 integration test', () => {
expect(Array.isArray(result2)).toBeFalsy(); expect(Array.isArray(result2)).toBeFalsy();
expect(result2).toBe(context); expect(result2).toBe(context);
expect(result2.lViewData).toBe(result1); expect(result2.lView).toBe(result1);
}); });
it('should cache the element context on an intermediate element that isn\'t pre-emptively monkey-patched', it('should cache the element context on an intermediate element that isn\'t pre-emptively monkey-patched',
@ -2244,9 +2244,9 @@ describe('render3 integration test', () => {
const shadowContext = getContext(header) !; const shadowContext = getContext(header) !;
const projectedContext = getContext(p) !; const projectedContext = getContext(p) !;
const parentComponentData = parentContext.lViewData; const parentComponentData = parentContext.lView;
const shadowComponentData = shadowContext.lViewData; const shadowComponentData = shadowContext.lView;
const projectedComponentData = projectedContext.lViewData; const projectedComponentData = projectedContext.lView;
expect(projectedComponentData).toBe(parentComponentData); expect(projectedComponentData).toBe(parentComponentData);
expect(shadowComponentData).not.toBe(parentComponentData); expect(shadowComponentData).not.toBe(parentComponentData);
@ -2310,23 +2310,23 @@ describe('render3 integration test', () => {
const hostElm = fixture.hostElement; const hostElm = fixture.hostElement;
const component = fixture.component; const component = fixture.component;
const componentLViewData = (component as any)[MONKEY_PATCH_KEY_NAME]; const componentLView = (component as any)[MONKEY_PATCH_KEY_NAME];
expect(Array.isArray(componentLViewData)).toBeTruthy(); expect(Array.isArray(componentLView)).toBeTruthy();
const hostLViewData = (hostElm as any)[MONKEY_PATCH_KEY_NAME]; const hostLView = (hostElm as any)[MONKEY_PATCH_KEY_NAME];
expect(hostLViewData).toBe(componentLViewData); expect(hostLView).toBe(componentLView);
const context1 = getContext(hostElm) !; const context1 = getContext(hostElm) !;
expect(context1.lViewData).toBe(hostLViewData); expect(context1.lView).toBe(hostLView);
expect(context1.native).toEqual(hostElm); expect(context1.native).toEqual(hostElm);
const context2 = getContext(component) !; const context2 = getContext(component) !;
expect(context2).toBe(context1); expect(context2).toBe(context1);
expect(context2.lViewData).toBe(hostLViewData); expect(context2.lView).toBe(hostLView);
expect(context2.native).toEqual(hostElm); expect(context2.native).toEqual(hostElm);
}); });
it('should by default monkey-patch the directives with LViewData so that they can be examined', it('should by default monkey-patch the directives with LView so that they can be examined',
() => { () => {
let myDir1Instance: MyDir1|null = null; let myDir1Instance: MyDir1|null = null;
let myDir2Instance: MyDir2|null = null; let myDir2Instance: MyDir2|null = null;
@ -2380,7 +2380,7 @@ describe('render3 integration test', () => {
const div1 = hostElm.querySelector('div:first-child') !as any; const div1 = hostElm.querySelector('div:first-child') !as any;
const div2 = hostElm.querySelector('div:last-child') !as any; const div2 = hostElm.querySelector('div:last-child') !as any;
const context = getContext(hostElm) !; const context = getContext(hostElm) !;
const componentView = context.lViewData[context.nodeIndex]; const componentView = context.lView[context.nodeIndex];
expect(componentView).toContain(myDir1Instance); expect(componentView).toContain(myDir1Instance);
expect(componentView).toContain(myDir2Instance); expect(componentView).toContain(myDir2Instance);
@ -2394,9 +2394,9 @@ describe('render3 integration test', () => {
const d2Context = getContext(myDir2Instance) !; const d2Context = getContext(myDir2Instance) !;
const d3Context = getContext(myDir3Instance) !; const d3Context = getContext(myDir3Instance) !;
expect(d1Context.lViewData).toEqual(componentView); expect(d1Context.lView).toEqual(componentView);
expect(d2Context.lViewData).toEqual(componentView); expect(d2Context.lView).toEqual(componentView);
expect(d3Context.lViewData).toEqual(componentView); expect(d3Context.lView).toEqual(componentView);
expect((myDir1Instance as any)[MONKEY_PATCH_KEY_NAME]).toBe(d1Context); expect((myDir1Instance as any)[MONKEY_PATCH_KEY_NAME]).toBe(d1Context);
expect((myDir2Instance as any)[MONKEY_PATCH_KEY_NAME]).toBe(d2Context); expect((myDir2Instance as any)[MONKEY_PATCH_KEY_NAME]).toBe(d2Context);
@ -2473,41 +2473,41 @@ describe('render3 integration test', () => {
const childCompHostElm = fixture.hostElement.querySelector('child-comp') !as any; const childCompHostElm = fixture.hostElement.querySelector('child-comp') !as any;
const lViewData = childCompHostElm[MONKEY_PATCH_KEY_NAME]; const lView = childCompHostElm[MONKEY_PATCH_KEY_NAME];
expect(Array.isArray(lViewData)).toBeTruthy(); expect(Array.isArray(lView)).toBeTruthy();
expect((myDir1Instance as any)[MONKEY_PATCH_KEY_NAME]).toBe(lViewData); expect((myDir1Instance as any)[MONKEY_PATCH_KEY_NAME]).toBe(lView);
expect((myDir2Instance as any)[MONKEY_PATCH_KEY_NAME]).toBe(lViewData); expect((myDir2Instance as any)[MONKEY_PATCH_KEY_NAME]).toBe(lView);
expect((childComponentInstance as any)[MONKEY_PATCH_KEY_NAME]).toBe(lViewData); expect((childComponentInstance as any)[MONKEY_PATCH_KEY_NAME]).toBe(lView);
const childNodeContext = getContext(childCompHostElm) !; const childNodeContext = getContext(childCompHostElm) !;
expect(childNodeContext.component).toBeFalsy(); expect(childNodeContext.component).toBeFalsy();
expect(childNodeContext.directives).toBeFalsy(); expect(childNodeContext.directives).toBeFalsy();
assertMonkeyPatchValueIsLViewData(myDir1Instance); assertMonkeyPatchValueIsLView(myDir1Instance);
assertMonkeyPatchValueIsLViewData(myDir2Instance); assertMonkeyPatchValueIsLView(myDir2Instance);
assertMonkeyPatchValueIsLViewData(childComponentInstance); assertMonkeyPatchValueIsLView(childComponentInstance);
expect(getContext(myDir1Instance)).toBe(childNodeContext); expect(getContext(myDir1Instance)).toBe(childNodeContext);
expect(childNodeContext.component).toBeFalsy(); expect(childNodeContext.component).toBeFalsy();
expect(childNodeContext.directives !.length).toEqual(2); expect(childNodeContext.directives !.length).toEqual(2);
assertMonkeyPatchValueIsLViewData(myDir1Instance, false); assertMonkeyPatchValueIsLView(myDir1Instance, false);
assertMonkeyPatchValueIsLViewData(myDir2Instance, false); assertMonkeyPatchValueIsLView(myDir2Instance, false);
assertMonkeyPatchValueIsLViewData(childComponentInstance); assertMonkeyPatchValueIsLView(childComponentInstance);
expect(getContext(myDir2Instance)).toBe(childNodeContext); expect(getContext(myDir2Instance)).toBe(childNodeContext);
expect(childNodeContext.component).toBeFalsy(); expect(childNodeContext.component).toBeFalsy();
expect(childNodeContext.directives !.length).toEqual(2); expect(childNodeContext.directives !.length).toEqual(2);
assertMonkeyPatchValueIsLViewData(myDir1Instance, false); assertMonkeyPatchValueIsLView(myDir1Instance, false);
assertMonkeyPatchValueIsLViewData(myDir2Instance, false); assertMonkeyPatchValueIsLView(myDir2Instance, false);
assertMonkeyPatchValueIsLViewData(childComponentInstance); assertMonkeyPatchValueIsLView(childComponentInstance);
expect(getContext(childComponentInstance)).toBe(childNodeContext); expect(getContext(childComponentInstance)).toBe(childNodeContext);
expect(childNodeContext.component).toBeTruthy(); expect(childNodeContext.component).toBeTruthy();
expect(childNodeContext.directives !.length).toEqual(2); expect(childNodeContext.directives !.length).toEqual(2);
assertMonkeyPatchValueIsLViewData(myDir1Instance, false); assertMonkeyPatchValueIsLView(myDir1Instance, false);
assertMonkeyPatchValueIsLViewData(myDir2Instance, false); assertMonkeyPatchValueIsLView(myDir2Instance, false);
assertMonkeyPatchValueIsLViewData(childComponentInstance, false); assertMonkeyPatchValueIsLView(childComponentInstance, false);
function assertMonkeyPatchValueIsLViewData(value: any, yesOrNo = true) { function assertMonkeyPatchValueIsLView(value: any, yesOrNo = true) {
expect(Array.isArray((value as any)[MONKEY_PATCH_KEY_NAME])).toBe(yesOrNo); expect(Array.isArray((value as any)[MONKEY_PATCH_KEY_NAME])).toBe(yesOrNo);
} }
}); });
@ -2560,16 +2560,16 @@ describe('render3 integration test', () => {
const context = getContext(child) !; const context = getContext(child) !;
expect(child[MONKEY_PATCH_KEY_NAME]).toBeTruthy(); expect(child[MONKEY_PATCH_KEY_NAME]).toBeTruthy();
const componentData = context.lViewData[context.nodeIndex]; const componentData = context.lView[context.nodeIndex];
const component = componentData[CONTEXT]; const component = componentData[CONTEXT];
expect(component instanceof ChildComp).toBeTruthy(); expect(component instanceof ChildComp).toBeTruthy();
expect(component[MONKEY_PATCH_KEY_NAME]).toBe(context.lViewData); expect(component[MONKEY_PATCH_KEY_NAME]).toBe(context.lView);
const componentContext = getContext(component) !; const componentContext = getContext(component) !;
expect(component[MONKEY_PATCH_KEY_NAME]).toBe(componentContext); expect(component[MONKEY_PATCH_KEY_NAME]).toBe(componentContext);
expect(componentContext.nodeIndex).toEqual(context.nodeIndex); expect(componentContext.nodeIndex).toEqual(context.nodeIndex);
expect(componentContext.native).toEqual(context.native); expect(componentContext.native).toEqual(context.native);
expect(componentContext.lViewData).toEqual(context.lViewData); expect(componentContext.lView).toEqual(context.lView);
}); });
}); });

View File

@ -7,9 +7,9 @@
*/ */
import {bind, defineComponent, defineDirective, markDirty, reference, textBinding} from '../../src/render3/index'; import {bind, defineComponent, defineDirective, markDirty, reference, textBinding} from '../../src/render3/index';
import {container, containerRefreshEnd, containerRefreshStart, element, elementEnd, elementStart, embeddedViewEnd, embeddedViewStart, listener, text} from '../../src/render3/instructions'; import {container, containerRefreshEnd, containerRefreshStart, element, elementEnd, elementStart, embeddedViewEnd, embeddedViewStart, getCurrentView, listener, text} from '../../src/render3/instructions';
import {RenderFlags} from '../../src/render3/interfaces/definition'; import {RenderFlags} from '../../src/render3/interfaces/definition';
import {getCurrentView, restoreView} from '../../src/render3/state'; import {restoreView} from '../../src/render3/state';
import {getRendererFactory2} from './imported_renderer2'; import {getRendererFactory2} from './imported_renderer2';
import {ComponentFixture, containerEl, createComponent, getDirectiveOnNode, renderToHtml, requestAnimationFrame} from './render_util'; import {ComponentFixture, containerEl, createComponent, getDirectiveOnNode, renderToHtml, requestAnimationFrame} from './render_util';

View File

@ -11,16 +11,16 @@ import {AttributeMarker, TAttributes, TNode, TNodeType} from '../../src/render3/
import {CssSelector, CssSelectorList, NG_PROJECT_AS_ATTR_NAME, SelectorFlags,} from '../../src/render3/interfaces/projection'; import {CssSelector, CssSelectorList, NG_PROJECT_AS_ATTR_NAME, SelectorFlags,} from '../../src/render3/interfaces/projection';
import {getProjectAsAttrValue, isNodeMatchingSelectorList, isNodeMatchingSelector} from '../../src/render3/node_selector_matcher'; import {getProjectAsAttrValue, isNodeMatchingSelectorList, isNodeMatchingSelector} from '../../src/render3/node_selector_matcher';
import {createTNode} from '@angular/core/src/render3/instructions'; import {createTNode} from '@angular/core/src/render3/instructions';
import {getViewData} from '@angular/core/src/render3/state'; import {getLView} from '@angular/core/src/render3/state';
function testLStaticData(tagName: string, attrs: TAttributes | null): TNode { function testLStaticData(tagName: string, attrs: TAttributes | null): TNode {
return createTNode(getViewData(), TNodeType.Element, 0, tagName, attrs, null); return createTNode(getLView(), TNodeType.Element, 0, tagName, attrs, null);
} }
describe('css selector matching', () => { describe('css selector matching', () => {
function isMatching(tagName: string, attrs: TAttributes | null, selector: CssSelector): boolean { function isMatching(tagName: string, attrs: TAttributes | null, selector: CssSelector): boolean {
return isNodeMatchingSelector( return isNodeMatchingSelector(
createTNode(getViewData(), TNodeType.Element, 0, tagName, attrs, null), selector); createTNode(getLView(), TNodeType.Element, 0, tagName, attrs, null), selector);
} }
describe('isNodeMatchingSimpleSelector', () => { describe('isNodeMatchingSimpleSelector', () => {

View File

@ -16,7 +16,7 @@ import {getNativeByIndex} from '../../src/render3/util';
import {bind, container, containerRefreshEnd, containerRefreshStart, directiveInject, element, elementContainerEnd, elementContainerStart, elementEnd, elementProperty, elementStart, embeddedViewEnd, embeddedViewStart, load, loadQueryList, reference, registerContentQuery, template, text} from '../../src/render3/instructions'; import {bind, container, containerRefreshEnd, containerRefreshStart, directiveInject, element, elementContainerEnd, elementContainerStart, elementEnd, elementProperty, elementStart, embeddedViewEnd, embeddedViewStart, load, loadQueryList, reference, registerContentQuery, template, text} from '../../src/render3/instructions';
import {RenderFlags} from '../../src/render3/interfaces/definition'; import {RenderFlags} from '../../src/render3/interfaces/definition';
import {query, queryRefresh} from '../../src/render3/query'; import {query, queryRefresh} from '../../src/render3/query';
import {getViewData} from '../../src/render3/state'; import {getLView} from '../../src/render3/state';
import {templateRefExtractor} from '../../src/render3/view_engine_compatibility_prebound'; import {templateRefExtractor} from '../../src/render3/view_engine_compatibility_prebound';
import {NgForOf, NgIf, NgTemplateOutlet} from './common_with_def'; import {NgForOf, NgIf, NgTemplateOutlet} from './common_with_def';
@ -115,7 +115,7 @@ describe('query', () => {
function(rf: RenderFlags, ctx: any) { function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) { if (rf & RenderFlags.Create) {
element(1, 'div', ['child', '']); element(1, 'div', ['child', '']);
elToQuery = getNativeByIndex(1, getViewData()); elToQuery = getNativeByIndex(1, getLView());
} }
}, },
2, 0, [Child], [], 2, 0, [Child], [],
@ -335,7 +335,7 @@ describe('query', () => {
function(rf: RenderFlags, ctx: any) { function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) { if (rf & RenderFlags.Create) {
element(1, 'div', null, ['foo', '']); element(1, 'div', null, ['foo', '']);
elToQuery = getNativeByIndex(1, getViewData()); elToQuery = getNativeByIndex(1, getLView());
element(3, 'div'); element(3, 'div');
} }
}, },
@ -372,7 +372,7 @@ describe('query', () => {
function(rf: RenderFlags, ctx: any) { function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) { if (rf & RenderFlags.Create) {
element(2, 'div', null, ['foo', '', 'bar', '']); element(2, 'div', null, ['foo', '', 'bar', '']);
elToQuery = getNativeByIndex(2, getViewData()); elToQuery = getNativeByIndex(2, getLView());
element(5, 'div'); element(5, 'div');
} }
}, },
@ -419,10 +419,10 @@ describe('query', () => {
function(rf: RenderFlags, ctx: any) { function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) { if (rf & RenderFlags.Create) {
element(1, 'div', null, ['foo', '']); element(1, 'div', null, ['foo', '']);
el1ToQuery = getNativeByIndex(1, getViewData()); el1ToQuery = getNativeByIndex(1, getLView());
element(3, 'div'); element(3, 'div');
element(4, 'div', null, ['bar', '']); element(4, 'div', null, ['bar', '']);
el2ToQuery = getNativeByIndex(4, getViewData()); el2ToQuery = getNativeByIndex(4, getLView());
} }
}, },
6, 0, [], [], 6, 0, [], [],
@ -458,7 +458,7 @@ describe('query', () => {
function(rf: RenderFlags, ctx: any) { function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) { if (rf & RenderFlags.Create) {
element(1, 'div', null, ['foo', '']); element(1, 'div', null, ['foo', '']);
elToQuery = getNativeByIndex(1, getViewData()); elToQuery = getNativeByIndex(1, getLView());
element(3, 'div'); element(3, 'div');
} }
}, },
@ -494,7 +494,7 @@ describe('query', () => {
function(rf: RenderFlags, ctx: any) { function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) { if (rf & RenderFlags.Create) {
elementContainerStart(1, null, ['foo', '']); elementContainerStart(1, null, ['foo', '']);
elToQuery = getNativeByIndex(1, getViewData()); elToQuery = getNativeByIndex(1, getLView());
elementContainerEnd(); elementContainerEnd();
} }
}, },
@ -530,7 +530,7 @@ describe('query', () => {
function(rf: RenderFlags, ctx: any) { function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) { if (rf & RenderFlags.Create) {
elementContainerStart(1, null, ['foo', '']); elementContainerStart(1, null, ['foo', '']);
elToQuery = getNativeByIndex(1, getViewData()); elToQuery = getNativeByIndex(1, getLView());
elementContainerEnd(); elementContainerEnd();
} }
}, },
@ -593,7 +593,7 @@ describe('query', () => {
elementContainerStart(2); elementContainerStart(2);
{ {
element(3, 'div', null, ['foo', '']); element(3, 'div', null, ['foo', '']);
elToQuery = getNativeByIndex(3, getViewData()); elToQuery = getNativeByIndex(3, getLView());
} }
elementContainerEnd(); elementContainerEnd();
} }
@ -1003,7 +1003,7 @@ describe('query', () => {
function(rf: RenderFlags, ctx: any) { function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) { if (rf & RenderFlags.Create) {
element(1, 'div', ['child', ''], ['foo', 'child']); element(1, 'div', ['child', ''], ['foo', 'child']);
div = getNativeByIndex(1, getViewData()); div = getNativeByIndex(1, getLView());
} }
}, },
3, 0, [Child], [], 3, 0, [Child], [],
@ -1038,7 +1038,7 @@ describe('query', () => {
function(rf: RenderFlags, ctx: any) { function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) { if (rf & RenderFlags.Create) {
element(1, 'div', ['child', ''], ['foo', '', 'bar', 'child']); element(1, 'div', ['child', ''], ['foo', '', 'bar', 'child']);
div = getNativeByIndex(1, getViewData()); div = getNativeByIndex(1, getLView());
} }
if (rf & RenderFlags.Update) { if (rf & RenderFlags.Update) {
childInstance = getDirectiveOnNode(1); childInstance = getDirectiveOnNode(1);
@ -1737,7 +1737,7 @@ describe('query', () => {
{ {
if (rf1 & RenderFlags.Create) { if (rf1 & RenderFlags.Create) {
element(0, 'div', null, ['foo', '']); element(0, 'div', null, ['foo', '']);
firstEl = getNativeByIndex(0, getViewData()); firstEl = getNativeByIndex(0, getLView());
} }
} }
embeddedViewEnd(); embeddedViewEnd();
@ -1789,10 +1789,10 @@ describe('query', () => {
function(rf: RenderFlags, ctx: any) { function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) { if (rf & RenderFlags.Create) {
element(1, 'span', null, ['foo', '']); element(1, 'span', null, ['foo', '']);
firstEl = getNativeByIndex(1, getViewData()); firstEl = getNativeByIndex(1, getLView());
container(3); container(3);
element(4, 'span', null, ['foo', '']); element(4, 'span', null, ['foo', '']);
lastEl = getNativeByIndex(4, getViewData()); lastEl = getNativeByIndex(4, getLView());
} }
if (rf & RenderFlags.Update) { if (rf & RenderFlags.Update) {
containerRefreshStart(3); containerRefreshStart(3);
@ -1802,7 +1802,7 @@ describe('query', () => {
{ {
if (rf1 & RenderFlags.Create) { if (rf1 & RenderFlags.Create) {
element(0, 'div', null, ['foo', '']); element(0, 'div', null, ['foo', '']);
viewEl = getNativeByIndex(0, getViewData()); viewEl = getNativeByIndex(0, getLView());
} }
} }
embeddedViewEnd(); embeddedViewEnd();
@ -1869,7 +1869,7 @@ describe('query', () => {
{ {
if (rf0 & RenderFlags.Create) { if (rf0 & RenderFlags.Create) {
element(0, 'div', null, ['foo', '']); element(0, 'div', null, ['foo', '']);
firstEl = getNativeByIndex(0, getViewData()); firstEl = getNativeByIndex(0, getLView());
} }
} }
embeddedViewEnd(); embeddedViewEnd();
@ -1879,7 +1879,7 @@ describe('query', () => {
{ {
if (rf1 & RenderFlags.Create) { if (rf1 & RenderFlags.Create) {
element(0, 'span', null, ['foo', '']); element(0, 'span', null, ['foo', '']);
lastEl = getNativeByIndex(0, getViewData()); lastEl = getNativeByIndex(0, getLView());
} }
} }
embeddedViewEnd(); embeddedViewEnd();
@ -1942,7 +1942,7 @@ describe('query', () => {
{ {
if (rf0 & RenderFlags.Create) { if (rf0 & RenderFlags.Create) {
element(0, 'div', null, ['foo', '']); element(0, 'div', null, ['foo', '']);
firstEl = getNativeByIndex(0, getViewData()); firstEl = getNativeByIndex(0, getLView());
container(2); container(2);
} }
if (rf0 & RenderFlags.Update) { if (rf0 & RenderFlags.Update) {
@ -1953,7 +1953,7 @@ describe('query', () => {
{ {
if (rf2) { if (rf2) {
element(0, 'span', null, ['foo', '']); element(0, 'span', null, ['foo', '']);
lastEl = getNativeByIndex(0, getViewData()); lastEl = getNativeByIndex(0, getLView());
} }
} }
embeddedViewEnd(); embeddedViewEnd();

View File

@ -11,6 +11,7 @@ import {ElementRef} from '@angular/core/src/linker/element_ref';
import {TemplateRef} from '@angular/core/src/linker/template_ref'; import {TemplateRef} from '@angular/core/src/linker/template_ref';
import {ViewContainerRef} from '@angular/core/src/linker/view_container_ref'; import {ViewContainerRef} from '@angular/core/src/linker/view_container_ref';
import {Renderer2} from '@angular/core/src/render/api'; import {Renderer2} from '@angular/core/src/render/api';
import {getLView} from '@angular/core/src/render3/state';
import {stringifyElement} from '@angular/platform-browser/testing/src/browser_util'; import {stringifyElement} from '@angular/platform-browser/testing/src/browser_util';
import {SWITCH_CHANGE_DETECTOR_REF_FACTORY__POST_R3__ as R3_CHANGE_DETECTOR_REF_FACTORY} from '../../src/change_detection/change_detector_ref'; import {SWITCH_CHANGE_DETECTOR_REF_FACTORY__POST_R3__ as R3_CHANGE_DETECTOR_REF_FACTORY} from '../../src/change_detection/change_detector_ref';
@ -28,8 +29,7 @@ import {renderTemplate} from '../../src/render3/instructions';
import {DirectiveDefList, DirectiveTypesOrFactory, PipeDef, PipeDefList, PipeTypesOrFactory} from '../../src/render3/interfaces/definition'; import {DirectiveDefList, DirectiveTypesOrFactory, PipeDef, PipeDefList, PipeTypesOrFactory} from '../../src/render3/interfaces/definition';
import {PlayerHandler} from '../../src/render3/interfaces/player'; import {PlayerHandler} from '../../src/render3/interfaces/player';
import {RElement, RText, Renderer3, RendererFactory3, domRendererFactory3} from '../../src/render3/interfaces/renderer'; import {RElement, RText, Renderer3, RendererFactory3, domRendererFactory3} from '../../src/render3/interfaces/renderer';
import {HEADER_OFFSET, LViewData} from '../../src/render3/interfaces/view'; import {HEADER_OFFSET, LView} from '../../src/render3/interfaces/view';
import {getViewData} from '../../src/render3/state';
import {Sanitizer} from '../../src/sanitization/security'; import {Sanitizer} from '../../src/sanitization/security';
import {Type} from '../../src/type'; import {Type} from '../../src/type';
@ -82,7 +82,7 @@ function noop() {}
* - access to the render `html`. * - access to the render `html`.
*/ */
export class TemplateFixture extends BaseFixture { export class TemplateFixture extends BaseFixture {
hostView: LViewData; hostView: LView;
private _directiveDefs: DirectiveDefList|null; private _directiveDefs: DirectiveDefList|null;
private _pipeDefs: PipeDefList|null; private _pipeDefs: PipeDefList|null;
private _sanitizer: Sanitizer|null; private _sanitizer: Sanitizer|null;
@ -179,7 +179,7 @@ export class ComponentFixture<T> extends BaseFixture {
export const document = ((typeof global == 'object' && global || window) as any).document; export const document = ((typeof global == 'object' && global || window) as any).document;
export let containerEl: HTMLElement = null !; export let containerEl: HTMLElement = null !;
let hostView: LViewData|null; let hostView: LView|null;
const isRenderer2 = const isRenderer2 =
typeof process == 'object' && process.argv[3] && process.argv[3] === '--r=renderer2'; typeof process == 'object' && process.argv[3] && process.argv[3] === '--r=renderer2';
// tslint:disable-next-line:no-console // tslint:disable-next-line:no-console
@ -323,7 +323,7 @@ export function createDirective(
/** Gets the directive on the given node at the given index */ /** Gets the directive on the given node at the given index */
export function getDirectiveOnNode(nodeIndex: number, dirIndex: number = 0) { export function getDirectiveOnNode(nodeIndex: number, dirIndex: number = 0) {
const directives = getDirectivesAtNodeIndex(nodeIndex + HEADER_OFFSET, getViewData(), true); const directives = getDirectivesAtNodeIndex(nodeIndex + HEADER_OFFSET, getLView(), true);
if (directives == null) { if (directives == null) {
throw new Error(`No directives exist on node in slot ${nodeIndex}`); throw new Error(`No directives exist on node in slot ${nodeIndex}`);
} }

View File

@ -8,12 +8,12 @@
import {createRootContext} from '../../../src/render3/component'; import {createRootContext} from '../../../src/render3/component';
import {getContext} from '../../../src/render3/context_discovery'; import {getContext} from '../../../src/render3/context_discovery';
import {defineComponent} from '../../../src/render3/index'; import {defineComponent} from '../../../src/render3/index';
import {createLViewData, createTView, elementClassProp, elementEnd, elementStart, elementStyleProp, elementStyling, elementStylingApply, elementStylingMap} from '../../../src/render3/instructions'; import {createLView, createTView, elementClassProp, elementEnd, elementStart, elementStyleProp, elementStyling, elementStylingApply, elementStylingMap} from '../../../src/render3/instructions';
import {InitialStylingFlags, RenderFlags} from '../../../src/render3/interfaces/definition'; import {InitialStylingFlags, RenderFlags} from '../../../src/render3/interfaces/definition';
import {BindingStore, BindingType, PlayState, Player, PlayerFactory, PlayerHandler} from '../../../src/render3/interfaces/player'; import {BindingStore, BindingType, PlayState, Player, PlayerFactory, PlayerHandler} from '../../../src/render3/interfaces/player';
import {RElement, Renderer3, domRendererFactory3} from '../../../src/render3/interfaces/renderer'; import {RElement, Renderer3, domRendererFactory3} from '../../../src/render3/interfaces/renderer';
import {StylingContext, StylingFlags, StylingIndex} from '../../../src/render3/interfaces/styling'; import {StylingContext, StylingFlags, StylingIndex} from '../../../src/render3/interfaces/styling';
import {CONTEXT, LViewData, LViewFlags, RootContext} from '../../../src/render3/interfaces/view'; import {CONTEXT, LView, LViewFlags, RootContext} from '../../../src/render3/interfaces/view';
import {addPlayer, getPlayers} from '../../../src/render3/players'; import {addPlayer, getPlayers} from '../../../src/render3/players';
import {ClassAndStylePlayerBuilder, createStylingContextTemplate, isContextDirty, renderStyleAndClassBindings as _renderStyling, setContextDirty, updateClassProp, updateStyleProp, updateStylingMap} from '../../../src/render3/styling/class_and_style_bindings'; import {ClassAndStylePlayerBuilder, createStylingContextTemplate, isContextDirty, renderStyleAndClassBindings as _renderStyling, setContextDirty, updateClassProp, updateStyleProp, updateStylingMap} from '../../../src/render3/styling/class_and_style_bindings';
import {CorePlayerHandler} from '../../../src/render3/styling/core_player_handler'; import {CorePlayerHandler} from '../../../src/render3/styling/core_player_handler';
@ -29,13 +29,13 @@ describe('style and class based bindings', () => {
let element: RElement|null = null; let element: RElement|null = null;
beforeEach(() => { element = document.createElement('div') as any; }); beforeEach(() => { element = document.createElement('div') as any; });
function createMockViewData(playerHandler: PlayerHandler, context: StylingContext): LViewData { function createMockViewData(playerHandler: PlayerHandler, context: StylingContext): LView {
const rootContext = const rootContext =
createRootContext(requestAnimationFrame.bind(window), playerHandler || null); createRootContext(requestAnimationFrame.bind(window), playerHandler || null);
const lViewData = createLViewData( const lView = createLView(
null, createTView(-1, null, 1, 0, null, null, null), rootContext, LViewFlags.IsRoot, null, createTView(-1, null, 1, 0, null, null, null), rootContext, LViewFlags.IsRoot,
domRendererFactory3, domRendererFactory3.createRenderer(element, null)); domRendererFactory3, domRendererFactory3.createRenderer(element, null));
return lViewData; return lView;
} }
function initContext( function initContext(
@ -44,18 +44,16 @@ describe('style and class based bindings', () => {
return allocStylingContext(element, createStylingContextTemplate(classes, styles, sanitizer)); return allocStylingContext(element, createStylingContextTemplate(classes, styles, sanitizer));
} }
function getRootContextInternal(lViewData: LViewData) { function getRootContextInternal(lView: LView) { return lView[CONTEXT] as RootContext; }
return lViewData[CONTEXT] as RootContext;
}
function renderStyles( function renderStyles(
context: StylingContext, firstRender?: boolean, renderer?: Renderer3, lViewData?: LViewData) { context: StylingContext, firstRender?: boolean, renderer?: Renderer3, lView?: LView) {
const store = new MockStylingStore(element as HTMLElement, BindingType.Style); const store = new MockStylingStore(element as HTMLElement, BindingType.Style);
const handler = new CorePlayerHandler(); const handler = new CorePlayerHandler();
_renderStyling( _renderStyling(
context, (renderer || {}) as Renderer3, context, (renderer || {}) as Renderer3,
getRootContextInternal(lViewData || createMockViewData(handler, context)), !!firstRender, getRootContextInternal(lView || createMockViewData(handler, context)), !!firstRender, null,
null, store); store);
return store.getValues(); return store.getValues();
} }
@ -64,10 +62,10 @@ describe('style and class based bindings', () => {
const handler = new CorePlayerHandler(); const handler = new CorePlayerHandler();
return function(context: StylingContext, firstRender?: boolean, renderer?: Renderer3): return function(context: StylingContext, firstRender?: boolean, renderer?: Renderer3):
{[key: string]: any} { {[key: string]: any} {
const lViewData = createMockViewData(handler, context); const lView = createMockViewData(handler, context);
_renderStyling( _renderStyling(
context, (renderer || {}) as Renderer3, getRootContextInternal(lViewData), context, (renderer || {}) as Renderer3, getRootContextInternal(lView), !!firstRender,
!!firstRender, null, store); null, store);
return store !.getValues(); return store !.getValues();
}; };
} }
@ -77,10 +75,10 @@ describe('style and class based bindings', () => {
const handler = new CorePlayerHandler(); const handler = new CorePlayerHandler();
return function(context: StylingContext, firstRender?: boolean, renderer?: Renderer3): return function(context: StylingContext, firstRender?: boolean, renderer?: Renderer3):
{[key: string]: any} { {[key: string]: any} {
const lViewData = createMockViewData(handler, context); const lView = createMockViewData(handler, context);
_renderStyling( _renderStyling(
context, (renderer || {}) as Renderer3, getRootContextInternal(lViewData), context, (renderer || {}) as Renderer3, getRootContextInternal(lView), !!firstRender,
!!firstRender, store); store);
return store !.getValues(); return store !.getValues();
}; };
} }
@ -91,10 +89,10 @@ describe('style and class based bindings', () => {
const handler = new CorePlayerHandler(); const handler = new CorePlayerHandler();
return function(context: StylingContext, firstRender?: boolean, renderer?: Renderer3): return function(context: StylingContext, firstRender?: boolean, renderer?: Renderer3):
{[key: string]: any} { {[key: string]: any} {
const lViewData = createMockViewData(handler, context); const lView = createMockViewData(handler, context);
_renderStyling( _renderStyling(
context, (renderer || {}) as Renderer3, getRootContextInternal(lViewData), context, (renderer || {}) as Renderer3, getRootContextInternal(lView), !!firstRender,
!!firstRender, classStore, styleStore); classStore, styleStore);
return [classStore.getValues(), styleStore.getValues()]; return [classStore.getValues(), styleStore.getValues()];
}; };
} }
@ -1599,7 +1597,7 @@ describe('style and class based bindings', () => {
it('should store active players in the player context and remove them once destroyed', () => { it('should store active players in the player context and remove them once destroyed', () => {
const context = initContext(null, []); const context = initContext(null, []);
const handler = new CorePlayerHandler(); const handler = new CorePlayerHandler();
const lViewData = createMockViewData(handler, context); const lView = createMockViewData(handler, context);
let currentStylePlayer: Player; let currentStylePlayer: Player;
const styleBuildFn = (element: HTMLElement, type: BindingType, value: any) => { const styleBuildFn = (element: HTMLElement, type: BindingType, value: any) => {
@ -1625,7 +1623,7 @@ describe('style and class based bindings', () => {
5, classPlayerBuilder, null, stylePlayerBuilder, null 5, classPlayerBuilder, null, stylePlayerBuilder, null
]); ]);
renderStyles(context, false, undefined, lViewData); renderStyles(context, false, undefined, lView);
expect(context[StylingIndex.PlayerContext]).toEqual([ expect(context[StylingIndex.PlayerContext]).toEqual([
5, classPlayerBuilder, currentClassPlayer !, stylePlayerBuilder, currentStylePlayer ! 5, classPlayerBuilder, currentClassPlayer !, stylePlayerBuilder, currentStylePlayer !
]); ]);
@ -1661,7 +1659,7 @@ describe('style and class based bindings', () => {
() => { () => {
const context = initContext(['width', 'height'], ['foo', 'bar']); const context = initContext(['width', 'height'], ['foo', 'bar']);
const handler = new CorePlayerHandler(); const handler = new CorePlayerHandler();
const lViewData = createMockViewData(handler, context); const lView = createMockViewData(handler, context);
const capturedStylePlayers: Player[] = []; const capturedStylePlayers: Player[] = [];
const styleBuildFn = (element: HTMLElement, type: BindingType, value: any) => { const styleBuildFn = (element: HTMLElement, type: BindingType, value: any) => {
@ -1701,7 +1699,7 @@ describe('style and class based bindings', () => {
barPlayerBuilder, null barPlayerBuilder, null
]); ]);
renderStyles(context, false, undefined, lViewData); renderStyles(context, false, undefined, lView);
const classMapPlayer = capturedClassPlayers.shift() !; const classMapPlayer = capturedClassPlayers.shift() !;
const barPlayer = capturedClassPlayers.shift() !; const barPlayer = capturedClassPlayers.shift() !;
const styleMapPlayer = capturedStylePlayers.shift() !; const styleMapPlayer = capturedStylePlayers.shift() !;
@ -1734,7 +1732,7 @@ describe('style and class based bindings', () => {
bazPlayerBuilder, null bazPlayerBuilder, null
]); ]);
renderStyles(context, false, undefined, lViewData); renderStyles(context, false, undefined, lView);
const heightPlayer = capturedStylePlayers.shift() !; const heightPlayer = capturedStylePlayers.shift() !;
const bazPlayer = capturedClassPlayers.shift() !; const bazPlayer = capturedClassPlayers.shift() !;
@ -1757,7 +1755,7 @@ describe('style and class based bindings', () => {
() => { () => {
const context = initContext(['width']); const context = initContext(['width']);
const handler = new CorePlayerHandler(); const handler = new CorePlayerHandler();
const lViewData = createMockViewData(handler, context); const lView = createMockViewData(handler, context);
const players: MockPlayer[] = []; const players: MockPlayer[] = [];
const buildFn = const buildFn =
@ -1772,7 +1770,7 @@ describe('style and class based bindings', () => {
let mapFactory = bindPlayerFactory(buildFn, {width: '200px'}); let mapFactory = bindPlayerFactory(buildFn, {width: '200px'});
updateStylingMap(context, null, mapFactory); updateStylingMap(context, null, mapFactory);
renderStyles(context, false, undefined, lViewData); renderStyles(context, false, undefined, lView);
expect(players.length).toEqual(1); expect(players.length).toEqual(1);
const p1 = players.pop() !; const p1 = players.pop() !;
@ -1780,7 +1778,7 @@ describe('style and class based bindings', () => {
mapFactory = bindPlayerFactory(buildFn, {width: '100px'}); mapFactory = bindPlayerFactory(buildFn, {width: '100px'});
updateStylingMap(context, null, mapFactory); updateStylingMap(context, null, mapFactory);
renderStyles(context, false, undefined, lViewData); renderStyles(context, false, undefined, lView);
expect(players.length).toEqual(1); expect(players.length).toEqual(1);
const p2 = players.pop() !; const p2 = players.pop() !;
@ -1792,7 +1790,7 @@ describe('style and class based bindings', () => {
() => { () => {
const context = initContext(['color'], ['foo']); const context = initContext(['color'], ['foo']);
const handler = new CorePlayerHandler(); const handler = new CorePlayerHandler();
const lViewData = createMockViewData(handler, context); const lView = createMockViewData(handler, context);
const stylePlayers: Player[] = []; const stylePlayers: Player[] = [];
const buildStyleFn = (element: HTMLElement, type: BindingType, value: any) => { const buildStyleFn = (element: HTMLElement, type: BindingType, value: any) => {
@ -1855,7 +1853,7 @@ describe('style and class based bindings', () => {
const fooPlayerBuilder = makePlayerBuilder(fooWithPlayerFactory, true); const fooPlayerBuilder = makePlayerBuilder(fooWithPlayerFactory, true);
updateStyleProp(context, 0, colorWithPlayerFactory as any); updateStyleProp(context, 0, colorWithPlayerFactory as any);
updateClassProp(context, 0, fooWithPlayerFactory as any); updateClassProp(context, 0, fooWithPlayerFactory as any);
renderStyles(context, false, undefined, lViewData); renderStyles(context, false, undefined, lView);
const p1 = classPlayers.shift(); const p1 = classPlayers.shift();
const p2 = stylePlayers.shift(); const p2 = stylePlayers.shift();
@ -1919,7 +1917,7 @@ describe('style and class based bindings', () => {
const fooWithoutPlayerFactory = false; const fooWithoutPlayerFactory = false;
updateStyleProp(context, 0, colorWithoutPlayerFactory); updateStyleProp(context, 0, colorWithoutPlayerFactory);
updateClassProp(context, 0, fooWithoutPlayerFactory); updateClassProp(context, 0, fooWithoutPlayerFactory);
renderStyles(context, false, undefined, lViewData); renderStyles(context, false, undefined, lView);
expect(context).toEqual([ expect(context).toEqual([
([9, null, null, null, null, null, null, null, null] as any), ([9, null, null, null, null, null, null, null, null] as any),
@ -1972,7 +1970,7 @@ describe('style and class based bindings', () => {
it('should not call a factory if no style and/or class values have been updated', () => { it('should not call a factory if no style and/or class values have been updated', () => {
const context = initContext([]); const context = initContext([]);
const handler = new CorePlayerHandler(); const handler = new CorePlayerHandler();
const lViewData = createMockViewData(handler, context); const lView = createMockViewData(handler, context);
let styleCalls = 0; let styleCalls = 0;
const buildStyleFn = (element: HTMLElement, type: BindingType, value: any) => { const buildStyleFn = (element: HTMLElement, type: BindingType, value: any) => {
@ -1993,28 +1991,28 @@ describe('style and class based bindings', () => {
expect(styleCalls).toEqual(0); expect(styleCalls).toEqual(0);
expect(classCalls).toEqual(0); expect(classCalls).toEqual(0);
renderStyles(context, false, undefined, lViewData); renderStyles(context, false, undefined, lView);
expect(styleCalls).toEqual(1); expect(styleCalls).toEqual(1);
expect(classCalls).toEqual(1); expect(classCalls).toEqual(1);
renderStyles(context, false, undefined, lViewData); renderStyles(context, false, undefined, lView);
expect(styleCalls).toEqual(1); expect(styleCalls).toEqual(1);
expect(classCalls).toEqual(1); expect(classCalls).toEqual(1);
styleFactory.value = {opacity: '0.5'}; styleFactory.value = {opacity: '0.5'};
updateStylingMap(context, classFactory, styleFactory); updateStylingMap(context, classFactory, styleFactory);
renderStyles(context, false, undefined, lViewData); renderStyles(context, false, undefined, lView);
expect(styleCalls).toEqual(2); expect(styleCalls).toEqual(2);
expect(classCalls).toEqual(1); expect(classCalls).toEqual(1);
classFactory.value = 'foo'; classFactory.value = 'foo';
updateStylingMap(context, classFactory, styleFactory); updateStylingMap(context, classFactory, styleFactory);
renderStyles(context, false, undefined, lViewData); renderStyles(context, false, undefined, lView);
expect(styleCalls).toEqual(2); expect(styleCalls).toEqual(2);
expect(classCalls).toEqual(2); expect(classCalls).toEqual(2);
updateStylingMap(context, 'foo', {opacity: '0.5'}); updateStylingMap(context, 'foo', {opacity: '0.5'});
renderStyles(context, false, undefined, lViewData); renderStyles(context, false, undefined, lView);
expect(styleCalls).toEqual(2); expect(styleCalls).toEqual(2);
expect(classCalls).toEqual(2); expect(classCalls).toEqual(2);
}); });
@ -2023,7 +2021,7 @@ describe('style and class based bindings', () => {
() => { () => {
const context = initContext(['color']); const context = initContext(['color']);
const handler = new CorePlayerHandler(); const handler = new CorePlayerHandler();
const lViewData = createMockViewData(handler, context); const lView = createMockViewData(handler, context);
let propPlayer: Player|null = null; let propPlayer: Player|null = null;
const propBuildFn = (element: HTMLElement, type: BindingType, value: any) => { const propBuildFn = (element: HTMLElement, type: BindingType, value: any) => {
@ -2038,14 +2036,14 @@ describe('style and class based bindings', () => {
const mapFactory = bindPlayerFactory(mapBuildFn, {color: 'black'}); const mapFactory = bindPlayerFactory(mapBuildFn, {color: 'black'});
updateStylingMap(context, null, mapFactory); updateStylingMap(context, null, mapFactory);
updateStyleProp(context, 0, 'green'); updateStyleProp(context, 0, 'green');
renderStyles(context, false, undefined, lViewData); renderStyles(context, false, undefined, lView);
expect(propPlayer).toBeFalsy(); expect(propPlayer).toBeFalsy();
expect(styleMapPlayer).toBeFalsy(); expect(styleMapPlayer).toBeFalsy();
const propFactory = bindPlayerFactory(propBuildFn, 'orange'); const propFactory = bindPlayerFactory(propBuildFn, 'orange');
updateStyleProp(context, 0, propFactory as any); updateStyleProp(context, 0, propFactory as any);
renderStyles(context, false, undefined, lViewData); renderStyles(context, false, undefined, lView);
expect(propPlayer).toBeTruthy(); expect(propPlayer).toBeTruthy();
expect(styleMapPlayer).toBeFalsy(); expect(styleMapPlayer).toBeFalsy();
@ -2053,7 +2051,7 @@ describe('style and class based bindings', () => {
propPlayer = styleMapPlayer = null; propPlayer = styleMapPlayer = null;
updateStyleProp(context, 0, null); updateStyleProp(context, 0, null);
renderStyles(context, false, undefined, lViewData); renderStyles(context, false, undefined, lView);
expect(propPlayer).toBeFalsy(); expect(propPlayer).toBeFalsy();
expect(styleMapPlayer).toBeTruthy(); expect(styleMapPlayer).toBeTruthy();
@ -2061,7 +2059,7 @@ describe('style and class based bindings', () => {
propPlayer = styleMapPlayer = null; propPlayer = styleMapPlayer = null;
updateStylingMap(context, null, null); updateStylingMap(context, null, null);
renderStyles(context, false, undefined, lViewData); renderStyles(context, false, undefined, lView);
expect(propPlayer).toBeFalsy(); expect(propPlayer).toBeFalsy();
expect(styleMapPlayer).toBeFalsy(); expect(styleMapPlayer).toBeFalsy();
@ -2070,7 +2068,7 @@ describe('style and class based bindings', () => {
it('should return the old player for styles when a follow-up player is instantiated', () => { it('should return the old player for styles when a follow-up player is instantiated', () => {
const context = initContext([]); const context = initContext([]);
const handler = new CorePlayerHandler(); const handler = new CorePlayerHandler();
const lViewData = createMockViewData(handler, context); const lView = createMockViewData(handler, context);
let previousPlayer: MockPlayer|null = null; let previousPlayer: MockPlayer|null = null;
let currentPlayer: MockPlayer|null = null; let currentPlayer: MockPlayer|null = null;
@ -2083,7 +2081,7 @@ describe('style and class based bindings', () => {
let factory = bindPlayerFactory<{[key: string]: any}>(buildFn, {width: '200px'}); let factory = bindPlayerFactory<{[key: string]: any}>(buildFn, {width: '200px'});
updateStylingMap(context, null, factory); updateStylingMap(context, null, factory);
renderStyles(context, false, undefined, lViewData); renderStyles(context, false, undefined, lView);
expect(previousPlayer).toEqual(null); expect(previousPlayer).toEqual(null);
expect(currentPlayer !.value).toEqual({width: '200px'}); expect(currentPlayer !.value).toEqual({width: '200px'});
@ -2091,7 +2089,7 @@ describe('style and class based bindings', () => {
factory = bindPlayerFactory(buildFn, {height: '200px'}); factory = bindPlayerFactory(buildFn, {height: '200px'});
updateStylingMap(context, null, factory); updateStylingMap(context, null, factory);
renderStyles(context, false, undefined, lViewData); renderStyles(context, false, undefined, lView);
expect(previousPlayer !.value).toEqual({width: '200px'}); expect(previousPlayer !.value).toEqual({width: '200px'});
expect(currentPlayer !.value).toEqual({width: null, height: '200px'}); expect(currentPlayer !.value).toEqual({width: null, height: '200px'});
@ -2100,7 +2098,7 @@ describe('style and class based bindings', () => {
it('should return the old player for classes when a follow-up player is instantiated', () => { it('should return the old player for classes when a follow-up player is instantiated', () => {
const context = initContext([]); const context = initContext([]);
const handler = new CorePlayerHandler(); const handler = new CorePlayerHandler();
const lViewData = createMockViewData(handler, context); const lView = createMockViewData(handler, context);
let currentPlayer: MockPlayer|null = null; let currentPlayer: MockPlayer|null = null;
let previousPlayer: MockPlayer|null = null; let previousPlayer: MockPlayer|null = null;
@ -2113,7 +2111,7 @@ describe('style and class based bindings', () => {
let factory = bindPlayerFactory<any>(buildFn, {foo: true}); let factory = bindPlayerFactory<any>(buildFn, {foo: true});
updateStylingMap(context, null, factory); updateStylingMap(context, null, factory);
renderStyles(context, false, undefined, lViewData); renderStyles(context, false, undefined, lView);
expect(currentPlayer).toBeTruthy(); expect(currentPlayer).toBeTruthy();
expect(previousPlayer).toBeFalsy(); expect(previousPlayer).toBeFalsy();
@ -2123,7 +2121,7 @@ describe('style and class based bindings', () => {
factory = bindPlayerFactory(buildFn, {bar: true}); factory = bindPlayerFactory(buildFn, {bar: true});
updateStylingMap(context, null, factory); updateStylingMap(context, null, factory);
renderStyles(context, false, undefined, lViewData); renderStyles(context, false, undefined, lView);
expect(currentPlayer).toBeTruthy(); expect(currentPlayer).toBeTruthy();
expect(previousPlayer).toBeTruthy(); expect(previousPlayer).toBeTruthy();
@ -2142,7 +2140,7 @@ describe('style and class based bindings', () => {
const context = initContext([], [], sanitizer); const context = initContext([], [], sanitizer);
const handler = new CorePlayerHandler(); const handler = new CorePlayerHandler();
const lViewData = createMockViewData(handler, context); const lView = createMockViewData(handler, context);
let values: {[key: string]: any}|null = null; let values: {[key: string]: any}|null = null;
const buildFn = const buildFn =
@ -2154,13 +2152,13 @@ describe('style and class based bindings', () => {
let factory = bindPlayerFactory<{[key: string]: any}>( let factory = bindPlayerFactory<{[key: string]: any}>(
buildFn, {width: '200px', height: '100px', opacity: '1'}); buildFn, {width: '200px', height: '100px', opacity: '1'});
updateStylingMap(context, null, factory); updateStylingMap(context, null, factory);
renderStyles(context, false, undefined, lViewData); renderStyles(context, false, undefined, lView);
expect(values !).toEqual({width: '200px-safe!', height: '100px-safe!', opacity: '1'}); expect(values !).toEqual({width: '200px-safe!', height: '100px-safe!', opacity: '1'});
factory = bindPlayerFactory(buildFn, {width: 'auto'}); factory = bindPlayerFactory(buildFn, {width: 'auto'});
updateStylingMap(context, null, factory); updateStylingMap(context, null, factory);
renderStyles(context, false, undefined, lViewData); renderStyles(context, false, undefined, lView);
expect(values !).toEqual({width: 'auto-safe!', height: null, opacity: null}); expect(values !).toEqual({width: 'auto-safe!', height: null, opacity: null});
}); });
@ -2169,7 +2167,7 @@ describe('style and class based bindings', () => {
() => { () => {
const context = initContext(['width'], ['foo', 'bar']); const context = initContext(['width'], ['foo', 'bar']);
const handler = new CorePlayerHandler(); const handler = new CorePlayerHandler();
const lViewData = createMockViewData(handler, context); const lView = createMockViewData(handler, context);
const players: Player[] = []; const players: Player[] = [];
const styleBuildFn = (element: HTMLElement, type: BindingType, value: any) => { const styleBuildFn = (element: HTMLElement, type: BindingType, value: any) => {
@ -2192,7 +2190,7 @@ describe('style and class based bindings', () => {
updateStyleProp(context, 0, bindPlayerFactory(styleBuildFn, '100px') as any); updateStyleProp(context, 0, bindPlayerFactory(styleBuildFn, '100px') as any);
updateClassProp(context, 0, bindPlayerFactory(classBuildFn, true) as any); updateClassProp(context, 0, bindPlayerFactory(classBuildFn, true) as any);
updateClassProp(context, 1, bindPlayerFactory(classBuildFn, true) as any); updateClassProp(context, 1, bindPlayerFactory(classBuildFn, true) as any);
renderStyles(context, false, undefined, lViewData); renderStyles(context, false, undefined, lView);
handler.flushPlayers(); handler.flushPlayers();
const [p1, p2, p3, p4, p5] = players; const [p1, p2, p3, p4, p5] = players;
@ -2210,7 +2208,7 @@ describe('style and class based bindings', () => {
expect(p4.state).toEqual(PlayState.Running); expect(p4.state).toEqual(PlayState.Running);
expect(p5.state).toEqual(PlayState.Running); expect(p5.state).toEqual(PlayState.Running);
renderStyles(context, false, undefined, lViewData); renderStyles(context, false, undefined, lView);
expect(p1.state).toEqual(PlayState.Destroyed); expect(p1.state).toEqual(PlayState.Destroyed);
expect(p2.state).toEqual(PlayState.Destroyed); expect(p2.state).toEqual(PlayState.Destroyed);
expect(p3.state).toEqual(PlayState.Destroyed); expect(p3.state).toEqual(PlayState.Destroyed);
@ -2267,7 +2265,7 @@ describe('style and class based bindings', () => {
const target = fixture.hostElement.querySelector('div') !as any; const target = fixture.hostElement.querySelector('div') !as any;
const elementContext = getContext(target) !; const elementContext = getContext(target) !;
const context = elementContext.lViewData[elementContext.nodeIndex] as StylingContext; const context = elementContext.lView[elementContext.nodeIndex] as StylingContext;
expect(players.length).toEqual(4); expect(players.length).toEqual(4);
const [p1, p2, p3, p4] = players; const [p1, p2, p3, p4] = players;

View File

@ -6,6 +6,8 @@
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import {devModeEqual} from '@angular/core/src/change_detection/change_detection_util';
import {flatten, isDifferent} from '../../src/render3/util'; import {flatten, isDifferent} from '../../src/render3/util';
describe('util', () => { describe('util', () => {
@ -14,53 +16,51 @@ describe('util', () => {
describe('checkNoChangeMode = false', () => { describe('checkNoChangeMode = false', () => {
it('should mark non-equal arguments as different', () => { it('should mark non-equal arguments as different', () => {
expect(isDifferent({}, {}, false)).toBeTruthy(); expect(isDifferent({}, {})).toBeTruthy();
expect(isDifferent('foo', 'bar', false)).toBeTruthy(); expect(isDifferent('foo', 'bar')).toBeTruthy();
expect(isDifferent(0, 1, false)).toBeTruthy(); expect(isDifferent(0, 1)).toBeTruthy();
}); });
it('should not mark equal arguments as different', () => { it('should not mark equal arguments as different', () => {
const obj = {}; const obj = {};
expect(isDifferent(obj, obj, false)).toBeFalsy(); expect(isDifferent(obj, obj)).toBeFalsy();
expect(isDifferent('foo', 'foo', false)).toBeFalsy(); expect(isDifferent('foo', 'foo')).toBeFalsy();
expect(isDifferent(1, 1, false)).toBeFalsy(); expect(isDifferent(1, 1)).toBeFalsy();
}); });
it('should not mark NaN as different', it('should not mark NaN as different', () => { expect(isDifferent(NaN, NaN)).toBeFalsy(); });
() => { expect(isDifferent(NaN, NaN, false)).toBeFalsy(); });
it('should mark NaN with other values as different', () => { it('should mark NaN with other values as different', () => {
expect(isDifferent(NaN, 'foo', false)).toBeTruthy(); expect(isDifferent(NaN, 'foo')).toBeTruthy();
expect(isDifferent(5, NaN, false)).toBeTruthy(); expect(isDifferent(5, NaN)).toBeTruthy();
}); });
}); });
describe('checkNoChangeMode = true', () => { describe('checkNoChangeMode = true', () => {
// Assert relaxed constraint in checkNoChangeMode // Assert relaxed constraint in checkNoChangeMode
it('should not mark non-equal arrays, object and function as different', () => { it('should not mark non-equal arrays, object and function as different', () => {
expect(isDifferent([], [], true)).toBeFalsy(); expect(!devModeEqual([], [])).toBeFalsy();
expect(isDifferent(() => 0, () => 0, true)).toBeFalsy(); expect(!devModeEqual(() => 0, () => 0)).toBeFalsy();
expect(isDifferent({}, {}, true)).toBeFalsy(); expect(!devModeEqual({}, {})).toBeFalsy();
}); });
it('should mark non-equal arguments as different', () => { it('should mark non-equal arguments as different', () => {
expect(isDifferent('foo', 'bar', true)).toBeTruthy(); expect(!devModeEqual('foo', 'bar')).toBeTruthy();
expect(isDifferent(0, 1, true)).toBeTruthy(); expect(!devModeEqual(0, 1)).toBeTruthy();
}); });
it('should not mark equal arguments as different', () => { it('should not mark equal arguments as different', () => {
const obj = {}; const obj = {};
expect(isDifferent(obj, obj, false)).toBeFalsy(); expect(isDifferent(obj, obj)).toBeFalsy();
expect(isDifferent('foo', 'foo', false)).toBeFalsy(); expect(isDifferent('foo', 'foo')).toBeFalsy();
expect(isDifferent(1, 1, false)).toBeFalsy(); expect(isDifferent(1, 1)).toBeFalsy();
}); });
it('should not mark NaN as different', it('should not mark NaN as different', () => { expect(isDifferent(NaN, NaN)).toBeFalsy(); });
() => { expect(isDifferent(NaN, NaN, false)).toBeFalsy(); });
it('should mark NaN with other values as different', () => { it('should mark NaN with other values as different', () => {
expect(isDifferent(NaN, 'foo', false)).toBeTruthy(); expect(isDifferent(NaN, 'foo')).toBeTruthy();
expect(isDifferent(5, NaN, false)).toBeTruthy(); expect(isDifferent(5, NaN)).toBeTruthy();
}); });
}); });

View File

@ -16,7 +16,7 @@ import {RElement} from '../../src/render3/interfaces/renderer';
import {templateRefExtractor} from '../../src/render3/view_engine_compatibility_prebound'; import {templateRefExtractor} from '../../src/render3/view_engine_compatibility_prebound';
import {NgModuleFactory} from '../../src/render3/ng_module_ref'; import {NgModuleFactory} from '../../src/render3/ng_module_ref';
import {pipe, pipeBind1} from '../../src/render3/pipe'; import {pipe, pipeBind1} from '../../src/render3/pipe';
import {getViewData} from '../../src/render3/state'; import {getLView} from '../../src/render3/state';
import {getNativeByIndex} from '../../src/render3/util'; import {getNativeByIndex} from '../../src/render3/util';
import {NgForOf} from '../../test/render3/common_with_def'; import {NgForOf} from '../../test/render3/common_with_def';
import {fixmeIvy} from '@angular/private/testing'; import {fixmeIvy} from '@angular/private/testing';
@ -2013,7 +2013,7 @@ describe('ViewContainerRef', () => {
element(1, 'div', ['bar', ''], ['foo', '']); element(1, 'div', ['bar', ''], ['foo', '']);
} }
// testing only // testing only
fooEl = getNativeByIndex(1, getViewData()); fooEl = getNativeByIndex(1, getLView());
}, },
viewQuery: function(rf: RenderFlags, ctx: any) { viewQuery: function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) { if (rf & RenderFlags.Create) {

View File

@ -7,10 +7,14 @@
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import {setTNodeAndViewData} from '@angular/core/src/render3/state';
import {bypassSanitizationTrustHtml, bypassSanitizationTrustResourceUrl, bypassSanitizationTrustScript, bypassSanitizationTrustStyle, bypassSanitizationTrustUrl} from '../../src/sanitization/bypass'; import {bypassSanitizationTrustHtml, bypassSanitizationTrustResourceUrl, bypassSanitizationTrustScript, bypassSanitizationTrustStyle, bypassSanitizationTrustUrl} from '../../src/sanitization/bypass';
import {sanitizeHtml, sanitizeResourceUrl, sanitizeScript, sanitizeStyle, sanitizeUrl} from '../../src/sanitization/sanitization'; import {sanitizeHtml, sanitizeResourceUrl, sanitizeScript, sanitizeStyle, sanitizeUrl} from '../../src/sanitization/sanitization';
describe('sanitization', () => { describe('sanitization', () => {
beforeEach(() => setTNodeAndViewData(null !, [] as any));
afterEach(() => setTNodeAndViewData(null !, null !));
class Wrap { class Wrap {
constructor(private value: string) {} constructor(private value: string) {}
toString() { return this.value; } toString() { return this.value; }