parent
f33dbf42fd
commit
d5b70e0c66
|
@ -14,7 +14,7 @@ import {Sanitizer} from '../sanitization/security';
|
||||||
|
|
||||||
import {assertComponentType, assertDefined} from './assert';
|
import {assertComponentType, assertDefined} from './assert';
|
||||||
import {queueInitHooks, queueLifecycleHooks} from './hooks';
|
import {queueInitHooks, queueLifecycleHooks} from './hooks';
|
||||||
import {CLEAN_PROMISE, ROOT_DIRECTIVE_INDICES, _getComponentHostLElementNode, baseDirectiveCreate, createLViewData, createTView, detectChangesInternal, enterView, executeInitAndContentHooks, getRootView, hostElement, initChangeDetectorIfExisting, leaveView, locateHostElement, setHostBindings,} from './instructions';
|
import {CLEAN_PROMISE, _getComponentHostLElementNode, baseDirectiveCreate, createLViewData, createTView, detectChangesInternal, enterView, executeInitAndContentHooks, getRootView, hostElement, initChangeDetectorIfExisting, leaveView, locateHostElement, setHostBindings, queueHostBindingForCheck,} from './instructions';
|
||||||
import {ComponentDef, ComponentDefInternal, ComponentType} from './interfaces/definition';
|
import {ComponentDef, ComponentDefInternal, ComponentType} from './interfaces/definition';
|
||||||
import {LElementNode} from './interfaces/node';
|
import {LElementNode} from './interfaces/node';
|
||||||
import {RElement, RendererFactory3, domRendererFactory3} from './interfaces/renderer';
|
import {RElement, RendererFactory3, domRendererFactory3} from './interfaces/renderer';
|
||||||
|
@ -122,6 +122,9 @@ export function renderComponent<T>(
|
||||||
|
|
||||||
// Create directive instance with factory() and store at index 0 in directives array
|
// Create directive instance with factory() and store at index 0 in directives array
|
||||||
component = baseDirectiveCreate(0, componentDef.factory() as T, componentDef);
|
component = baseDirectiveCreate(0, componentDef.factory() as T, componentDef);
|
||||||
|
if (componentDef.hostBindings) {
|
||||||
|
queueHostBindingForCheck(0, componentDef.hostVars);
|
||||||
|
}
|
||||||
rootContext.components.push(component);
|
rootContext.components.push(component);
|
||||||
(elementNode.data as LViewData)[CONTEXT] = component;
|
(elementNode.data as LViewData)[CONTEXT] = component;
|
||||||
initChangeDetectorIfExisting(elementNode.nodeInjector, component, elementNode.data !);
|
initChangeDetectorIfExisting(elementNode.nodeInjector, component, elementNode.data !);
|
||||||
|
@ -129,7 +132,7 @@ export function renderComponent<T>(
|
||||||
opts.hostFeatures && opts.hostFeatures.forEach((feature) => feature(component, componentDef));
|
opts.hostFeatures && opts.hostFeatures.forEach((feature) => feature(component, componentDef));
|
||||||
|
|
||||||
executeInitAndContentHooks();
|
executeInitAndContentHooks();
|
||||||
setHostBindings(ROOT_DIRECTIVE_INDICES);
|
setHostBindings(rootView[TVIEW].hostBindings);
|
||||||
detectChangesInternal(elementNode.data as LViewData, elementNode, component);
|
detectChangesInternal(elementNode.data as LViewData, elementNode, component);
|
||||||
} finally {
|
} finally {
|
||||||
leaveView(oldView);
|
leaveView(oldView);
|
||||||
|
|
|
@ -18,7 +18,7 @@ import {Type} from '../type';
|
||||||
|
|
||||||
import {assertComponentType, assertDefined} from './assert';
|
import {assertComponentType, assertDefined} from './assert';
|
||||||
import {LifecycleHooksFeature, createRootContext} from './component';
|
import {LifecycleHooksFeature, createRootContext} from './component';
|
||||||
import {baseDirectiveCreate, createLNode, createLViewData, createTView, elementCreate, enterView, hostElement, initChangeDetectorIfExisting, locateHostElement, renderEmbeddedTemplate} from './instructions';
|
import {adjustBlueprintForNewNode, baseDirectiveCreate, createLNode, createLViewData, createTView, elementCreate, enterView, hostElement, initChangeDetectorIfExisting, locateHostElement, renderEmbeddedTemplate} from './instructions';
|
||||||
import {ComponentDefInternal, ComponentType, RenderFlags} from './interfaces/definition';
|
import {ComponentDefInternal, ComponentType, RenderFlags} from './interfaces/definition';
|
||||||
import {LElementNode, TNode, TNodeType} from './interfaces/node';
|
import {LElementNode, TNode, TNodeType} from './interfaces/node';
|
||||||
import {RElement, RendererFactory3, domRendererFactory3} from './interfaces/renderer';
|
import {RElement, RendererFactory3, domRendererFactory3} from './interfaces/renderer';
|
||||||
|
@ -156,6 +156,7 @@ export class ComponentFactory<T> extends viewEngine_ComponentFactory<T> {
|
||||||
let firstTNode: TNode|null = null;
|
let firstTNode: TNode|null = null;
|
||||||
let previousTNode: TNode|null = null;
|
let previousTNode: TNode|null = null;
|
||||||
for (let j = 0; j < nodeList.length; j++) {
|
for (let j = 0; j < nodeList.length; j++) {
|
||||||
|
adjustBlueprintForNewNode(rootView);
|
||||||
const lNode =
|
const lNode =
|
||||||
createLNode(++index, TNodeType.Element, nodeList[j] as RElement, null, null);
|
createLNode(++index, TNodeType.Element, nodeList[j] as RElement, null, null);
|
||||||
if (previousTNode) {
|
if (previousTNode) {
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {assertEqual, assertLessThan} from './assert';
|
import {assertEqual, assertLessThan} from './assert';
|
||||||
import {NO_CHANGE, _getViewData, bindingUpdated, bindingUpdated2, bindingUpdated3, bindingUpdated4, createLNode, getPreviousOrParentNode, getRenderer, load, resetApplicationState} from './instructions';
|
import {NO_CHANGE, _getViewData, adjustBlueprintForNewNode, bindingUpdated, bindingUpdated2, bindingUpdated3, bindingUpdated4, createLNode, getPreviousOrParentNode, getRenderer, load, resetApplicationState} from './instructions';
|
||||||
import {RENDER_PARENT} from './interfaces/container';
|
import {RENDER_PARENT} from './interfaces/container';
|
||||||
import {LContainerNode, LNode, TContainerNode, TElementNode, TNodeType} from './interfaces/node';
|
import {LContainerNode, LNode, TContainerNode, TElementNode, TNodeType} from './interfaces/node';
|
||||||
import {BINDING_INDEX, HEADER_OFFSET, TVIEW} from './interfaces/view';
|
import {BINDING_INDEX, HEADER_OFFSET, TVIEW} from './interfaces/view';
|
||||||
|
@ -330,8 +330,10 @@ export function i18nApply(startIndex: number, instructions: I18nInstruction[]):
|
||||||
// If we were to only create a `RNode` then projections won't move the text.
|
// If we were to only create a `RNode` then projections won't move the text.
|
||||||
// Create text node at the current end of viewData. Must subtract header offset because
|
// Create text node at the current end of viewData. Must subtract header offset because
|
||||||
// createLNode takes a raw index (not adjusted by header offset).
|
// createLNode takes a raw index (not adjusted by header offset).
|
||||||
|
adjustBlueprintForNewNode(viewData);
|
||||||
|
const lastNodeIndex = viewData.length - 1;
|
||||||
const textLNode =
|
const textLNode =
|
||||||
createLNode(viewData.length - HEADER_OFFSET, TNodeType.Element, textRNode, null, null);
|
createLNode(lastNodeIndex - HEADER_OFFSET, TNodeType.Element, textRNode, null, null);
|
||||||
localPreviousNode = appendI18nNode(textLNode, localParentNode, localPreviousNode);
|
localPreviousNode = appendI18nNode(textLNode, localParentNode, localPreviousNode);
|
||||||
resetApplicationState();
|
resetApplicationState();
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -22,7 +22,7 @@ import {AttributeMarker, InitialInputData, InitialInputs, LContainerNode, LEleme
|
||||||
import {CssSelectorList, NG_PROJECT_AS_ATTR_NAME} from './interfaces/projection';
|
import {CssSelectorList, NG_PROJECT_AS_ATTR_NAME} from './interfaces/projection';
|
||||||
import {LQueries} from './interfaces/query';
|
import {LQueries} from './interfaces/query';
|
||||||
import {ProceduralRenderer3, RComment, RElement, RNode, RText, Renderer3, RendererFactory3, RendererStyleFlags3, isProceduralRenderer} from './interfaces/renderer';
|
import {ProceduralRenderer3, RComment, RElement, RNode, RText, Renderer3, RendererFactory3, RendererStyleFlags3, isProceduralRenderer} from './interfaces/renderer';
|
||||||
import {BINDING_INDEX, CLEANUP, CONTENT_QUERIES, CONTEXT, CurrentMatchesList, DECLARATION_VIEW, DIRECTIVES, FLAGS, HEADER_OFFSET, HOST_NODE, INJECTOR, LViewData, LViewFlags, NEXT, OpaqueViewState, PARENT, QUERIES, RENDERER, RootContext, SANITIZER, TAIL, TData, TVIEW, TView} from './interfaces/view';
|
import {BINDING_INDEX, CLEANUP, CONTAINER_INDEX, CONTENT_QUERIES, CONTEXT, CurrentMatchesList, DECLARATION_VIEW, DIRECTIVES, FLAGS, HEADER_OFFSET, HOST_NODE, INJECTOR, LViewData, LViewFlags, NEXT, OpaqueViewState, PARENT, QUERIES, RENDERER, RootContext, SANITIZER, TAIL, TData, TVIEW, TView} from './interfaces/view';
|
||||||
import {assertNodeOfPossibleTypes, assertNodeType} from './node_assert';
|
import {assertNodeOfPossibleTypes, assertNodeType} from './node_assert';
|
||||||
import {appendChild, appendProjectedNode, canInsertNativeNode, createTextNode, findComponentHost, getChildLNode, getLViewChild, getNextLNode, getParentLNode, insertView, removeView} from './node_manipulation';
|
import {appendChild, appendProjectedNode, canInsertNativeNode, createTextNode, findComponentHost, getChildLNode, getLViewChild, getNextLNode, getParentLNode, insertView, removeView} from './node_manipulation';
|
||||||
import {isNodeMatchingSelectorList, matchingSelectorIndex} from './node_selector_matcher';
|
import {isNodeMatchingSelectorList, matchingSelectorIndex} from './node_selector_matcher';
|
||||||
|
@ -48,17 +48,6 @@ const _CLEAN_PROMISE = Promise.resolve(null);
|
||||||
*/
|
*/
|
||||||
export type SanitizerFn = (value: any) => string;
|
export type SanitizerFn = (value: any) => string;
|
||||||
|
|
||||||
/**
|
|
||||||
* Directive and element indices for top-level directive.
|
|
||||||
*
|
|
||||||
* Saved here to avoid re-instantiating an array on every change detection run.
|
|
||||||
*
|
|
||||||
* Note: Element is not actually stored at index 0 because of the LViewData
|
|
||||||
* header, but the host bindings function expects an index that is NOT adjusted
|
|
||||||
* because it will ultimately be fed to instructions like elementProperty.
|
|
||||||
*/
|
|
||||||
const _ROOT_DIRECTIVE_INDICES = [0, 0];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TView.data needs to fill the same number of slots as the LViewData header
|
* TView.data needs to fill the same number of slots as the LViewData header
|
||||||
* so the indices of nodes are consistent between LViewData and TView.data.
|
* so the indices of nodes are consistent between LViewData and TView.data.
|
||||||
|
@ -346,7 +335,7 @@ export function setHostBindings(bindings: number[] | null): void {
|
||||||
for (let i = 0; i < bindings.length; i += 2) {
|
for (let i = 0; i < bindings.length; i += 2) {
|
||||||
const dirIndex = bindings[i];
|
const dirIndex = bindings[i];
|
||||||
const def = defs[dirIndex] as DirectiveDefInternal<any>;
|
const def = defs[dirIndex] as DirectiveDefInternal<any>;
|
||||||
def.hostBindings && def.hostBindings(dirIndex, bindings[i + 1]);
|
def.hostBindings !(dirIndex, bindings[i + 1]);
|
||||||
bindingRootIndex = viewData[BINDING_INDEX] = bindingRootIndex + def.hostVars;
|
bindingRootIndex = viewData[BINDING_INDEX] = bindingRootIndex + def.hostVars;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -383,26 +372,14 @@ export function executeInitAndContentHooks(): void {
|
||||||
export function createLViewData<T>(
|
export function createLViewData<T>(
|
||||||
renderer: Renderer3, tView: TView, context: T | null, flags: LViewFlags,
|
renderer: Renderer3, tView: TView, context: T | null, flags: LViewFlags,
|
||||||
sanitizer?: Sanitizer | null): LViewData {
|
sanitizer?: Sanitizer | null): LViewData {
|
||||||
// TODO(kara): create from blueprint
|
const instance = tView.blueprint.slice() as LViewData;
|
||||||
return [
|
instance[PARENT] = viewData;
|
||||||
tView, // tView
|
instance[FLAGS] = flags | LViewFlags.CreationMode | LViewFlags.Attached | LViewFlags.RunInit;
|
||||||
viewData, // parent
|
instance[CONTEXT] = context;
|
||||||
null, // next
|
instance[INJECTOR] = viewData ? viewData[INJECTOR] : null;
|
||||||
null, // queries
|
instance[RENDERER] = renderer;
|
||||||
flags | LViewFlags.CreationMode | LViewFlags.Attached | LViewFlags.RunInit, // flags
|
instance[SANITIZER] = sanitizer || null;
|
||||||
null !, // hostNode
|
return instance;
|
||||||
tView.bindingStartIndex, // bindingIndex
|
|
||||||
null, // directives
|
|
||||||
null, // cleanupInstances
|
|
||||||
context, // context
|
|
||||||
viewData ? viewData[INJECTOR] : null, // injector
|
|
||||||
renderer, // renderer
|
|
||||||
sanitizer || null, // sanitizer
|
|
||||||
null, // tail
|
|
||||||
-1, // containerIndex
|
|
||||||
null, // contentQueries
|
|
||||||
null // declarationView
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -474,13 +451,13 @@ export function createLNode(
|
||||||
const adjustedIndex = index + HEADER_OFFSET;
|
const adjustedIndex = index + HEADER_OFFSET;
|
||||||
|
|
||||||
// This is an element or container or projection node
|
// This is an element or container or projection node
|
||||||
ngDevMode && assertDataNext(adjustedIndex);
|
|
||||||
const tData = tView.data;
|
const tData = tView.data;
|
||||||
|
ngDevMode && assertLessThan(
|
||||||
|
adjustedIndex, viewData.length, `Slot should have been initialized with null`);
|
||||||
|
|
||||||
viewData[adjustedIndex] = node;
|
viewData[adjustedIndex] = node;
|
||||||
|
|
||||||
// Every node adds a value to the static data array to avoid a sparse array
|
if (tData[adjustedIndex] == null) {
|
||||||
if (adjustedIndex >= tData.length) {
|
|
||||||
const tNode = tData[adjustedIndex] =
|
const tNode = tData[adjustedIndex] =
|
||||||
createTNode(type, adjustedIndex, name, attrs, tParent, null);
|
createTNode(type, adjustedIndex, name, attrs, tParent, null);
|
||||||
if (!isParent && previousOrParentNode) {
|
if (!isParent && previousOrParentNode) {
|
||||||
|
@ -504,8 +481,9 @@ export function createLNode(
|
||||||
// View nodes and host elements need to set their host node (components set host nodes later)
|
// View nodes and host elements need to set their host node (components set host nodes later)
|
||||||
if ((type & TNodeType.ViewOrElement) === TNodeType.ViewOrElement && isState) {
|
if ((type & TNodeType.ViewOrElement) === TNodeType.ViewOrElement && isState) {
|
||||||
const lViewData = state as LViewData;
|
const lViewData = state as LViewData;
|
||||||
ngDevMode && assertNotDefined(
|
ngDevMode &&
|
||||||
lViewData[HOST_NODE], 'lViewData[HOST_NODE] should not have been initialized');
|
assertEqual(
|
||||||
|
lViewData[HOST_NODE], null, 'lViewData[HOST_NODE] should not have been initialized');
|
||||||
lViewData[HOST_NODE] = node;
|
lViewData[HOST_NODE] = node;
|
||||||
if (firstTemplatePass) lViewData[TVIEW].node = node.tNode;
|
if (firstTemplatePass) lViewData[TVIEW].node = node.tNode;
|
||||||
}
|
}
|
||||||
|
@ -515,6 +493,20 @@ export function createLNode(
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When LNodes are created dynamically after a view blueprint is created (e.g. through
|
||||||
|
* i18nApply() or ComponentFactory.create), we need to adjust the blueprint for future
|
||||||
|
* template passes.
|
||||||
|
*/
|
||||||
|
export function adjustBlueprintForNewNode(view: LViewData) {
|
||||||
|
const tView = view[TVIEW];
|
||||||
|
if (tView.firstTemplatePass) {
|
||||||
|
tView.hostBindingStartIndex++;
|
||||||
|
tView.blueprint.push(null);
|
||||||
|
view.push(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////
|
//////////////////////////
|
||||||
//// Render
|
//// Render
|
||||||
|
@ -664,7 +656,7 @@ export function renderComponentOrTemplate<T>(
|
||||||
|
|
||||||
// Element was stored at 0 in data and directive was stored at 0 in directives
|
// Element was stored at 0 in data and directive was stored at 0 in directives
|
||||||
// in renderComponent()
|
// in renderComponent()
|
||||||
setHostBindings(_ROOT_DIRECTIVE_INDICES);
|
setHostBindings(tView.hostBindings);
|
||||||
componentRefresh(HEADER_OFFSET);
|
componentRefresh(HEADER_OFFSET);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -910,19 +902,23 @@ export function resolveDirective(
|
||||||
/** Stores index of component's host element so it will be queued for view refresh during CD. */
|
/** Stores index of component's host element so it will be queued for view refresh during CD. */
|
||||||
function queueComponentIndexForCheck(): void {
|
function queueComponentIndexForCheck(): void {
|
||||||
if (firstTemplatePass) {
|
if (firstTemplatePass) {
|
||||||
(tView.components || (tView.components = [])).push(viewData.length - 1);
|
(tView.components || (tView.components = [])).push(previousOrParentNode.tNode.index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Stores index of directive and host element so it will be queued for binding refresh during CD.
|
/** Stores index of directive and host element so it will be queued for binding refresh during CD.
|
||||||
*/
|
*/
|
||||||
function queueHostBindingForCheck(dirIndex: number): void {
|
export function queueHostBindingForCheck(dirIndex: number, hostVars: number): void {
|
||||||
// Must subtract the header offset because hostBindings functions are generated with
|
// Must subtract the header offset because hostBindings functions are generated with
|
||||||
// instructions that expect element indices that are NOT adjusted (e.g. elementProperty).
|
// instructions that expect element indices that are NOT adjusted (e.g. elementProperty).
|
||||||
ngDevMode &&
|
ngDevMode &&
|
||||||
assertEqual(firstTemplatePass, true, 'Should only be called in first template pass.');
|
assertEqual(firstTemplatePass, true, 'Should only be called in first template pass.');
|
||||||
|
for (let i = 0; i < hostVars; i++) {
|
||||||
|
tView.blueprint.push(NO_CHANGE);
|
||||||
|
viewData.push(NO_CHANGE);
|
||||||
|
}
|
||||||
(tView.hostBindings || (tView.hostBindings = [
|
(tView.hostBindings || (tView.hostBindings = [
|
||||||
])).push(dirIndex, viewData.length - 1 - HEADER_OFFSET);
|
])).push(dirIndex, previousOrParentNode.tNode.index - HEADER_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the context for a ChangeDetectorRef to the given instance. */
|
/** Sets the context for a ChangeDetectorRef to the given instance. */
|
||||||
|
@ -1005,10 +1001,11 @@ function saveResolvedLocalsInData(
|
||||||
lNode: LNodeWithLocalRefs, localRefExtractor: LocalRefExtractor): void {
|
lNode: LNodeWithLocalRefs, localRefExtractor: LocalRefExtractor): void {
|
||||||
const localNames = lNode.tNode.localNames;
|
const localNames = lNode.tNode.localNames;
|
||||||
if (localNames) {
|
if (localNames) {
|
||||||
|
let localIndex = lNode.tNode.index + 1;
|
||||||
for (let i = 0; i < localNames.length; i += 2) {
|
for (let i = 0; i < localNames.length; i += 2) {
|
||||||
const index = localNames[i + 1] as number;
|
const index = localNames[i + 1] as number;
|
||||||
const value = index === -1 ? localRefExtractor(lNode) : directives ![index];
|
const value = index === -1 ? localRefExtractor(lNode) : directives ![index];
|
||||||
viewData.push(value);
|
viewData[localIndex++] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1055,15 +1052,21 @@ export function createTView(
|
||||||
viewQuery: ComponentQuery<any>| null): TView {
|
viewQuery: ComponentQuery<any>| null): TView {
|
||||||
ngDevMode && ngDevMode.tView++;
|
ngDevMode && ngDevMode.tView++;
|
||||||
const bindingStartIndex = HEADER_OFFSET + consts;
|
const bindingStartIndex = HEADER_OFFSET + consts;
|
||||||
return {
|
// This length does not yet contain host bindings from child directives because at this point,
|
||||||
|
// we don't know which directives are active on this template. As soon as a directive is matched
|
||||||
|
// that has a host binding, we will update the blueprint with that def's hostVars count.
|
||||||
|
const initialViewLength = bindingStartIndex + vars;
|
||||||
|
const blueprint = createViewBlueprint(bindingStartIndex, initialViewLength);
|
||||||
|
return blueprint[TVIEW] = {
|
||||||
id: viewIndex,
|
id: viewIndex,
|
||||||
|
blueprint: blueprint,
|
||||||
template: templateFn,
|
template: templateFn,
|
||||||
viewQuery: viewQuery,
|
viewQuery: viewQuery,
|
||||||
node: null !,
|
node: null !,
|
||||||
data: HEADER_FILLER.slice(), // Fill in to match HEADER_OFFSET in LViewData
|
data: HEADER_FILLER.slice(), // Fill in to match HEADER_OFFSET in LViewData
|
||||||
childIndex: -1, // Children set in addToViewTree(), if any
|
childIndex: -1, // Children set in addToViewTree(), if any
|
||||||
bindingStartIndex: bindingStartIndex,
|
bindingStartIndex: bindingStartIndex,
|
||||||
hostBindingStartIndex: bindingStartIndex + vars,
|
hostBindingStartIndex: initialViewLength,
|
||||||
directives: null,
|
directives: null,
|
||||||
firstTemplatePass: true,
|
firstTemplatePass: true,
|
||||||
initHooks: null,
|
initHooks: null,
|
||||||
|
@ -1084,6 +1087,15 @@ export function createTView(
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createViewBlueprint(bindingStartIndex: number, initialViewLength: number): LViewData {
|
||||||
|
const blueprint = new Array(initialViewLength)
|
||||||
|
.fill(null, 0, bindingStartIndex)
|
||||||
|
.fill(NO_CHANGE, bindingStartIndex) as LViewData;
|
||||||
|
blueprint[CONTAINER_INDEX] = -1;
|
||||||
|
blueprint[BINDING_INDEX] = bindingStartIndex;
|
||||||
|
return blueprint;
|
||||||
|
}
|
||||||
|
|
||||||
function setUpAttributes(native: RElement, attrs: TAttributes): void {
|
function setUpAttributes(native: RElement, attrs: TAttributes): void {
|
||||||
const isProc = isProceduralRenderer(renderer);
|
const isProc = isProceduralRenderer(renderer);
|
||||||
let i = 0;
|
let i = 0;
|
||||||
|
@ -1680,7 +1692,7 @@ export function directiveCreate<T>(
|
||||||
// any projected components.
|
// any projected components.
|
||||||
queueInitHooks(directiveDefIdx, directiveDef.onInit, directiveDef.doCheck, tView);
|
queueInitHooks(directiveDefIdx, directiveDef.onInit, directiveDef.doCheck, tView);
|
||||||
|
|
||||||
if (directiveDef.hostBindings) queueHostBindingForCheck(directiveDefIdx);
|
if (directiveDef.hostBindings) queueHostBindingForCheck(directiveDefIdx, directiveDef.hostVars);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tNode && tNode.attrs) {
|
if (tNode && tNode.attrs) {
|
||||||
|
@ -2758,8 +2770,10 @@ export function getBinding(bindingIndex: number): any {
|
||||||
/** Updates binding if changed, then returns whether it was updated. */
|
/** Updates binding if changed, then returns whether it was updated. */
|
||||||
export function bindingUpdated(bindingIndex: number, value: any): boolean {
|
export function bindingUpdated(bindingIndex: number, value: any): boolean {
|
||||||
ngDevMode && assertNotEqual(value, NO_CHANGE, 'Incoming value should never be NO_CHANGE.');
|
ngDevMode && assertNotEqual(value, NO_CHANGE, 'Incoming value should never be NO_CHANGE.');
|
||||||
|
ngDevMode && assertLessThan(
|
||||||
|
bindingIndex, viewData.length, `Slot should have been initialized to NO_CHANGE`);
|
||||||
|
|
||||||
if (bindingIndex >= viewData.length) {
|
if (viewData[bindingIndex] === NO_CHANGE) {
|
||||||
viewData[bindingIndex] = value;
|
viewData[bindingIndex] = value;
|
||||||
} else if (isDifferent(viewData[bindingIndex], value, checkNoChangesMode)) {
|
} else if (isDifferent(viewData[bindingIndex], value, checkNoChangesMode)) {
|
||||||
throwErrorIfNoChangesMode(creationMode, checkNoChangesMode, viewData[bindingIndex], value);
|
throwErrorIfNoChangesMode(creationMode, checkNoChangesMode, viewData[bindingIndex], value);
|
||||||
|
@ -2843,4 +2857,3 @@ export function _getComponentHostLElementNode<T>(component: T): LElementNode {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const CLEAN_PROMISE = _CLEAN_PROMISE;
|
export const CLEAN_PROMISE = _CLEAN_PROMISE;
|
||||||
export const ROOT_DIRECTIVE_INDICES = _ROOT_DIRECTIVE_INDICES;
|
|
||||||
|
|
|
@ -253,6 +253,12 @@ export interface TView {
|
||||||
*/
|
*/
|
||||||
readonly id: number;
|
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.
|
||||||
|
*/
|
||||||
|
blueprint: LViewData;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The template function used to refresh the view of dynamically created views
|
* The template function used to refresh the view of dynamically created views
|
||||||
* and components. Will be null for inline views.
|
* and components. Will be null for inline views.
|
||||||
|
|
|
@ -56,6 +56,9 @@
|
||||||
{
|
{
|
||||||
"name": "NG_PROJECT_AS_ATTR_NAME"
|
"name": "NG_PROJECT_AS_ATTR_NAME"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "NO_CHANGE"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "PARENT"
|
"name": "PARENT"
|
||||||
},
|
},
|
||||||
|
@ -72,7 +75,7 @@
|
||||||
"name": "RENDER_PARENT"
|
"name": "RENDER_PARENT"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ROOT_DIRECTIVE_INDICES"
|
"name": "SANITIZER"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "TVIEW"
|
"name": "TVIEW"
|
||||||
|
@ -83,9 +86,6 @@
|
||||||
{
|
{
|
||||||
"name": "_CLEAN_PROMISE"
|
"name": "_CLEAN_PROMISE"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "_ROOT_DIRECTIVE_INDICES"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "_getComponentHostLElementNode"
|
"name": "_getComponentHostLElementNode"
|
||||||
},
|
},
|
||||||
|
@ -143,6 +143,9 @@
|
||||||
{
|
{
|
||||||
"name": "createTextNode"
|
"name": "createTextNode"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "createViewBlueprint"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "createViewQuery"
|
"name": "createViewQuery"
|
||||||
},
|
},
|
||||||
|
@ -239,6 +242,9 @@
|
||||||
{
|
{
|
||||||
"name": "nextNgElementId"
|
"name": "nextNgElementId"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "queueHostBindingForCheck"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "readElementValue"
|
"name": "readElementValue"
|
||||||
},
|
},
|
||||||
|
|
|
@ -131,9 +131,6 @@
|
||||||
{
|
{
|
||||||
"name": "RENDER_PARENT"
|
"name": "RENDER_PARENT"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "ROOT_DIRECTIVE_INDICES"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "RecordViewTuple"
|
"name": "RecordViewTuple"
|
||||||
},
|
},
|
||||||
|
@ -203,9 +200,6 @@
|
||||||
{
|
{
|
||||||
"name": "_DuplicateMap"
|
"name": "_DuplicateMap"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "_ROOT_DIRECTIVE_INDICES"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "_THROW_IF_NOT_FOUND"
|
"name": "_THROW_IF_NOT_FOUND"
|
||||||
},
|
},
|
||||||
|
@ -413,6 +407,9 @@
|
||||||
{
|
{
|
||||||
"name": "createTextNode"
|
"name": "createTextNode"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "createViewBlueprint"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "createViewQuery"
|
"name": "createViewQuery"
|
||||||
},
|
},
|
||||||
|
|
|
@ -105,7 +105,7 @@ describe('change detection', () => {
|
||||||
selectors: [['my-comp']],
|
selectors: [['my-comp']],
|
||||||
factory: () => comp = new MyComponent(),
|
factory: () => comp = new MyComponent(),
|
||||||
consts: 2,
|
consts: 2,
|
||||||
vars: 1,
|
vars: 2,
|
||||||
/**
|
/**
|
||||||
* {{ doCheckCount }} - {{ name }}
|
* {{ doCheckCount }} - {{ name }}
|
||||||
* <button (click)="onClick()"></button>
|
* <button (click)="onClick()"></button>
|
||||||
|
|
|
@ -109,7 +109,7 @@ describe('@angular/common integration', () => {
|
||||||
template: (rf: RenderFlags, ctx: MyApp) => {
|
template: (rf: RenderFlags, ctx: MyApp) => {
|
||||||
if (rf & RenderFlags.Create) {
|
if (rf & RenderFlags.Create) {
|
||||||
elementStart(0, 'ul');
|
elementStart(0, 'ul');
|
||||||
{ template(1, liTemplate, 2, 1, undefined, ['ngForOf', '']); }
|
{ template(1, liTemplate, 2, 3, undefined, ['ngForOf', '']); }
|
||||||
elementEnd();
|
elementEnd();
|
||||||
}
|
}
|
||||||
if (rf & RenderFlags.Update) {
|
if (rf & RenderFlags.Update) {
|
||||||
|
@ -246,7 +246,7 @@ describe('@angular/common integration', () => {
|
||||||
function liTemplate(rf: RenderFlags, ctx: any) {
|
function liTemplate(rf: RenderFlags, ctx: any) {
|
||||||
if (rf & RenderFlags.Create) {
|
if (rf & RenderFlags.Create) {
|
||||||
elementStart(0, 'li');
|
elementStart(0, 'li');
|
||||||
{ template(1, spanTemplate, 2, 1, null, ['ngForOf', '']); }
|
{ template(1, spanTemplate, 2, 3, null, ['ngForOf', '']); }
|
||||||
elementEnd();
|
elementEnd();
|
||||||
}
|
}
|
||||||
if (rf & RenderFlags.Update) {
|
if (rf & RenderFlags.Update) {
|
||||||
|
@ -335,7 +335,7 @@ describe('@angular/common integration', () => {
|
||||||
function divTemplate(rf: RenderFlags, ctx: any) {
|
function divTemplate(rf: RenderFlags, ctx: any) {
|
||||||
if (rf & RenderFlags.Create) {
|
if (rf & RenderFlags.Create) {
|
||||||
elementStart(0, 'div');
|
elementStart(0, 'div');
|
||||||
{ template(1, pTemplate, 3, 1, null, ['ngForOf', '']); }
|
{ template(1, pTemplate, 3, 2, null, ['ngForOf', '']); }
|
||||||
elementEnd();
|
elementEnd();
|
||||||
}
|
}
|
||||||
if (rf & RenderFlags.Update) {
|
if (rf & RenderFlags.Update) {
|
||||||
|
@ -441,7 +441,7 @@ describe('@angular/common integration', () => {
|
||||||
function innerDivTemplate(rf: RenderFlags, ctx: any) {
|
function innerDivTemplate(rf: RenderFlags, ctx: any) {
|
||||||
if (rf & RenderFlags.Create) {
|
if (rf & RenderFlags.Create) {
|
||||||
elementStart(0, 'div');
|
elementStart(0, 'div');
|
||||||
{ template(1, spanTemplate, 2, 1, null, ['ngForOf', '']); }
|
{ template(1, spanTemplate, 2, 2, null, ['ngForOf', '']); }
|
||||||
elementEnd();
|
elementEnd();
|
||||||
}
|
}
|
||||||
if (rf & RenderFlags.Update) {
|
if (rf & RenderFlags.Update) {
|
||||||
|
@ -681,7 +681,7 @@ describe('@angular/common integration', () => {
|
||||||
function itemTemplate7(rf: RenderFlags, ctx: any) {
|
function itemTemplate7(rf: RenderFlags, ctx: any) {
|
||||||
if (rf & RenderFlags.Create) {
|
if (rf & RenderFlags.Create) {
|
||||||
elementStart(0, 'span');
|
elementStart(0, 'span');
|
||||||
{ template(1, itemTemplate8, 2, 1, null, ['ngForOf', '']); }
|
{ template(1, itemTemplate8, 2, 10, null, ['ngForOf', '']); }
|
||||||
elementEnd();
|
elementEnd();
|
||||||
}
|
}
|
||||||
if (rf & RenderFlags.Update) {
|
if (rf & RenderFlags.Update) {
|
||||||
|
|
|
@ -103,6 +103,7 @@ describe('components & directives', () => {
|
||||||
type: HostBindingDir,
|
type: HostBindingDir,
|
||||||
selectors: [['', 'hostBindingDir', '']],
|
selectors: [['', 'hostBindingDir', '']],
|
||||||
factory: function HostBindingDir_Factory() { return new HostBindingDir(); },
|
factory: function HostBindingDir_Factory() { return new HostBindingDir(); },
|
||||||
|
hostVars: 1,
|
||||||
hostBindings: function HostBindingDir_HostBindings(dirIndex: $number$, elIndex: $number$) {
|
hostBindings: function HostBindingDir_HostBindings(dirIndex: $number$, elIndex: $number$) {
|
||||||
$r3$.ɵelementProperty(
|
$r3$.ɵelementProperty(
|
||||||
elIndex, 'id', $r3$.ɵbind($r3$.ɵloadDirective<HostBindingDir>(dirIndex).dirId));
|
elIndex, 'id', $r3$.ɵbind($r3$.ɵloadDirective<HostBindingDir>(dirIndex).dirId));
|
||||||
|
@ -256,6 +257,7 @@ describe('components & directives', () => {
|
||||||
type: HostBindingDir,
|
type: HostBindingDir,
|
||||||
selectors: [['', 'hostBindingDir', '']],
|
selectors: [['', 'hostBindingDir', '']],
|
||||||
factory: function HostBindingDir_Factory() { return new HostBindingDir(); },
|
factory: function HostBindingDir_Factory() { return new HostBindingDir(); },
|
||||||
|
hostVars: 1,
|
||||||
hostBindings: function HostBindingDir_HostBindings(dirIndex: $number$, elIndex: $number$) {
|
hostBindings: function HostBindingDir_HostBindings(dirIndex: $number$, elIndex: $number$) {
|
||||||
$r3$.ɵelementAttribute(
|
$r3$.ɵelementAttribute(
|
||||||
elIndex, 'aria-label',
|
elIndex, 'aria-label',
|
||||||
|
@ -446,7 +448,7 @@ describe('components & directives', () => {
|
||||||
selectors: [['my-array-comp']],
|
selectors: [['my-array-comp']],
|
||||||
factory: function MyArrayComp_Factory() { return new MyArrayComp(); },
|
factory: function MyArrayComp_Factory() { return new MyArrayComp(); },
|
||||||
consts: 1,
|
consts: 1,
|
||||||
vars: 1,
|
vars: 2,
|
||||||
template: function MyArrayComp_Template(rf: $RenderFlags$, ctx: $MyArrayComp$) {
|
template: function MyArrayComp_Template(rf: $RenderFlags$, ctx: $MyArrayComp$) {
|
||||||
if (rf & 1) {
|
if (rf & 1) {
|
||||||
$r3$.ɵtext(0);
|
$r3$.ɵtext(0);
|
||||||
|
@ -479,7 +481,7 @@ describe('components & directives', () => {
|
||||||
selectors: [['my-app']],
|
selectors: [['my-app']],
|
||||||
factory: function MyApp_Factory() { return new MyApp(); },
|
factory: function MyApp_Factory() { return new MyApp(); },
|
||||||
consts: 1,
|
consts: 1,
|
||||||
vars: 1,
|
vars: 0,
|
||||||
template: function MyApp_Template(rf: $RenderFlags$, ctx: $MyApp$) {
|
template: function MyApp_Template(rf: $RenderFlags$, ctx: $MyApp$) {
|
||||||
if (rf & 1) {
|
if (rf & 1) {
|
||||||
$r3$.ɵelement(0, 'my-array-comp');
|
$r3$.ɵelement(0, 'my-array-comp');
|
||||||
|
|
|
@ -91,7 +91,7 @@ describe('elements', () => {
|
||||||
selectors: [['local-ref-comp']],
|
selectors: [['local-ref-comp']],
|
||||||
factory: function LocalRefComp_Factory() { return new LocalRefComp(); },
|
factory: function LocalRefComp_Factory() { return new LocalRefComp(); },
|
||||||
consts: 4,
|
consts: 4,
|
||||||
vars: 1,
|
vars: 2,
|
||||||
template: function LocalRefComp_Template(rf: $RenderFlags$, ctx: $LocalRefComp$) {
|
template: function LocalRefComp_Template(rf: $RenderFlags$, ctx: $LocalRefComp$) {
|
||||||
if (rf & 1) {
|
if (rf & 1) {
|
||||||
$r3$.ɵelement(0, 'div', $e0_attrs$, $e0_locals$);
|
$r3$.ɵelement(0, 'div', $e0_attrs$, $e0_locals$);
|
||||||
|
@ -135,7 +135,7 @@ describe('elements', () => {
|
||||||
type: ListenerComp,
|
type: ListenerComp,
|
||||||
selectors: [['listener-comp']],
|
selectors: [['listener-comp']],
|
||||||
factory: function ListenerComp_Factory() { return new ListenerComp(); },
|
factory: function ListenerComp_Factory() { return new ListenerComp(); },
|
||||||
consts: 1,
|
consts: 2,
|
||||||
vars: 0,
|
vars: 0,
|
||||||
template: function ListenerComp_Template(rf: $RenderFlags$, ctx: $ListenerComp$) {
|
template: function ListenerComp_Template(rf: $RenderFlags$, ctx: $ListenerComp$) {
|
||||||
if (rf & 1) {
|
if (rf & 1) {
|
||||||
|
|
|
@ -276,7 +276,7 @@ describe('encapsulation', () => {
|
||||||
static ngComponentDef = defineComponent({
|
static ngComponentDef = defineComponent({
|
||||||
type: LeafComponentwith,
|
type: LeafComponentwith,
|
||||||
selectors: [['leaf']],
|
selectors: [['leaf']],
|
||||||
consts: 1,
|
consts: 2,
|
||||||
vars: 0,
|
vars: 0,
|
||||||
template: function(rf: RenderFlags, ctx: LeafComponentwith) {
|
template: function(rf: RenderFlags, ctx: LeafComponentwith) {
|
||||||
if (rf & RenderFlags.Create) {
|
if (rf & RenderFlags.Create) {
|
||||||
|
|
|
@ -828,7 +828,7 @@ describe('di', () => {
|
||||||
const tmp2 = reference(2) as any;
|
const tmp2 = reference(2) as any;
|
||||||
textBinding(3, interpolation2('', tmp2.value, '-', tmp1.value, ''));
|
textBinding(3, interpolation2('', tmp2.value, '-', tmp1.value, ''));
|
||||||
}
|
}
|
||||||
}, 4, 1, [Directive, DirectiveSameInstance]);
|
}, 4, 2, [Directive, DirectiveSameInstance]);
|
||||||
|
|
||||||
const fixture = new ComponentFixture(App);
|
const fixture = new ComponentFixture(App);
|
||||||
expect(fixture.html).toEqual('<div dir="" dirsame="">ElementRef-true</div>');
|
expect(fixture.html).toEqual('<div dir="" dirsame="">ElementRef-true</div>');
|
||||||
|
@ -872,7 +872,7 @@ describe('di', () => {
|
||||||
const App = createComponent('app', function(rf: RenderFlags, ctx: any) {
|
const App = createComponent('app', function(rf: RenderFlags, ctx: any) {
|
||||||
if (rf & RenderFlags.Create) {
|
if (rf & RenderFlags.Create) {
|
||||||
template(0, function() {
|
template(0, function() {
|
||||||
}, 0, 1, undefined, ['dir', '', 'dirSame', ''], ['dir', 'dir', 'dirSame', 'dirSame']);
|
}, 0, 0, undefined, ['dir', '', 'dirSame', ''], ['dir', 'dir', 'dirSame', 'dirSame']);
|
||||||
text(3);
|
text(3);
|
||||||
}
|
}
|
||||||
if (rf & RenderFlags.Update) {
|
if (rf & RenderFlags.Update) {
|
||||||
|
@ -880,7 +880,7 @@ describe('di', () => {
|
||||||
const tmp2 = reference(2) as any;
|
const tmp2 = reference(2) as any;
|
||||||
textBinding(3, interpolation2('', tmp1.value, '-', tmp2.value, ''));
|
textBinding(3, interpolation2('', tmp1.value, '-', tmp2.value, ''));
|
||||||
}
|
}
|
||||||
}, 4, 1, [Directive, DirectiveSameInstance]);
|
}, 4, 2, [Directive, DirectiveSameInstance]);
|
||||||
|
|
||||||
const fixture = new ComponentFixture(App);
|
const fixture = new ComponentFixture(App);
|
||||||
expect(fixture.html).toEqual('TemplateRef-true');
|
expect(fixture.html).toEqual('TemplateRef-true');
|
||||||
|
@ -933,7 +933,7 @@ describe('di', () => {
|
||||||
const tmp2 = reference(2) as any;
|
const tmp2 = reference(2) as any;
|
||||||
textBinding(3, interpolation2('', tmp1.value, '-', tmp2.value, ''));
|
textBinding(3, interpolation2('', tmp1.value, '-', tmp2.value, ''));
|
||||||
}
|
}
|
||||||
}, 4, 1, [Directive, DirectiveSameInstance]);
|
}, 4, 2, [Directive, DirectiveSameInstance]);
|
||||||
|
|
||||||
const fixture = new ComponentFixture(App);
|
const fixture = new ComponentFixture(App);
|
||||||
expect(fixture.html).toEqual('<div dir="" dirsame="">ViewContainerRef-true</div>');
|
expect(fixture.html).toEqual('<div dir="" dirsame="">ViewContainerRef-true</div>');
|
||||||
|
@ -1217,7 +1217,7 @@ describe('di', () => {
|
||||||
exist = injectAttribute('exist');
|
exist = injectAttribute('exist');
|
||||||
nonExist = injectAttribute('nonExist');
|
nonExist = injectAttribute('nonExist');
|
||||||
}
|
}
|
||||||
});
|
}, 1);
|
||||||
|
|
||||||
new ComponentFixture(MyApp);
|
new ComponentFixture(MyApp);
|
||||||
expect(exist).toEqual('existValue');
|
expect(exist).toEqual('existValue');
|
||||||
|
@ -1376,7 +1376,7 @@ describe('di', () => {
|
||||||
if (rf & RenderFlags.Update) {
|
if (rf & RenderFlags.Update) {
|
||||||
containerRefreshStart(1);
|
containerRefreshStart(1);
|
||||||
{
|
{
|
||||||
let rf1 = embeddedViewStart(0, 4, 1);
|
let rf1 = embeddedViewStart(0, 4, 2);
|
||||||
if (rf1 & RenderFlags.Create) {
|
if (rf1 & RenderFlags.Create) {
|
||||||
elementStart(
|
elementStart(
|
||||||
0, 'span', ['childDir', '', 'child2Dir', ''],
|
0, 'span', ['childDir', '', 'child2Dir', ''],
|
||||||
|
@ -1408,7 +1408,7 @@ describe('di', () => {
|
||||||
describe('getOrCreateNodeInjector', () => {
|
describe('getOrCreateNodeInjector', () => {
|
||||||
it('should handle initial undefined state', () => {
|
it('should handle initial undefined state', () => {
|
||||||
const contentView = createLViewData(
|
const contentView = createLViewData(
|
||||||
null !, createTView(-1, null, 0, 0, null, null, null), null, LViewFlags.CheckAlways);
|
null !, createTView(-1, null, 1, 0, null, null, null), null, LViewFlags.CheckAlways);
|
||||||
const oldView = enterView(contentView, null !);
|
const oldView = enterView(contentView, null !);
|
||||||
try {
|
try {
|
||||||
const parent = createLNode(0, TNodeType.Element, null, null, null, null);
|
const parent = createLNode(0, TNodeType.Element, null, null, null, null);
|
||||||
|
|
|
@ -365,7 +365,7 @@ describe('exports', () => {
|
||||||
if (rf & RenderFlags.Create) {
|
if (rf & RenderFlags.Create) {
|
||||||
elementStart(0, 'input', ['value', 'one'], ['outerInput', '']);
|
elementStart(0, 'input', ['value', 'one'], ['outerInput', '']);
|
||||||
elementEnd();
|
elementEnd();
|
||||||
template(2, outerTemplate, 5, 0, '', [AttributeMarker.SelectOnly, 'ngIf']);
|
template(2, outerTemplate, 5, 2, '', [AttributeMarker.SelectOnly, 'ngIf']);
|
||||||
}
|
}
|
||||||
if (rf & RenderFlags.Update) {
|
if (rf & RenderFlags.Update) {
|
||||||
elementProperty(2, 'ngIf', bind(app.outer));
|
elementProperty(2, 'ngIf', bind(app.outer));
|
||||||
|
@ -379,7 +379,7 @@ describe('exports', () => {
|
||||||
text(1);
|
text(1);
|
||||||
elementStart(2, 'input', ['value', 'two'], ['innerInput', '']);
|
elementStart(2, 'input', ['value', 'two'], ['innerInput', '']);
|
||||||
elementEnd();
|
elementEnd();
|
||||||
template(4, innerTemplate, 2, 1, '', [AttributeMarker.SelectOnly, 'ngIf']);
|
template(4, innerTemplate, 2, 2, '', [AttributeMarker.SelectOnly, 'ngIf']);
|
||||||
}
|
}
|
||||||
elementEnd();
|
elementEnd();
|
||||||
}
|
}
|
||||||
|
|
|
@ -196,7 +196,7 @@ describe('Runtime i18n', () => {
|
||||||
factory: () => new MyApp(),
|
factory: () => new MyApp(),
|
||||||
selectors: [['my-app']],
|
selectors: [['my-app']],
|
||||||
consts: 1,
|
consts: 1,
|
||||||
vars: 1,
|
vars: 2,
|
||||||
// Initial template:
|
// Initial template:
|
||||||
// <div i18n i18n-title title="{{exp1}}{{exp2}}"></div>
|
// <div i18n i18n-title title="{{exp1}}{{exp2}}"></div>
|
||||||
|
|
||||||
|
@ -1199,7 +1199,7 @@ describe('Runtime i18n', () => {
|
||||||
selectors: [['parent']],
|
selectors: [['parent']],
|
||||||
directives: [Child],
|
directives: [Child],
|
||||||
factory: () => new Parent(),
|
factory: () => new Parent(),
|
||||||
consts: 4,
|
consts: 7,
|
||||||
vars: 2,
|
vars: 2,
|
||||||
template: (rf: RenderFlags, cmp: Parent) => {
|
template: (rf: RenderFlags, cmp: Parent) => {
|
||||||
if (rf & RenderFlags.Create) {
|
if (rf & RenderFlags.Create) {
|
||||||
|
@ -1512,7 +1512,7 @@ describe('Runtime i18n', () => {
|
||||||
factory: () => new MyApp(),
|
factory: () => new MyApp(),
|
||||||
selectors: [['my-app']],
|
selectors: [['my-app']],
|
||||||
consts: 1,
|
consts: 1,
|
||||||
vars: 1,
|
vars: 4,
|
||||||
// Initial template:
|
// Initial template:
|
||||||
// <div i18n i18n-title title="{{exp1}}{{exp2}}"></div>
|
// <div i18n i18n-title title="{{exp1}}{{exp2}}"></div>
|
||||||
|
|
||||||
|
@ -1550,7 +1550,7 @@ describe('Runtime i18n', () => {
|
||||||
factory: () => new MyApp(),
|
factory: () => new MyApp(),
|
||||||
selectors: [['my-app']],
|
selectors: [['my-app']],
|
||||||
consts: 1,
|
consts: 1,
|
||||||
vars: 1,
|
vars: 3,
|
||||||
// Initial template:
|
// Initial template:
|
||||||
// <div i18n i18n-title title="{{exp1}}{{exp2}}{{exp3}}"></div>
|
// <div i18n i18n-title title="{{exp1}}{{exp2}}{{exp3}}"></div>
|
||||||
|
|
||||||
|
@ -1587,7 +1587,7 @@ describe('Runtime i18n', () => {
|
||||||
factory: () => new MyApp(),
|
factory: () => new MyApp(),
|
||||||
selectors: [['my-app']],
|
selectors: [['my-app']],
|
||||||
consts: 1,
|
consts: 1,
|
||||||
vars: 1,
|
vars: 4,
|
||||||
// Initial template:
|
// Initial template:
|
||||||
// <div i18n i18n-title title="{{exp1}}{{exp2}}{{exp3}}{{exp4}}"></div>
|
// <div i18n i18n-title title="{{exp1}}{{exp2}}{{exp3}}{{exp4}}"></div>
|
||||||
|
|
||||||
|
@ -1626,7 +1626,7 @@ describe('Runtime i18n', () => {
|
||||||
factory: () => new MyApp(),
|
factory: () => new MyApp(),
|
||||||
selectors: [['my-app']],
|
selectors: [['my-app']],
|
||||||
consts: 1,
|
consts: 1,
|
||||||
vars: 1,
|
vars: 5,
|
||||||
// Initial template:
|
// Initial template:
|
||||||
// <div i18n i18n-title title="{{exp1}}{{exp2}}{{exp3}}{{exp4}}{{exp5}}"></div>
|
// <div i18n i18n-title title="{{exp1}}{{exp2}}{{exp3}}{{exp4}}{{exp5}}"></div>
|
||||||
|
|
||||||
|
@ -1670,7 +1670,7 @@ describe('Runtime i18n', () => {
|
||||||
factory: () => new MyApp(),
|
factory: () => new MyApp(),
|
||||||
selectors: [['my-app']],
|
selectors: [['my-app']],
|
||||||
consts: 1,
|
consts: 1,
|
||||||
vars: 1,
|
vars: 6,
|
||||||
// Initial template:
|
// Initial template:
|
||||||
// <div i18n i18n-title title="{{exp1}}{{exp2}}{{exp3}}{{exp4}}{{exp5}}{{exp6}}"></div>
|
// <div i18n i18n-title title="{{exp1}}{{exp2}}{{exp3}}{{exp4}}{{exp5}}{{exp6}}"></div>
|
||||||
|
|
||||||
|
@ -1716,7 +1716,7 @@ describe('Runtime i18n', () => {
|
||||||
factory: () => new MyApp(),
|
factory: () => new MyApp(),
|
||||||
selectors: [['my-app']],
|
selectors: [['my-app']],
|
||||||
consts: 1,
|
consts: 1,
|
||||||
vars: 1,
|
vars: 7,
|
||||||
// Initial template:
|
// Initial template:
|
||||||
// <div i18n i18n-title
|
// <div i18n i18n-title
|
||||||
// title="{{exp1}}{{exp2}}{{exp3}}{{exp4}}{{exp5}}{{exp6}}{{exp7}}"></div>
|
// title="{{exp1}}{{exp2}}{{exp3}}{{exp4}}{{exp5}}{{exp6}}{{exp7}}"></div>
|
||||||
|
@ -1771,7 +1771,7 @@ describe('Runtime i18n', () => {
|
||||||
factory: () => new MyApp(),
|
factory: () => new MyApp(),
|
||||||
selectors: [['my-app']],
|
selectors: [['my-app']],
|
||||||
consts: 1,
|
consts: 1,
|
||||||
vars: 1,
|
vars: 8,
|
||||||
// Initial template:
|
// Initial template:
|
||||||
// <div i18n i18n-title
|
// <div i18n i18n-title
|
||||||
// title="{{exp1}}{{exp2}}{{exp3}}{{exp4}}{{exp5}}{{exp6}}{{exp7}}{{exp8}}"></div>
|
// title="{{exp1}}{{exp2}}{{exp3}}{{exp4}}{{exp5}}{{exp6}}{{exp7}}{{exp8}}"></div>
|
||||||
|
|
|
@ -40,7 +40,7 @@ describe('instructions', () => {
|
||||||
|
|
||||||
describe('bind', () => {
|
describe('bind', () => {
|
||||||
it('should update bindings when value changes', () => {
|
it('should update bindings when value changes', () => {
|
||||||
const t = new TemplateFixture(createAnchor, () => {}, 1);
|
const t = new TemplateFixture(createAnchor, () => {}, 1, 1);
|
||||||
|
|
||||||
t.update(() => elementProperty(0, 'title', bind('Hello')));
|
t.update(() => elementProperty(0, 'title', bind('Hello')));
|
||||||
expect(t.html).toEqual('<a title="Hello"></a>');
|
expect(t.html).toEqual('<a title="Hello"></a>');
|
||||||
|
|
|
@ -340,6 +340,7 @@ describe('render3 integration test', () => {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
factory: () => cmptInstance = new TodoComponentHostBinding,
|
factory: () => cmptInstance = new TodoComponentHostBinding,
|
||||||
|
hostVars: 1,
|
||||||
hostBindings: function(directiveIndex: number, elementIndex: number): void {
|
hostBindings: function(directiveIndex: number, elementIndex: number): void {
|
||||||
// host bindings
|
// host bindings
|
||||||
elementProperty(
|
elementProperty(
|
||||||
|
@ -930,7 +931,7 @@ describe('render3 integration test', () => {
|
||||||
containerRefreshStart(1);
|
containerRefreshStart(1);
|
||||||
{
|
{
|
||||||
for (let subTree of ctx.tree.subTrees || []) {
|
for (let subTree of ctx.tree.subTrees || []) {
|
||||||
const rf0 = embeddedViewStart(0, 1, 0);
|
const rf0 = embeddedViewStart(0, 3, 0);
|
||||||
{ showTree(rf0, {tree: subTree}); }
|
{ showTree(rf0, {tree: subTree}); }
|
||||||
embeddedViewEnd();
|
embeddedViewEnd();
|
||||||
}
|
}
|
||||||
|
@ -967,14 +968,14 @@ describe('render3 integration test', () => {
|
||||||
if (rf & RenderFlags.Update) {
|
if (rf & RenderFlags.Update) {
|
||||||
containerRefreshStart(0);
|
containerRefreshStart(0);
|
||||||
{
|
{
|
||||||
const rf0 = embeddedViewStart(0, 1, 0);
|
const rf0 = embeddedViewStart(0, 3, 0);
|
||||||
{ showTree(rf0, {tree: ctx.beforeTree}); }
|
{ showTree(rf0, {tree: ctx.beforeTree}); }
|
||||||
embeddedViewEnd();
|
embeddedViewEnd();
|
||||||
}
|
}
|
||||||
containerRefreshEnd();
|
containerRefreshEnd();
|
||||||
containerRefreshStart(2);
|
containerRefreshStart(2);
|
||||||
{
|
{
|
||||||
const rf0 = embeddedViewStart(0, 1, 0);
|
const rf0 = embeddedViewStart(0, 3, 0);
|
||||||
{ showTree(rf0, {tree: ctx.afterTree}); }
|
{ showTree(rf0, {tree: ctx.afterTree}); }
|
||||||
embeddedViewEnd();
|
embeddedViewEnd();
|
||||||
}
|
}
|
||||||
|
@ -997,7 +998,7 @@ describe('render3 integration test', () => {
|
||||||
elementProperty(0, 'afterTree', bind(ctx.afterTree));
|
elementProperty(0, 'afterTree', bind(ctx.afterTree));
|
||||||
containerRefreshStart(1);
|
containerRefreshStart(1);
|
||||||
{
|
{
|
||||||
const rf0 = embeddedViewStart(0, 1, 0);
|
const rf0 = embeddedViewStart(0, 3, 0);
|
||||||
{ showTree(rf0, {tree: ctx.projectedTree}); }
|
{ showTree(rf0, {tree: ctx.projectedTree}); }
|
||||||
embeddedViewEnd();
|
embeddedViewEnd();
|
||||||
}
|
}
|
||||||
|
@ -1109,15 +1110,15 @@ describe('render3 integration test', () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let args = ['(', 0, 'a', 1, 'b', 2, 'c', 3, 'd', 4, 'e', 5, 'f', 6, 'g', 7, ')'];
|
let args = ['(', 0, 'a', 1, 'b', 2, 'c', 3, 'd', 4, 'e', 5, 'f', 6, 'g', 7, ')'];
|
||||||
expect(renderToHtml(Template, args, 1, 10))
|
expect(renderToHtml(Template, args, 1, 54))
|
||||||
.toEqual(
|
.toEqual(
|
||||||
'<b a="(0a1b2c3d4e5f6g7)" a0="0" a1="(0)" a2="(0a1)" a3="(0a1b2)" a4="(0a1b2c3)" a5="(0a1b2c3d4)" a6="(0a1b2c3d4e5)" a7="(0a1b2c3d4e5f6)" a8="(0a1b2c3d4e5f6g7)"></b>');
|
'<b a="(0a1b2c3d4e5f6g7)" a0="0" a1="(0)" a2="(0a1)" a3="(0a1b2)" a4="(0a1b2c3)" a5="(0a1b2c3d4)" a6="(0a1b2c3d4e5)" a7="(0a1b2c3d4e5f6)" a8="(0a1b2c3d4e5f6g7)"></b>');
|
||||||
args = args.reverse();
|
args = args.reverse();
|
||||||
expect(renderToHtml(Template, args, 1, 10))
|
expect(renderToHtml(Template, args, 1, 54))
|
||||||
.toEqual(
|
.toEqual(
|
||||||
'<b a=")7g6f5e4d3c2b1a0(" a0="7" a1=")7(" a2=")7g6(" a3=")7g6f5(" a4=")7g6f5e4(" a5=")7g6f5e4d3(" a6=")7g6f5e4d3c2(" a7=")7g6f5e4d3c2b1(" a8=")7g6f5e4d3c2b1a0("></b>');
|
'<b a=")7g6f5e4d3c2b1a0(" a0="7" a1=")7(" a2=")7g6(" a3=")7g6f5(" a4=")7g6f5e4(" a5=")7g6f5e4d3(" a6=")7g6f5e4d3c2(" a7=")7g6f5e4d3c2b1(" a8=")7g6f5e4d3c2b1a0("></b>');
|
||||||
args = args.reverse();
|
args = args.reverse();
|
||||||
expect(renderToHtml(Template, args, 1, 10))
|
expect(renderToHtml(Template, args, 1, 54))
|
||||||
.toEqual(
|
.toEqual(
|
||||||
'<b a="(0a1b2c3d4e5f6g7)" a0="0" a1="(0)" a2="(0a1)" a3="(0a1b2)" a4="(0a1b2c3)" a5="(0a1b2c3d4)" a6="(0a1b2c3d4e5)" a7="(0a1b2c3d4e5f6)" a8="(0a1b2c3d4e5f6g7)"></b>');
|
'<b a="(0a1b2c3d4e5f6g7)" a0="0" a1="(0)" a2="(0a1)" a3="(0a1b2)" a4="(0a1b2c3)" a5="(0a1b2c3d4)" a6="(0a1b2c3d4e5)" a7="(0a1b2c3d4e5f6)" a8="(0a1b2c3d4e5f6g7)"></b>');
|
||||||
});
|
});
|
||||||
|
@ -1136,14 +1137,16 @@ describe('render3 integration test', () => {
|
||||||
containerRefreshStart(1);
|
containerRefreshStart(1);
|
||||||
{
|
{
|
||||||
if (true) {
|
if (true) {
|
||||||
let rf1 = embeddedViewStart(1, 1, 0);
|
let rf1 = embeddedViewStart(1, 1, 1);
|
||||||
{
|
{
|
||||||
if (rf1 & RenderFlags.Create) {
|
if (rf1 & RenderFlags.Create) {
|
||||||
elementStart(0, 'b');
|
elementStart(0, 'b');
|
||||||
{}
|
{}
|
||||||
elementEnd();
|
elementEnd();
|
||||||
}
|
}
|
||||||
elementAttribute(0, 'title', bind(ctx.title));
|
if (rf1 & RenderFlags.Update) {
|
||||||
|
elementAttribute(0, 'title', bind(ctx.title));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
embeddedViewEnd();
|
embeddedViewEnd();
|
||||||
}
|
}
|
||||||
|
@ -1182,6 +1185,7 @@ describe('render3 integration test', () => {
|
||||||
factory: function HostBindingDir_Factory() {
|
factory: function HostBindingDir_Factory() {
|
||||||
return hostBindingDir = new HostBindingDir();
|
return hostBindingDir = new HostBindingDir();
|
||||||
},
|
},
|
||||||
|
hostVars: 1,
|
||||||
hostBindings: function HostBindingDir_HostBindings(dirIndex: number, elIndex: number) {
|
hostBindings: function HostBindingDir_HostBindings(dirIndex: number, elIndex: number) {
|
||||||
elementAttribute(
|
elementAttribute(
|
||||||
elIndex, 'aria-label', bind(loadDirective<HostBindingDir>(dirIndex).label));
|
elIndex, 'aria-label', bind(loadDirective<HostBindingDir>(dirIndex).label));
|
||||||
|
|
|
@ -41,7 +41,7 @@ describe('lifecycles', () => {
|
||||||
elementEnd();
|
elementEnd();
|
||||||
}
|
}
|
||||||
}, 2);
|
}, 2);
|
||||||
let Parent = createOnInitComponent('parent', getParentTemplate('comp'), 1, [Comp]);
|
let Parent = createOnInitComponent('parent', getParentTemplate('comp'), 1, 1, [Comp]);
|
||||||
let ProjectedComp = createOnInitComponent('projected', (rf: RenderFlags, ctx: any) => {
|
let ProjectedComp = createOnInitComponent('projected', (rf: RenderFlags, ctx: any) => {
|
||||||
if (rf & RenderFlags.Create) {
|
if (rf & RenderFlags.Create) {
|
||||||
text(0, 'content');
|
text(0, 'content');
|
||||||
|
@ -49,7 +49,8 @@ describe('lifecycles', () => {
|
||||||
}, 1);
|
}, 1);
|
||||||
|
|
||||||
function createOnInitComponent(
|
function createOnInitComponent(
|
||||||
name: string, template: ComponentTemplate<any>, consts: number, directives: any[] = []) {
|
name: string, template: ComponentTemplate<any>, consts: number, vars: number = 0,
|
||||||
|
directives: any[] = []) {
|
||||||
return class Component {
|
return class Component {
|
||||||
val: string = '';
|
val: string = '';
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
|
@ -61,7 +62,7 @@ describe('lifecycles', () => {
|
||||||
type: Component,
|
type: Component,
|
||||||
selectors: [[name]],
|
selectors: [[name]],
|
||||||
consts: consts,
|
consts: consts,
|
||||||
vars: 0,
|
vars: vars,
|
||||||
factory: () => new Component(),
|
factory: () => new Component(),
|
||||||
inputs: {val: 'val'}, template,
|
inputs: {val: 'val'}, template,
|
||||||
directives: directives
|
directives: directives
|
||||||
|
|
|
@ -236,7 +236,7 @@ describe('pipe', () => {
|
||||||
containerRefreshStart(4);
|
containerRefreshStart(4);
|
||||||
{
|
{
|
||||||
for (let i of [1, 2]) {
|
for (let i of [1, 2]) {
|
||||||
let rf1 = embeddedViewStart(1, 2, 0);
|
let rf1 = embeddedViewStart(1, 2, 3);
|
||||||
{
|
{
|
||||||
if (rf1 & RenderFlags.Create) {
|
if (rf1 & RenderFlags.Create) {
|
||||||
elementStart(0, 'div');
|
elementStart(0, 'div');
|
||||||
|
|
|
@ -510,7 +510,7 @@ describe('object literals', () => {
|
||||||
containerRefreshStart(0);
|
containerRefreshStart(0);
|
||||||
{
|
{
|
||||||
for (let i = 0; i < 2; i++) {
|
for (let i = 0; i < 2; i++) {
|
||||||
let rf1 = embeddedViewStart(0, 1, 0);
|
let rf1 = embeddedViewStart(0, 1, 4);
|
||||||
if (rf1 & RenderFlags.Create) {
|
if (rf1 & RenderFlags.Create) {
|
||||||
elementStart(0, 'object-comp');
|
elementStart(0, 'object-comp');
|
||||||
objectComps.push(loadDirective(0));
|
objectComps.push(loadDirective(0));
|
||||||
|
@ -531,12 +531,12 @@ describe('object literals', () => {
|
||||||
const e0_ff = (v1: any, v2: any) => { return {opacity: v1, duration: v2}; };
|
const e0_ff = (v1: any, v2: any) => { return {opacity: v1, duration: v2}; };
|
||||||
|
|
||||||
const configs = [{opacity: 0, duration: 500}, {opacity: 1, duration: 600}];
|
const configs = [{opacity: 0, duration: 500}, {opacity: 1, duration: 600}];
|
||||||
renderToHtml(Template, {configs}, 1, 4, defs);
|
renderToHtml(Template, {configs}, 1, 0, defs);
|
||||||
expect(objectComps[0].config).toEqual({opacity: 0, duration: 500});
|
expect(objectComps[0].config).toEqual({opacity: 0, duration: 500});
|
||||||
expect(objectComps[1].config).toEqual({opacity: 1, duration: 600});
|
expect(objectComps[1].config).toEqual({opacity: 1, duration: 600});
|
||||||
|
|
||||||
configs[0].duration = 1000;
|
configs[0].duration = 1000;
|
||||||
renderToHtml(Template, {configs}, 1, 4, defs);
|
renderToHtml(Template, {configs}, 1, 0, defs);
|
||||||
expect(objectComps[0].config).toEqual({opacity: 0, duration: 1000});
|
expect(objectComps[0].config).toEqual({opacity: 0, duration: 1000});
|
||||||
expect(objectComps[1].config).toEqual({opacity: 1, duration: 600});
|
expect(objectComps[1].config).toEqual({opacity: 1, duration: 600});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1148,7 +1148,7 @@ describe('query', () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
7, 0, [ViewContainerManipulatorDirective], [],
|
9, 0, [ViewContainerManipulatorDirective], [],
|
||||||
function(rf: RenderFlags, ctx: any) {
|
function(rf: RenderFlags, ctx: any) {
|
||||||
if (rf & RenderFlags.Create) {
|
if (rf & RenderFlags.Create) {
|
||||||
query(0, ['foo'], true, QUERY_READ_FROM_NODE);
|
query(0, ['foo'], true, QUERY_READ_FROM_NODE);
|
||||||
|
|
|
@ -89,7 +89,7 @@ export class TemplateFixture extends BaseFixture {
|
||||||
*/
|
*/
|
||||||
update(updateBlock?: () => void): void {
|
update(updateBlock?: () => void): void {
|
||||||
renderTemplate(
|
renderTemplate(
|
||||||
this.hostNode.native, updateBlock || this.updateBlock, 0, null !, this.vars,
|
this.hostNode.native, updateBlock || this.updateBlock, 0, this.vars, null !,
|
||||||
this._rendererFactory, this.hostNode, this._directiveDefs, this._pipeDefs, this._sanitizer);
|
this._rendererFactory, this.hostNode, this._directiveDefs, this._pipeDefs, this._sanitizer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -166,12 +166,12 @@ describe('styling', () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
expect(renderToHtml(Template, {
|
expect(renderToHtml(
|
||||||
myStyles: {width: '200px', height: '200px'},
|
Template, {myStyles: {width: '200px', height: '200px'}, myWidth: '300px'}, 1))
|
||||||
myWidth: '300px'
|
.toEqual('<span style="width: 300px; height: 200px; opacity: 0.5;"></span>');
|
||||||
})).toEqual('<span style="width: 300px; height: 200px; opacity: 0.5;"></span>');
|
|
||||||
|
|
||||||
expect(renderToHtml(Template, {myStyles: {width: '200px', height: null}, myWidth: null}))
|
expect(
|
||||||
|
renderToHtml(Template, {myStyles: {width: '200px', height: null}, myWidth: null}, 1))
|
||||||
.toEqual('<span style="width: 200px; height: 100px; opacity: 0.5;"></span>');
|
.toEqual('<span style="width: 200px; height: 100px; opacity: 0.5;"></span>');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -123,7 +123,7 @@ describe('ViewContainerRef', () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const fixture = new TemplateFixture(
|
const fixture = new TemplateFixture(
|
||||||
createTemplate, updateTemplate, 3, 1, [HeaderComponent, DirectiveWithVCRef]);
|
createTemplate, updateTemplate, 4, 1, [HeaderComponent, DirectiveWithVCRef]);
|
||||||
expect(fixture.html).toEqual('<header-cmp vcref=""></header-cmp><footer></footer>');
|
expect(fixture.html).toEqual('<header-cmp vcref=""></header-cmp><footer></footer>');
|
||||||
|
|
||||||
createView('A');
|
createView('A');
|
||||||
|
@ -643,7 +643,7 @@ describe('ViewContainerRef', () => {
|
||||||
|
|
||||||
function rowTemplate(rf: RenderFlags, ctx: any) {
|
function rowTemplate(rf: RenderFlags, ctx: any) {
|
||||||
if (rf & RenderFlags.Create) {
|
if (rf & RenderFlags.Create) {
|
||||||
template(0, cellTemplate, 2, 1, null, null, ['cellTemplate', ''], templateRefExtractor);
|
template(0, cellTemplate, 2, 3, null, null, ['cellTemplate', ''], templateRefExtractor);
|
||||||
element(2, 'loop-comp');
|
element(2, 'loop-comp');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue