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
const context = loadContext(this.nativeNode as HTMLElement, false) !;
if (!context) return [];
const lView = context.lViewData;
const lView = context.lView;
const tView = lView[TVIEW];
const tNode = tView.data[context.nodeIndex] as TNode;
const providerTokens: any[] = [];
@ -268,7 +268,7 @@ class DebugElement__POST_R3__ extends DebugNode__POST_R3__ implements DebugEleme
get properties(): {[key: string]: any;} {
const context = loadContext(this.nativeNode) !;
const lView = context.lViewData;
const lView = context.lView;
const tView = lView[TVIEW];
const tNode = tView.data[context.nodeIndex] as TNode;
const properties = {};

View File

@ -1,17 +1,17 @@
# View Data Explanation
`LViewData` 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.
`TView.data` is a corollary to the `LViewData` and contains information which can be shared across the template instances.
`LView` and `TView.data` are how the Ivy renderer keeps track of the internal data needed to render the template.
`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 `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.
For example index `123` may point to a component instance in the `LViewData` but a component type in `TView.data`.
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 `LView` but a component type in `TView.data`.
The layout is as such:
| Section | `LViewData` | `TView.data`
| Section | `LView` | `TView.data`
| ---------- | ------------------------------------------------------------ | --------------------------------------------------
| `HEADER` | contextual data | mostly `null`
| `CONSTS` | DOM, pipe, and local ref instances |
@ -22,7 +22,7 @@ The layout is as such:
## `HEADER`
`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`
@ -57,7 +57,7 @@ class MyApp {
The above will create following layout:
| Index | `LViewData` | `TView.data`
| Index | `LView` | `TView.data`
| ----: | ----------- | ------------
| `HEADER`
| `CONSTS`
@ -70,9 +70,9 @@ The above will create following layout:
NOTE:
- 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.
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`
@ -109,7 +109,7 @@ class MyApp {
The above will create following layout:
| Index | `LViewData` | `TView.data`
| Index | `LView` | `TView.data`
| ----: | ----------- | ------------
| `HEADER`
| `CONSTS`
@ -121,7 +121,7 @@ The above will create following layout:
| ... | ... | ...
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.
@ -182,7 +182,7 @@ class Tooltip {
The above will create the following layout:
| Index | `LViewData` | `TView.data`
| Index | `LView` | `TView.data`
| ----: | ----------- | ------------
| `HEADER`
| `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:
- The injection token stored in `TView.data`
- The token factory stored in `LProtoViewData` and subsequently in `LViewData`
- The value for the injection token stored in `LViewData`. (Replacing token factory upon creation).
- The token factory stored in `LProtoViewData` and subsequently in `LView`
- 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`.
Injection tokens are sorted into three sections:
@ -321,7 +321,7 @@ class Child {
The above will create the following layout:
| Index | `LViewData` | `TView.data`
| Index | `LView` | `TView.data`
| ----: | ------------ | -------------
| `HEADER`
| `CONSTS`
@ -366,9 +366,9 @@ function isFactory(obj: any): obj is Factory {
Pseudo code:
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.
3. Read the value of `lViewData[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(lViewData[index])` then return the cached value as is.
3. Read the value of `lView[index]` at that location.
- 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(lView[index])` then return the cached value as is.
# `EXPANDO` and Injecting Special Objects.
@ -437,6 +437,6 @@ function inject(token: any): any {
TODO
## Combining `LContainer` with `LViewData`
## Combining `LContainer` with `LView`
TODO

View File

@ -7,6 +7,8 @@
*/
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
// 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) {
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 {publishDefaultGlobalUtils} from './global_utils';
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 {TElementNode, TNodeFlags, TNodeType} from './interfaces/node';
import {PlayerHandler} from './interfaces/player';
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 {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 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,
renderer, undefined, opts.injector || null);
@ -154,12 +154,11 @@ export function renderComponent<T>(
* @returns Component view created
*/
export function createRootComponentView(
rNode: RElement | null, def: ComponentDef<any>, rootView: LViewData,
rendererFactory: RendererFactory3, renderer: Renderer3,
sanitizer?: Sanitizer | null): LViewData {
rNode: RElement | null, def: ComponentDef<any>, rootView: LView,
rendererFactory: RendererFactory3, renderer: Renderer3, sanitizer?: Sanitizer | null): LView {
resetComponentState();
const tView = rootView[TVIEW];
const componentView = createLViewData(
const componentView = createLView(
rootView,
getOrCreateTView(
def.template, def.consts, def.vars, def.directiveDefs, def.pipeDefs, def.viewQuery),
@ -185,8 +184,8 @@ export function createRootComponentView(
* renderComponent() and ViewContainerRef.createComponent().
*/
export function createRootComponent<T>(
componentView: LViewData, componentDef: ComponentDef<T>, rootView: LViewData,
rootContext: RootContext, hostFeatures: HostFeature[] | null): any {
componentView: LView, componentDef: ComponentDef<T>, rootView: LView, rootContext: RootContext,
hostFeatures: HostFeature[] | null): any {
const tView = rootView[TVIEW];
// Create directive instance with factory() and store at next index in viewData
const component = instantiateRootComponent(tView, rootView, componentDef);
@ -226,7 +225,7 @@ export function createRootContext(
* ```
*/
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;
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 {getComponentDef} from './definition';
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 {TContainerNode, TElementContainerNode, TElementNode, TNode, TNodeType} from './interfaces/node';
import {RElement, RendererFactory3, domRendererFactory3, isProceduralRenderer} from './interfaces/renderer';
import {SanitizerFn} from './interfaces/sanitization';
import {HEADER_OFFSET, LViewData, LViewFlags, RootContext, TVIEW} from './interfaces/view';
import {HEADER_OFFSET, LView, LViewFlags, RootContext, TVIEW} from './interfaces/view';
import {enterView, leaveView} from './state';
import {defaultScheduler, getTNode} from './util';
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.
const rootView: LViewData = createLViewData(
const rootLView = createLView(
null, createTView(-1, null, 1, 0, null, null, null), rootContext, rootFlags,
rendererFactory, renderer, sanitizer, rootViewInjector);
// rootView is the parent when bootstrapping
const oldView = enterView(rootView, null);
const oldLView = enterView(rootLView, null);
let component: T;
let tElementNode: TElementNode;
@ -159,14 +159,14 @@ export class ComponentFactory<T> extends viewEngine_ComponentFactory<T> {
if (rendererFactory.begin) rendererFactory.begin();
const componentView = createRootComponentView(
hostRNode, this.componentDef, rootView, rendererFactory, renderer);
tElementNode = getTNode(0, rootView) as TElementNode;
hostRNode, this.componentDef, rootLView, rendererFactory, renderer);
tElementNode = getTNode(0, rootLView) as TElementNode;
// 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.
if (projectableNodes) {
let index = 0;
const tView = rootView[TVIEW];
const tView = rootLView[TVIEW];
const projection: TNode[] = tElementNode.projection = [];
for (let i = 0; i < projectableNodes.length; i++) {
const nodeList = projectableNodes[i];
@ -181,7 +181,7 @@ export class ComponentFactory<T> extends viewEngine_ComponentFactory<T> {
tView.expandoStartIndex++;
tView.blueprint.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 =
createNodeAtIndex(index, TNodeType.Element, nodeList[j] as RElement, null, null);
@ -196,17 +196,17 @@ export class ComponentFactory<T> extends viewEngine_ComponentFactory<T> {
// executed here?
// Angular 5 reference: https://stackblitz.com/edit/lifecycle-hooks-vcref
component = createRootComponent(
componentView, this.componentDef, rootView, rootContext, [LifecycleHooksFeature]);
componentView, this.componentDef, rootLView, rootContext, [LifecycleHooksFeature]);
refreshDescendantViews(rootView, RenderFlags.Create);
refreshDescendantViews(rootLView, RenderFlags.Create);
} finally {
leaveView(oldView, true);
leaveView(oldLView, true);
if (rendererFactory.end) rendererFactory.end();
}
const componentRef = new ComponentRef(
this.componentType, component,
createElementRef(viewEngine_ElementRef, tElementNode, rootView), rootView, tElementNode);
createElementRef(viewEngine_ElementRef, tElementNode, rootLView), rootLView, tElementNode);
if (isInternalRootView) {
// 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(
componentType: Type<T>, instance: T, public location: viewEngine_ElementRef,
private _rootView: LViewData,
private _rootLView: LView,
private _tNode: TElementNode|TContainerNode|TElementContainerNode) {
super();
this.instance = instance;
this.hostView = this.changeDetectorRef = new RootViewRef<T>(_rootView);
this.hostView._tViewNode = createViewNode(-1, _rootView);
this.hostView = this.changeDetectorRef = new RootViewRef<T>(_rootLView);
this.hostView._tViewNode = createViewNode(-1, _rootLView);
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 {
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 {TNode, TNodeFlags} from './interfaces/node';
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';
@ -23,7 +23,7 @@ import {getComponentViewByIndex, getNativeByTNode, readElementValue, readPatched
* monkey-patched property to derive the `LContext` data. Once called then the monkey-patched
* 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
* function is called it may mutate the provided element\'s, component\'s or any of the associated
* directive\'s monkey-patch values.
@ -39,28 +39,28 @@ import {getComponentViewByIndex, getNativeByTNode, readElementValue, readPatched
export function getContext(target: any): LContext|null {
let mpValue = readPatchedData(target);
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
if (Array.isArray(mpValue)) {
const lViewData: LViewData = mpValue !;
const lView: LView = mpValue !;
let nodeIndex: number;
let component: any = undefined;
let directives: any[]|null|undefined = undefined;
if (isComponentInstance(target)) {
nodeIndex = findViaComponent(lViewData, target);
nodeIndex = findViaComponent(lView, target);
if (nodeIndex == -1) {
throw new Error('The provided component was not found in the application');
}
component = target;
} else if (isDirectiveInstance(target)) {
nodeIndex = findViaDirective(lViewData, target);
nodeIndex = findViaDirective(lView, target);
if (nodeIndex == -1) {
throw new Error('The provided directive was not found in the application');
}
directives = getDirectivesAtNodeIndex(nodeIndex, lViewData, false);
directives = getDirectivesAtNodeIndex(nodeIndex, lView, false);
} else {
nodeIndex = findViaNativeElement(lViewData, target as RElement);
nodeIndex = findViaNativeElement(lView, target as RElement);
if (nodeIndex == -1) {
return null;
}
@ -70,11 +70,11 @@ export function getContext(target: any): LContext|null {
// are expensive. Instead, only the target data (the element, compontent or
// directive details) are filled into the context. If called multiple times
// 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 context: LContext = (existingCtx && !Array.isArray(existingCtx)) ?
existingCtx :
createLContext(lViewData, nodeIndex, native);
createLContext(lView, nodeIndex, native);
// only when the component has been discovered then update the monkey-patch
if (component && context.component === undefined) {
@ -103,23 +103,23 @@ export function getContext(target: any): LContext|null {
while (parent = parent.parentNode) {
const parentContext = readPatchedData(parent);
if (parentContext) {
let lViewData: LViewData|null;
let lView: LView|null;
if (Array.isArray(parentContext)) {
lViewData = parentContext as LViewData;
lView = parentContext as LView;
} else {
lViewData = parentContext.lViewData;
lView = parentContext.lView;
}
// the edge of the app was also reached here through another means
// (maybe because the DOM was changed manually).
if (!lViewData) {
if (!lView) {
return null;
}
const index = findViaNativeElement(lViewData, rElement);
const index = findViaNativeElement(lView, rElement);
if (index >= 0) {
const native = readElementValue(lViewData[index]);
const context = createLContext(lViewData, index, native);
const native = readElementValue(lView[index]);
const context = createLContext(lView, index, native);
attachPatchData(native, context);
mpValue = context;
break;
@ -133,9 +133,9 @@ export function getContext(target: any): LContext|null {
/**
* 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 {
lViewData,
lView,
nodeIndex,
native,
component: undefined,
@ -150,20 +150,20 @@ function createLContext(lViewData: LViewData, nodeIndex: number, native: RElemen
* @param componentInstance
* @returns The component's view
*/
export function getComponentViewByInstance(componentInstance: {}): LViewData {
let lViewData = readPatchedData(componentInstance);
let view: LViewData;
export function getComponentViewByInstance(componentInstance: {}): LView {
let lView = readPatchedData(componentInstance);
let view: LView;
if (Array.isArray(lViewData)) {
const nodeIndex = findViaComponent(lViewData, componentInstance);
view = getComponentViewByIndex(nodeIndex, lViewData);
const context = createLContext(lViewData, nodeIndex, view[HOST] as RElement);
if (Array.isArray(lView)) {
const nodeIndex = findViaComponent(lView, componentInstance);
view = getComponentViewByIndex(nodeIndex, lView);
const context = createLContext(lView, nodeIndex, view[HOST] as RElement);
context.component = componentInstance;
attachPatchData(componentInstance, context);
attachPatchData(context.native, context);
} else {
const context = lViewData as any as LContext;
view = getComponentViewByIndex(context.nodeIndex, context.lViewData);
const context = lView as any as LContext;
view = getComponentViewByIndex(context.nodeIndex, context.lView);
}
return view;
}
@ -172,7 +172,7 @@ export function getComponentViewByInstance(componentInstance: {}): LViewData {
* Assigns the given data to the given target (which could be a component,
* 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;
}
@ -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 {
let tNode = lViewData[TVIEW].firstChild;
function findViaNativeElement(lView: LView, target: RElement): number {
let tNode = lView[TVIEW].firstChild;
while (tNode) {
const native = getNativeByTNode(tNode, lViewData) !;
const native = getNativeByTNode(tNode, lView) !;
if (native === target) {
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 {
const componentIndices = lViewData[TVIEW].components;
function findViaComponent(lView: LView, componentInstance: {}): number {
const componentIndices = lView[TVIEW].components;
if (componentIndices) {
for (let i = 0; i < componentIndices.length; i++) {
const elementComponentIndex = componentIndices[i];
const componentView = getComponentViewByIndex(elementComponentIndex, lViewData);
const componentView = getComponentViewByIndex(elementComponentIndex, lView);
if (componentView[CONTEXT] === componentInstance) {
return elementComponentIndex;
}
}
} else {
const rootComponentView = getComponentViewByIndex(HEADER_OFFSET, lViewData);
const rootComponentView = getComponentViewByIndex(HEADER_OFFSET, lView);
const rootComponent = rootComponentView[CONTEXT];
if (rootComponent === componentInstance) {
// 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)
// 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
// in the view data. We loop through the nodes and check their
// list of directives for the instance.
let tNode = lViewData[TVIEW].firstChild;
let tNode = lView[TVIEW].firstChild;
while (tNode) {
const directiveIndexStart = getDirectiveStartIndex(tNode);
const directiveIndexEnd = getDirectiveEndIndex(tNode, directiveIndexStart);
for (let i = directiveIndexStart; i < directiveIndexEnd; i++) {
if (lViewData[i] === directiveInstance) {
if (lView[i] === directiveInstance) {
return tNode.index;
}
}
@ -267,39 +267,38 @@ function findViaDirective(lViewData: LViewData, directiveInstance: {}): number {
* provided list of directive index values.
*
* @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
*/
export function getDirectivesAtNodeIndex(
nodeIndex: number, lViewData: LViewData, includeComponents: boolean): any[]|null {
const tNode = lViewData[TVIEW].data[nodeIndex] as TNode;
nodeIndex: number, lView: LView, includeComponents: boolean): any[]|null {
const tNode = lView[TVIEW].data[nodeIndex] as TNode;
let directiveStartIndex = getDirectiveStartIndex(tNode);
if (directiveStartIndex == 0) return EMPTY_ARRAY;
const directiveEndIndex = getDirectiveEndIndex(tNode, 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 {
const tNode = lViewData[TVIEW].data[nodeIndex] as TNode;
export function getComponentAtNodeIndex(nodeIndex: number, lView: LView): {}|null {
const tNode = lView[TVIEW].data[nodeIndex] as 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
* exist on a given element.
*/
export function discoverLocalRefs(lViewData: LViewData, nodeIndex: number): {[key: string]: any}|
null {
const tNode = lViewData[TVIEW].data[nodeIndex] as TNode;
export function discoverLocalRefs(lView: LView, nodeIndex: number): {[key: string]: any}|null {
const tNode = lView[TVIEW].data[nodeIndex] as TNode;
if (tNode && tNode.localNames) {
const result: {[key: string]: any} = {};
for (let i = 0; i < tNode.localNames.length; i += 2) {
const localRefName = tNode.localNames[i];
const directiveIndex = tNode.localNames[i + 1] as number;
result[localRefName] =
directiveIndex === -1 ? getNativeByTNode(tNode, lViewData) ! : lViewData[directiveIndex];
directiveIndex === -1 ? getNativeByTNode(tNode, lView) ! : lView[directiveIndex];
}
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.
*
* 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.
*/
// 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).
*
* 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.
*/
vars: number;
@ -76,7 +76,7 @@ export function defineComponent<T>(componentDefinition: {
/**
* 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.
*/
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.
*
* 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.
*/
hostVars?: number;

View File

@ -18,9 +18,9 @@ import {NG_ELEMENT_ID} from './fields';
import {DirectiveDef} from './interfaces/definition';
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 {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 {_getViewData, getPreviousOrParentTNode, getViewData, setTNodeAndViewData} from './state';
import {getLView, getPreviousOrParentTNode, setTNodeAndViewData} from './state';
import {getParentInjectorIndex, getParentInjectorView, hasParentInjector, isComponent, stringify} from './util';
/**
@ -130,7 +130,7 @@ export function bloomAdd(
* @returns Node injector
*/
export function getOrCreateNodeInjectorForNode(
tNode: TElementNode | TContainerNode | TElementContainerNode, hostView: LViewData): number {
tNode: TElementNode | TContainerNode | TElementContainerNode, hostView: LView): number {
const existingInjectorIndex = getInjectorIndex(tNode, hostView);
if (existingInjectorIndex !== -1) {
return existingInjectorIndex;
@ -150,18 +150,18 @@ export function getOrCreateNodeInjectorForNode(
const parentLoc = getParentInjectorLocation(tNode, hostView);
const parentIndex = getParentInjectorIndex(parentLoc);
const parentView: LViewData = getParentInjectorView(parentLoc, hostView);
const parentLView = getParentInjectorView(parentLoc, hostView);
const injectorIndex = tNode.injectorIndex;
// 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
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
// and its own cumulative bloom (which contains tokens for all ancestors)
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 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.
@ -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`
*/
export function getParentInjectorLocation(tNode: TNode, view: LViewData): RelativeInjectorLocation {
export function getParentInjectorLocation(tNode: TNode, view: LView): RelativeInjectorLocation {
if (tNode.parent && tNode.parent.injectorIndex !== -1) {
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
*/
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);
}
@ -292,7 +292,7 @@ export function injectAttributeImpl(tNode: TNode, attrNameToInject: string): str
* @returns the value from the injector or `null` when not found
*/
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,
notFoundValue?: any): T|null {
const bloomHash = bloomHashBitOrFactory(token);
@ -300,8 +300,8 @@ export function getOrCreateInjectable<T>(
// so just call the factory function to create it.
if (typeof bloomHash === 'function') {
const savePreviousOrParentTNode = getPreviousOrParentTNode();
const saveViewData = getViewData();
setTNodeAndViewData(tNode, lViewData);
const saveLView = getLView();
setTNodeAndViewData(tNode, lView);
try {
const value = bloomHash();
if (value == null && !(flags & InjectFlags.Optional)) {
@ -310,7 +310,7 @@ export function getOrCreateInjectable<T>(
return value;
}
} finally {
setTNodeAndViewData(savePreviousOrParentTNode, saveViewData);
setTNodeAndViewData(savePreviousOrParentTNode, saveLView);
}
} else if (typeof bloomHash == 'number') {
// 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
// tree. This is used to know if viewProviders can be accessed on the current injector.
let previousTView: TView|null = null;
let injectorIndex = getInjectorIndex(tNode, lViewData);
let injectorIndex = getInjectorIndex(tNode, lView);
let parentLocation: RelativeInjectorLocation = NO_PARENT_INJECTOR;
// If we should skip this injector, or if there is no injector on this node, start by searching
// the parent injector.
if (injectorIndex === -1 || flags & InjectFlags.SkipSelf) {
parentLocation = injectorIndex === -1 ? getParentInjectorLocation(tNode, lViewData) :
lViewData[injectorIndex + PARENT_INJECTOR];
parentLocation = injectorIndex === -1 ? getParentInjectorLocation(tNode, lView) :
lView[injectorIndex + PARENT_INJECTOR];
if (!shouldSearchParent(flags, parentLocation)) {
injectorIndex = -1;
} else {
previousTView = lViewData[TVIEW];
previousTView = lView[TVIEW];
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
// *isn't* a match.
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.
const tView = lViewData[TVIEW];
const tView = lView[TVIEW];
if (bloomHasToken(bloomHash, injectorIndex, tView.data)) {
// 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 instance.
const instance: T|null =
searchTokensOnInjector<T>(injectorIndex, lViewData, token, previousTView);
searchTokensOnInjector<T>(injectorIndex, lView, token, previousTView);
if (instance !== NOT_FOUND) {
return instance;
}
}
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.
// Traverse up the tree and continue searching.
previousTView = tView;
injectorIndex = getParentInjectorIndex(parentLocation);
lViewData = getParentInjectorView(parentLocation, lViewData);
lView = getParentInjectorView(parentLocation, lView);
} else {
// 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
@ -375,7 +375,7 @@ export function getOrCreateInjectable<T>(
}
if ((flags & (InjectFlags.Self | InjectFlags.Host)) === 0) {
const moduleInjector = lViewData[INJECTOR];
const moduleInjector = lView[INJECTOR];
if (moduleInjector) {
return moduleInjector.get(token, notFoundValue, flags & InjectFlags.Optional);
} else {
@ -392,7 +392,7 @@ export function getOrCreateInjectable<T>(
const NOT_FOUND = {};
function searchTokensOnInjector<T>(
injectorIndex: number, injectorView: LViewData, token: Type<T>| InjectionToken<T>,
injectorIndex: number, injectorView: LView, token: Type<T>| InjectionToken<T>,
previousTView: TView | null) {
const currentTView = injectorView[TVIEW];
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.
*
* @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 canAccessViewProviders Whether view providers should be considered.
* @returns Index of a found directive or provider, or null when none found.
*/
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 {
const tView = view[TVIEW];
const tView = lView[TVIEW];
const nodeFlags = tNode.flags;
const nodeProviderIndexes = tNode.providerIndexes;
const tInjectables = tView.data;
@ -463,7 +463,7 @@ export function locateDirectiveOrProvider<T>(
* instantiates the `injectable` and caches the value.
*/
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];
if (isFactory(value)) {
const factory: NodeInjectorFactory = value;
@ -477,7 +477,7 @@ export function getNodeInjectable(
previousInjectImplementation = setInjectImplementation(factory.injectImpl);
}
const savePreviousOrParentTNode = getPreviousOrParentTNode();
const saveViewData = getViewData();
const saveLView = getLView();
setTNodeAndViewData(tNode, lData);
try {
value = lData[index] = factory.factory(null, tData, lData, tNode);
@ -485,7 +485,7 @@ export function getNodeInjectable(
if (factory.injectImpl) setInjectImplementation(previousInjectImplementation);
setIncludeViewProviders(previousIncludeViewProviders);
factory.resolving = false;
setTNodeAndViewData(savePreviousOrParentTNode, saveViewData);
setTNodeAndViewData(savePreviousOrParentTNode, saveLView);
}
}
return value;
@ -510,7 +510,7 @@ export function bloomHashBitOrFactory(token: Type<any>| InjectionToken<any>): nu
}
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.
// 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.
@ -548,21 +548,20 @@ function shouldSearchParent(flags: InjectFlags, parentLocation: RelativeInjector
export function injectInjector() {
const tNode = getPreviousOrParentTNode() as TElementNode | TContainerNode | TElementContainerNode;
return new NodeInjector(tNode, getViewData());
return new NodeInjector(tNode, getLView());
}
export class NodeInjector implements Injector {
private _injectorIndex: number;
constructor(
private _tNode: TElementNode|TContainerNode|TElementContainerNode,
private _lView: LViewData) {
private _tNode: TElementNode|TContainerNode|TElementContainerNode, private _lView: LView) {
this._injectorIndex = getOrCreateNodeInjectorForNode(_tNode, _lView);
}
get(token: any): any {
const previousTNode = getPreviousOrParentTNode();
const previousLView = _getViewData();
const previousLView = getLView();
setTNodeAndViewData(this._tNode, this._lView);
try {
return getOrCreateInjectable(this._tNode, this._lView, token);

View File

@ -16,8 +16,8 @@ import {diPublicInInjector, getNodeInjectable, getOrCreateNodeInjectorForNode} f
import {directiveInject} from './instructions';
import {NodeInjectorFactory} from './interfaces/injector';
import {TContainerNode, TElementContainerNode, TElementNode, TNodeFlags, TNodeProviderIndexes} from './interfaces/node';
import {LViewData, TData, TVIEW, TView} from './interfaces/view';
import {getPreviousOrParentTNode, getViewData} from './state';
import {LView, TData, TVIEW, TView} from './interfaces/view';
import {getLView, getPreviousOrParentTNode} from './state';
import {isComponentDef} from './util';
@ -42,8 +42,8 @@ import {isComponentDef} from './util';
*/
export function providersResolver<T>(
def: DirectiveDef<T>, providers: Provider[], viewProviders: Provider[]): void {
const viewData = getViewData();
const tView: TView = viewData[TVIEW];
const lView = getLView();
const tView: TView = lView[TVIEW];
if (tView.firstTemplatePass) {
const isComponent = isComponentDef(def);
@ -71,7 +71,7 @@ function resolveProvider(
provider[i], tInjectables, lInjectablesBlueprint, isComponent, isViewProvider);
}
} else {
const viewData = getViewData();
const lView = getLView();
let token: any = isTypeProvider(provider) ? provider : resolveForwardRef(provider.provide);
let providerFactory: () => any = providerToFactory(provider);
@ -92,8 +92,8 @@ function resolveProvider(
diPublicInInjector(
getOrCreateNodeInjectorForNode(
previousOrParentTNode as TElementNode | TContainerNode | TElementContainerNode,
viewData),
viewData, token);
lView),
lView, token);
tInjectables.push(token);
previousOrParentTNode.flags += 1 << TNodeFlags.DirectiveStartingIndexShift;
if (isViewProvider) {
@ -101,10 +101,10 @@ function resolveProvider(
TNodeProviderIndexes.CptViewProvidersCountShifter;
}
lInjectablesBlueprint.push(factory);
viewData.push(factory);
lView.push(factory);
} else {
lInjectablesBlueprint[existingFactoryIndex] = factory;
viewData[existingFactoryIndex] = factory;
lView[existingFactoryIndex] = factory;
}
} else {
// Multi provider case:
@ -143,8 +143,8 @@ function resolveProvider(
diPublicInInjector(
getOrCreateNodeInjectorForNode(
previousOrParentTNode as TElementNode | TContainerNode | TElementContainerNode,
viewData),
viewData, token);
lView),
lView, token);
const factory = multiFactory(
isViewProvider ? multiViewProvidersFactoryResolver : multiProvidersFactoryResolver,
lInjectablesBlueprint.length, isViewProvider, isComponent, providerFactory);
@ -158,7 +158,7 @@ function resolveProvider(
TNodeProviderIndexes.CptViewProvidersCountShifter;
}
lInjectablesBlueprint.push(factory);
viewData.push(factory);
lView.push(factory);
} else {
// Cases 1.b and 2.b
multiFactoryAdd(
@ -197,8 +197,7 @@ function indexOf(item: any, arr: any[], begin: number, end: number) {
* Use this with `multi` `providers`.
*/
function multiProvidersFactoryResolver(
this: NodeInjectorFactory, _: null, tData: TData, lData: LViewData,
tNode: TElementNode): any[] {
this: NodeInjectorFactory, _: null, tData: TData, lData: LView, tNode: TElementNode): any[] {
return multiResolve(this.multi !, []);
}
@ -208,8 +207,7 @@ function multiProvidersFactoryResolver(
* This factory knows how to concatenate itself with the existing `multi` `providers`.
*/
function multiViewProvidersFactoryResolver(
this: NodeInjectorFactory, _: null, tData: TData, lData: LViewData,
tNode: TElementNode): any[] {
this: NodeInjectorFactory, _: null, tData: TData, lData: LView, tNode: TElementNode): any[] {
const factories = this.multi !;
let result: any[];
if (this.providerFactory) {
@ -246,9 +244,8 @@ function multiResolve(factories: Array<() => any>, result: any[]): any[] {
* Creates a multi factory.
*/
function multiFactory(
factoryFn:
(this: NodeInjectorFactory, _: null, tData: TData, lData: LViewData, tNode: TElementNode) =>
any,
factoryFn: (
this: NodeInjectorFactory, _: null, tData: TData, lData: LView, tNode: TElementNode) => any,
index: number, isViewProvider: boolean, isComponent: boolean,
f: () => any): NodeInjectorFactory {
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 {LContext} from './interfaces/context';
import {TElementNode} from './interfaces/node';
import {CONTEXT, FLAGS, HOST, LViewData, LViewFlags, PARENT, RootContext, TVIEW} from './interfaces/view';
import {readPatchedLViewData, stringify} from './util';
import {CONTEXT, FLAGS, HOST, LView, LViewFlags, PARENT, RootContext, TVIEW} from './interfaces/view';
import {readPatchedLView, stringify} from './util';
import {NodeInjector} from './view_engine_compatibility';
@ -42,7 +42,7 @@ export function getComponent<T = {}>(element: Element): T|null {
const context = loadContext(element) !;
if (context.component === undefined) {
context.component = getComponentAtNodeIndex(context.nodeIndex, context.lViewData);
context.component = getComponentAtNodeIndex(context.nodeIndex, context.lView);
}
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 {
const context = loadContext(element) !;
let lView: LViewData = context.lViewData;
let lView: LView = context.lView;
while (lView[PARENT] && lView[HOST] === null) {
// As long as lView[HOST] is null we know we are part of sub-template such as `*ngIf`
lView = lView[PARENT] !;
@ -86,10 +86,10 @@ export function getViewComponent<T = {}>(element: Element | {}): T|null {
* the application where the target is situated.
*
*/
export function getRootContext(target: LViewData | {}): RootContext {
const lViewData = Array.isArray(target) ? target : loadContext(target) !.lViewData;
const rootLViewData = getRootView(lViewData);
return rootLViewData[CONTEXT] as RootContext;
export function getRootContext(target: LView | {}): RootContext {
const lView = Array.isArray(target) ? target : loadContext(target) !.lView;
const rootLView = getRootView(lView);
return rootLView[CONTEXT] as RootContext;
}
/**
@ -114,9 +114,9 @@ export function getRootComponents(target: {}): any[] {
*/
export function getInjector(target: {}): Injector {
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) !;
if (context.directives === undefined) {
context.directives = getDirectivesAtNodeIndex(context.nodeIndex, context.lViewData, false);
context.directives = getDirectivesAtNodeIndex(context.nodeIndex, context.lView, false);
}
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
* reaching the root `LViewData`.
* Retrieve the root view from any component by walking the parent `LView` until
* reaching the root `LView`.
*
* @param componentOrView any component or view
*
*/
export function getRootView(componentOrView: LViewData | {}): LViewData {
let lViewData: LViewData;
export function getRootView(componentOrView: LView | {}): LView {
let lView: LView;
if (Array.isArray(componentOrView)) {
ngDevMode && assertDefined(componentOrView, 'lViewData');
lViewData = componentOrView as LViewData;
ngDevMode && assertDefined(componentOrView, 'lView');
lView = componentOrView as LView;
} else {
ngDevMode && assertDefined(componentOrView, 'component');
lViewData = readPatchedLViewData(componentOrView) !;
lView = readPatchedLView(componentOrView) !;
}
while (lViewData && !(lViewData[FLAGS] & LViewFlags.IsRoot)) {
lViewData = lViewData[PARENT] !;
while (lView && !(lView[FLAGS] & LViewFlags.IsRoot)) {
lView = lView[PARENT] !;
}
return lViewData;
return lView;
}
/**
@ -188,7 +188,7 @@ export function getLocalRefs(target: {}): {[key: string]: any} {
const context = loadContext(target) !;
if (context.localRefs === undefined) {
context.localRefs = discoverLocalRefs(context.lViewData, context.nodeIndex);
context.localRefs = discoverLocalRefs(context.lView, context.nodeIndex);
}
return context.localRefs || {};

View File

@ -20,16 +20,14 @@ export function throwMultipleComponentError(tNode: TNode): never {
/** Throws an ExpressionChangedAfterChecked error if checkNoChanges mode is on. */
export function throwErrorIfNoChangesMode(
creationMode: boolean, checkNoChangesMode: boolean, oldValue: any, currValue: any): never|void {
if (checkNoChangesMode) {
let msg =
`ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: '${oldValue}'. Current value: '${currValue}'.`;
if (creationMode) {
msg +=
` 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 ?`;
}
// TODO: include debug context
throw new Error(msg);
creationMode: boolean, oldValue: any, currValue: any): never|void {
let msg =
`ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: '${oldValue}'. Current value: '${currValue}'.`;
if (creationMode) {
msg +=
` 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 ?`;
}
// TODO: include debug context
throw new Error(msg);
}

View File

@ -9,7 +9,7 @@
import {assertEqual} from './assert';
import {DirectiveDef} from './interfaces/definition';
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
* 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 tView The current TView
*/
@ -96,8 +96,7 @@ function queueDestroyHooks(def: DirectiveDef<any>, tView: TView, i: number): voi
*
* @param currentView The current view
*/
export function executeInitHooks(
currentView: LViewData, tView: TView, creationMode: boolean): void {
export function executeInitHooks(currentView: LView, tView: TView, creationMode: boolean): void {
if (currentView[FLAGS] & LViewFlags.RunInit) {
executeHooks(currentView, tView.initHooks, tView.checkHooks, creationMode);
currentView[FLAGS] &= ~LViewFlags.RunInit;
@ -110,7 +109,7 @@ export function executeInitHooks(
* @param currentView The current view
*/
export function executeHooks(
data: LViewData, allHooks: HookData | null, checkHooks: HookData | null,
data: LView, allHooks: HookData | null, checkHooks: HookData | null,
creationMode: boolean): void {
const hooksToCall = creationMode ? allHooks : checkHooks;
if (hooksToCall) {

View File

@ -166,7 +166,7 @@ const i18nUpdateOpCodes = <I18nUpdateOpCodes>[
// has changed then execute update OpCodes.
// has NOT changed then skip `7` values and start processing next OpCodes.
0b1, 7,
// Concatenate `newValue = 'Hello ' + lViewData[bindIndex-1] + '!';`.
// Concatenate `newValue = 'Hello ' + lView[bindIndex-1] + '!';`.
'Hello ', // accumulate('Hello ');
-1, // accumulate(-1);
'!', // accumulate('!');
@ -305,13 +305,13 @@ const tI18n = <TI18n>{
create: <I18nMutateOpCodes>[ // Processed by `i18nEnd`
// Equivalent to:
// // Assume expandoIndex = 100;
// const node = lViewData[expandoIndex++] = document.createTextNode('');
// lViewData[2].insertBefore(node, lViewData[3]);
// const node = lView[expandoIndex++] = document.createTextNode('');
// lView[2].insertBefore(node, lView[3]);
"", 2 << SHIFT_PARENT | 3 << SHIFT_REF | InsertBefore,
// Equivalent to:
// // Assume expandoIndex = 101;
// const node = lViewData[expandoIndex++] = document.createTextNode('.');
// lViewData[0].appendChild(node);
// const node = lView[expandoIndex++] = document.createTextNode('.');
// lView[0].appendChild(node);
'.', 2 << SHIFT_PARENT | AppendChild,
],
update: <I18nUpdateOpCodes>[ // Processed by `i18nApply`
@ -323,7 +323,7 @@ const tI18n = <TI18n>{
-1, // accumulate(-1);
'is rendered as: ', // accumulate('is rendered as: ');
// 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,
}
@ -369,8 +369,8 @@ const tI18n = <TI18n>{
create: <I18nMutateOpCodes>[
// Equivalent to:
// // Assume expandoIndex = 200;
// const node = lViewData[expandoIndex++] = document.createComment('');
// lViewData[1].appendChild(node);
// const node = lView[expandoIndex++] = document.createComment('');
// lView[1].appendChild(node);
COMMENT_MARKER, '', 1 << SHIFT_PARENT | AppendChild,
],
update: <I18nUpdateOpCodes>[
@ -380,12 +380,12 @@ const tI18n = <TI18n>{
// has NOT changed then skip `2` values and start processing next OpCodes.
0b1, 2,
-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,
// NOTE: the bit mask here is the logical OR of all of the masks in the ICU.
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_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.
@ -401,75 +401,75 @@ const tI18n = <TI18n>{
// Case: `0`: `{no <b title="none">emails</b>!}`
<I18nMutateOpCodes>[
// // assume expandoIndex == 203
// const node = lViewData[expandoIndex++] = document.createTextNode('no ');
// lViewData[1].appendChild(node);
// const node = lView[expandoIndex++] = document.createTextNode('no ');
// lView[1].appendChild(node);
'no ', 1 << SHIFT_PARENT | AppendChild,
// Equivalent to:
// // assume expandoIndex == 204
// const node = lViewData[expandoIndex++] = document.createElement('b');
// lViewData[1].appendChild(node);
// const node = lView[expandoIndex++] = document.createElement('b');
// lView[1].appendChild(node);
ELEMENT_MARKER, 'b', 1 << SHIFT_PARENT | AppendChild,
// const node = lViewData[204];
// const node = lView[204];
// node.setAttribute('title', 'none');
204 << SHIFT_REF | Select, 'title', 'none'
// // assume expandoIndex == 205
// const node = lViewData[expandoIndex++] = document.createTextNode('email');
// lViewData[1].appendChild(node);
// const node = lView[expandoIndex++] = document.createTextNode('email');
// lView[1].appendChild(node);
'email', 204 << SHIFT_PARENT | AppendChild,
]
// Case: `1`: `{one <i>email</i>}`
<I18nMutateOpCodes>[
// // assume expandoIndex == 203
// const node = lViewData[expandoIndex++] = document.createTextNode('no ');
// lViewData[1].appendChild(node, lViewData[2]);
// const node = lView[expandoIndex++] = document.createTextNode('no ');
// lView[1].appendChild(node, lView[2]);
'one ', 1 << SHIFT_PARENT | AppendChild,
// Equivalent to:
// // assume expandoIndex == 204
// const node = lViewData[expandoIndex++] = document.createElement('b');
// lViewData[1].appendChild(node);
// const node = lView[expandoIndex++] = document.createElement('b');
// lView[1].appendChild(node);
ELEMENT_MARKER, 'i', 1 << SHIFT_PARENT | AppendChild,
// // assume expandoIndex == 205
// const node = lViewData[expandoIndex++] = document.createTextNode('email');
// lViewData[1].appendChild(node);
// const node = lView[expandoIndex++] = document.createTextNode('email');
// lView[1].appendChild(node);
'email', 204 << SHIFT_PARENT | AppendChild,
]
// Case: `"other"`: `{<7B>0<EFBFBD> <span title="<22>0<EFBFBD>">emails</span>}`
<I18nMutateOpCodes>[
// // assume expandoIndex == 203
// const node = lViewData[expandoIndex++] = document.createTextNode('');
// lViewData[1].appendChild(node);
// const node = lView[expandoIndex++] = document.createTextNode('');
// lView[1].appendChild(node);
'', 1 << SHIFT_PARENT | AppendChild,
// Equivalent to:
// // assume expandoIndex == 204
// const node = lViewData[expandoIndex++] = document.createComment('span');
// lViewData[1].appendChild(node);
// const node = lView[expandoIndex++] = document.createComment('span');
// lView[1].appendChild(node);
ELEMENT_MARKER, 'span', 1 << SHIFT_PARENT | AppendChild,
// // assume expandoIndex == 205
// const node = lViewData[expandoIndex++] = document.createTextNode('emails');
// lViewData[1].appendChild(node);
// const node = lView[expandoIndex++] = document.createTextNode('emails');
// lView[1].appendChild(node);
'emails', 204 << SHIFT_PARENT | AppendChild,
]
],
remove: [
// Case: `0`: `{no <b title="none">emails</b>!}`
<I18nMutateOpCodes>[
// lViewData[1].remove(lViewData[203]);
// lView[1].remove(lView[203]);
1 << SHIFT_PARENT | 203 << SHIFT_REF | Remove,
// lViewData[1].remove(lViewData[204]);
// lView[1].remove(lView[204]);
1 << SHIFT_PARENT | 204 << SHIFT_REF | Remove,
]
// Case: `1`: `{one <i>email</i>}`
<I18nMutateOpCodes>[
// lViewData[1].remove(lViewData[203]);
// lView[1].remove(lView[203]);
1 << SHIFT_PARENT | 203 << SHIFT_REF | Remove,
// lViewData[1].remove(lViewData[204]);
// lView[1].remove(lView[204]);
1 << SHIFT_PARENT | 204 << SHIFT_REF | Remove,
]
// Case: `"other"`: `{<7B>0<EFBFBD> <span title="<22>0<EFBFBD>">emails</span>}`
<I18nMutateOpCodes>[
// lViewData[1].remove(lViewData[203]);
// lView[1].remove(lView[203]);
1 << SHIFT_PARENT | 203 << SHIFT_REF | Remove,
// lViewData[1].remove(lViewData[204]);
// lView[1].remove(lView[204]);
1 << SHIFT_PARENT | 204 << SHIFT_REF | Remove,
]
],
@ -496,9 +496,9 @@ const tI18n = <TI18n>{
// has changed then execute update OpCodes.
// has NOT changed then skip `4` values and start processing next OpCodes.
0b1, 4,
// Concatenate `newValue = '' + lViewData[bindIndex -1];`.
// Concatenate `newValue = '' + lView[bindIndex -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.
204 << SHIFT_REF | Attr, 'title', null
]
@ -555,12 +555,12 @@ const tI18n = <TI18n>{
// if (first_execution_for_tview) {
// ngDevMode && assertEquals(tView.blueprint.length, expandoIndex);
// tView.blueprint.push(null);
// ngDevMode && assertEquals(lViewData.length, expandoIndex);
// lViewData.push(node);
// ngDevMode && assertEquals(lView.length, expandoIndex);
// lView.push(node);
// } else {
// lViewData[expandoIndex] = node; // save expandoIndex == 100;
// lView[expandoIndex] = node; // save expandoIndex == 100;
// }
// lViewData[0].appendChild(node);
// lView[0].appendChild(node);
// expandoIndex++;
"", 0 << SHIFT_PARENT | AppendChild,
],
@ -636,14 +636,14 @@ const tI18n = <TI18n>{
// has NOT changed then skip `2` values and start processing next OpCodes.
0b1, 2,
-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,
// NOTE: the bit mask here is the logical OR of all of the masks in the ICU.
0b1, 4,
'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_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.
@ -700,7 +700,7 @@ const tI18n = <TI18n>{
// has changed then execute update OpCodes.
// has NOT changed then skip `1` values and start processing next OpCodes.
-1, 2,
-1, // accumulate(lViewData[bindIndex-1]);
-1, // accumulate(lView[bindIndex-1]);
'emails', // accumulate('no emails');
]
]
@ -789,8 +789,8 @@ const tI18n = <TI18n>{
expandoStartIndex: 100, // Assume in this example EXPANDO starts at 100
create: <I18nMutateOpCodes>[ // Processed by `i18nEnd`
// Equivalent to:
// const node = lViewData[expandoIndex++] = document.createTextNode('');
// lViewData[0].insertBefore(node, lViewData[3]);
// const node = lView[expandoIndex++] = document.createTextNode('');
// lView[0].insertBefore(node, lView[3]);
"Translated text", 0 << SHIFT_PARENT | AppendChild,
],
update: <I18nUpdateOpCodes>[ ],
@ -799,8 +799,8 @@ const tI18n = <TI18n>{
```
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.
- 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.
- 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 `LView` which would tell the OpCode processor that it is dealing with a synthetic parent.
## Nested ICUs
@ -882,12 +882,12 @@ const tI18n = <TI18n>{
// has NOT changed then skip `2` values and start processing next OpCodes.
0b1, 2,
-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,
// NOTE: the bit mask here is the logical OR of all of the masks in the ICU.
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_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.
@ -925,12 +925,12 @@ const tI18n = <TI18n>{
-2, ' ', 100 << SHIFT_REF | Text, // Case: `<60>0<EFBFBD> `
0b10, 5,
-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,
// NOTE: the bit mask here is the logical OR of all of the masks int the ICU.
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,
],
]

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -9,7 +9,7 @@
import {LQueries} from './query';
import {RComment, RElement} from './renderer';
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 VIEWS = 1;
// 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 RENDER_PARENT = 7;
/**
* 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
* views), so we can jump to viewOrContainer[NEXT] in the same way regardless
* 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
* are no longer required.
*/
[VIEWS]: LViewData[];
[VIEWS]: LView[];
/**
* Access to the parent view is necessary so we can propagate back
* 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
* 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
@ -72,13 +72,13 @@ export interface LContainer extends Array<any> {
/**
* The host element of this LContainer.
*
* The host could be an LViewData if this container is on a component node.
* In that case, the component LViewData is its HOST.
* The host could be an LView if this container is on a component node.
* 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
* binding.
*/
[HOST]: RElement|RComment|StylingContext|LViewData;
[HOST]: RElement|RComment|StylingContext|LView;
/** The comment element that serves as an anchor for this LContainer. */
[NATIVE]: RComment;

View File

@ -8,7 +8,7 @@
import {RElement} from './renderer';
import {LViewData} from './view';
import {LView} from './view';
/**
* 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
* 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
* 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.
*/
lViewData: LViewData;
lView: LView;
/**
* 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.
*
* 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.
*/
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.
*
* 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.
*/
// 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).
*
* 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.
*/
readonly vars: number;

View File

@ -74,60 +74,60 @@ export interface COMMENT_MARKER { marker: 'comment'; }
* // For adding text nodes
* // ---------------------
* // Equivalent to:
* // const node = lViewData[index++] = document.createTextNode('abc');
* // lViewData[1].insertBefore(node, lViewData[2]);
* // const node = lView[index++] = document.createTextNode('abc');
* // lView[1].insertBefore(node, lView[2]);
* 'abc', 1 << SHIFT_PARENT | 2 << SHIFT_REF | InsertBefore,
*
* // Equivalent to:
* // const node = lViewData[index++] = document.createTextNode('xyz');
* // lViewData[1].appendChild(node);
* // const node = lView[index++] = document.createTextNode('xyz');
* // lView[1].appendChild(node);
* 'xyz', 1 << SHIFT_PARENT | AppendChild,
*
* // For adding element nodes
* // ---------------------
* // Equivalent to:
* // const node = lViewData[index++] = document.createElement('div');
* // lViewData[1].insertBefore(node, lViewData[2]);
* // const node = lView[index++] = document.createElement('div');
* // lView[1].insertBefore(node, lView[2]);
* ELEMENT_MARKER, 'div', 1 << SHIFT_PARENT | 2 << SHIFT_REF | InsertBefore,
*
* // Equivalent to:
* // const node = lViewData[index++] = document.createElement('div');
* // lViewData[1].appendChild(node);
* // const node = lView[index++] = document.createElement('div');
* // lView[1].appendChild(node);
* ELEMENT_MARKER, 'div', 1 << SHIFT_PARENT | AppendChild,
*
* // For adding comment nodes
* // ---------------------
* // Equivalent to:
* // const node = lViewData[index++] = document.createComment('');
* // lViewData[1].insertBefore(node, lViewData[2]);
* // const node = lView[index++] = document.createComment('');
* // lView[1].insertBefore(node, lView[2]);
* COMMENT_MARKER, '', 1 << SHIFT_PARENT | 2 << SHIFT_REF | InsertBefore,
*
* // Equivalent to:
* // const node = lViewData[index++] = document.createComment('');
* // lViewData[1].appendChild(node);
* // const node = lView[index++] = document.createComment('');
* // lView[1].appendChild(node);
* COMMENT_MARKER, '', 1 << SHIFT_PARENT | AppendChild,
*
* // For moving existing nodes to a different location
* // --------------------------------------------------
* // Equivalent to:
* // const node = lViewData[1];
* // lViewData[2].insertBefore(node, lViewData[3]);
* // const node = lView[1];
* // lView[2].insertBefore(node, lView[3]);
* 1 << SHIFT_REF | Select, 2 << SHIFT_PARENT | 3 << SHIFT_REF | InsertBefore,
*
* // Equivalent to:
* // const node = lViewData[1];
* // lViewData[2].appendChild(node);
* // const node = lView[1];
* // lView[2].appendChild(node);
* 1 << SHIFT_REF | Select, 2 << SHIFT_PARENT | AppendChild,
*
* // For removing existing nodes
* // --------------------------------------------------
* // const node = lViewData[1];
* // removeChild(tView.data(1), node, lViewData);
* // const node = lView[1];
* // removeChild(tView.data(1), node, lView);
* 1 << SHIFT_REF | Remove,
*
* // For writing attributes
* // --------------------------------------------------
* // const node = lViewData[1];
* // const node = lView[1];
* // node.setAttribute('attr', 'value');
* 1 << SHIFT_REF | Select, 'attr', 'value'
* // 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 NOT changed then skip `7` values and start processing next OpCodes.
* 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',
* // Update attribute: `elementAttribute(1, 'title', sanitizerFn(newValue));`
* 1 << SHIFT_REF | Attr, 'title', sanitizerFn,
@ -206,9 +206,9 @@ export const enum I18nUpdateOpCode {
* // has changed then execute update OpCodes.
* // has NOT changed then skip `4` values and start processing next OpCodes.
* 0b100, 4,
* // Concatenate `newValue = 'Hello ' + lViewData[bindIndex -2] + '!';`.
* // Concatenate `newValue = 'Hello ' + lView[bindIndex -2] + '!';`.
* 'Hello ', -2, '!',
* // Update text: `lViewData[1].textContent = newValue;`
* // Update text: `lView[1].textContent = newValue;`
* 1 << SHIFT_REF | Text,
*
* // The following OpCodes represent: `<div i18n>{exp4, plural, ... }">`
@ -216,14 +216,14 @@ export const enum I18nUpdateOpCode {
* // has changed then execute update OpCodes.
* // has NOT changed then skip `4` values and start processing next OpCodes.
* 0b1000, 4,
* // Concatenate `newValue = lViewData[bindIndex -1];`.
* // Concatenate `newValue = lView[bindIndex -1];`.
* -1,
* // Switch ICU: `icuSwitchCase(lViewData[1], 0, newValue);`
* // Switch ICU: `icuSwitchCase(lView[1], 0, newValue);`
* 0 << SHIFT_ICU | 1 << SHIFT_REF | IcuSwitch,
*
* // Note `changeMask & -1` is always true, so the IcuUpdate will always execute.
* -1, 1,
* // Update ICU: `icuUpdateCase(lViewData[1], 0);`
* // Update ICU: `icuUpdateCase(lView[1], 0);`
* 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 {Type} from '../../type';
import {TElementNode} from './node';
import {LViewData, TData} from './view';
import {LView, TData} from './view';
export const TNODE = 8;
export const PARENT_INJECTOR = 8;
@ -19,7 +19,7 @@ export const INJECTOR_SIZE = 9;
/**
* 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.
*/
export interface RelativeInjectorLocation { __brand__: 'RelativeInjectorLocationFlags'; }
@ -34,10 +34,10 @@ export const enum RelativeInjectorLocationFlags {
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
* 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
* 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.
*
* 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`
* 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
@ -226,7 +226,7 @@ export class NodeInjectorFactory {
* array where existing instances of injectables are stored. This is used in case
* of multi shadow is needed. See `multi` field documentation.
*/
lData: LViewData,
lView: LView,
/**
* The TNode of the same element injector.
*/

View File

@ -7,7 +7,7 @@
*/
import {StylingContext} from './styling';
import {LViewData, TView} from './view';
import {LView, TView} from './view';
/**
@ -103,7 +103,7 @@ export interface TNode {
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
* traversing the node tree.
@ -113,7 +113,7 @@ export interface TNode {
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.
*
@ -361,7 +361,7 @@ export interface TContainerNode extends TNode {
/** Static data for an <ng-container> */
export interface TElementContainerNode extends TNode {
/** Index in the LViewData[] array. */
/** Index in the LView[] array. */
index: number;
child: TElementNode|TTextNode|TContainerNode|TElementContainerNode|TProjectionNode|null;
parent: TElementNode|TElementContainerNode|null;
@ -371,7 +371,7 @@ export interface TElementContainerNode extends TNode {
/** Static data for an ICU expression */
export interface TIcuContainerNode extends TNode {
/** Index in the LViewData[] array. */
/** Index in the LView[] array. */
index: number;
child: TElementNode|TTextNode|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;
* - `<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';
// 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.
// Uglify will inline these when minifying so there shouldn't be a cost.
export const TVIEW = 0;
@ -42,11 +42,11 @@ export const TAIL = 14;
export const CONTAINER_INDEX = 15;
export const CONTENT_QUERIES = 16;
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;
// 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
// the actual interface, which should be kept private.
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
* own `LViewData`. When processing a particular view, we set the `viewData` to that
* `LViewData`. When that view is done processing, the `viewData` is set back to
* whatever the original `viewData` was before (the parent `LViewData`).
* own `LView`. When processing a particular view, we set the `viewData` to that
* `LView`. When that view is done processing, the `viewData` is set back to
* whatever the original `viewData` was before (the parent `LView`).
*
* 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.
*/
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
* 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
* `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.
*
* This is the "insertion" view for embedded views. This allows us to properly
* 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
* 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
* 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]: 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.
*/
@ -135,7 +135,7 @@ export interface LViewData extends Array<any> {
* 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.
*/
// TODO: flatten into LViewData[]
// TODO: flatten into LView[]
[CLEANUP]: any[]|null;
/**
@ -160,12 +160,12 @@ export interface LViewData extends Array<any> {
[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
* 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
@ -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
* 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's template function with the proper contexts. Context should be inherited from
* 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
* 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 {
/**
* Whether or not the view is in creationMode.
@ -265,10 +265,10 @@ export interface TView {
readonly id: number;
/**
* This is a blueprint used to generate LViewData instances for this TView. Copying this
* blueprint is faster than creating a new LViewData from scratch.
* This is a blueprint used to generate LView instances for this TView. Copying this
* 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
@ -313,9 +313,9 @@ export interface TView {
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.
* 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
* 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 {unusedValueExportToPlacateAjd as unused3} from './interfaces/projection';
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 {getNativeByTNode, isLContainer, isRootView, readElementValue, stringify} from './util';
const unusedValueToPlacateAjd = unused1 + unused2 + unused3 + unused4 + unused5;
/** 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) {
return getHostNative(currentView);
} 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,
* 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;
return hostTNode && hostTNode.type !== TNodeType.View ?
(getNativeByTNode(hostTNode, currentView[PARENT] !) as RElement) :
null;
}
export function getLContainer(tNode: TViewNode, embeddedView: LViewData): LContainer|null {
export function getLContainer(tNode: TViewNode, embeddedView: LView): LContainer|null {
if (tNode.index === -1) {
// 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.
@ -68,7 +68,7 @@ export function getLContainer(tNode: TViewNode, embeddedView: LViewData): LConta
* Retrieves render parent for a given view.
* 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);
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
* 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
@ -107,7 +107,7 @@ const projectionNodeStack: (LViewData | TNode)[] = [];
* Insert.
*/
function walkTNodeTree(
viewToWalk: LViewData, action: WalkTNodeTreeAction, renderer: Renderer3,
viewToWalk: LView, action: WalkTNodeTreeAction, renderer: Renderer3,
renderParent: RElement | null, beforeNode?: RNode | null) {
const rootTNode = viewToWalk[TVIEW].node as TViewNode;
let projectionNodeIndex = -1;
@ -159,7 +159,7 @@ function walkTNodeTree(
if (nextTNode === null) {
// this last node was projected, we need to get back down to its projection node
if (tNode.next === null && (tNode.flags & TNodeFlags.isProjected)) {
currentView = projectionNodeStack[projectionNodeIndex--] as LViewData;
currentView = projectionNodeStack[projectionNodeIndex--] as LView;
tNode = projectionNodeStack[projectionNodeIndex--] as TNode;
}
nextTNode = tNode.next;
@ -184,7 +184,7 @@ function walkTNodeTree(
}
if (tNode.type === TNodeType.View && currentView[NEXT]) {
currentView = currentView[NEXT] as LViewData;
currentView = currentView[NEXT] as LView;
nextTNode = currentView[TVIEW].node;
} else {
nextTNode = tNode.next;
@ -198,19 +198,19 @@ function walkTNodeTree(
/**
* 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
*/
export function findComponentView(lViewData: LViewData): LViewData {
let rootTNode = lViewData[HOST_NODE];
export function findComponentView(lView: LView): LView {
let rootTNode = lView[HOST_NODE];
while (rootTNode && rootTNode.type === TNodeType.View) {
ngDevMode && assertDefined(lViewData[PARENT], 'viewData.parent');
lViewData = lViewData[PARENT] !;
rootTNode = lViewData[HOST_NODE];
ngDevMode && assertDefined(lView[PARENT], 'lView.parent');
lView = lView[PARENT] !;
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
*/
export function addRemoveViewFromContainer(
viewToWalk: LViewData, insertMode: true, beforeNode: RNode | null): void;
export function addRemoveViewFromContainer(viewToWalk: LViewData, insertMode: false): void;
viewToWalk: LView, insertMode: true, beforeNode: RNode | null): void;
export function addRemoveViewFromContainer(viewToWalk: LView, insertMode: false): void;
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);
ngDevMode && assertNodeType(viewToWalk[TVIEW].node as TNode, TNodeType.View);
if (renderParent) {
@ -278,22 +278,22 @@ export function addRemoveViewFromContainer(
*
* @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 (rootView[TVIEW].childIndex === -1) {
return cleanUpView(rootView);
}
let viewOrContainer: LViewData|LContainer|null = getLViewChild(rootView);
let viewOrContainer: LView|LContainer|null = getLViewChild(rootView);
while (viewOrContainer) {
let next: LViewData|LContainer|null = null;
let next: LView|LContainer|null = null;
if (viewOrContainer.length >= HEADER_OFFSET) {
// If LViewData, traverse down to child.
const view = viewOrContainer as LViewData;
// If LView, traverse down to child.
const view = viewOrContainer as LView;
if (view[TVIEW].childIndex > -1) next = getLViewChild(view);
} else {
// If container, traverse down to its first LViewData.
// If container, traverse down to its first LView.
const container = viewOrContainer as LContainer;
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
*/
export function insertView(
lView: LViewData, lContainer: LContainer, parentView: LViewData, index: number,
lView: LView, lContainer: LContainer, parentView: LView, index: number,
containerIndex: number) {
const views = lContainer[VIEWS];
@ -374,7 +374,7 @@ export function detachView(lContainer: LContainer, removeIndex: number, detached
const views = lContainer[VIEWS];
const viewToDetach = views[removeIndex];
if (removeIndex > 0) {
views[removeIndex - 1][NEXT] = viewToDetach[NEXT] as LViewData;
views[removeIndex - 1][NEXT] = viewToDetach[NEXT] as LView;
}
views.splice(removeIndex, 1);
if (!detached) {
@ -405,10 +405,10 @@ export function removeView(
destroyLView(view);
}
/** Gets the child of the given LViewData */
export function getLViewChild(viewData: LViewData): LViewData|LContainer|null {
const childIndex = viewData[TVIEW].childIndex;
return childIndex === -1 ? null : viewData[childIndex];
/** Gets the child of the given LView */
export function getLViewChild(lView: LView): LView|LContainer|null {
const childIndex = lView[TVIEW].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.
*/
export function destroyLView(view: LViewData) {
export function destroyLView(view: LView) {
const renderer = view[RENDERER];
if (isProceduralRenderer(renderer) && renderer.destroyNode) {
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
* @returns The correct parent LViewOrLContainer
*/
export function getParentState(state: LViewData | LContainer, rootView: LViewData): LViewData|
LContainer|null {
export function getParentState(state: LView | LContainer, rootView: LView): LView|LContainer|null {
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) {
// if it's an embedded view, the state needs to go up to the container, in case the
// 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 {
// otherwise, use parent view for containers or component views
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.
*
* @param view The LViewData to clean up
* @param view The LView to clean up
*/
function cleanUpView(viewOrContainer: LViewData | LContainer): void {
if ((viewOrContainer as LViewData).length >= HEADER_OFFSET) {
const view = viewOrContainer as LViewData;
function cleanUpView(viewOrContainer: LView | LContainer): void {
if ((viewOrContainer as LView).length >= HEADER_OFFSET) {
const view = viewOrContainer as LView;
removeListeners(view);
executeOnDestroys(view);
executePipeOnDestroys(view);
@ -473,32 +472,32 @@ function cleanUpView(viewOrContainer: LViewData | LContainer): void {
}
/** Removes listeners and unsubscribes from output subscriptions */
function removeListeners(viewData: LViewData): void {
const cleanup = viewData[TVIEW].cleanup !;
function removeListeners(lView: LView): void {
const cleanup = lView[TVIEW].cleanup !;
if (cleanup != null) {
for (let i = 0; i < cleanup.length - 1; i += 2) {
if (typeof cleanup[i] === 'string') {
// This is a listener with the native renderer
const native = readElementValue(viewData[cleanup[i + 1]]);
const listener = viewData[CLEANUP] ![cleanup[i + 2]];
const native = readElementValue(lView[cleanup[i + 1]]);
const listener = lView[CLEANUP] ![cleanup[i + 2]];
native.removeEventListener(cleanup[i], listener, cleanup[i + 3]);
i += 2;
} else if (typeof cleanup[i] === 'number') {
// 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();
} else {
// 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);
}
}
viewData[CLEANUP] = null;
lView[CLEANUP] = null;
}
}
/** Calls onDestroy hooks for this view */
function executeOnDestroys(view: LViewData): void {
function executeOnDestroys(view: LView): void {
const tView = view[TVIEW];
let destroyHooks: HookData|null;
if (tView != null && (destroyHooks = tView.destroyHooks) != null) {
@ -507,14 +506,14 @@ function executeOnDestroys(view: LViewData): void {
}
/** Calls pipe destroy hooks for this view */
function executePipeOnDestroys(viewData: LViewData): void {
const pipeDestroyHooks = viewData[TVIEW] && viewData[TVIEW].pipeDestroyHooks;
function executePipeOnDestroys(lView: LView): void {
const pipeDestroyHooks = lView[TVIEW] && lView[TVIEW].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 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
@ -565,7 +564,7 @@ function canInsertNativeChildOfElement(tNode: TNode): boolean {
* and
* 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.
const container = getLContainer(viewTNode, view) !;
if (container == null || container[RENDER_PARENT] == null) {
@ -597,7 +596,7 @@ function canInsertNativeChildOfView(viewTNode: TViewNode, view: LViewData): bool
* @param currentView Current LView being processed.
* @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 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
*/
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)) {
const renderer = currentView[RENDERER];
const parentEl = getParentNative(childTNode, currentView);
@ -700,9 +699,9 @@ function getHighestElementContainer(ngContainer: TNode): TNode {
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) {
const view = views[index + 1] as LViewData;
const view = views[index + 1] as LView;
const viewTNode = view[HOST_NODE] as TViewNode;
return viewTNode.child ? getNativeByTNode(viewTNode.child, view) : containerNative;
} else {
@ -718,8 +717,7 @@ export function getBeforeNodeForView(index: number, views: LViewData[], containe
* @param currentView The current LView
* @returns Whether or not the child was removed
*/
export function removeChild(
childTNode: TNode, childEl: RNode | null, currentView: LViewData): boolean {
export function removeChild(childTNode: TNode, childEl: RNode | null, currentView: LView): boolean {
// We only remove the element if not in View or not projected.
if (childEl !== null && canInsertNativeNode(childTNode, currentView)) {
const parentNative = getParentNative(childTNode, currentView) !as RElement;
@ -741,8 +739,8 @@ export function removeChild(
* @param projectionView Projection view (view above current)
*/
export function appendProjectedNode(
projectedTNode: TNode, tProjectionNode: TNode, currentView: LViewData,
projectionView: LViewData): void {
projectedTNode: TNode, tProjectionNode: TNode, currentView: LView,
projectionView: LView): void {
const native = getNativeByTNode(projectedTNode, projectionView);
appendChild(native, tProjectionNode, currentView);

View File

@ -10,9 +10,9 @@ import {PipeTransform} from '../change_detection/pipe_transform';
import {load, store} from './instructions';
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 {getTView} from './state';
import {getLView} from './state';
/**
* Create a pipe.
@ -22,7 +22,7 @@ import {getTView} from './state';
* @returns T the instance of the pipe.
*/
export function pipe(index: number, pipeName: string): any {
const tView = getTView();
const tView = getLView()[TVIEW];
let pipeDef: PipeDef<any>;
const adjustedIndex = index + HEADER_OFFSET;
@ -152,5 +152,5 @@ export function pipeBindV(index: number, slotOffset: number, values: any[]): any
}
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 lViewData = context.lViewData;
const lView = context.lView;
const playerContext = getOrCreatePlayerContext(element, context) !;
const rootContext = getRootContext(lViewData);
const rootContext = getRootContext(lView);
addPlayerInternal(playerContext, rootContext, element, player, 0, ref);
scheduleTick(rootContext, RootContextFlags.FlushPlayers);
}
@ -60,7 +60,7 @@ export function getPlayers(ref: ComponentInstance | DirectiveInstance | HTMLElem
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;
return playerContext ? getPlayersInternal(playerContext) : [];
}

View File

@ -6,8 +6,9 @@
* found in the LICENSE file at https://angular.io/license
*/
import {bindingUpdated, bindingUpdated2, bindingUpdated3, bindingUpdated4, getBinding, updateBinding} from './instructions';
import {getBindingRoot, getCreationMode} from './state';
import {bindingUpdated, bindingUpdated2, bindingUpdated3, bindingUpdated4, getBinding, updateBinding} from './bindings';
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 {
// TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings
const bindingIndex = getBindingRoot() + slotOffset;
const lView = getLView();
return getCreationMode() ?
updateBinding(bindingIndex, thisArg ? pureFn.call(thisArg) : pureFn()) :
getBinding(bindingIndex);
updateBinding(lView, bindingIndex, thisArg ? pureFn.call(thisArg) : pureFn()) :
getBinding(lView, bindingIndex);
}
/**
@ -58,10 +60,11 @@ export function pureFunction0<T>(slotOffset: number, pureFn: () => T, thisArg?:
export function pureFunction1(
slotOffset: number, pureFn: (v: any) => any, exp: any, thisArg?: any): any {
// TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings
const lView = getLView();
const bindingIndex = getBindingRoot() + slotOffset;
return bindingUpdated(bindingIndex, exp) ?
updateBinding(bindingIndex + 1, thisArg ? pureFn.call(thisArg, exp) : pureFn(exp)) :
getBinding(bindingIndex + 1);
return bindingUpdated(lView, bindingIndex, exp) ?
updateBinding(lView, bindingIndex + 1, thisArg ? pureFn.call(thisArg, exp) : pureFn(exp)) :
getBinding(lView, bindingIndex + 1);
}
/**
@ -80,10 +83,12 @@ export function pureFunction2(
thisArg?: any): any {
// TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings
const bindingIndex = getBindingRoot() + slotOffset;
return bindingUpdated2(bindingIndex, exp1, exp2) ?
const lView = getLView();
return bindingUpdated2(lView, bindingIndex, exp1, exp2) ?
updateBinding(
bindingIndex + 2, thisArg ? pureFn.call(thisArg, exp1, exp2) : pureFn(exp1, exp2)) :
getBinding(bindingIndex + 2);
lView, 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 {
// TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings
const bindingIndex = getBindingRoot() + slotOffset;
return bindingUpdated3(bindingIndex, exp1, exp2, exp3) ?
const lView = getLView();
return bindingUpdated3(lView, bindingIndex, exp1, exp2, exp3) ?
updateBinding(
bindingIndex + 3,
lView, bindingIndex + 3,
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 {
// TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings
const bindingIndex = getBindingRoot() + slotOffset;
return bindingUpdated4(bindingIndex, exp1, exp2, exp3, exp4) ?
const lView = getLView();
return bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4) ?
updateBinding(
bindingIndex + 4,
lView, bindingIndex + 4,
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 {
// TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings
const bindingIndex = getBindingRoot() + slotOffset;
const different = bindingUpdated4(bindingIndex, exp1, exp2, exp3, exp4);
return bindingUpdated(bindingIndex + 4, exp5) || different ?
const lView = getLView();
const different = bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4);
return bindingUpdated(lView, bindingIndex + 4, exp5) || different ?
updateBinding(
bindingIndex + 5, thisArg ? pureFn.call(thisArg, exp1, exp2, exp3, exp4, exp5) :
pureFn(exp1, exp2, exp3, exp4, exp5)) :
getBinding(bindingIndex + 5);
lView, bindingIndex + 5, thisArg ? pureFn.call(thisArg, exp1, exp2, exp3, exp4, exp5) :
pureFn(exp1, exp2, exp3, exp4, exp5)) :
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 {
// TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings
const bindingIndex = getBindingRoot() + slotOffset;
const different = bindingUpdated4(bindingIndex, exp1, exp2, exp3, exp4);
return bindingUpdated2(bindingIndex + 4, exp5, exp6) || different ?
const lView = getLView();
const different = bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4);
return bindingUpdated2(lView, bindingIndex + 4, exp5, exp6) || different ?
updateBinding(
bindingIndex + 6, thisArg ? pureFn.call(thisArg, exp1, exp2, exp3, exp4, exp5, exp6) :
pureFn(exp1, exp2, exp3, exp4, exp5, exp6)) :
getBinding(bindingIndex + 6);
lView, bindingIndex + 6, thisArg ?
pureFn.call(thisArg, exp1, exp2, exp3, exp4, exp5, exp6) :
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 {
// TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings
const bindingIndex = getBindingRoot() + slotOffset;
let different = bindingUpdated4(bindingIndex, exp1, exp2, exp3, exp4);
return bindingUpdated3(bindingIndex + 4, exp5, exp6, exp7) || different ?
const lView = getLView();
let different = bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4);
return bindingUpdated3(lView, bindingIndex + 4, exp5, exp6, exp7) || different ?
updateBinding(
bindingIndex + 7, thisArg ?
lView, bindingIndex + 7, thisArg ?
pureFn.call(thisArg, 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 {
// TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings
const bindingIndex = getBindingRoot() + slotOffset;
const different = bindingUpdated4(bindingIndex, exp1, exp2, exp3, exp4);
return bindingUpdated4(bindingIndex + 4, exp5, exp6, exp7, exp8) || different ?
const lView = getLView();
const different = bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4);
return bindingUpdated4(lView, bindingIndex + 4, exp5, exp6, exp7, exp8) || different ?
updateBinding(
bindingIndex + 8, thisArg ?
lView, bindingIndex + 8, thisArg ?
pureFn.call(thisArg, 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
let bindingIndex = getBindingRoot() + slotOffset;
let different = false;
const lView = getLView();
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)) :
getBinding(bindingIndex);
return different ? updateBinding(lView, bindingIndex, pureFn.apply(thisArg, exps)) :
getBinding(lView, bindingIndex);
}

View File

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

View File

@ -6,58 +6,18 @@
* found in the LICENSE file at https://angular.io/license
*/
import {Sanitizer} from '../sanitization/security';
import {assertDefined, assertEqual} from './assert';
import {assertDefined} from './assert';
import {executeHooks} from './hooks';
import {TElementNode, TNode, TNodeFlags, TViewNode} from './interfaces/node';
import {LQueries} from './interfaces/query';
import {Renderer3, RendererFactory3} from './interfaces/renderer';
import {BINDING_INDEX, CLEANUP, CONTEXT, DECLARATION_VIEW, FLAGS, HOST_NODE, LViewData, LViewFlags, OpaqueViewState, QUERIES, RENDERER, RENDERER_FACTORY, SANITIZER, TVIEW, TView} from './interfaces/view';
import {assertDataInRangeInternal, isContentQueryHost} from './util';
import {BINDING_INDEX, CONTEXT, DECLARATION_VIEW, FLAGS, HOST_NODE, LView, LViewFlags, OpaqueViewState, QUERIES, TVIEW} from './interfaces/view';
import {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
* 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;
@ -142,19 +102,8 @@ export function disableBindings(): void {
bindingsEnabled = false;
}
/**
* Returns the current OpaqueViewState instance.
*
* 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;
export function getLView(): LView {
return lView;
}
/**
@ -167,7 +116,7 @@ export function _getViewData(): LViewData {
* @param viewToRestore The OpaqueViewState instance to restore.
*/
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. */
@ -182,9 +131,9 @@ export function setPreviousOrParentTNode(tNode: TNode) {
previousOrParentTNode = tNode;
}
export function setTNodeAndViewData(tNode: TNode, view: LViewData) {
export function setTNodeAndViewData(tNode: TNode, view: LView) {
previousOrParentTNode = tNode;
viewData = view;
lView = view;
}
/**
@ -203,24 +152,6 @@ export function setIsParent(value: boolean): void {
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:
* - 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(
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
// in subsequent template passes, the cloning occurs before directive instantiation.
if (previousOrParentTNode && previousOrParentTNode !== viewData[HOST_NODE] &&
if (previousOrParentTNode && previousOrParentTNode !== lView[HOST_NODE] &&
!isContentQueryHost(previousOrParentTNode)) {
currentQueries && (currentQueries = currentQueries.clone());
currentQueries && (currentQueries = lView[QUERIES] = currentQueries.clone());
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
* any local variables that need to be stored between invocations.
*/
let viewData: LViewData;
/**
* 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;
}
let lView: LView;
/**
* The last viewData retrieved by nextContext().
@ -275,21 +198,13 @@ export function getViewData(): LViewData {
*
* 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)
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.
*
@ -345,33 +260,29 @@ export function setBindingRoot(value: number) {
* @param host Element to which the View is a child of
* @returns the previous state;
*/
export function enterView(
newView: LViewData, hostTNode: TElementNode | TViewNode | null): LViewData {
const oldView: LViewData = viewData;
tView = newView && newView[TVIEW];
export function enterView(newView: LView, hostTNode: TElementNode | TViewNode | null): LView {
const oldView = lView;
if (newView) {
const tView = newView[TVIEW];
creationMode = newView && (newView[FLAGS] & LViewFlags.CreationMode) === LViewFlags.CreationMode;
firstTemplatePass = newView && tView.firstTemplatePass;
bindingRootIndex = newView && tView.bindingStartIndex;
rendererFactory = newView && newView[RENDERER_FACTORY];
renderer = newView && newView[RENDERER];
creationMode = (newView[FLAGS] & LViewFlags.CreationMode) === LViewFlags.CreationMode;
firstTemplatePass = tView.firstTemplatePass;
bindingRootIndex = tView.bindingStartIndex;
}
previousOrParentTNode = hostTNode !;
isParent = true;
viewData = contextViewData = newView;
oldView && (oldView[QUERIES] = currentQueries);
currentQueries = newView && newView[QUERIES];
lView = contextLView = newView;
return oldView;
}
export function nextContextImpl<T = any>(level: number = 1): T {
contextViewData = walkUpViews(level, contextViewData !);
return contextViewData[CONTEXT] as T;
contextLView = walkUpViews(level, contextLView !);
return contextLView[CONTEXT] as T;
}
function walkUpViews(nestingLevel: number, currentView: LViewData): LViewData {
function walkUpViews(nestingLevel: number, currentView: LView): LView {
while (nestingLevel > 0) {
ngDevMode && assertDefined(
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
* 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 (!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
viewData[FLAGS] &= ~(LViewFlags.CreationMode | LViewFlags.Dirty);
lView[FLAGS] &= ~(LViewFlags.CreationMode | LViewFlags.Dirty);
}
viewData[FLAGS] |= LViewFlags.RunInit;
viewData[BINDING_INDEX] = tView.bindingStartIndex;
lView[FLAGS] |= LViewFlags.RunInit;
lView[BINDING_INDEX] = tView.bindingStartIndex;
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 {Renderer3, RendererStyleFlags3, isProceduralRenderer} from '../interfaces/renderer';
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 {getRootContext} from '../util';
@ -479,7 +479,7 @@ export function updateClassProp(
* @returns number the total amount of players that got queued for animation (if any)
*/
export function renderStyleAndClassBindings(
context: StylingContext, renderer: Renderer3, rootOrView: RootContext | LViewData,
context: StylingContext, renderer: Renderer3, rootOrView: RootContext | LView,
isFirstRender: boolean, classesStore?: BindingStore | null,
stylesStore?: BindingStore | null): number {
let totalPlayersQueued = 0;

View File

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

View File

@ -6,10 +6,9 @@
* found in the LICENSE file at https://angular.io/license
*/
import {devModeEqual} from '../change_detection/change_detection_util';
import {global} from '../util';
import {assertDefined, assertLessThan} from './assert';
import {assertDataInRange, assertDefined} from './assert';
import {ACTIVE_INDEX, LContainer} from './interfaces/container';
import {LContext, MONKEY_PATCH_KEY_NAME} from './interfaces/context';
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 {RComment, RElement, RText} from './interfaces/renderer';
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.
*/
export function isDifferent(a: any, b: any, checkNoChangesMode: boolean): boolean {
if (ngDevMode && checkNoChangesMode) {
return !devModeEqual(a, b);
}
export function isDifferent(a: any, b: any): boolean {
// NaN is the only value that is not equal to itself so the first
// test checks if both a and b are not NaN
return !(a !== a && b !== b) && a !== b;
@ -67,29 +63,24 @@ export function flatten(list: any[]): any[] {
return result;
}
/** Retrieves a value from any `LViewData` or `TData`. */
export function loadInternal<T>(index: number, arr: LViewData | TData): T {
ngDevMode && assertDataInRangeInternal(index + HEADER_OFFSET, arr);
return arr[index + HEADER_OFFSET];
}
export function assertDataInRangeInternal(index: number, arr: any[]) {
assertLessThan(index, arr ? arr.length : 0, 'index expected to be a valid data index');
/** Retrieves a value from any `LView` or `TData`. */
export function loadInternal<T>(view: LView | TData, index: number): T {
ngDevMode && assertDataInRange(view, index + HEADER_OFFSET);
return view[index + HEADER_OFFSET];
}
/**
* 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,
* 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,
* 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.
*
* @param value The initial value in `LViewData`
* @param value The initial value in `LView`
*/
export function readElementValue(value: RElement | StylingContext | LContainer | LViewData):
RElement {
export function readElementValue(value: RElement | StylingContext | LContainer | LView): RElement {
while (Array.isArray(value)) {
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
* from any containers, component views, or style contexts.
*/
export function getNativeByIndex(index: number, arr: LViewData): RElement {
return readElementValue(arr[index + HEADER_OFFSET]);
export function getNativeByIndex(index: number, lView: LView): RElement {
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]);
}
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;
}
export function getComponentViewByIndex(nodeIndex: number, hostView: LViewData): LViewData {
// Could be an LViewData or an LContainer. If LContainer, unwrap to find LViewData.
export function getComponentViewByIndex(nodeIndex: number, hostView: LView): LView {
// Could be an LView or an LContainer. If LContainer, unwrap to find LView.
const slotValue = hostView[nodeIndex];
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';
}
export function isRootView(target: LViewData): boolean {
export function isRootView(target: LView): boolean {
return (target[FLAGS] & LViewFlags.IsRoot) !== 0;
}
/**
* Retrieve the root view from any component by walking the parent `LViewData` until
* reaching the root `LViewData`.
* Retrieve the root view from any component by walking the parent `LView` until
* reaching the root `LView`.
*
* @param component any component
*/
export function getRootView(target: LViewData | {}): LViewData {
export function getRootView(target: LView | {}): LView {
ngDevMode && assertDefined(target, 'component');
let lViewData = Array.isArray(target) ? (target as LViewData) : readPatchedLViewData(target) !;
while (lViewData && !(lViewData[FLAGS] & LViewFlags.IsRoot)) {
lViewData = lViewData[PARENT] !;
let lView = Array.isArray(target) ? (target as LView) : readPatchedLView(target) !;
while (lView && !(lView[FLAGS] & LViewFlags.IsRoot)) {
lView = lView[PARENT] !;
}
return lViewData;
return lView;
}
export function getRootContext(viewOrComponent: LViewData | {}): RootContext {
export function getRootContext(viewOrComponent: LView | {}): RootContext {
const rootView = getRootView(viewOrComponent);
ngDevMode &&
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
* 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];
}
export function readPatchedLViewData(target: any): LViewData|null {
export function readPatchedLView(target: any): LView|null {
const value = readPatchedData(target);
if (value) {
return Array.isArray(value) ? value : (value as LContext).lViewData;
return Array.isArray(value) ? value : (value as LContext).lView;
}
return null;
}
@ -195,11 +186,10 @@ export function getParentInjectorViewOffset(parentLocation: RelativeInjectorLoca
* injector.
*
* @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
* @returns The LViewData instance that contains the parent injector
* @param startView The LView instance from which to start walking up the view tree
* @returns The LView instance that contains the parent injector
*/
export function getParentInjectorView(
location: RelativeInjectorLocation, startView: LViewData): LViewData {
export function getParentInjectorView(location: RelativeInjectorLocation, startView: LView): LView {
let viewOffset = getParentInjectorViewOffset(location);
let parentView = startView;
// 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.
*
* @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
* @returns The TNode of the parent injector
*/
export function getParentInjectorTNode(
location: RelativeInjectorLocation, startView: LViewData, startTNode: TNode): TElementNode|
location: RelativeInjectorLocation, startView: LView, startTNode: TNode): TElementNode|
TContainerNode|null {
if (startTNode.parent && startTNode.parent.injectorIndex !== -1) {
// 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 {LQueries} from './interfaces/query';
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 {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 {ViewRef} from './view_ref';
@ -41,7 +41,7 @@ import {ViewRef} from './view_ref';
*/
export function injectElementRef(ElementRefToken: typeof ViewEngine_ElementRef):
ViewEngine_ElementRef {
return createElementRef(ElementRefToken, getPreviousOrParentTNode(), getViewData());
return createElementRef(ElementRefToken, getPreviousOrParentTNode(), getLView());
}
let R3ElementRef: {new (native: RElement | RComment): ViewEngine_ElementRef};
@ -56,7 +56,7 @@ let R3ElementRef: {new (native: RElement | RComment): ViewEngine_ElementRef};
*/
export function createElementRef(
ElementRefToken: typeof ViewEngine_ElementRef, tNode: TNode,
view: LViewData): ViewEngine_ElementRef {
view: LView): ViewEngine_ElementRef {
if (!R3ElementRef) {
// TODO: Fix class name, should be ElementRef, but there appears to be a rollup bug
R3ElementRef = class ElementRef_ extends ElementRefToken {};
@ -66,7 +66,7 @@ export function createElementRef(
let R3TemplateRef: {
new (
_declarationParentView: LViewData, elementRef: ViewEngine_ElementRef, _tView: TView,
_declarationParentView: LView, elementRef: ViewEngine_ElementRef, _tView: TView,
_renderer: Renderer3, _queries: LQueries | null, _injectorIndex: number):
ViewEngine_TemplateRef<any>
};
@ -80,7 +80,7 @@ export function injectTemplateRef<T>(
TemplateRefToken: typeof ViewEngine_TemplateRef,
ElementRefToken: typeof ViewEngine_ElementRef): ViewEngine_TemplateRef<T>|null {
return createTemplateRef<T>(
TemplateRefToken, ElementRefToken, getPreviousOrParentTNode(), getViewData());
TemplateRefToken, ElementRefToken, getPreviousOrParentTNode(), getLView());
}
/**
@ -94,12 +94,12 @@ export function injectTemplateRef<T>(
*/
export function createTemplateRef<T>(
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) {
// TODO: Fix class name, should be TemplateRef, but there appears to be a rollup bug
R3TemplateRef = class TemplateRef_<T> extends TemplateRefToken<T> {
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 _injectorIndex: number) {
super();
@ -107,7 +107,7 @@ export function createTemplateRef<T>(
createEmbeddedView(
context: T, container?: LContainer,
hostTNode?: TElementNode|TContainerNode|TElementContainerNode, hostView?: LViewData,
hostTNode?: TElementNode|TContainerNode|TElementContainerNode, hostView?: LView,
index?: number): viewEngine_EmbeddedViewRef<T> {
const lView = createEmbeddedViewAndNode(
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');
return new R3TemplateRef(
hostView, createElementRef(ElementRefToken, hostTNode, hostView), hostTNode.tViews as TView,
getRenderer(), hostContainer[QUERIES], hostTNode.injectorIndex);
getLView()[RENDERER], hostContainer[QUERIES], hostTNode.injectorIndex);
} else {
return null;
}
@ -137,7 +137,7 @@ export function createTemplateRef<T>(
let R3ViewContainerRef: {
new (
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 {
const previousTNode =
getPreviousOrParentTNode() as TElementNode | TElementContainerNode | TContainerNode;
return createContainerRef(ViewContainerRefToken, ElementRefToken, previousTNode, getViewData());
return createContainerRef(ViewContainerRefToken, ElementRefToken, previousTNode, getLView());
}
export class NodeInjector implements Injector {
constructor(
private _tNode: TElementNode|TContainerNode|TElementContainerNode,
private _hostView: LViewData) {}
private _tNode: TElementNode|TContainerNode|TElementContainerNode, private _hostView: LView) {
}
get(token: any, notFoundValue?: any): any {
return getOrCreateInjectable(
@ -178,7 +178,7 @@ export function createContainerRef(
ViewContainerRefToken: typeof ViewEngine_ViewContainerRef,
ElementRefToken: typeof ViewEngine_ElementRef,
hostTNode: TElementNode|TContainerNode|TElementContainerNode,
hostView: LViewData): ViewEngine_ViewContainerRef {
hostView: LView): ViewEngine_ViewContainerRef {
if (!R3ViewContainerRef) {
// TODO: Fix class name, should be ViewContainerRef, but there appears to be a rollup bug
R3ViewContainerRef = class ViewContainerRef_ extends ViewContainerRefToken {
@ -187,7 +187,7 @@ export function createContainerRef(
constructor(
private _lContainer: LContainer,
private _hostTNode: TElementNode|TContainerNode|TElementContainerNode,
private _hostView: LViewData) {
private _hostView: LView) {
super();
}
@ -249,7 +249,7 @@ export function createContainerRef(
if (viewRef.destroyed) {
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);
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) */
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
*/
export function createViewRef(
hostTNode: TNode, hostView: LViewData, context: any): ViewEngine_ChangeDetectorRef {
hostTNode: TNode, hostView: LView, context: any): ViewEngine_ChangeDetectorRef {
if (isComponent(hostTNode)) {
const componentIndex = hostTNode.flags >> TNodeFlags.DirectiveStartingIndexShift;
const componentView = getComponentViewByIndex(hostTNode.index, hostView);
@ -365,7 +365,7 @@ export function createViewRef(
return null !;
}
function getOrCreateRenderer2(view: LViewData): Renderer2 {
function getOrCreateRenderer2(view: LView): Renderer2 {
const renderer = view[RENDERER];
if (isProceduralRenderer(renderer)) {
return renderer as Renderer2;
@ -376,5 +376,5 @@ function getOrCreateRenderer2(view: LViewData): Renderer2 {
/** Returns a Renderer2 (or throws when application was bootstrapped with Renderer3) */
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 {TNode} from './interfaces/node';
import {LViewData} from './interfaces/view';
import {LView} from './interfaces/view';
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
* `<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);
}

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 {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 {getRendererFactory} from './state';
import {getNativeByTNode} from './util';
@ -33,42 +32,42 @@ export class ViewRef<T> implements viewEngine_EmbeddedViewRef<T>, viewEngine_Int
/**
* @internal
*/
_view: LViewData;
public _tViewNode: TViewNode|null = null;
/**
* @internal
*/
_tViewNode: TViewNode|null = null;
public _lView: LView;
get rootNodes(): any[] {
if (this._view[HOST] == null) {
const tView = this._view[HOST_NODE] as TViewNode;
return collectNativeNodes(this._view, tView, []);
if (this._lView[HOST] == null) {
const tView = this._lView[HOST_NODE] as TViewNode;
return collectNativeNodes(this._lView, tView, []);
}
return [];
}
constructor(_view: LViewData, private _context: T|null, private _componentIndex: number) {
this._view = _view;
constructor(_lView: LView, private _context: T|null, private _componentIndex: number) {
this._lView = _lView;
}
get context(): T { return this._context ? this._context : this._lookUpContext(); }
get destroyed(): boolean {
return (this._view[FLAGS] & LViewFlags.Destroyed) === LViewFlags.Destroyed;
return (this._lView[FLAGS] & LViewFlags.Destroyed) === LViewFlags.Destroyed;
}
destroy(): void {
if (this._appRef) {
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 = 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.
@ -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.
@ -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.
@ -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.
@ -241,7 +240,7 @@ export class ViewRef<T> implements viewEngine_EmbeddedViewRef<T>, viewEngine_Int
* See {@link ChangeDetectorRef#detach detach} for more information.
*/
detectChanges(): void {
const rendererFactory = this._view[RENDERER_FACTORY];
const rendererFactory = this._lView[RENDERER_FACTORY];
if (rendererFactory.begin) {
rendererFactory.begin();
}
@ -266,13 +265,13 @@ export class ViewRef<T> implements viewEngine_EmbeddedViewRef<T>, viewEngine_Int
attachToAppRef(appRef: ApplicationRef) { this._appRef = appRef; }
private _lookUpContext(): T {
return this._context = this._view[PARENT] ![this._componentIndex] as T;
return this._context = this._lView[PARENT] ![this._componentIndex] as T;
}
}
/** @internal */
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); }
@ -281,7 +280,7 @@ export class RootViewRef<T> extends ViewRef<T> {
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;
while (tNodeChild) {

View File

@ -6,7 +6,8 @@
* 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 {BypassType, allowSanitizationBypass} from './bypass';
@ -31,9 +32,9 @@ import {_sanitizeUrl as _sanitizeUrl} from './url_sanitizer';
* and urls have been removed.
*/
export function sanitizeHtml(unsafeHtml: any): string {
const s = getCurrentSanitizer();
if (s) {
return s.sanitize(SecurityContext.HTML, unsafeHtml) || '';
const sanitizer = getLView()[SANITIZER];
if (sanitizer) {
return sanitizer.sanitize(SecurityContext.HTML, unsafeHtml) || '';
}
if (allowSanitizationBypass(unsafeHtml, BypassType.Html)) {
return unsafeHtml.toString();
@ -55,9 +56,9 @@ export function sanitizeHtml(unsafeHtml: any): string {
* dangerous javascript and urls have been removed.
*/
export function sanitizeStyle(unsafeStyle: any): string {
const s = getCurrentSanitizer();
if (s) {
return s.sanitize(SecurityContext.STYLE, unsafeStyle) || '';
const sanitizer = getLView()[SANITIZER];
if (sanitizer) {
return sanitizer.sanitize(SecurityContext.STYLE, unsafeStyle) || '';
}
if (allowSanitizationBypass(unsafeStyle, BypassType.Style)) {
return unsafeStyle.toString();
@ -80,9 +81,9 @@ export function sanitizeStyle(unsafeStyle: any): string {
* all of the dangerous javascript has been removed.
*/
export function sanitizeUrl(unsafeUrl: any): string {
const s = getCurrentSanitizer();
if (s) {
return s.sanitize(SecurityContext.URL, unsafeUrl) || '';
const sanitizer = getLView()[SANITIZER];
if (sanitizer) {
return sanitizer.sanitize(SecurityContext.URL, unsafeUrl) || '';
}
if (allowSanitizationBypass(unsafeUrl, BypassType.Url)) {
return unsafeUrl.toString();
@ -100,9 +101,9 @@ export function sanitizeUrl(unsafeUrl: any): string {
* only trusted `url`s have been allowed to pass.
*/
export function sanitizeResourceUrl(unsafeResourceUrl: any): string {
const s = getCurrentSanitizer();
if (s) {
return s.sanitize(SecurityContext.RESOURCE_URL, unsafeResourceUrl) || '';
const sanitizer = getLView()[SANITIZER];
if (sanitizer) {
return sanitizer.sanitize(SecurityContext.RESOURCE_URL, unsafeResourceUrl) || '';
}
if (allowSanitizationBypass(unsafeResourceUrl, BypassType.ResourceUrl)) {
return unsafeResourceUrl.toString();
@ -113,16 +114,17 @@ export function sanitizeResourceUrl(unsafeResourceUrl: any): string {
/**
* 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.
* @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 {
const s = getCurrentSanitizer();
if (s) {
return s.sanitize(SecurityContext.SCRIPT, unsafeScript) || '';
const sanitizer = getLView()[SANITIZER];
if (sanitizer) {
return sanitizer.sanitize(SecurityContext.SCRIPT, unsafeScript) || '';
}
if (allowSanitizationBypass(unsafeScript, BypassType.Script)) {
return unsafeScript.toString();

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1116,7 +1116,7 @@ function declareTests(config?: {useJit: boolean}) {
.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', () => {
@Component({template: ''})
class RootComp {
@ -1156,7 +1156,7 @@ function declareTests(config?: {useJit: boolean}) {
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', () => {
@Component({template: ''})
class RootComp {
@ -1197,7 +1197,7 @@ function declareTests(config?: {useJit: boolean}) {
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',
() => {
@Component({template: ''})

View File

@ -8,10 +8,11 @@
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 {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 {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 {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 {AttributeMarker, TNodeType} from '../../src/render3/interfaces/node';
import {getNativeByIndex} from '../../src/render3/util';
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 {getRendererFactory2} from './imported_renderer2';
@ -1264,7 +1264,7 @@ describe('di', () => {
if (rf & RenderFlags.Create) {
elementStart(0, 'div', ['dir', '', 'dirSame', '']);
elementEnd();
div = getNativeByIndex(0, getViewData());
div = getNativeByIndex(0, getLView());
}
}, 1, 0, [Directive, DirectiveSameInstance]);
@ -2020,7 +2020,7 @@ describe('di', () => {
describe('getOrCreateNodeInjector', () => {
it('should handle initial undefined state', () => {
const contentView = createLViewData(
const contentView = createLView(
null, createTView(-1, null, 1, 0, null, null, null), null, LViewFlags.CheckAlways,
{} as any, {} as any);
const oldView = enterView(contentView, null);

View File

@ -422,7 +422,7 @@ describe('host bindings', () => {
vars: 0,
hostVars: 8,
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) {
elementProperty(elIndex, 'id', bind(pureFunction1(3, ff, ctx.id)));
elementProperty(elIndex, 'dir', bind(ctx.dir));
@ -498,7 +498,7 @@ describe('host bindings', () => {
vars: 0,
hostVars: 3,
hostBindings: (rf: RenderFlags, ctx: HostBindingComp, elIndex: number) => {
// LViewData: [..., id, ctx.id, pf1]
// LView: [..., id, ctx.id, pf1]
if (rf & RenderFlags.Update) {
elementProperty(elIndex, 'id', bind(pureFunction1(1, ff, ctx.id)));
}
@ -527,7 +527,7 @@ describe('host bindings', () => {
factory: () => hostBindingDir = new HostBindingDir(),
hostVars: 3,
hostBindings: (rf: RenderFlags, ctx: HostBindingDir, elIndex: number) => {
// LViewData [..., title, ctx.title, pf1]
// LView [..., title, ctx.title, pf1]
if (rf & RenderFlags.Update) {
elementProperty(elIndex, 'title', bind(pureFunction1(1, ff1, ctx.title)));
}
@ -589,7 +589,7 @@ describe('host bindings', () => {
vars: 0,
hostVars: 6,
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) {
elementProperty(
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 {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';
const Component: typeof _Component = function(...args: any[]): any {
@ -691,8 +691,8 @@ describe('Runtime i18n', () => {
const opCodes = tView.data[index + HEADER_OFFSET] as I18nUpdateOpCodes;
expect(opCodes).toEqual([]);
expect((getNativeByIndex(0, fixture.hostView as LViewData) as any as Element)
.getAttribute('title'))
expect(
(getNativeByIndex(0, fixture.hostView as LView) as any as Element).getAttribute('title'))
.toEqual(MSG_title);
});

View File

@ -2034,14 +2034,14 @@ describe('render3 integration test', () => {
const section = fixture.hostElement.querySelector('section') !;
const sectionContext = getContext(section) !;
const sectionLView = sectionContext.lViewData !;
const sectionLView = sectionContext.lView !;
expect(sectionContext.nodeIndex).toEqual(HEADER_OFFSET);
expect(sectionLView.length).toBeGreaterThan(HEADER_OFFSET);
expect(sectionContext.native).toBe(section);
const div = fixture.hostElement.querySelector('div') !;
const divContext = getContext(div) !;
const divLView = divContext.lViewData !;
const divLView = divContext.lView !;
expect(divContext.nodeIndex).toEqual(HEADER_OFFSET + 1);
expect(divLView.length).toBeGreaterThan(HEADER_OFFSET);
expect(divContext.native).toBe(div);
@ -2077,7 +2077,7 @@ describe('render3 integration test', () => {
expect(Array.isArray(result2)).toBeFalsy();
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',
@ -2244,9 +2244,9 @@ describe('render3 integration test', () => {
const shadowContext = getContext(header) !;
const projectedContext = getContext(p) !;
const parentComponentData = parentContext.lViewData;
const shadowComponentData = shadowContext.lViewData;
const projectedComponentData = projectedContext.lViewData;
const parentComponentData = parentContext.lView;
const shadowComponentData = shadowContext.lView;
const projectedComponentData = projectedContext.lView;
expect(projectedComponentData).toBe(parentComponentData);
expect(shadowComponentData).not.toBe(parentComponentData);
@ -2310,23 +2310,23 @@ describe('render3 integration test', () => {
const hostElm = fixture.hostElement;
const component = fixture.component;
const componentLViewData = (component as any)[MONKEY_PATCH_KEY_NAME];
expect(Array.isArray(componentLViewData)).toBeTruthy();
const componentLView = (component as any)[MONKEY_PATCH_KEY_NAME];
expect(Array.isArray(componentLView)).toBeTruthy();
const hostLViewData = (hostElm as any)[MONKEY_PATCH_KEY_NAME];
expect(hostLViewData).toBe(componentLViewData);
const hostLView = (hostElm as any)[MONKEY_PATCH_KEY_NAME];
expect(hostLView).toBe(componentLView);
const context1 = getContext(hostElm) !;
expect(context1.lViewData).toBe(hostLViewData);
expect(context1.lView).toBe(hostLView);
expect(context1.native).toEqual(hostElm);
const context2 = getContext(component) !;
expect(context2).toBe(context1);
expect(context2.lViewData).toBe(hostLViewData);
expect(context2.lView).toBe(hostLView);
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 myDir2Instance: MyDir2|null = null;
@ -2380,7 +2380,7 @@ describe('render3 integration test', () => {
const div1 = hostElm.querySelector('div:first-child') !as any;
const div2 = hostElm.querySelector('div:last-child') !as any;
const context = getContext(hostElm) !;
const componentView = context.lViewData[context.nodeIndex];
const componentView = context.lView[context.nodeIndex];
expect(componentView).toContain(myDir1Instance);
expect(componentView).toContain(myDir2Instance);
@ -2394,9 +2394,9 @@ describe('render3 integration test', () => {
const d2Context = getContext(myDir2Instance) !;
const d3Context = getContext(myDir3Instance) !;
expect(d1Context.lViewData).toEqual(componentView);
expect(d2Context.lViewData).toEqual(componentView);
expect(d3Context.lViewData).toEqual(componentView);
expect(d1Context.lView).toEqual(componentView);
expect(d2Context.lView).toEqual(componentView);
expect(d3Context.lView).toEqual(componentView);
expect((myDir1Instance as any)[MONKEY_PATCH_KEY_NAME]).toBe(d1Context);
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 lViewData = childCompHostElm[MONKEY_PATCH_KEY_NAME];
expect(Array.isArray(lViewData)).toBeTruthy();
expect((myDir1Instance as any)[MONKEY_PATCH_KEY_NAME]).toBe(lViewData);
expect((myDir2Instance as any)[MONKEY_PATCH_KEY_NAME]).toBe(lViewData);
expect((childComponentInstance as any)[MONKEY_PATCH_KEY_NAME]).toBe(lViewData);
const lView = childCompHostElm[MONKEY_PATCH_KEY_NAME];
expect(Array.isArray(lView)).toBeTruthy();
expect((myDir1Instance as any)[MONKEY_PATCH_KEY_NAME]).toBe(lView);
expect((myDir2Instance as any)[MONKEY_PATCH_KEY_NAME]).toBe(lView);
expect((childComponentInstance as any)[MONKEY_PATCH_KEY_NAME]).toBe(lView);
const childNodeContext = getContext(childCompHostElm) !;
expect(childNodeContext.component).toBeFalsy();
expect(childNodeContext.directives).toBeFalsy();
assertMonkeyPatchValueIsLViewData(myDir1Instance);
assertMonkeyPatchValueIsLViewData(myDir2Instance);
assertMonkeyPatchValueIsLViewData(childComponentInstance);
assertMonkeyPatchValueIsLView(myDir1Instance);
assertMonkeyPatchValueIsLView(myDir2Instance);
assertMonkeyPatchValueIsLView(childComponentInstance);
expect(getContext(myDir1Instance)).toBe(childNodeContext);
expect(childNodeContext.component).toBeFalsy();
expect(childNodeContext.directives !.length).toEqual(2);
assertMonkeyPatchValueIsLViewData(myDir1Instance, false);
assertMonkeyPatchValueIsLViewData(myDir2Instance, false);
assertMonkeyPatchValueIsLViewData(childComponentInstance);
assertMonkeyPatchValueIsLView(myDir1Instance, false);
assertMonkeyPatchValueIsLView(myDir2Instance, false);
assertMonkeyPatchValueIsLView(childComponentInstance);
expect(getContext(myDir2Instance)).toBe(childNodeContext);
expect(childNodeContext.component).toBeFalsy();
expect(childNodeContext.directives !.length).toEqual(2);
assertMonkeyPatchValueIsLViewData(myDir1Instance, false);
assertMonkeyPatchValueIsLViewData(myDir2Instance, false);
assertMonkeyPatchValueIsLViewData(childComponentInstance);
assertMonkeyPatchValueIsLView(myDir1Instance, false);
assertMonkeyPatchValueIsLView(myDir2Instance, false);
assertMonkeyPatchValueIsLView(childComponentInstance);
expect(getContext(childComponentInstance)).toBe(childNodeContext);
expect(childNodeContext.component).toBeTruthy();
expect(childNodeContext.directives !.length).toEqual(2);
assertMonkeyPatchValueIsLViewData(myDir1Instance, false);
assertMonkeyPatchValueIsLViewData(myDir2Instance, false);
assertMonkeyPatchValueIsLViewData(childComponentInstance, false);
assertMonkeyPatchValueIsLView(myDir1Instance, false);
assertMonkeyPatchValueIsLView(myDir2Instance, 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);
}
});
@ -2560,16 +2560,16 @@ describe('render3 integration test', () => {
const context = getContext(child) !;
expect(child[MONKEY_PATCH_KEY_NAME]).toBeTruthy();
const componentData = context.lViewData[context.nodeIndex];
const componentData = context.lView[context.nodeIndex];
const component = componentData[CONTEXT];
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) !;
expect(component[MONKEY_PATCH_KEY_NAME]).toBe(componentContext);
expect(componentContext.nodeIndex).toEqual(context.nodeIndex);
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 {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 {getCurrentView, restoreView} from '../../src/render3/state';
import {restoreView} from '../../src/render3/state';
import {getRendererFactory2} from './imported_renderer2';
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 {getProjectAsAttrValue, isNodeMatchingSelectorList, isNodeMatchingSelector} from '../../src/render3/node_selector_matcher';
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 {
return createTNode(getViewData(), TNodeType.Element, 0, tagName, attrs, null);
return createTNode(getLView(), TNodeType.Element, 0, tagName, attrs, null);
}
describe('css selector matching', () => {
function isMatching(tagName: string, attrs: TAttributes | null, selector: CssSelector): boolean {
return isNodeMatchingSelector(
createTNode(getViewData(), TNodeType.Element, 0, tagName, attrs, null), selector);
createTNode(getLView(), TNodeType.Element, 0, tagName, attrs, null), selector);
}
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 {RenderFlags} from '../../src/render3/interfaces/definition';
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 {NgForOf, NgIf, NgTemplateOutlet} from './common_with_def';
@ -115,7 +115,7 @@ describe('query', () => {
function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
element(1, 'div', ['child', '']);
elToQuery = getNativeByIndex(1, getViewData());
elToQuery = getNativeByIndex(1, getLView());
}
},
2, 0, [Child], [],
@ -335,7 +335,7 @@ describe('query', () => {
function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
element(1, 'div', null, ['foo', '']);
elToQuery = getNativeByIndex(1, getViewData());
elToQuery = getNativeByIndex(1, getLView());
element(3, 'div');
}
},
@ -372,7 +372,7 @@ describe('query', () => {
function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
element(2, 'div', null, ['foo', '', 'bar', '']);
elToQuery = getNativeByIndex(2, getViewData());
elToQuery = getNativeByIndex(2, getLView());
element(5, 'div');
}
},
@ -419,10 +419,10 @@ describe('query', () => {
function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
element(1, 'div', null, ['foo', '']);
el1ToQuery = getNativeByIndex(1, getViewData());
el1ToQuery = getNativeByIndex(1, getLView());
element(3, 'div');
element(4, 'div', null, ['bar', '']);
el2ToQuery = getNativeByIndex(4, getViewData());
el2ToQuery = getNativeByIndex(4, getLView());
}
},
6, 0, [], [],
@ -458,7 +458,7 @@ describe('query', () => {
function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
element(1, 'div', null, ['foo', '']);
elToQuery = getNativeByIndex(1, getViewData());
elToQuery = getNativeByIndex(1, getLView());
element(3, 'div');
}
},
@ -494,7 +494,7 @@ describe('query', () => {
function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
elementContainerStart(1, null, ['foo', '']);
elToQuery = getNativeByIndex(1, getViewData());
elToQuery = getNativeByIndex(1, getLView());
elementContainerEnd();
}
},
@ -530,7 +530,7 @@ describe('query', () => {
function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
elementContainerStart(1, null, ['foo', '']);
elToQuery = getNativeByIndex(1, getViewData());
elToQuery = getNativeByIndex(1, getLView());
elementContainerEnd();
}
},
@ -593,7 +593,7 @@ describe('query', () => {
elementContainerStart(2);
{
element(3, 'div', null, ['foo', '']);
elToQuery = getNativeByIndex(3, getViewData());
elToQuery = getNativeByIndex(3, getLView());
}
elementContainerEnd();
}
@ -1003,7 +1003,7 @@ describe('query', () => {
function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
element(1, 'div', ['child', ''], ['foo', 'child']);
div = getNativeByIndex(1, getViewData());
div = getNativeByIndex(1, getLView());
}
},
3, 0, [Child], [],
@ -1038,7 +1038,7 @@ describe('query', () => {
function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
element(1, 'div', ['child', ''], ['foo', '', 'bar', 'child']);
div = getNativeByIndex(1, getViewData());
div = getNativeByIndex(1, getLView());
}
if (rf & RenderFlags.Update) {
childInstance = getDirectiveOnNode(1);
@ -1737,7 +1737,7 @@ describe('query', () => {
{
if (rf1 & RenderFlags.Create) {
element(0, 'div', null, ['foo', '']);
firstEl = getNativeByIndex(0, getViewData());
firstEl = getNativeByIndex(0, getLView());
}
}
embeddedViewEnd();
@ -1789,10 +1789,10 @@ describe('query', () => {
function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
element(1, 'span', null, ['foo', '']);
firstEl = getNativeByIndex(1, getViewData());
firstEl = getNativeByIndex(1, getLView());
container(3);
element(4, 'span', null, ['foo', '']);
lastEl = getNativeByIndex(4, getViewData());
lastEl = getNativeByIndex(4, getLView());
}
if (rf & RenderFlags.Update) {
containerRefreshStart(3);
@ -1802,7 +1802,7 @@ describe('query', () => {
{
if (rf1 & RenderFlags.Create) {
element(0, 'div', null, ['foo', '']);
viewEl = getNativeByIndex(0, getViewData());
viewEl = getNativeByIndex(0, getLView());
}
}
embeddedViewEnd();
@ -1869,7 +1869,7 @@ describe('query', () => {
{
if (rf0 & RenderFlags.Create) {
element(0, 'div', null, ['foo', '']);
firstEl = getNativeByIndex(0, getViewData());
firstEl = getNativeByIndex(0, getLView());
}
}
embeddedViewEnd();
@ -1879,7 +1879,7 @@ describe('query', () => {
{
if (rf1 & RenderFlags.Create) {
element(0, 'span', null, ['foo', '']);
lastEl = getNativeByIndex(0, getViewData());
lastEl = getNativeByIndex(0, getLView());
}
}
embeddedViewEnd();
@ -1942,7 +1942,7 @@ describe('query', () => {
{
if (rf0 & RenderFlags.Create) {
element(0, 'div', null, ['foo', '']);
firstEl = getNativeByIndex(0, getViewData());
firstEl = getNativeByIndex(0, getLView());
container(2);
}
if (rf0 & RenderFlags.Update) {
@ -1953,7 +1953,7 @@ describe('query', () => {
{
if (rf2) {
element(0, 'span', null, ['foo', '']);
lastEl = getNativeByIndex(0, getViewData());
lastEl = getNativeByIndex(0, getLView());
}
}
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 {ViewContainerRef} from '@angular/core/src/linker/view_container_ref';
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 {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 {PlayerHandler} from '../../src/render3/interfaces/player';
import {RElement, RText, Renderer3, RendererFactory3, domRendererFactory3} from '../../src/render3/interfaces/renderer';
import {HEADER_OFFSET, LViewData} from '../../src/render3/interfaces/view';
import {getViewData} from '../../src/render3/state';
import {HEADER_OFFSET, LView} from '../../src/render3/interfaces/view';
import {Sanitizer} from '../../src/sanitization/security';
import {Type} from '../../src/type';
@ -82,7 +82,7 @@ function noop() {}
* - access to the render `html`.
*/
export class TemplateFixture extends BaseFixture {
hostView: LViewData;
hostView: LView;
private _directiveDefs: DirectiveDefList|null;
private _pipeDefs: PipeDefList|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 let containerEl: HTMLElement = null !;
let hostView: LViewData|null;
let hostView: LView|null;
const isRenderer2 =
typeof process == 'object' && process.argv[3] && process.argv[3] === '--r=renderer2';
// tslint:disable-next-line:no-console
@ -323,7 +323,7 @@ export function createDirective(
/** Gets the directive on the given node at the given index */
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) {
throw new Error(`No directives exist on node in slot ${nodeIndex}`);
}

View File

@ -8,12 +8,12 @@
import {createRootContext} from '../../../src/render3/component';
import {getContext} from '../../../src/render3/context_discovery';
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 {BindingStore, BindingType, PlayState, Player, PlayerFactory, PlayerHandler} from '../../../src/render3/interfaces/player';
import {RElement, Renderer3, domRendererFactory3} from '../../../src/render3/interfaces/renderer';
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 {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';
@ -29,13 +29,13 @@ describe('style and class based bindings', () => {
let element: RElement|null = null;
beforeEach(() => { element = document.createElement('div') as any; });
function createMockViewData(playerHandler: PlayerHandler, context: StylingContext): LViewData {
function createMockViewData(playerHandler: PlayerHandler, context: StylingContext): LView {
const rootContext =
createRootContext(requestAnimationFrame.bind(window), playerHandler || null);
const lViewData = createLViewData(
const lView = createLView(
null, createTView(-1, null, 1, 0, null, null, null), rootContext, LViewFlags.IsRoot,
domRendererFactory3, domRendererFactory3.createRenderer(element, null));
return lViewData;
return lView;
}
function initContext(
@ -44,18 +44,16 @@ describe('style and class based bindings', () => {
return allocStylingContext(element, createStylingContextTemplate(classes, styles, sanitizer));
}
function getRootContextInternal(lViewData: LViewData) {
return lViewData[CONTEXT] as RootContext;
}
function getRootContextInternal(lView: LView) { return lView[CONTEXT] as RootContext; }
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 handler = new CorePlayerHandler();
_renderStyling(
context, (renderer || {}) as Renderer3,
getRootContextInternal(lViewData || createMockViewData(handler, context)), !!firstRender,
null, store);
getRootContextInternal(lView || createMockViewData(handler, context)), !!firstRender, null,
store);
return store.getValues();
}
@ -64,10 +62,10 @@ describe('style and class based bindings', () => {
const handler = new CorePlayerHandler();
return function(context: StylingContext, firstRender?: boolean, renderer?: Renderer3):
{[key: string]: any} {
const lViewData = createMockViewData(handler, context);
const lView = createMockViewData(handler, context);
_renderStyling(
context, (renderer || {}) as Renderer3, getRootContextInternal(lViewData),
!!firstRender, null, store);
context, (renderer || {}) as Renderer3, getRootContextInternal(lView), !!firstRender,
null, store);
return store !.getValues();
};
}
@ -77,10 +75,10 @@ describe('style and class based bindings', () => {
const handler = new CorePlayerHandler();
return function(context: StylingContext, firstRender?: boolean, renderer?: Renderer3):
{[key: string]: any} {
const lViewData = createMockViewData(handler, context);
const lView = createMockViewData(handler, context);
_renderStyling(
context, (renderer || {}) as Renderer3, getRootContextInternal(lViewData),
!!firstRender, store);
context, (renderer || {}) as Renderer3, getRootContextInternal(lView), !!firstRender,
store);
return store !.getValues();
};
}
@ -91,10 +89,10 @@ describe('style and class based bindings', () => {
const handler = new CorePlayerHandler();
return function(context: StylingContext, firstRender?: boolean, renderer?: Renderer3):
{[key: string]: any} {
const lViewData = createMockViewData(handler, context);
const lView = createMockViewData(handler, context);
_renderStyling(
context, (renderer || {}) as Renderer3, getRootContextInternal(lViewData),
!!firstRender, classStore, styleStore);
context, (renderer || {}) as Renderer3, getRootContextInternal(lView), !!firstRender,
classStore, styleStore);
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', () => {
const context = initContext(null, []);
const handler = new CorePlayerHandler();
const lViewData = createMockViewData(handler, context);
const lView = createMockViewData(handler, context);
let currentStylePlayer: Player;
const styleBuildFn = (element: HTMLElement, type: BindingType, value: any) => {
@ -1625,7 +1623,7 @@ describe('style and class based bindings', () => {
5, classPlayerBuilder, null, stylePlayerBuilder, null
]);
renderStyles(context, false, undefined, lViewData);
renderStyles(context, false, undefined, lView);
expect(context[StylingIndex.PlayerContext]).toEqual([
5, classPlayerBuilder, currentClassPlayer !, stylePlayerBuilder, currentStylePlayer !
]);
@ -1661,7 +1659,7 @@ describe('style and class based bindings', () => {
() => {
const context = initContext(['width', 'height'], ['foo', 'bar']);
const handler = new CorePlayerHandler();
const lViewData = createMockViewData(handler, context);
const lView = createMockViewData(handler, context);
const capturedStylePlayers: Player[] = [];
const styleBuildFn = (element: HTMLElement, type: BindingType, value: any) => {
@ -1701,7 +1699,7 @@ describe('style and class based bindings', () => {
barPlayerBuilder, null
]);
renderStyles(context, false, undefined, lViewData);
renderStyles(context, false, undefined, lView);
const classMapPlayer = capturedClassPlayers.shift() !;
const barPlayer = capturedClassPlayers.shift() !;
const styleMapPlayer = capturedStylePlayers.shift() !;
@ -1734,7 +1732,7 @@ describe('style and class based bindings', () => {
bazPlayerBuilder, null
]);
renderStyles(context, false, undefined, lViewData);
renderStyles(context, false, undefined, lView);
const heightPlayer = capturedStylePlayers.shift() !;
const bazPlayer = capturedClassPlayers.shift() !;
@ -1757,7 +1755,7 @@ describe('style and class based bindings', () => {
() => {
const context = initContext(['width']);
const handler = new CorePlayerHandler();
const lViewData = createMockViewData(handler, context);
const lView = createMockViewData(handler, context);
const players: MockPlayer[] = [];
const buildFn =
@ -1772,7 +1770,7 @@ describe('style and class based bindings', () => {
let mapFactory = bindPlayerFactory(buildFn, {width: '200px'});
updateStylingMap(context, null, mapFactory);
renderStyles(context, false, undefined, lViewData);
renderStyles(context, false, undefined, lView);
expect(players.length).toEqual(1);
const p1 = players.pop() !;
@ -1780,7 +1778,7 @@ describe('style and class based bindings', () => {
mapFactory = bindPlayerFactory(buildFn, {width: '100px'});
updateStylingMap(context, null, mapFactory);
renderStyles(context, false, undefined, lViewData);
renderStyles(context, false, undefined, lView);
expect(players.length).toEqual(1);
const p2 = players.pop() !;
@ -1792,7 +1790,7 @@ describe('style and class based bindings', () => {
() => {
const context = initContext(['color'], ['foo']);
const handler = new CorePlayerHandler();
const lViewData = createMockViewData(handler, context);
const lView = createMockViewData(handler, context);
const stylePlayers: Player[] = [];
const buildStyleFn = (element: HTMLElement, type: BindingType, value: any) => {
@ -1855,7 +1853,7 @@ describe('style and class based bindings', () => {
const fooPlayerBuilder = makePlayerBuilder(fooWithPlayerFactory, true);
updateStyleProp(context, 0, colorWithPlayerFactory as any);
updateClassProp(context, 0, fooWithPlayerFactory as any);
renderStyles(context, false, undefined, lViewData);
renderStyles(context, false, undefined, lView);
const p1 = classPlayers.shift();
const p2 = stylePlayers.shift();
@ -1919,7 +1917,7 @@ describe('style and class based bindings', () => {
const fooWithoutPlayerFactory = false;
updateStyleProp(context, 0, colorWithoutPlayerFactory);
updateClassProp(context, 0, fooWithoutPlayerFactory);
renderStyles(context, false, undefined, lViewData);
renderStyles(context, false, undefined, lView);
expect(context).toEqual([
([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', () => {
const context = initContext([]);
const handler = new CorePlayerHandler();
const lViewData = createMockViewData(handler, context);
const lView = createMockViewData(handler, context);
let styleCalls = 0;
const buildStyleFn = (element: HTMLElement, type: BindingType, value: any) => {
@ -1993,28 +1991,28 @@ describe('style and class based bindings', () => {
expect(styleCalls).toEqual(0);
expect(classCalls).toEqual(0);
renderStyles(context, false, undefined, lViewData);
renderStyles(context, false, undefined, lView);
expect(styleCalls).toEqual(1);
expect(classCalls).toEqual(1);
renderStyles(context, false, undefined, lViewData);
renderStyles(context, false, undefined, lView);
expect(styleCalls).toEqual(1);
expect(classCalls).toEqual(1);
styleFactory.value = {opacity: '0.5'};
updateStylingMap(context, classFactory, styleFactory);
renderStyles(context, false, undefined, lViewData);
renderStyles(context, false, undefined, lView);
expect(styleCalls).toEqual(2);
expect(classCalls).toEqual(1);
classFactory.value = 'foo';
updateStylingMap(context, classFactory, styleFactory);
renderStyles(context, false, undefined, lViewData);
renderStyles(context, false, undefined, lView);
expect(styleCalls).toEqual(2);
expect(classCalls).toEqual(2);
updateStylingMap(context, 'foo', {opacity: '0.5'});
renderStyles(context, false, undefined, lViewData);
renderStyles(context, false, undefined, lView);
expect(styleCalls).toEqual(2);
expect(classCalls).toEqual(2);
});
@ -2023,7 +2021,7 @@ describe('style and class based bindings', () => {
() => {
const context = initContext(['color']);
const handler = new CorePlayerHandler();
const lViewData = createMockViewData(handler, context);
const lView = createMockViewData(handler, context);
let propPlayer: Player|null = null;
const propBuildFn = (element: HTMLElement, type: BindingType, value: any) => {
@ -2038,14 +2036,14 @@ describe('style and class based bindings', () => {
const mapFactory = bindPlayerFactory(mapBuildFn, {color: 'black'});
updateStylingMap(context, null, mapFactory);
updateStyleProp(context, 0, 'green');
renderStyles(context, false, undefined, lViewData);
renderStyles(context, false, undefined, lView);
expect(propPlayer).toBeFalsy();
expect(styleMapPlayer).toBeFalsy();
const propFactory = bindPlayerFactory(propBuildFn, 'orange');
updateStyleProp(context, 0, propFactory as any);
renderStyles(context, false, undefined, lViewData);
renderStyles(context, false, undefined, lView);
expect(propPlayer).toBeTruthy();
expect(styleMapPlayer).toBeFalsy();
@ -2053,7 +2051,7 @@ describe('style and class based bindings', () => {
propPlayer = styleMapPlayer = null;
updateStyleProp(context, 0, null);
renderStyles(context, false, undefined, lViewData);
renderStyles(context, false, undefined, lView);
expect(propPlayer).toBeFalsy();
expect(styleMapPlayer).toBeTruthy();
@ -2061,7 +2059,7 @@ describe('style and class based bindings', () => {
propPlayer = styleMapPlayer = null;
updateStylingMap(context, null, null);
renderStyles(context, false, undefined, lViewData);
renderStyles(context, false, undefined, lView);
expect(propPlayer).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', () => {
const context = initContext([]);
const handler = new CorePlayerHandler();
const lViewData = createMockViewData(handler, context);
const lView = createMockViewData(handler, context);
let previousPlayer: 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'});
updateStylingMap(context, null, factory);
renderStyles(context, false, undefined, lViewData);
renderStyles(context, false, undefined, lView);
expect(previousPlayer).toEqual(null);
expect(currentPlayer !.value).toEqual({width: '200px'});
@ -2091,7 +2089,7 @@ describe('style and class based bindings', () => {
factory = bindPlayerFactory(buildFn, {height: '200px'});
updateStylingMap(context, null, factory);
renderStyles(context, false, undefined, lViewData);
renderStyles(context, false, undefined, lView);
expect(previousPlayer !.value).toEqual({width: '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', () => {
const context = initContext([]);
const handler = new CorePlayerHandler();
const lViewData = createMockViewData(handler, context);
const lView = createMockViewData(handler, context);
let currentPlayer: 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});
updateStylingMap(context, null, factory);
renderStyles(context, false, undefined, lViewData);
renderStyles(context, false, undefined, lView);
expect(currentPlayer).toBeTruthy();
expect(previousPlayer).toBeFalsy();
@ -2123,7 +2121,7 @@ describe('style and class based bindings', () => {
factory = bindPlayerFactory(buildFn, {bar: true});
updateStylingMap(context, null, factory);
renderStyles(context, false, undefined, lViewData);
renderStyles(context, false, undefined, lView);
expect(currentPlayer).toBeTruthy();
expect(previousPlayer).toBeTruthy();
@ -2142,7 +2140,7 @@ describe('style and class based bindings', () => {
const context = initContext([], [], sanitizer);
const handler = new CorePlayerHandler();
const lViewData = createMockViewData(handler, context);
const lView = createMockViewData(handler, context);
let values: {[key: string]: any}|null = null;
const buildFn =
@ -2154,13 +2152,13 @@ describe('style and class based bindings', () => {
let factory = bindPlayerFactory<{[key: string]: any}>(
buildFn, {width: '200px', height: '100px', opacity: '1'});
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'});
factory = bindPlayerFactory(buildFn, {width: 'auto'});
updateStylingMap(context, null, factory);
renderStyles(context, false, undefined, lViewData);
renderStyles(context, false, undefined, lView);
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 handler = new CorePlayerHandler();
const lViewData = createMockViewData(handler, context);
const lView = createMockViewData(handler, context);
const players: Player[] = [];
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);
updateClassProp(context, 0, 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();
const [p1, p2, p3, p4, p5] = players;
@ -2210,7 +2208,7 @@ describe('style and class based bindings', () => {
expect(p4.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(p2.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 elementContext = getContext(target) !;
const context = elementContext.lViewData[elementContext.nodeIndex] as StylingContext;
const context = elementContext.lView[elementContext.nodeIndex] as StylingContext;
expect(players.length).toEqual(4);
const [p1, p2, p3, p4] = players;

View File

@ -6,6 +6,8 @@
* 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';
describe('util', () => {
@ -14,53 +16,51 @@ describe('util', () => {
describe('checkNoChangeMode = false', () => {
it('should mark non-equal arguments as different', () => {
expect(isDifferent({}, {}, false)).toBeTruthy();
expect(isDifferent('foo', 'bar', false)).toBeTruthy();
expect(isDifferent(0, 1, false)).toBeTruthy();
expect(isDifferent({}, {})).toBeTruthy();
expect(isDifferent('foo', 'bar')).toBeTruthy();
expect(isDifferent(0, 1)).toBeTruthy();
});
it('should not mark equal arguments as different', () => {
const obj = {};
expect(isDifferent(obj, obj, false)).toBeFalsy();
expect(isDifferent('foo', 'foo', false)).toBeFalsy();
expect(isDifferent(1, 1, false)).toBeFalsy();
expect(isDifferent(obj, obj)).toBeFalsy();
expect(isDifferent('foo', 'foo')).toBeFalsy();
expect(isDifferent(1, 1)).toBeFalsy();
});
it('should not mark NaN as different',
() => { expect(isDifferent(NaN, NaN, false)).toBeFalsy(); });
it('should not mark NaN as different', () => { expect(isDifferent(NaN, NaN)).toBeFalsy(); });
it('should mark NaN with other values as different', () => {
expect(isDifferent(NaN, 'foo', false)).toBeTruthy();
expect(isDifferent(5, NaN, false)).toBeTruthy();
expect(isDifferent(NaN, 'foo')).toBeTruthy();
expect(isDifferent(5, NaN)).toBeTruthy();
});
});
describe('checkNoChangeMode = true', () => {
// Assert relaxed constraint in checkNoChangeMode
it('should not mark non-equal arrays, object and function as different', () => {
expect(isDifferent([], [], true)).toBeFalsy();
expect(isDifferent(() => 0, () => 0, true)).toBeFalsy();
expect(isDifferent({}, {}, true)).toBeFalsy();
expect(!devModeEqual([], [])).toBeFalsy();
expect(!devModeEqual(() => 0, () => 0)).toBeFalsy();
expect(!devModeEqual({}, {})).toBeFalsy();
});
it('should mark non-equal arguments as different', () => {
expect(isDifferent('foo', 'bar', true)).toBeTruthy();
expect(isDifferent(0, 1, true)).toBeTruthy();
expect(!devModeEqual('foo', 'bar')).toBeTruthy();
expect(!devModeEqual(0, 1)).toBeTruthy();
});
it('should not mark equal arguments as different', () => {
const obj = {};
expect(isDifferent(obj, obj, false)).toBeFalsy();
expect(isDifferent('foo', 'foo', false)).toBeFalsy();
expect(isDifferent(1, 1, false)).toBeFalsy();
expect(isDifferent(obj, obj)).toBeFalsy();
expect(isDifferent('foo', 'foo')).toBeFalsy();
expect(isDifferent(1, 1)).toBeFalsy();
});
it('should not mark NaN as different',
() => { expect(isDifferent(NaN, NaN, false)).toBeFalsy(); });
it('should not mark NaN as different', () => { expect(isDifferent(NaN, NaN)).toBeFalsy(); });
it('should mark NaN with other values as different', () => {
expect(isDifferent(NaN, 'foo', false)).toBeTruthy();
expect(isDifferent(5, NaN, false)).toBeTruthy();
expect(isDifferent(NaN, 'foo')).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 {NgModuleFactory} from '../../src/render3/ng_module_ref';
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 {NgForOf} from '../../test/render3/common_with_def';
import {fixmeIvy} from '@angular/private/testing';
@ -2013,7 +2013,7 @@ describe('ViewContainerRef', () => {
element(1, 'div', ['bar', ''], ['foo', '']);
}
// testing only
fooEl = getNativeByIndex(1, getViewData());
fooEl = getNativeByIndex(1, getLView());
},
viewQuery: function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {

View File

@ -7,10 +7,14 @@
* 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 {sanitizeHtml, sanitizeResourceUrl, sanitizeScript, sanitizeStyle, sanitizeUrl} from '../../src/sanitization/sanitization';
describe('sanitization', () => {
beforeEach(() => setTNodeAndViewData(null !, [] as any));
afterEach(() => setTNodeAndViewData(null !, null !));
class Wrap {
constructor(private value: string) {}
toString() { return this.value; }