perf(ivy): move attributes array into component def (#32798)
Currently Ivy stores the element attributes into an array above the component def and passes it into the relevant instructions, however the problem is that upon minification the array will get a unique name which won't compress very well. These changes move the attributes array into the component def and pass in the index into the instructions instead. Before: ``` const _c0 = ['foo', 'bar']; SomeComp.ngComponentDef = defineComponent({ template: function() { element(0, 'div', _c0); } }); ``` After: ``` SomeComp.ngComponentDef = defineComponent({ consts: [['foo', 'bar']], template: function() { element(0, 'div', 0); } }); ``` A couple of cases that this PR doesn't handle: * Template references are still in a separate array. * i18n attributes are still in a separate array. PR Close #32798
This commit is contained in:

committed by
Alex Rickabaugh

parent
b2b917d2d8
commit
d5b87d32b0
@ -14,7 +14,7 @@ The layout is as such:
|
||||
| Section | `LView` | `TView.data`
|
||||
| ---------- | ------------------------------------------------------------ | --------------------------------------------------
|
||||
| `HEADER` | contextual data | mostly `null`
|
||||
| `CONSTS` | DOM, pipe, and local ref instances |
|
||||
| `DECLS` | DOM, pipe, and local ref instances |
|
||||
| `VARS` | binding values | property names
|
||||
| `EXPANDO` | host bindings; directive instances; providers; dynamic nodes | host prop names; directive tokens; provider tokens; `null`
|
||||
|
||||
@ -25,10 +25,10 @@ The layout is as such:
|
||||
Mostly information such as parent `LView`, `Sanitizer`, `TView`, and many more bits of information needed for template rendering.
|
||||
|
||||
|
||||
## `CONSTS`
|
||||
## `DECLS`
|
||||
|
||||
`CONSTS` contain the DOM elements, pipe instances, and local refs.
|
||||
The size of the `CONSTS` section is declared in the property `consts` of the component definition.
|
||||
`DECLS` contain the DOM elements, pipe instances, and local refs.
|
||||
The size of the `DECLS` section is declared in the property `decls` of the component definition.
|
||||
|
||||
```typescript
|
||||
@Component({
|
||||
@ -38,7 +38,7 @@ class MyApp {
|
||||
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
...,
|
||||
consts: 5,
|
||||
decls: 5,
|
||||
template: function(rf: RenderFlags, ctx: MyApp) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
ɵɵelementStart(0, 'div');
|
||||
@ -89,7 +89,7 @@ class MyApp {
|
||||
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
...,
|
||||
consts: 2, // Two DOM Elements.
|
||||
decls: 2, // Two DOM Elements.
|
||||
vars: 2, // Two bindings.
|
||||
template: function(rf: RenderFlags, ctx: MyApp) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
@ -142,7 +142,7 @@ class MyApp {
|
||||
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
...,
|
||||
consts: 1,
|
||||
decls: 1,
|
||||
template: function(rf: RenderFlags, ctx: MyApp) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
ɵɵelement(0, 'child', ['tooltip', null]);
|
||||
@ -276,7 +276,7 @@ class MyApp {
|
||||
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
...,
|
||||
consts: 1,
|
||||
decls: 1,
|
||||
template: function(rf: RenderFlags, ctx: MyApp) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
ɵɵelement(0, 'child');
|
||||
|
@ -128,7 +128,7 @@ export function renderComponent<T>(
|
||||
const rootContext = createRootContext(opts.scheduler, opts.playerHandler);
|
||||
|
||||
const renderer = rendererFactory.createRenderer(hostRNode, componentDef);
|
||||
const rootTView = createTView(-1, null, 1, 0, null, null, null, null);
|
||||
const rootTView = createTView(-1, null, 1, 0, null, null, null, null, null);
|
||||
const rootView: LView = createLView(
|
||||
null, rootTView, rootContext, rootFlags, null, null, rendererFactory, renderer, undefined,
|
||||
opts.injector || null);
|
||||
|
@ -161,7 +161,7 @@ export class ComponentFactory<T> extends viewEngine_ComponentFactory<T> {
|
||||
}
|
||||
|
||||
// Create the root view. Uses empty TView and ContentTemplate.
|
||||
const rootTView = createTView(-1, null, 1, 0, null, null, null, null);
|
||||
const rootTView = createTView(-1, null, 1, 0, null, null, null, null, null);
|
||||
const rootLView = createLView(
|
||||
null, rootTView, rootContext, rootFlags, null, null, rendererFactory, renderer, sanitizer,
|
||||
rootViewInjector);
|
||||
|
@ -18,6 +18,7 @@ import {stringify} from '../util/stringify';
|
||||
import {EMPTY_ARRAY, EMPTY_OBJ} from './empty';
|
||||
import {NG_BASE_DEF, NG_COMPONENT_DEF, NG_DIRECTIVE_DEF, NG_FACTORY_DEF, NG_LOCALE_ID_DEF, NG_MODULE_DEF, NG_PIPE_DEF} from './fields';
|
||||
import {ComponentDef, ComponentDefFeature, ComponentTemplate, ComponentType, ContentQueriesFunction, DirectiveDef, DirectiveDefFeature, DirectiveType, DirectiveTypesOrFactory, FactoryFn, HostBindingsFunction, PipeDef, PipeType, PipeTypesOrFactory, ViewQueriesFunction, ɵɵBaseDef} from './interfaces/definition';
|
||||
import {TAttributes} from './interfaces/node';
|
||||
// while SelectorFlags is unused here, it's required so that types don't get resolved lazily
|
||||
// see: https://github.com/Microsoft/web-build-tools/issues/1050
|
||||
import {CssSelectorList, SelectorFlags} from './interfaces/projection';
|
||||
@ -56,7 +57,7 @@ export function ɵɵdefineComponent<T>(componentDefinition: {
|
||||
* can pre-fill the array and set the binding start index.
|
||||
*/
|
||||
// TODO(kara): remove queries from this count
|
||||
consts: number;
|
||||
decls: number;
|
||||
|
||||
/**
|
||||
* The number of bindings in this component template (including pure fn bindings).
|
||||
@ -171,6 +172,9 @@ export function ɵɵdefineComponent<T>(componentDefinition: {
|
||||
*/
|
||||
template: ComponentTemplate<T>;
|
||||
|
||||
/** Constants for the nodes in the component's view. */
|
||||
consts?: TAttributes[];
|
||||
|
||||
/**
|
||||
* An array of `ngContent[selector]` values that were found in the template.
|
||||
*/
|
||||
@ -248,10 +252,11 @@ export function ɵɵdefineComponent<T>(componentDefinition: {
|
||||
const def: Mutable<ComponentDef<any>, keyof ComponentDef<any>> = {
|
||||
type: type,
|
||||
providersResolver: null,
|
||||
consts: componentDefinition.consts,
|
||||
decls: componentDefinition.decls,
|
||||
vars: componentDefinition.vars,
|
||||
factory: null,
|
||||
template: componentDefinition.template || null !,
|
||||
consts: componentDefinition.consts || null,
|
||||
ngContentSelectors: componentDefinition.ngContentSelectors,
|
||||
hostBindings: componentDefinition.hostBindings || null,
|
||||
contentQueries: componentDefinition.contentQueries || null,
|
||||
|
@ -22,7 +22,7 @@ import {DirectiveDef} from '../interfaces/definition';
|
||||
* type: ComponentWithProviders,
|
||||
* selectors: [['component-with-providers']],
|
||||
* factory: () => new ComponentWithProviders(directiveInject(GreeterDE as any)),
|
||||
* consts: 1,
|
||||
* decls: 1,
|
||||
* vars: 1,
|
||||
* template: function(fs: RenderFlags, ctx: ComponentWithProviders) {
|
||||
* if (fs & RenderFlags.Create) {
|
||||
|
@ -53,10 +53,10 @@ export function ɵɵcontainer(index: number): void {
|
||||
*
|
||||
* @param index The index of the container in the data array
|
||||
* @param templateFn Inline template
|
||||
* @param consts The number of nodes, local refs, and pipes for this template
|
||||
* @param decls The number of nodes, local refs, and pipes for this template
|
||||
* @param vars The number of bindings for this template
|
||||
* @param tagName The name of the container element, if applicable
|
||||
* @param attrs The attrs attached to the container, if applicable
|
||||
* @param constsIndex Index of template in the `consts` array.
|
||||
* @param localRefs A set of local reference bindings on the element.
|
||||
* @param localRefExtractor A function which extracts local-refs values from the template.
|
||||
* Defaults to the current element associated with the local-ref.
|
||||
@ -64,22 +64,25 @@ export function ɵɵcontainer(index: number): void {
|
||||
* @codeGenApi
|
||||
*/
|
||||
export function ɵɵtemplate(
|
||||
index: number, templateFn: ComponentTemplate<any>| null, consts: number, vars: number,
|
||||
tagName?: string | null, attrs?: TAttributes | null, localRefs?: string[] | null,
|
||||
index: number, templateFn: ComponentTemplate<any>| null, decls: number, vars: number,
|
||||
tagName?: string | null, constsIndex?: number | null, localRefs?: string[] | null,
|
||||
localRefExtractor?: LocalRefExtractor) {
|
||||
const lView = getLView();
|
||||
const tView = lView[TVIEW];
|
||||
const tViewConsts = tView.consts;
|
||||
|
||||
// TODO: consider a separate node type for templates
|
||||
const tContainerNode = containerInternal(lView, index, tagName || null, attrs || null);
|
||||
const tContainerNode = containerInternal(
|
||||
lView, index, tagName || null,
|
||||
tViewConsts === null || constsIndex == null ? null : tViewConsts[constsIndex]);
|
||||
if (tView.firstTemplatePass) {
|
||||
ngDevMode && ngDevMode.firstTemplatePass++;
|
||||
resolveDirectives(tView, lView, tContainerNode, localRefs || null);
|
||||
registerPostOrderHooks(tView, tContainerNode);
|
||||
|
||||
const embeddedTView = tContainerNode.tViews = createTView(
|
||||
-1, templateFn, consts, vars, tView.directiveRegistry, tView.pipeRegistry, null,
|
||||
tView.schemas);
|
||||
-1, templateFn, decls, vars, tView.directiveRegistry, tView.pipeRegistry, null,
|
||||
tView.schemas, tViewConsts);
|
||||
const embeddedTViewNode = createTNode(tView, null, TNodeType.View, -1, null, null) as TViewNode;
|
||||
embeddedTViewNode.injectorIndex = tContainerNode.injectorIndex;
|
||||
embeddedTView.node = embeddedTViewNode;
|
||||
|
@ -32,8 +32,7 @@ import {registerInitialStylingOnTNode} from './styling';
|
||||
*
|
||||
* @param index Index of the element in the LView array
|
||||
* @param name Name of the DOM Node
|
||||
* @param attrs Statically bound set of attributes, classes, and styles to be written into the DOM
|
||||
* element on creation. Use [AttributeMarker] to denote the meaning of this array.
|
||||
* @param constsIndex Index of the element in the `consts` array.
|
||||
* @param localRefs A set of local reference bindings on the element.
|
||||
*
|
||||
* Attributes and localRefs are passed as an array of strings where elements with an even index
|
||||
@ -43,24 +42,25 @@ import {registerInitialStylingOnTNode} from './styling';
|
||||
* @codeGenApi
|
||||
*/
|
||||
export function ɵɵelementStart(
|
||||
index: number, name: string, attrs?: TAttributes | null, localRefs?: string[] | null): void {
|
||||
index: number, name: string, constsIndex?: number | null, localRefs?: string[] | null): void {
|
||||
const lView = getLView();
|
||||
const tView = lView[TVIEW];
|
||||
const tViewConsts = tView.consts;
|
||||
const consts = tViewConsts === null || constsIndex == null ? null : tViewConsts[constsIndex];
|
||||
ngDevMode && assertEqual(
|
||||
lView[BINDING_INDEX], tView.bindingStartIndex,
|
||||
'elements should be created before any bindings ');
|
||||
'elements should be created before any bindings');
|
||||
|
||||
ngDevMode && ngDevMode.rendererCreateElement++;
|
||||
ngDevMode && assertDataInRange(lView, index + HEADER_OFFSET);
|
||||
const renderer = lView[RENDERER];
|
||||
const native = lView[index + HEADER_OFFSET] = elementCreate(name, renderer, getNamespace());
|
||||
const tNode =
|
||||
getOrCreateTNode(tView, lView[T_HOST], index, TNodeType.Element, name, attrs || null);
|
||||
const tNode = getOrCreateTNode(tView, lView[T_HOST], index, TNodeType.Element, name, consts);
|
||||
|
||||
if (attrs != null) {
|
||||
const lastAttrIndex = setUpAttributes(renderer, native, attrs);
|
||||
if (consts != null) {
|
||||
const lastAttrIndex = setUpAttributes(renderer, native, consts);
|
||||
if (tView.firstTemplatePass) {
|
||||
registerInitialStylingOnTNode(tNode, attrs, lastAttrIndex);
|
||||
registerInitialStylingOnTNode(tNode, consts, lastAttrIndex);
|
||||
}
|
||||
}
|
||||
|
||||
@ -146,15 +146,14 @@ export function ɵɵelementEnd(): void {
|
||||
*
|
||||
* @param index Index of the element in the data array
|
||||
* @param name Name of the DOM Node
|
||||
* @param attrs Statically bound set of attributes, classes, and styles to be written into the DOM
|
||||
* element on creation. Use [AttributeMarker] to denote the meaning of this array.
|
||||
* @param constsIndex Index of the element in the `consts` array.
|
||||
* @param localRefs A set of local reference bindings on the element.
|
||||
*
|
||||
* @codeGenApi
|
||||
*/
|
||||
export function ɵɵelement(
|
||||
index: number, name: string, attrs?: TAttributes | null, localRefs?: string[] | null): void {
|
||||
ɵɵelementStart(index, name, attrs, localRefs);
|
||||
index: number, name: string, constsIndex?: number | null, localRefs?: string[] | null): void {
|
||||
ɵɵelementStart(index, name, constsIndex, localRefs);
|
||||
ɵɵelementEnd();
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,7 @@ import {registerInitialStylingOnTNode} from './styling';
|
||||
* The instruction must later be followed by `elementContainerEnd()` call.
|
||||
*
|
||||
* @param index Index of the element in the LView array
|
||||
* @param attrs Set of attributes to be used when matching directives.
|
||||
* @param constsIndex Index of the container in the `consts` array.
|
||||
* @param localRefs A set of local reference bindings on the element.
|
||||
*
|
||||
* Even if this instruction accepts a set of attributes no actual attribute values are propagated to
|
||||
@ -36,11 +36,13 @@ import {registerInitialStylingOnTNode} from './styling';
|
||||
* @codeGenApi
|
||||
*/
|
||||
export function ɵɵelementContainerStart(
|
||||
index: number, attrs?: TAttributes | null, localRefs?: string[] | null): void {
|
||||
index: number, constsIndex?: number | null, localRefs?: string[] | null): void {
|
||||
const lView = getLView();
|
||||
const tView = lView[TVIEW];
|
||||
const renderer = lView[RENDERER];
|
||||
const tagName = 'ng-container';
|
||||
const tViewConsts = tView.consts;
|
||||
const consts = tViewConsts === null || constsIndex == null ? null : tViewConsts[constsIndex];
|
||||
ngDevMode && assertEqual(
|
||||
lView[BINDING_INDEX], tView.bindingStartIndex,
|
||||
'element containers should be created before any bindings');
|
||||
@ -50,14 +52,13 @@ export function ɵɵelementContainerStart(
|
||||
const native = lView[index + HEADER_OFFSET] = renderer.createComment(ngDevMode ? tagName : '');
|
||||
|
||||
ngDevMode && assertDataInRange(lView, index - 1);
|
||||
const tNode = getOrCreateTNode(
|
||||
tView, lView[T_HOST], index, TNodeType.ElementContainer, tagName, attrs || null);
|
||||
const tNode =
|
||||
getOrCreateTNode(tView, lView[T_HOST], index, TNodeType.ElementContainer, tagName, consts);
|
||||
|
||||
|
||||
if (attrs && tView.firstTemplatePass) {
|
||||
if (consts && tView.firstTemplatePass) {
|
||||
// While ng-container doesn't necessarily support styling, we use the style context to identify
|
||||
// and execute directives on the ng-container.
|
||||
registerInitialStylingOnTNode(tNode, attrs as TAttributes, 0);
|
||||
registerInitialStylingOnTNode(tNode, consts as TAttributes, 0);
|
||||
}
|
||||
|
||||
appendChild(native, tNode, lView);
|
||||
@ -113,13 +114,13 @@ export function ɵɵelementContainerEnd(): void {
|
||||
* and {@link elementContainerEnd}
|
||||
*
|
||||
* @param index Index of the element in the LView array
|
||||
* @param attrs Set of attributes to be used when matching directives.
|
||||
* @param constsIndex Index of the container in the `consts` array.
|
||||
* @param localRefs A set of local reference bindings on the element.
|
||||
*
|
||||
* @codeGenApi
|
||||
*/
|
||||
export function ɵɵelementContainer(
|
||||
index: number, attrs?: TAttributes | null, localRefs?: string[] | null): void {
|
||||
ɵɵelementContainerStart(index, attrs, localRefs);
|
||||
index: number, constsIndex?: number | null, localRefs?: string[] | null): void {
|
||||
ɵɵelementContainerStart(index, constsIndex, localRefs);
|
||||
ɵɵelementContainerEnd();
|
||||
}
|
||||
|
@ -28,8 +28,7 @@ import {assignTViewNodeToLView, createLView, createTView, refreshView, renderVie
|
||||
*
|
||||
* @codeGenApi
|
||||
*/
|
||||
export function ɵɵembeddedViewStart(
|
||||
viewBlockId: number, consts: number, vars: number): RenderFlags {
|
||||
export function ɵɵembeddedViewStart(viewBlockId: number, decls: number, vars: number): RenderFlags {
|
||||
const lView = getLView();
|
||||
const previousOrParentTNode = getPreviousOrParentTNode();
|
||||
// The previous node can be a view node if we are processing an inline for loop
|
||||
@ -47,9 +46,8 @@ export function ɵɵembeddedViewStart(
|
||||
} else {
|
||||
// When we create a new LView, we always reset the state of the instructions.
|
||||
viewToRender = createLView(
|
||||
lView,
|
||||
getOrCreateEmbeddedTView(viewBlockId, consts, vars, containerTNode as TContainerNode), null,
|
||||
LViewFlags.CheckAlways, null, null);
|
||||
lView, getOrCreateEmbeddedTView(viewBlockId, decls, vars, containerTNode as TContainerNode),
|
||||
null, LViewFlags.CheckAlways, null, null);
|
||||
|
||||
const tParentNode = getIsParent() ? previousOrParentTNode :
|
||||
previousOrParentTNode && previousOrParentTNode.parent;
|
||||
@ -75,13 +73,13 @@ export function ɵɵembeddedViewStart(
|
||||
* it with the same index (since it's in the same template).
|
||||
*
|
||||
* @param viewIndex The index of the TView in TNode.tViews
|
||||
* @param consts The number of nodes, local refs, and pipes in this template
|
||||
* @param decls The number of nodes, local refs, and pipes in this template
|
||||
* @param vars The number of bindings and pure function bindings in this template
|
||||
* @param container The parent container in which to look for the view's static data
|
||||
* @returns TView
|
||||
*/
|
||||
function getOrCreateEmbeddedTView(
|
||||
viewIndex: number, consts: number, vars: number, parent: TContainerNode): TView {
|
||||
viewIndex: number, decls: number, vars: number, parent: TContainerNode): TView {
|
||||
const tView = getLView()[TVIEW];
|
||||
ngDevMode && assertNodeType(parent, TNodeType.Container);
|
||||
const containerTViews = parent.tViews as TView[];
|
||||
@ -89,7 +87,8 @@ function getOrCreateEmbeddedTView(
|
||||
ngDevMode && assertEqual(Array.isArray(containerTViews), true, 'TViews should be in an array');
|
||||
if (viewIndex >= containerTViews.length || containerTViews[viewIndex] == null) {
|
||||
containerTViews[viewIndex] = createTView(
|
||||
viewIndex, null, consts, vars, tView.directiveRegistry, tView.pipeRegistry, null, null);
|
||||
viewIndex, null, decls, vars, tView.directiveRegistry, tView.pipeRegistry, null, null,
|
||||
tView.consts);
|
||||
}
|
||||
return containerTViews[viewIndex];
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ import {initNgDevMode} from '../../util/ng_dev_mode';
|
||||
import {ACTIVE_INDEX, CONTAINER_HEADER_OFFSET, LContainer, MOVED_VIEWS, NATIVE} from '../interfaces/container';
|
||||
import {DirectiveDefList, PipeDefList, ViewQueriesFunction} from '../interfaces/definition';
|
||||
import {COMMENT_MARKER, ELEMENT_MARKER, I18nMutateOpCode, I18nMutateOpCodes, I18nUpdateOpCode, I18nUpdateOpCodes, TIcu} from '../interfaces/i18n';
|
||||
import {PropertyAliases, TContainerNode, TElementNode, TNode as ITNode, TNode, TNodeFlags, TNodeProviderIndexes, TNodeType, TViewNode} from '../interfaces/node';
|
||||
import {PropertyAliases, TAttributes, TContainerNode, TElementNode, TNode as ITNode, TNode, TNodeFlags, TNodeProviderIndexes, TNodeType, TViewNode} from '../interfaces/node';
|
||||
import {SelectorFlags} from '../interfaces/projection';
|
||||
import {TQueries} from '../interfaces/query';
|
||||
import {RComment, RElement, RNode} from '../interfaces/renderer';
|
||||
@ -102,6 +102,7 @@ export const TViewConstructor = class TView implements ITView {
|
||||
public pipeRegistry: PipeDefList|null, //
|
||||
public firstChild: TNode|null, //
|
||||
public schemas: SchemaMetadata[]|null, //
|
||||
public consts: TAttributes[]|null, //
|
||||
) {}
|
||||
|
||||
get template_(): string {
|
||||
|
@ -569,8 +569,8 @@ export function saveResolvedLocalsInData(
|
||||
*/
|
||||
export function getOrCreateTView(def: ComponentDef<any>): TView {
|
||||
return def.tView || (def.tView = createTView(
|
||||
-1, def.template, def.consts, def.vars, def.directiveDefs, def.pipeDefs,
|
||||
def.viewQuery, def.schemas));
|
||||
-1, def.template, def.decls, def.vars, def.directiveDefs, def.pipeDefs,
|
||||
def.viewQuery, def.schemas, def.consts));
|
||||
}
|
||||
|
||||
|
||||
@ -579,18 +579,20 @@ export function getOrCreateTView(def: ComponentDef<any>): TView {
|
||||
*
|
||||
* @param viewIndex The viewBlockId for inline views, or -1 if it's a component/dynamic
|
||||
* @param templateFn Template function
|
||||
* @param consts The number of nodes, local refs, and pipes in this template
|
||||
* @param decls The number of nodes, local refs, and pipes in this template
|
||||
* @param directives Registry of directives for this view
|
||||
* @param pipes Registry of pipes for this view
|
||||
* @param viewQuery View queries for this view
|
||||
* @param schemas Schemas for this view
|
||||
* @param consts Constants for this view
|
||||
*/
|
||||
export function createTView(
|
||||
viewIndex: number, templateFn: ComponentTemplate<any>| null, consts: number, vars: number,
|
||||
viewIndex: number, templateFn: ComponentTemplate<any>| null, decls: number, vars: number,
|
||||
directives: DirectiveDefListOrFactory | null, pipes: PipeDefListOrFactory | null,
|
||||
viewQuery: ViewQueriesFunction<any>| null, schemas: SchemaMetadata[] | null): TView {
|
||||
viewQuery: ViewQueriesFunction<any>| null, schemas: SchemaMetadata[] | null,
|
||||
consts: TAttributes[] | null): TView {
|
||||
ngDevMode && ngDevMode.tView++;
|
||||
const bindingStartIndex = HEADER_OFFSET + consts;
|
||||
const bindingStartIndex = HEADER_OFFSET + decls;
|
||||
// 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.
|
||||
@ -627,7 +629,7 @@ export function createTView(
|
||||
typeof pipes === 'function' ? pipes() : pipes, // pipeRegistry: PipeDefList|null,
|
||||
null, // firstChild: TNode|null,
|
||||
schemas, // schemas: SchemaMetadata[]|null,
|
||||
) :
|
||||
consts) : // consts: TAttributes[]
|
||||
{
|
||||
id: viewIndex,
|
||||
blueprint: blueprint,
|
||||
@ -656,6 +658,7 @@ export function createTView(
|
||||
pipeRegistry: typeof pipes === 'function' ? pipes() : pipes,
|
||||
firstChild: null,
|
||||
schemas: schemas,
|
||||
consts: consts,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,8 @@
|
||||
import {SchemaMetadata, ViewEncapsulation} from '../../core';
|
||||
import {ProcessProvidersFunction} from '../../di/interface/provider';
|
||||
import {Type} from '../../interface/type';
|
||||
|
||||
import {TAttributes} from './node';
|
||||
import {CssSelectorList} from './projection';
|
||||
import {TView} from './view';
|
||||
|
||||
@ -241,6 +243,9 @@ export interface ComponentDef<T> extends DirectiveDef<T> {
|
||||
*/
|
||||
readonly template: ComponentTemplate<T>;
|
||||
|
||||
/** Constants associated with the component's view. */
|
||||
readonly consts: TAttributes[]|null;
|
||||
|
||||
/**
|
||||
* An array of `ngContent[selector]` values that were found in the template.
|
||||
*/
|
||||
@ -258,7 +263,7 @@ export interface ComponentDef<T> extends DirectiveDef<T> {
|
||||
* can pre-fill the array and set the binding start index.
|
||||
*/
|
||||
// TODO(kara): remove queries from this count
|
||||
readonly consts: number;
|
||||
readonly decls: number;
|
||||
|
||||
/**
|
||||
* The number of bindings in this component template (including pure fn bindings).
|
||||
|
@ -15,7 +15,7 @@ import {Sanitizer} from '../../sanitization/sanitizer';
|
||||
import {LContainer} from './container';
|
||||
import {ComponentDef, ComponentTemplate, DirectiveDef, DirectiveDefList, HostBindingsFunction, PipeDef, PipeDefList, ViewQueriesFunction} from './definition';
|
||||
import {I18nUpdateOpCodes, TI18n} from './i18n';
|
||||
import {TElementNode, TNode, TViewNode} from './node';
|
||||
import {TAttributes, TElementNode, TNode, TViewNode} from './node';
|
||||
import {PlayerHandler} from './player';
|
||||
import {LQueries, TQueries} from './query';
|
||||
import {RElement, Renderer3, RendererFactory3} from './renderer';
|
||||
@ -387,7 +387,7 @@ export interface TView {
|
||||
/**
|
||||
* 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 `LView`, the length of this
|
||||
* Unlike the "decls" 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.
|
||||
*
|
||||
@ -561,6 +561,12 @@ export interface TView {
|
||||
* Set of schemas that declare elements to be allowed inside the view.
|
||||
*/
|
||||
schemas: SchemaMetadata[]|null;
|
||||
|
||||
/**
|
||||
* Array of attributes for all of the elements in the view. Used
|
||||
* for directive matching and attribute bindings.
|
||||
*/
|
||||
consts: TAttributes[]|null;
|
||||
}
|
||||
|
||||
export const enum RootContextFlags {Empty = 0b00, DetectChanges = 0b01, FlushPlayers = 0b10}
|
||||
|
@ -14,7 +14,7 @@ import {isCreationMode} from './util/view_utils';
|
||||
/**
|
||||
* Bindings for pure functions are stored after regular bindings.
|
||||
*
|
||||
* |------consts------|---------vars---------| |----- hostVars (dir1) ------|
|
||||
* |-------decls------|---------vars---------| |----- hostVars (dir1) ------|
|
||||
* ------------------------------------------------------------------------------------------
|
||||
* | nodes/refs/pipes | bindings | fn slots | injector | dir1 | host bindings | host slots |
|
||||
* ------------------------------------------------------------------------------------------
|
||||
|
@ -320,66 +320,6 @@
|
||||
{
|
||||
"name": "_c1"
|
||||
},
|
||||
{
|
||||
"name": "_c10"
|
||||
},
|
||||
{
|
||||
"name": "_c11"
|
||||
},
|
||||
{
|
||||
"name": "_c12"
|
||||
},
|
||||
{
|
||||
"name": "_c13"
|
||||
},
|
||||
{
|
||||
"name": "_c14"
|
||||
},
|
||||
{
|
||||
"name": "_c15"
|
||||
},
|
||||
{
|
||||
"name": "_c16"
|
||||
},
|
||||
{
|
||||
"name": "_c17"
|
||||
},
|
||||
{
|
||||
"name": "_c18"
|
||||
},
|
||||
{
|
||||
"name": "_c19"
|
||||
},
|
||||
{
|
||||
"name": "_c2"
|
||||
},
|
||||
{
|
||||
"name": "_c20"
|
||||
},
|
||||
{
|
||||
"name": "_c21"
|
||||
},
|
||||
{
|
||||
"name": "_c3"
|
||||
},
|
||||
{
|
||||
"name": "_c4"
|
||||
},
|
||||
{
|
||||
"name": "_c5"
|
||||
},
|
||||
{
|
||||
"name": "_c6"
|
||||
},
|
||||
{
|
||||
"name": "_c7"
|
||||
},
|
||||
{
|
||||
"name": "_c8"
|
||||
},
|
||||
{
|
||||
"name": "_c9"
|
||||
},
|
||||
{
|
||||
"name": "_currentInjector"
|
||||
},
|
||||
|
@ -37,7 +37,7 @@ describe('iv perf test', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: Component,
|
||||
selectors: [['div']],
|
||||
consts: 1,
|
||||
decls: 1,
|
||||
vars: 0,
|
||||
template: function Template(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
|
@ -29,7 +29,7 @@ describe('change detection', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: MyComponent,
|
||||
selectors: [['my-comp']],
|
||||
consts: 2,
|
||||
decls: 2,
|
||||
vars: 1,
|
||||
template: (rf: RenderFlags, ctx: MyComponent) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
@ -105,7 +105,7 @@ describe('change detection', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: MyComponent,
|
||||
selectors: [['my-comp']],
|
||||
consts: 2,
|
||||
decls: 2,
|
||||
vars: 2,
|
||||
/**
|
||||
* {{ doCheckCount }} - {{ name }}
|
||||
@ -143,7 +143,7 @@ describe('change detection', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: ManualComponent,
|
||||
selectors: [['manual-comp']],
|
||||
consts: 2,
|
||||
decls: 2,
|
||||
vars: 2,
|
||||
/**
|
||||
* {{ doCheckCount }} - {{ name }}
|
||||
@ -179,7 +179,7 @@ describe('change detection', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: ManualApp,
|
||||
selectors: [['manual-app']],
|
||||
consts: 1,
|
||||
decls: 1,
|
||||
vars: 1,
|
||||
/** <manual-comp [name]="name"></manual-comp> */
|
||||
template: (rf: RenderFlags, ctx: ManualApp) => {
|
||||
@ -234,7 +234,7 @@ describe('change detection', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: ButtonParent,
|
||||
selectors: [['button-parent']],
|
||||
consts: 2,
|
||||
decls: 2,
|
||||
vars: 1,
|
||||
/** {{ doCheckCount }} - <manual-comp></manual-comp> */
|
||||
template: (rf: RenderFlags, ctx: ButtonParent) => {
|
||||
@ -311,7 +311,7 @@ describe('change detection', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: MyComponent,
|
||||
selectors: [['my-comp']],
|
||||
consts: 1,
|
||||
decls: 1,
|
||||
vars: 1,
|
||||
template: (rf: RenderFlags, ctx: MyComponent) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
|
@ -24,7 +24,7 @@ describe('ComponentFactory', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: TestComponent,
|
||||
selectors: [['test', 'foo'], ['bar']],
|
||||
consts: 0,
|
||||
decls: 0,
|
||||
vars: 0,
|
||||
template: () => undefined,
|
||||
});
|
||||
@ -46,7 +46,7 @@ describe('ComponentFactory', () => {
|
||||
type: TestComponent,
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
selectors: [['test', 'foo'], ['bar']],
|
||||
consts: 0,
|
||||
decls: 0,
|
||||
vars: 0,
|
||||
template: () => undefined,
|
||||
ngContentSelectors: ['*', 'a', 'b'],
|
||||
@ -94,7 +94,7 @@ describe('ComponentFactory', () => {
|
||||
type: TestComponent,
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
selectors: [['test']],
|
||||
consts: 0,
|
||||
decls: 0,
|
||||
vars: 0,
|
||||
template: () => undefined,
|
||||
});
|
||||
|
@ -26,7 +26,7 @@ describe('component', () => {
|
||||
type: CounterComponent,
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
selectors: [['counter']],
|
||||
consts: 1,
|
||||
decls: 1,
|
||||
vars: 1,
|
||||
template: function(rf: RenderFlags, ctx: CounterComponent) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
@ -76,7 +76,7 @@ describe('component', () => {
|
||||
type: MyComponent,
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
selectors: [['my-component']],
|
||||
consts: 1,
|
||||
decls: 1,
|
||||
vars: 1,
|
||||
template: function(fs: RenderFlags, ctx: MyComponent) {
|
||||
if (fs & RenderFlags.Create) {
|
||||
@ -119,7 +119,7 @@ describe('component', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: Comp,
|
||||
selectors: [['comp']],
|
||||
consts: 1,
|
||||
decls: 1,
|
||||
vars: 1,
|
||||
template: (rf: RenderFlags, ctx: Comp) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
@ -178,9 +178,10 @@ it('should not invoke renderer destroy method for embedded views', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: Comp,
|
||||
selectors: [['comp']],
|
||||
consts: 3,
|
||||
decls: 3,
|
||||
vars: 1,
|
||||
directives: [NgIf],
|
||||
consts: [[AttributeMarker.Template, 'ngIf']],
|
||||
/**
|
||||
* <div>Root view</div>
|
||||
* <div *ngIf="visible">Child view</div>
|
||||
@ -190,8 +191,7 @@ it('should not invoke renderer destroy method for embedded views', () => {
|
||||
ɵɵelementStart(0, 'div');
|
||||
ɵɵtext(1, 'Root view');
|
||||
ɵɵelementEnd();
|
||||
ɵɵtemplate(
|
||||
2, MyComponent_div_Template_2, 2, 0, 'div', [AttributeMarker.Template, 'ngIf']);
|
||||
ɵɵtemplate(2, MyComponent_div_Template_2, 2, 0, 'div', 0);
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
ɵɵadvance(2);
|
||||
@ -252,7 +252,7 @@ describe('component with a container', () => {
|
||||
type: WrapperComponent,
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
selectors: [['wrapper']],
|
||||
consts: 1,
|
||||
decls: 1,
|
||||
vars: 0,
|
||||
template: function ChildComponentTemplate(rf: RenderFlags, ctx: {items: string[]}) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
@ -329,7 +329,7 @@ describe('recursive components', () => {
|
||||
type: TreeComponent,
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
selectors: [['tree-comp']],
|
||||
consts: 3,
|
||||
decls: 3,
|
||||
vars: 1,
|
||||
template: (rf: RenderFlags, ctx: TreeComponent) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
@ -395,18 +395,14 @@ describe('recursive components', () => {
|
||||
type: NgIfTree,
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
selectors: [['ng-if-tree']],
|
||||
consts: 3,
|
||||
decls: 3,
|
||||
vars: 3,
|
||||
consts: [[AttributeMarker.Bindings, 'data', AttributeMarker.Template, 'ngIf']],
|
||||
template: (rf: RenderFlags, ctx: NgIfTree) => {
|
||||
|
||||
if (rf & RenderFlags.Create) {
|
||||
ɵɵtext(0);
|
||||
ɵɵtemplate(
|
||||
1, IfTemplate, 1, 1, 'ng-if-tree',
|
||||
[AttributeMarker.Bindings, 'data', AttributeMarker.Template, 'ngIf']);
|
||||
ɵɵtemplate(
|
||||
2, IfTemplate2, 1, 1, 'ng-if-tree',
|
||||
[AttributeMarker.Bindings, 'data', AttributeMarker.Template, 'ngIf']);
|
||||
ɵɵtemplate(1, IfTemplate, 1, 1, 'ng-if-tree', 0);
|
||||
ɵɵtemplate(2, IfTemplate2, 1, 1, 'ng-if-tree', 0);
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
ɵɵtextInterpolate(ctx.data.value);
|
||||
@ -415,7 +411,6 @@ describe('recursive components', () => {
|
||||
ɵɵadvance(1);
|
||||
ɵɵproperty('ngIf', ctx.data.right);
|
||||
}
|
||||
|
||||
},
|
||||
inputs: {data: 'data'},
|
||||
});
|
||||
@ -543,7 +538,7 @@ describe('recursive components', () => {
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
selectors: [['test-inputs']],
|
||||
inputs: {minifiedName: 'unminifiedName'},
|
||||
consts: 0,
|
||||
decls: 0,
|
||||
vars: 0,
|
||||
template: function(rf: RenderFlags, ctx: TestInputsComponent): void {
|
||||
// Template not needed for this test
|
||||
|
@ -702,7 +702,7 @@ describe('JS control flow', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: Comp,
|
||||
selectors: [['comp']],
|
||||
consts: 0,
|
||||
decls: 0,
|
||||
vars: 0,
|
||||
template: function(rf: RenderFlags, ctx: Comp) {}
|
||||
});
|
||||
@ -716,7 +716,7 @@ describe('JS control flow', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: App,
|
||||
selectors: [['app']],
|
||||
consts: 3,
|
||||
decls: 3,
|
||||
vars: 0,
|
||||
template: function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
@ -772,7 +772,7 @@ describe('JS control flow', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: Comp,
|
||||
selectors: [['comp']],
|
||||
consts: 0,
|
||||
decls: 0,
|
||||
vars: 0,
|
||||
template: function(rf: RenderFlags, ctx: Comp) {}
|
||||
});
|
||||
@ -786,7 +786,7 @@ describe('JS control flow', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: App,
|
||||
selectors: [['app']],
|
||||
consts: 3,
|
||||
decls: 3,
|
||||
vars: 0,
|
||||
template: function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
|
@ -66,9 +66,9 @@ describe('di', () => {
|
||||
/** <div dirA></div> */
|
||||
const App = createComponent('app', function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
ɵɵelement(0, 'div', ['dirA', '']);
|
||||
ɵɵelement(0, 'div', 0);
|
||||
}
|
||||
}, 1, 0, [DirA, DirB]);
|
||||
}, 1, 0, [DirA, DirB], [], undefined, [], [], undefined, [['dirA', '']]);
|
||||
|
||||
expect(() => { new ComponentFixture(App); }).not.toThrow();
|
||||
expect(dirA !.dirB).toEqual(null);
|
||||
@ -92,13 +92,17 @@ describe('di', () => {
|
||||
* <div dirA dirC></div>
|
||||
* </div>
|
||||
*/
|
||||
const App = createComponent('app', function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
ɵɵelementStart(0, 'div', ['dirB', '']);
|
||||
ɵɵelement(1, 'div', ['dirA', '', 'dirC', '']);
|
||||
ɵɵelementEnd();
|
||||
}
|
||||
}, 2, 0, [DirA, DirB, DirC]);
|
||||
const App = createComponent(
|
||||
'app',
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
ɵɵelementStart(0, 'div', 0);
|
||||
ɵɵelement(1, 'div', 1);
|
||||
ɵɵelementEnd();
|
||||
}
|
||||
},
|
||||
2, 0, [DirA, DirB, DirC], [], undefined, [], [], undefined,
|
||||
[['dirB', ''], ['dirA', '', 'dirC', '']]);
|
||||
|
||||
expect(() => {
|
||||
(DirA as any)['__NG_ELEMENT_ID__'] = 1;
|
||||
@ -117,7 +121,7 @@ describe('di', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: MyComp,
|
||||
selectors: [['my-comp']],
|
||||
consts: 1,
|
||||
decls: 1,
|
||||
vars: 0,
|
||||
template: function(rf: RenderFlags, ctx: MyComp) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
@ -219,8 +223,8 @@ describe('di', () => {
|
||||
describe('getOrCreateNodeInjector', () => {
|
||||
it('should handle initial undefined state', () => {
|
||||
const contentView = createLView(
|
||||
null, createTView(-1, null, 1, 0, null, null, null, null), null, LViewFlags.CheckAlways,
|
||||
null, null, {} as any, {} as any);
|
||||
null, createTView(-1, null, 1, 0, null, null, null, null, null), null,
|
||||
LViewFlags.CheckAlways, null, null, {} as any, {} as any);
|
||||
const oldView = selectView(contentView, null);
|
||||
try {
|
||||
const parentTNode =
|
||||
|
@ -22,16 +22,7 @@ import {ComponentFixture, TemplateFixture} from './render_util';
|
||||
describe('instructions', () => {
|
||||
function createAnchor() { ɵɵelement(0, 'a'); }
|
||||
|
||||
function createDiv(initialClasses?: string[] | null, initialStyles?: string[] | null) {
|
||||
const attrs: any[] = [];
|
||||
if (initialClasses) {
|
||||
attrs.push(AttributeMarker.Classes, ...initialClasses);
|
||||
}
|
||||
if (initialStyles) {
|
||||
attrs.push(AttributeMarker.Styles, ...initialStyles);
|
||||
}
|
||||
ɵɵelement(0, 'div', attrs);
|
||||
}
|
||||
function createDiv() { ɵɵelement(0, 'div', 0); }
|
||||
|
||||
function createScript() { ɵɵelement(0, 'script'); }
|
||||
|
||||
@ -85,8 +76,8 @@ describe('instructions', () => {
|
||||
describe('element', () => {
|
||||
it('should create an element with the correct perf counters', () => {
|
||||
const t = new TemplateFixture(() => {
|
||||
ɵɵelement(0, 'div', ['id', 'test', 'title', 'Hello']);
|
||||
}, () => {}, 1);
|
||||
ɵɵelement(0, 'div', 0);
|
||||
}, () => {}, 1, 0, null, null, null, undefined, [['id', 'test', 'title', 'Hello']]);
|
||||
|
||||
const div = (t.hostElement as HTMLElement).querySelector('div') !;
|
||||
expect(div.id).toEqual('test');
|
||||
@ -164,12 +155,13 @@ describe('instructions', () => {
|
||||
});
|
||||
|
||||
describe('styleMap', () => {
|
||||
function createDivWithStyle() {
|
||||
ɵɵelement(0, 'div', [AttributeMarker.Styles, 'height', '10px']);
|
||||
}
|
||||
const attrs = [[AttributeMarker.Styles, 'height', '10px']];
|
||||
|
||||
function createDivWithStyle() { ɵɵelement(0, 'div', 0); }
|
||||
|
||||
it('should add style', () => {
|
||||
const fixture = new TemplateFixture(createDivWithStyle, () => {}, 1);
|
||||
const fixture = new TemplateFixture(
|
||||
createDivWithStyle, () => {}, 1, 0, null, null, null, undefined, attrs);
|
||||
fixture.update(() => { ɵɵstyleMap({'background-color': 'red'}); });
|
||||
expect(fixture.html).toEqual('<div style="background-color: red; height: 10px;"></div>');
|
||||
});
|
||||
@ -213,13 +205,10 @@ describe('instructions', () => {
|
||||
|
||||
describe('performance counters', () => {
|
||||
it('should create tViews only once for each nested level', () => {
|
||||
const _c0 = [AttributeMarker.Template, 'ngFor', 'ngForOf'];
|
||||
const _c1 = [AttributeMarker.Template, 'ngFor', 'ngForOf'];
|
||||
|
||||
function ToDoAppComponent_NgForOf_Template_0(rf: RenderFlags, ctx0: NgForOfContext<any>) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
ɵɵelementStart(0, 'ul');
|
||||
ɵɵtemplate(1, ToDoAppComponent_NgForOf_NgForOf_Template_1, 2, 1, 'li', _c1);
|
||||
ɵɵtemplate(1, ToDoAppComponent_NgForOf_NgForOf_Template_1, 2, 1, 'li', 0);
|
||||
ɵɵelementEnd();
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
@ -255,11 +244,12 @@ describe('instructions', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: NestedLoops,
|
||||
selectors: [['nested-loops']],
|
||||
consts: 1,
|
||||
decls: 1,
|
||||
vars: 1,
|
||||
consts: [[AttributeMarker.Template, 'ngFor', 'ngForOf']],
|
||||
template: function ToDoAppComponent_Template(rf: RenderFlags, ctx: NestedLoops) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
ɵɵtemplate(0, ToDoAppComponent_NgForOf_Template_0, 2, 1, 'ul', _c0);
|
||||
ɵɵtemplate(0, ToDoAppComponent_NgForOf_Template_0, 2, 1, 'ul', 0);
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
ɵɵproperty('ngForOf', ctx.rows);
|
||||
@ -498,6 +488,6 @@ function stripStyleWsCharacters(value: string): string {
|
||||
}
|
||||
|
||||
function createTemplateFixtureWithSanitizer(
|
||||
buildFn: () => any, consts: number, sanitizer: Sanitizer) {
|
||||
return new TemplateFixture(buildFn, () => {}, consts, 0, null, null, sanitizer);
|
||||
buildFn: () => any, decls: number, sanitizer: Sanitizer) {
|
||||
return new TemplateFixture(buildFn, () => {}, decls, 0, null, null, sanitizer);
|
||||
}
|
||||
|
@ -121,7 +121,7 @@ describe('render3 integration test', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
selectors: [['child']],
|
||||
type: ChildComponent,
|
||||
consts: 3,
|
||||
decls: 3,
|
||||
vars: 0,
|
||||
template: function ChildComponentTemplate(
|
||||
rf: RenderFlags, ctx: {beforeTree: Tree, afterTree: Tree}) {
|
||||
@ -203,7 +203,7 @@ describe('component styles', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: StyledComp,
|
||||
styles: ['div { color: red; }'],
|
||||
consts: 1,
|
||||
decls: 1,
|
||||
vars: 0,
|
||||
encapsulation: 100,
|
||||
selectors: [['foo']],
|
||||
@ -230,7 +230,7 @@ describe('component animations', () => {
|
||||
static ngFactoryDef = () => new AnimComp();
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: AnimComp,
|
||||
consts: 0,
|
||||
decls: 0,
|
||||
vars: 0,
|
||||
data: {
|
||||
animation: [
|
||||
@ -257,7 +257,7 @@ describe('component animations', () => {
|
||||
static ngFactoryDef = () => new AnimComp();
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: AnimComp,
|
||||
consts: 0,
|
||||
decls: 0,
|
||||
vars: 0,
|
||||
data: {
|
||||
animation: [],
|
||||
@ -277,12 +277,13 @@ describe('component animations', () => {
|
||||
static ngFactoryDef = () => new AnimComp();
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: AnimComp,
|
||||
consts: 1,
|
||||
decls: 1,
|
||||
vars: 1,
|
||||
selectors: [['foo']],
|
||||
consts: [[AttributeMarker.Bindings, '@fooAnimation']],
|
||||
template: (rf: RenderFlags, ctx: AnimComp) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
ɵɵelement(0, 'div', [AttributeMarker.Bindings, '@fooAnimation']);
|
||||
ɵɵelement(0, 'div', 0);
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
ɵɵattribute('@fooAnimation', ctx.animationValue);
|
||||
@ -313,12 +314,13 @@ describe('component animations', () => {
|
||||
static ngFactoryDef = () => new AnimComp();
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: AnimComp,
|
||||
consts: 1,
|
||||
decls: 1,
|
||||
vars: 1,
|
||||
selectors: [['foo']],
|
||||
consts: [['@fooAnimation', '']],
|
||||
template: (rf: RenderFlags, ctx: AnimComp) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
ɵɵelement(0, 'div', ['@fooAnimation', '']);
|
||||
ɵɵelement(0, 'div', 0);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -361,7 +363,7 @@ describe('component animations', () => {
|
||||
// static ngFactoryDef = () => new ParentComp();
|
||||
// static ngComponentDef = ɵɵdefineComponent({
|
||||
// type: ParentComp,
|
||||
// consts: 1,
|
||||
// decls: 1,
|
||||
// vars: 1,
|
||||
// selectors: [['foo']],
|
||||
// template: (rf: RenderFlags, ctx: ParentComp) => {
|
||||
@ -392,7 +394,7 @@ describe('element discovery', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: StructuredComp,
|
||||
selectors: [['structured-comp']],
|
||||
consts: 2,
|
||||
decls: 2,
|
||||
vars: 0,
|
||||
template: (rf: RenderFlags, ctx: StructuredComp) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
@ -424,7 +426,7 @@ describe('element discovery', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: ChildComp,
|
||||
selectors: [['child-comp']],
|
||||
consts: 3,
|
||||
decls: 3,
|
||||
vars: 0,
|
||||
template: (rf: RenderFlags, ctx: ChildComp) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
@ -442,7 +444,7 @@ describe('element discovery', () => {
|
||||
type: ParentComp,
|
||||
selectors: [['parent-comp']],
|
||||
directives: [ChildComp],
|
||||
consts: 2,
|
||||
decls: 2,
|
||||
vars: 0,
|
||||
template: (rf: RenderFlags, ctx: ParentComp) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
@ -475,8 +477,9 @@ describe('element discovery', () => {
|
||||
type: StructuredComp,
|
||||
selectors: [['structured-comp']],
|
||||
directives: [NgIf],
|
||||
consts: 2,
|
||||
decls: 2,
|
||||
vars: 1,
|
||||
consts: [['ngIf', '']],
|
||||
template: (rf: RenderFlags, ctx: StructuredComp) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
ɵɵelementStart(0, 'section');
|
||||
@ -487,7 +490,7 @@ describe('element discovery', () => {
|
||||
ɵɵelementEnd();
|
||||
ɵɵelement(2, 'div');
|
||||
}
|
||||
}, 3, 0, 'ng-template', ['ngIf', '']);
|
||||
}, 3, 0, 'ng-template', 0);
|
||||
ɵɵelementEnd();
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
@ -524,7 +527,7 @@ describe('element discovery', () => {
|
||||
type: StructuredComp,
|
||||
selectors: [['structured-comp']],
|
||||
directives: [NgIf],
|
||||
consts: 2,
|
||||
decls: 2,
|
||||
vars: 0,
|
||||
template: (rf: RenderFlags, ctx: StructuredComp) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
@ -561,7 +564,7 @@ describe('element discovery', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: StructuredComp,
|
||||
selectors: [['structured-comp']],
|
||||
consts: 1,
|
||||
decls: 1,
|
||||
vars: 0,
|
||||
template: (rf: RenderFlags, ctx: StructuredComp) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
@ -593,7 +596,7 @@ describe('element discovery', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: StructuredComp,
|
||||
selectors: [['structured-comp']],
|
||||
consts: 2,
|
||||
decls: 2,
|
||||
vars: 0,
|
||||
template: (rf: RenderFlags, ctx: StructuredComp) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
@ -626,7 +629,7 @@ describe('element discovery', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: StructuredComp,
|
||||
selectors: [['structured-comp']],
|
||||
consts: 1,
|
||||
decls: 1,
|
||||
vars: 0,
|
||||
template: (rf: RenderFlags, ctx: StructuredComp) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
@ -674,7 +677,7 @@ describe('element discovery', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: ProjectorComp,
|
||||
selectors: [['projector-comp']],
|
||||
consts: 4,
|
||||
decls: 4,
|
||||
vars: 0,
|
||||
template: (rf: RenderFlags, ctx: ProjectorComp) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
@ -698,7 +701,7 @@ describe('element discovery', () => {
|
||||
type: ParentComp,
|
||||
selectors: [['parent-comp']],
|
||||
directives: [ProjectorComp],
|
||||
consts: 5,
|
||||
decls: 5,
|
||||
vars: 0,
|
||||
template: (rf: RenderFlags, ctx: ParentComp) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
@ -771,7 +774,7 @@ describe('element discovery', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: StructuredComp,
|
||||
selectors: [['structured-comp']],
|
||||
consts: 1,
|
||||
decls: 1,
|
||||
vars: 0,
|
||||
template: (rf: RenderFlags, ctx: StructuredComp) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
@ -798,7 +801,7 @@ describe('element discovery', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: StructuredComp,
|
||||
selectors: [['structured-comp']],
|
||||
consts: 0,
|
||||
decls: 0,
|
||||
vars: 0,
|
||||
template: (rf: RenderFlags, ctx: StructuredComp) => {}
|
||||
});
|
||||
@ -856,12 +859,13 @@ describe('element discovery', () => {
|
||||
type: StructuredComp,
|
||||
selectors: [['structured-comp']],
|
||||
directives: [MyDir1, MyDir2, MyDir3],
|
||||
consts: 2,
|
||||
decls: 2,
|
||||
vars: 0,
|
||||
consts: [['my-dir-1', '', 'my-dir-2', ''], ['my-dir-3']],
|
||||
template: (rf: RenderFlags, ctx: StructuredComp) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
ɵɵelement(0, 'div', ['my-dir-1', '', 'my-dir-2', '']);
|
||||
ɵɵelement(1, 'div', ['my-dir-3']);
|
||||
ɵɵelement(0, 'div', 0);
|
||||
ɵɵelement(1, 'div', 1);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -932,7 +936,7 @@ describe('element discovery', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: ChildComp,
|
||||
selectors: [['child-comp']],
|
||||
consts: 1,
|
||||
decls: 1,
|
||||
vars: 0,
|
||||
template: (rf: RenderFlags, ctx: ChildComp) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
@ -948,11 +952,12 @@ describe('element discovery', () => {
|
||||
type: ParentComp,
|
||||
selectors: [['parent-comp']],
|
||||
directives: [ChildComp, MyDir1, MyDir2],
|
||||
consts: 1,
|
||||
decls: 1,
|
||||
vars: 0,
|
||||
consts: [['my-dir-1', '', 'my-dir-2', '']],
|
||||
template: (rf: RenderFlags, ctx: ParentComp) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
ɵɵelement(0, 'child-comp', ['my-dir-1', '', 'my-dir-2', '']);
|
||||
ɵɵelement(0, 'child-comp', 0);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -1009,7 +1014,7 @@ describe('element discovery', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: ChildComp,
|
||||
selectors: [['child-comp']],
|
||||
consts: 3,
|
||||
decls: 3,
|
||||
vars: 0,
|
||||
template: (rf: RenderFlags, ctx: ChildComp) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
@ -1027,7 +1032,7 @@ describe('element discovery', () => {
|
||||
type: ParentComp,
|
||||
selectors: [['parent-comp']],
|
||||
directives: [ChildComp],
|
||||
consts: 2,
|
||||
decls: 2,
|
||||
vars: 0,
|
||||
template: (rf: RenderFlags, ctx: ParentComp) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
@ -1070,7 +1075,7 @@ describe('sanitization', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: SanitizationComp,
|
||||
selectors: [['sanitize-this']],
|
||||
consts: 1,
|
||||
decls: 1,
|
||||
vars: 1,
|
||||
template: (rf: RenderFlags, ctx: SanitizationComp) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
@ -1128,11 +1133,12 @@ describe('sanitization', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: SimpleComp,
|
||||
selectors: [['sanitize-this']],
|
||||
consts: 1,
|
||||
decls: 1,
|
||||
vars: 0,
|
||||
consts: [['unsafeUrlHostBindingDir', '']],
|
||||
template: (rf: RenderFlags, ctx: SimpleComp) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
ɵɵelement(0, 'blockquote', ['unsafeUrlHostBindingDir', '']);
|
||||
ɵɵelement(0, 'blockquote', 0);
|
||||
}
|
||||
},
|
||||
directives: [UnsafeUrlHostBindingDir]
|
||||
|
@ -46,7 +46,7 @@ describe('lifecycles', () => {
|
||||
}, 1);
|
||||
|
||||
function createOnInitComponent(
|
||||
name: string, template: ComponentTemplate<any>, consts: number, vars: number = 0,
|
||||
name: string, template: ComponentTemplate<any>, decls: number, vars: number = 0,
|
||||
directives: any[] = []) {
|
||||
return class Component {
|
||||
val: string = '';
|
||||
@ -59,7 +59,7 @@ describe('lifecycles', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: Component,
|
||||
selectors: [[name]],
|
||||
consts: consts,
|
||||
decls: decls,
|
||||
vars: vars,
|
||||
inputs: {val: 'val'}, template,
|
||||
directives: directives
|
||||
|
@ -37,7 +37,7 @@ describe('event listeners', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: MyComp,
|
||||
selectors: [['comp']],
|
||||
consts: 2,
|
||||
decls: 2,
|
||||
vars: 0,
|
||||
/** <button (click)="onClick()"> Click me </button> */
|
||||
template: function CompTemplate(rf: RenderFlags, ctx: any) {
|
||||
@ -70,7 +70,7 @@ describe('event listeners', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: MyCompWithGlobalListeners,
|
||||
selectors: [['comp']],
|
||||
consts: 1,
|
||||
decls: 1,
|
||||
vars: 0,
|
||||
template: function CompTemplate(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
@ -138,7 +138,7 @@ describe('event listeners', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: PreventDefaultComp,
|
||||
selectors: [['prevent-default-comp']],
|
||||
consts: 2,
|
||||
decls: 2,
|
||||
vars: 0,
|
||||
/** <button (click)="onClick($event)">Click</button> */
|
||||
template: (rf: RenderFlags, ctx: PreventDefaultComp) => {
|
||||
@ -329,7 +329,7 @@ describe('event listeners', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: AppComp,
|
||||
selectors: [['app-comp']],
|
||||
consts: 1,
|
||||
decls: 1,
|
||||
vars: 0,
|
||||
template: function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
@ -390,7 +390,7 @@ describe('event listeners', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: AppComp,
|
||||
selectors: [['app-comp']],
|
||||
consts: 1,
|
||||
decls: 1,
|
||||
vars: 0,
|
||||
template: function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
@ -454,7 +454,7 @@ describe('event listeners', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: AppComp,
|
||||
selectors: [['app-comp']],
|
||||
consts: 1,
|
||||
decls: 1,
|
||||
vars: 0,
|
||||
template: function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
@ -533,7 +533,7 @@ describe('event listeners', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: MyComp,
|
||||
selectors: [['comp']],
|
||||
consts: 1,
|
||||
decls: 1,
|
||||
vars: 0,
|
||||
template: function CompTemplate(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
@ -594,10 +594,10 @@ describe('event listeners', () => {
|
||||
}
|
||||
|
||||
const fixture = new TemplateFixture(() => {
|
||||
ɵɵelementStart(0, 'button', ['hostListenerDir', '']);
|
||||
ɵɵelementStart(0, 'button', 0);
|
||||
ɵɵtext(1, 'Click');
|
||||
ɵɵelementEnd();
|
||||
}, () => {}, 2, 0, [HostListenerDir]);
|
||||
}, () => {}, 2, 0, [HostListenerDir], null, null, undefined, [['hostListenerDir', '']]);
|
||||
|
||||
const button = fixture.hostElement.querySelector('button') !;
|
||||
|
||||
@ -610,8 +610,8 @@ describe('event listeners', () => {
|
||||
|
||||
it('should support global host listeners on directives', () => {
|
||||
const fixture = new TemplateFixture(() => {
|
||||
ɵɵelement(0, 'div', ['hostListenerDir', '']);
|
||||
}, () => {}, 1, 0, [GlobalHostListenerDir]);
|
||||
ɵɵelement(0, 'div', 0);
|
||||
}, () => {}, 1, 0, [GlobalHostListenerDir], null, null, undefined, [['hostListenerDir', '']]);
|
||||
|
||||
const doc = fixture.hostElement.ownerDocument !;
|
||||
|
||||
@ -636,7 +636,7 @@ describe('event listeners', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: MyComp,
|
||||
selectors: [['comp']],
|
||||
consts: 2,
|
||||
decls: 2,
|
||||
vars: 0,
|
||||
/** <button (click)="onClick(data.a, data.b)"> Click me </button> */
|
||||
template: function CompTemplate(rf: RenderFlags, ctx: any) {
|
||||
@ -917,7 +917,7 @@ describe('event listeners', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: App,
|
||||
selectors: [['app']],
|
||||
consts: 3,
|
||||
decls: 3,
|
||||
vars: 0,
|
||||
template: (rf: RenderFlags, ctx: App) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
|
@ -26,7 +26,7 @@ describe('outputs', () => {
|
||||
type: ButtonToggle,
|
||||
selectors: [['button-toggle']],
|
||||
template: function(rf: RenderFlags, ctx: any) {},
|
||||
consts: 0,
|
||||
decls: 0,
|
||||
vars: 0,
|
||||
outputs: {change: 'change', resetStream: 'reset'}
|
||||
});
|
||||
@ -80,7 +80,7 @@ describe('outputs', () => {
|
||||
ɵɵembeddedViewEnd();
|
||||
} else {
|
||||
if (ɵɵembeddedViewStart(1, 1, 0)) {
|
||||
ɵɵelementStart(0, 'div', ['otherDir', '']);
|
||||
ɵɵelementStart(0, 'div', 0);
|
||||
{
|
||||
ɵɵlistener('change', function() { return ctx.onChange(); });
|
||||
}
|
||||
@ -95,13 +95,14 @@ describe('outputs', () => {
|
||||
|
||||
let counter = 0;
|
||||
const ctx = {condition: true, onChange: () => counter++, onClick: () => {}};
|
||||
renderToHtml(Template, ctx, 3, 0, deps);
|
||||
const attrs = [['otherDir', '']];
|
||||
renderToHtml(Template, ctx, 3, 0, deps, null, null, false, attrs);
|
||||
|
||||
buttonToggle !.change.next();
|
||||
expect(counter).toEqual(1);
|
||||
|
||||
ctx.condition = false;
|
||||
renderToHtml(Template, ctx, 3, 0, deps);
|
||||
renderToHtml(Template, ctx, 3, 0, deps, null, null, false, attrs);
|
||||
expect(counter).toEqual(1);
|
||||
|
||||
otherDir !.changeStream.next();
|
||||
|
@ -68,7 +68,7 @@ function testTemplate(rf: RenderFlags, ctx: any) {
|
||||
}
|
||||
|
||||
const viewTNode = createTNode(null !, null, TNodeType.View, -1, null, null) as TViewNode;
|
||||
const embeddedTView = createTView(-1, testTemplate, 21, 0, null, null, null, null);
|
||||
const embeddedTView = createTView(-1, testTemplate, 21, 0, null, null, null, null, null);
|
||||
|
||||
// initialize global state
|
||||
resetComponentState();
|
||||
@ -89,4 +89,4 @@ while (createTime()) {
|
||||
console.profileEnd();
|
||||
|
||||
// report results
|
||||
elementTextCreate.report();
|
||||
elementTextCreate.report();
|
||||
|
@ -28,47 +28,46 @@ import {createAndRenderLView} from '../setup';
|
||||
<button (click)="clickListener()" (input)="inputListener()"></button>
|
||||
</div>
|
||||
`;
|
||||
const _c0 = [3, 'click', 'input'];
|
||||
function testTemplate(rf: RenderFlags, ctx: any) {
|
||||
if (rf & 1) {
|
||||
ɵɵelementStart(0, 'div');
|
||||
ɵɵelementStart(1, 'button', _c0);
|
||||
ɵɵelementStart(1, 'button', 0);
|
||||
ɵɵlistener('click', function clickListener() {});
|
||||
ɵɵlistener('input', function inputListener() {});
|
||||
ɵɵelementEnd();
|
||||
ɵɵelementStart(2, 'button', _c0);
|
||||
ɵɵelementStart(2, 'button', 0);
|
||||
ɵɵlistener('click', function clickListener() {});
|
||||
ɵɵlistener('input', function inputListener() {});
|
||||
ɵɵelementEnd();
|
||||
ɵɵelementStart(3, 'button', _c0);
|
||||
ɵɵelementStart(3, 'button', 0);
|
||||
ɵɵlistener('click', function clickListener() {});
|
||||
ɵɵlistener('input', function inputListener() {});
|
||||
ɵɵelementEnd();
|
||||
ɵɵelementStart(4, 'button', _c0);
|
||||
ɵɵelementStart(4, 'button', 0);
|
||||
ɵɵlistener('click', function clickListener() {});
|
||||
ɵɵlistener('input', function inputListener() {});
|
||||
ɵɵelementEnd();
|
||||
ɵɵelementStart(5, 'button', _c0);
|
||||
ɵɵelementStart(5, 'button', 0);
|
||||
ɵɵlistener('click', function clickListener() {});
|
||||
ɵɵlistener('input', function inputListener() {});
|
||||
ɵɵelementEnd();
|
||||
ɵɵelementStart(6, 'button', _c0);
|
||||
ɵɵelementStart(6, 'button', 0);
|
||||
ɵɵlistener('click', function clickListener() {});
|
||||
ɵɵlistener('input', function inputListener() {});
|
||||
ɵɵelementEnd();
|
||||
ɵɵelementStart(7, 'button', _c0);
|
||||
ɵɵelementStart(7, 'button', 0);
|
||||
ɵɵlistener('click', function clickListener() {});
|
||||
ɵɵlistener('input', function inputListener() {});
|
||||
ɵɵelementEnd();
|
||||
ɵɵelementStart(8, 'button', _c0);
|
||||
ɵɵelementStart(8, 'button', 0);
|
||||
ɵɵlistener('click', function clickListener() {});
|
||||
ɵɵlistener('input', function inputListener() {});
|
||||
ɵɵelementEnd();
|
||||
ɵɵelementStart(9, 'button', _c0);
|
||||
ɵɵelementStart(9, 'button', 0);
|
||||
ɵɵlistener('click', function clickListener() {});
|
||||
ɵɵlistener('input', function inputListener() {});
|
||||
ɵɵelementEnd();
|
||||
ɵɵelementStart(10, 'button', _c0);
|
||||
ɵɵelementStart(10, 'button', 0);
|
||||
ɵɵlistener('click', function clickListener() {});
|
||||
ɵɵlistener('input', function inputListener() {});
|
||||
ɵɵelementEnd();
|
||||
@ -77,7 +76,8 @@ function testTemplate(rf: RenderFlags, ctx: any) {
|
||||
}
|
||||
|
||||
const viewTNode = createTNode(null !, null, TNodeType.View, -1, null, null) as TViewNode;
|
||||
const embeddedTView = createTView(-1, testTemplate, 11, 0, null, null, null, null);
|
||||
const embeddedTView =
|
||||
createTView(-1, testTemplate, 11, 0, null, null, null, null, [[3, 'click', 'input']]);
|
||||
|
||||
// initialize global state
|
||||
resetComponentState();
|
||||
@ -96,4 +96,4 @@ while (createTime()) {
|
||||
console.profileEnd();
|
||||
|
||||
// report results
|
||||
listenersCreate.report();
|
||||
listenersCreate.report();
|
||||
|
@ -7,7 +7,7 @@
|
||||
*/
|
||||
import {addToViewTree, createLContainer, createLView, createTNode, createTView, getOrCreateTNode, renderView} from '../../../src/render3/instructions/shared';
|
||||
import {ComponentTemplate} from '../../../src/render3/interfaces/definition';
|
||||
import {TNodeType, TViewNode} from '../../../src/render3/interfaces/node';
|
||||
import {TAttributes, TNodeType, TViewNode} from '../../../src/render3/interfaces/node';
|
||||
import {RComment} from '../../../src/render3/interfaces/renderer';
|
||||
import {LView, LViewFlags, TView} from '../../../src/render3/interfaces/view';
|
||||
import {insertView} from '../../../src/render3/node_manipulation';
|
||||
@ -23,10 +23,10 @@ export function createAndRenderLView(
|
||||
}
|
||||
|
||||
export function setupRootViewWithEmbeddedViews(
|
||||
templateFn: ComponentTemplate<any>| null, consts: number, vars: number, noOfViews: number,
|
||||
embeddedViewContext: any = {}): LView {
|
||||
templateFn: ComponentTemplate<any>| null, decls: number, vars: number, noOfViews: number,
|
||||
embeddedViewContext: any = {}, consts: TAttributes[] | null = null): LView {
|
||||
// Create a root view with a container
|
||||
const rootTView = createTView(-1, null, 1, 0, null, null, null, null);
|
||||
const rootTView = createTView(-1, null, 1, 0, null, null, null, null, consts);
|
||||
const tContainerNode = getOrCreateTNode(rootTView, null, 0, TNodeType.Container, null, null);
|
||||
const rootLView = createLView(
|
||||
null, rootTView, {}, LViewFlags.CheckAlways | LViewFlags.IsRoot, null, null,
|
||||
@ -38,7 +38,7 @@ export function setupRootViewWithEmbeddedViews(
|
||||
|
||||
|
||||
// create test embedded views
|
||||
const embeddedTView = createTView(-1, templateFn, consts, vars, null, null, null, null);
|
||||
const embeddedTView = createTView(-1, templateFn, decls, vars, null, null, null, null, null);
|
||||
const viewTNode = createTNode(rootTView, null, TNodeType.View, -1, null, null) as TViewNode;
|
||||
|
||||
// create embedded views and add them to the container
|
||||
@ -54,4 +54,4 @@ export function setupRootViewWithEmbeddedViews(
|
||||
renderView(rootLView, rootTView, null);
|
||||
|
||||
return rootLView;
|
||||
}
|
||||
}
|
||||
|
@ -31,18 +31,17 @@ import {setupRootViewWithEmbeddedViews} from '../setup';
|
||||
</ng-template>`;
|
||||
function testTemplate(rf: RenderFlags, ctx: any) {
|
||||
if (rf & 1) {
|
||||
ɵɵelementStart(0, 'div', [AttributeMarker.Classes, 'list']);
|
||||
ɵɵelement(1, 'div', [AttributeMarker.Classes, 'item', AttributeMarker.Styles, 'width', '50px']);
|
||||
ɵɵelement(2, 'div', [AttributeMarker.Classes, 'item', AttributeMarker.Styles, 'width', '50px']);
|
||||
ɵɵelement(3, 'div', [AttributeMarker.Classes, 'item', AttributeMarker.Styles, 'width', '50px']);
|
||||
ɵɵelement(4, 'div', [AttributeMarker.Classes, 'item', AttributeMarker.Styles, 'width', '50px']);
|
||||
ɵɵelement(5, 'div', [AttributeMarker.Classes, 'item', AttributeMarker.Styles, 'width', '50px']);
|
||||
ɵɵelement(6, 'div', [AttributeMarker.Classes, 'item', AttributeMarker.Styles, 'width', '50px']);
|
||||
ɵɵelement(7, 'div', [AttributeMarker.Classes, 'item', AttributeMarker.Styles, 'width', '50px']);
|
||||
ɵɵelement(8, 'div', [AttributeMarker.Classes, 'item', AttributeMarker.Styles, 'width', '50px']);
|
||||
ɵɵelement(9, 'div', [AttributeMarker.Classes, 'item', AttributeMarker.Styles, 'width', '50px']);
|
||||
ɵɵelement(
|
||||
10, 'div', [AttributeMarker.Classes, 'item', AttributeMarker.Styles, 'width', '50px']);
|
||||
ɵɵelementStart(0, 'div', 0);
|
||||
ɵɵelement(1, 'div', 1);
|
||||
ɵɵelement(2, 'div', 1);
|
||||
ɵɵelement(3, 'div', 1);
|
||||
ɵɵelement(4, 'div', 1);
|
||||
ɵɵelement(5, 'div', 1);
|
||||
ɵɵelement(6, 'div', 1);
|
||||
ɵɵelement(7, 'div', 1);
|
||||
ɵɵelement(8, 'div', 1);
|
||||
ɵɵelement(9, 'div', 1);
|
||||
ɵɵelement(10, 'div', 1);
|
||||
ɵɵelementEnd();
|
||||
}
|
||||
if (rf & 2) {
|
||||
@ -80,7 +79,10 @@ function testTemplate(rf: RenderFlags, ctx: any) {
|
||||
}
|
||||
|
||||
|
||||
const rootLView = setupRootViewWithEmbeddedViews(testTemplate, 11, 10, 1000);
|
||||
const rootLView = setupRootViewWithEmbeddedViews(testTemplate, 11, 10, 1000, undefined, [
|
||||
[AttributeMarker.Classes, 'list'],
|
||||
[AttributeMarker.Classes, 'item', AttributeMarker.Styles, 'width', '50px']
|
||||
]);
|
||||
const rootTView = rootLView[TVIEW];
|
||||
|
||||
// scenario to benchmark
|
||||
|
@ -873,7 +873,7 @@ describe('providers', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: Repeated,
|
||||
selectors: [['repeated']],
|
||||
consts: 2,
|
||||
decls: 2,
|
||||
vars: 2,
|
||||
template: function(fs: RenderFlags, ctx: Repeated) {
|
||||
if (fs & RenderFlags.Create) {
|
||||
@ -904,7 +904,7 @@ describe('providers', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: ComponentWithProviders,
|
||||
selectors: [['component-with-providers']],
|
||||
consts: 2,
|
||||
decls: 2,
|
||||
vars: 0,
|
||||
template: function(fs: RenderFlags, ctx: ComponentWithProviders) {
|
||||
if (fs & RenderFlags.Create) {
|
||||
@ -959,7 +959,7 @@ describe('providers', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: Repeated,
|
||||
selectors: [['repeated']],
|
||||
consts: 2,
|
||||
decls: 2,
|
||||
vars: 2,
|
||||
template: function(fs: RenderFlags, ctx: Repeated) {
|
||||
if (fs & RenderFlags.Create) {
|
||||
@ -993,7 +993,7 @@ describe('providers', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: ComponentWithProviders,
|
||||
selectors: [['component-with-providers']],
|
||||
consts: 2,
|
||||
decls: 2,
|
||||
vars: 0,
|
||||
template: function(fs: RenderFlags, ctx: ComponentWithProviders) {
|
||||
if (fs & RenderFlags.Create) {
|
||||
@ -1042,7 +1042,7 @@ describe('providers', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: EmbeddedComponent,
|
||||
selectors: [['embedded-cmp']],
|
||||
consts: 1,
|
||||
decls: 1,
|
||||
vars: 1,
|
||||
template: (rf: RenderFlags, cmp: EmbeddedComponent) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
@ -1065,7 +1065,7 @@ describe('providers', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: HostComponent,
|
||||
selectors: [['host-cmp']],
|
||||
consts: 1,
|
||||
decls: 1,
|
||||
vars: 0,
|
||||
template: (rf: RenderFlags, cmp: HostComponent) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
@ -1089,7 +1089,7 @@ describe('providers', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: AppComponent,
|
||||
selectors: [['app-cmp']],
|
||||
consts: 1,
|
||||
decls: 1,
|
||||
vars: 0,
|
||||
template: (rf: RenderFlags, cmp: AppComponent) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
@ -1251,7 +1251,7 @@ describe('providers', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: MyComponent,
|
||||
selectors: [['my-cmp']],
|
||||
consts: 1,
|
||||
decls: 1,
|
||||
vars: 0,
|
||||
template: (rf: RenderFlags, cmp: MyComponent) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
@ -1278,7 +1278,7 @@ describe('providers', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: AppComponent,
|
||||
selectors: [['app-cmp']],
|
||||
consts: 1,
|
||||
decls: 1,
|
||||
vars: 0,
|
||||
template: (rf: RenderFlags, cmp: AppComponent) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
@ -1343,7 +1343,7 @@ describe('providers', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: MyComponent,
|
||||
selectors: [['my-comp']],
|
||||
consts: 1,
|
||||
decls: 1,
|
||||
vars: 0,
|
||||
template: (rf: RenderFlags, ctx: MyComponent) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
@ -1370,7 +1370,7 @@ describe('providers', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: App,
|
||||
selectors: [['app-cmp']],
|
||||
consts: 2,
|
||||
decls: 2,
|
||||
vars: 0,
|
||||
template: (rf: RenderFlags, ctx: App) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
@ -1445,7 +1445,7 @@ function expectProvidersScenario(defs: {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: ViewChildComponent,
|
||||
selectors: [['view-child']],
|
||||
consts: 1,
|
||||
decls: 1,
|
||||
vars: 0,
|
||||
template: function(fs: RenderFlags, ctx: ViewChildComponent) {
|
||||
if (fs & RenderFlags.Create) {
|
||||
@ -1473,7 +1473,7 @@ function expectProvidersScenario(defs: {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: ContentChildComponent,
|
||||
selectors: [['content-child']],
|
||||
consts: 1,
|
||||
decls: 1,
|
||||
vars: 0,
|
||||
template: function(fs: RenderFlags, ctx: ParentComponent) {
|
||||
if (fs & RenderFlags.Create) {
|
||||
@ -1504,7 +1504,7 @@ function expectProvidersScenario(defs: {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: ParentComponent,
|
||||
selectors: [['parent']],
|
||||
consts: 1,
|
||||
decls: 1,
|
||||
vars: 0,
|
||||
template: function(fs: RenderFlags, ctx: ParentComponent) {
|
||||
if (fs & RenderFlags.Create) {
|
||||
@ -1541,7 +1541,7 @@ function expectProvidersScenario(defs: {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: App,
|
||||
selectors: [['app']],
|
||||
consts: 2,
|
||||
decls: 2,
|
||||
vars: 0,
|
||||
template: function(fs: RenderFlags, ctx: App) {
|
||||
if (fs & RenderFlags.Create) {
|
||||
|
@ -23,7 +23,7 @@ describe('object literals', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: ObjectComp,
|
||||
selectors: [['object-comp']],
|
||||
consts: 0,
|
||||
decls: 0,
|
||||
vars: 1,
|
||||
template: function ObjectComp_Template() {},
|
||||
inputs: {config: 'config'}
|
||||
|
@ -113,7 +113,7 @@ describe('query', () => {
|
||||
'cmpt',
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
ɵɵelement(0, 'div', ['child', '']);
|
||||
ɵɵelement(0, 'div', 0);
|
||||
elToQuery = getNativeByIndex(0, getLView());
|
||||
}
|
||||
},
|
||||
@ -127,7 +127,8 @@ describe('query', () => {
|
||||
ɵɵqueryRefresh(tmp = ɵɵloadQuery<QueryList<any>>()) &&
|
||||
(ctx.query = tmp as QueryList<any>);
|
||||
}
|
||||
});
|
||||
},
|
||||
[], [], undefined, [['child', '']]);
|
||||
|
||||
const cmptInstance = renderComponent(Cmpt);
|
||||
const qList = (cmptInstance.query as QueryList<any>);
|
||||
@ -150,7 +151,7 @@ describe('query', () => {
|
||||
'cmpt',
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
ɵɵelementStart(0, 'div', ['child', '', 'otherChild', '']);
|
||||
ɵɵelementStart(0, 'div', 0);
|
||||
{ otherChildInstance = getDirectiveOnNode(0, 1); }
|
||||
ɵɵelementEnd();
|
||||
}
|
||||
@ -165,7 +166,8 @@ describe('query', () => {
|
||||
ɵɵqueryRefresh(tmp = ɵɵloadQuery<QueryList<any>>()) &&
|
||||
(ctx.query = tmp as QueryList<any>);
|
||||
}
|
||||
});
|
||||
},
|
||||
[], [], undefined, [['child', '', 'otherChild', '']]);
|
||||
|
||||
const cmptInstance = renderComponent(Cmpt);
|
||||
const qList = (cmptInstance.query as QueryList<any>);
|
||||
@ -186,7 +188,7 @@ describe('query', () => {
|
||||
'cmpt',
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
ɵɵelement(0, 'div', ['child', '']);
|
||||
ɵɵelement(0, 'div', 0);
|
||||
}
|
||||
},
|
||||
1, 0, [Child, OtherChild], [],
|
||||
@ -199,7 +201,8 @@ describe('query', () => {
|
||||
ɵɵqueryRefresh(tmp = ɵɵloadQuery<QueryList<any>>()) &&
|
||||
(ctx.query = tmp as QueryList<any>);
|
||||
}
|
||||
});
|
||||
},
|
||||
[], [], undefined, [['child', '']]);
|
||||
|
||||
const cmptInstance = renderComponent(Cmpt);
|
||||
const qList = (cmptInstance.query as QueryList<any>);
|
||||
@ -249,11 +252,12 @@ describe('query', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: App,
|
||||
selectors: [['app']],
|
||||
consts: 1,
|
||||
decls: 1,
|
||||
vars: 0,
|
||||
consts: [['myDir']],
|
||||
template: function App_Template(rf: RenderFlags, ctx: App) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
ɵɵelement(0, 'div', ['myDir']);
|
||||
ɵɵelement(0, 'div', 0);
|
||||
}
|
||||
},
|
||||
viewQuery: function(rf: RenderFlags, ctx: App) {
|
||||
@ -294,11 +298,12 @@ describe('query', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: App,
|
||||
selectors: [['app']],
|
||||
consts: 1,
|
||||
decls: 1,
|
||||
vars: 0,
|
||||
consts: [['myDir']],
|
||||
template: function App_Template(rf: RenderFlags, ctx: App) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
ɵɵelement(0, 'div', ['myDir']);
|
||||
ɵɵelement(0, 'div', 0);
|
||||
}
|
||||
},
|
||||
viewQuery: function(rf: RenderFlags, ctx: App) {
|
||||
@ -837,7 +842,7 @@ describe('query', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: Child,
|
||||
selectors: [['child']],
|
||||
consts: 0,
|
||||
decls: 0,
|
||||
vars: 0,
|
||||
template: (rf: RenderFlags, ctx: Child) => {},
|
||||
exportAs: ['child']
|
||||
@ -890,7 +895,7 @@ describe('query', () => {
|
||||
'cmpt',
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
ɵɵelement(0, 'div', ['child', ''], ['foo', 'child']);
|
||||
ɵɵelement(0, 'div', 0, ['foo', 'child']);
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
childInstance = getDirectiveOnNode(0);
|
||||
@ -906,7 +911,8 @@ describe('query', () => {
|
||||
ɵɵqueryRefresh(tmp = ɵɵloadQuery<QueryList<any>>()) &&
|
||||
(ctx.query = tmp as QueryList<any>);
|
||||
}
|
||||
});
|
||||
},
|
||||
[], [], undefined, [['child', '']]);
|
||||
|
||||
const cmptInstance = renderComponent(Cmpt);
|
||||
const qList = (cmptInstance.query as QueryList<any>);
|
||||
@ -929,8 +935,7 @@ describe('query', () => {
|
||||
'cmpt',
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
ɵɵelement(
|
||||
0, 'div', ['child1', '', 'child2', ''], ['foo', 'child1', 'bar', 'child2']);
|
||||
ɵɵelement(0, 'div', 0, ['foo', 'child1', 'bar', 'child2']);
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
child1Instance = getDirectiveOnNode(0, 0);
|
||||
@ -947,7 +952,8 @@ describe('query', () => {
|
||||
ɵɵqueryRefresh(tmp = ɵɵloadQuery<QueryList<any>>()) &&
|
||||
(ctx.query = tmp as QueryList<any>);
|
||||
}
|
||||
});
|
||||
},
|
||||
[], [], undefined, [['child1', '', 'child2', '']]);
|
||||
|
||||
const cmptInstance = renderComponent(Cmpt);
|
||||
const qList = (cmptInstance.query as QueryList<any>);
|
||||
@ -971,7 +977,7 @@ describe('query', () => {
|
||||
'cmpt',
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
ɵɵelement(0, 'div', ['child', ''], ['foo', 'child', 'bar', 'child']);
|
||||
ɵɵelement(0, 'div', 0, ['foo', 'child', 'bar', 'child']);
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
childInstance = getDirectiveOnNode(0);
|
||||
@ -990,7 +996,8 @@ describe('query', () => {
|
||||
ɵɵqueryRefresh(tmp = ɵɵloadQuery<QueryList<any>>()) &&
|
||||
(ctx.barQuery = tmp as QueryList<any>);
|
||||
}
|
||||
});
|
||||
},
|
||||
[], [], undefined, [['child', '']]);
|
||||
|
||||
const cmptInstance = renderComponent(Cmpt);
|
||||
|
||||
@ -1017,7 +1024,7 @@ describe('query', () => {
|
||||
'cmpt',
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
ɵɵelement(0, 'div', ['child', ''], ['foo', 'child']);
|
||||
ɵɵelement(0, 'div', 0, ['foo', 'child']);
|
||||
div = getNativeByIndex(0, getLView());
|
||||
}
|
||||
},
|
||||
@ -1031,7 +1038,8 @@ describe('query', () => {
|
||||
ɵɵqueryRefresh(tmp = ɵɵloadQuery<QueryList<any>>()) &&
|
||||
(ctx.query = tmp as QueryList<any>);
|
||||
}
|
||||
});
|
||||
},
|
||||
[], [], undefined, [['child', '']]);
|
||||
|
||||
const cmptInstance = renderComponent(Cmpt);
|
||||
const qList = (cmptInstance.query as QueryList<any>);
|
||||
@ -1053,7 +1061,7 @@ describe('query', () => {
|
||||
'cmpt',
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
ɵɵelement(0, 'div', ['child', ''], ['foo', '', 'bar', 'child']);
|
||||
ɵɵelement(0, 'div', 0, ['foo', '', 'bar', 'child']);
|
||||
div = getNativeByIndex(0, getLView());
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
@ -1070,7 +1078,8 @@ describe('query', () => {
|
||||
ɵɵqueryRefresh(tmp = ɵɵloadQuery<QueryList<any>>()) &&
|
||||
(ctx.query = tmp as QueryList<any>);
|
||||
}
|
||||
});
|
||||
},
|
||||
[], [], undefined, [['child', '']]);
|
||||
|
||||
const cmptInstance = renderComponent(Cmpt);
|
||||
const qList = (cmptInstance.query as QueryList<any>);
|
||||
@ -1092,7 +1101,7 @@ describe('query', () => {
|
||||
'cmpt',
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
ɵɵelement(0, 'div', ['foo', '']);
|
||||
ɵɵelement(0, 'div', 0);
|
||||
}
|
||||
},
|
||||
2, 0, [Child], [],
|
||||
@ -1105,7 +1114,8 @@ describe('query', () => {
|
||||
ɵɵqueryRefresh(tmp = ɵɵloadQuery<QueryList<any>>()) &&
|
||||
(ctx.query = tmp as QueryList<any>);
|
||||
}
|
||||
});
|
||||
},
|
||||
[], [], undefined, [['foo', '']]);
|
||||
|
||||
const {component} = new ComponentFixture(Cmpt);
|
||||
const qList = component.query;
|
||||
@ -1126,7 +1136,7 @@ describe('query', () => {
|
||||
'cmpt',
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
ɵɵelement(0, 'div', ['child', '']);
|
||||
ɵɵelement(0, 'div', 0);
|
||||
}
|
||||
},
|
||||
1, 0, [Child, OtherChild], [],
|
||||
@ -1139,7 +1149,8 @@ describe('query', () => {
|
||||
ɵɵqueryRefresh(tmp = ɵɵloadQuery<QueryList<any>>()) &&
|
||||
(ctx.query = tmp as QueryList<any>);
|
||||
}
|
||||
});
|
||||
},
|
||||
[], [], undefined, [['child', '']]);
|
||||
|
||||
const {component} = new ComponentFixture(Cmpt);
|
||||
const qList = component.query;
|
||||
@ -1160,7 +1171,7 @@ describe('query', () => {
|
||||
'cmpt',
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
ɵɵelement(0, 'div', ['child', '']);
|
||||
ɵɵelement(0, 'div', 0);
|
||||
}
|
||||
},
|
||||
1, 0, [Child, OtherChild], [],
|
||||
@ -1173,7 +1184,8 @@ describe('query', () => {
|
||||
ɵɵqueryRefresh(tmp = ɵɵloadQuery<QueryList<any>>()) &&
|
||||
(ctx.query = tmp as QueryList<any>);
|
||||
}
|
||||
});
|
||||
},
|
||||
[], [], undefined, [['child', '']]);
|
||||
|
||||
const {component} = new ComponentFixture(Cmpt);
|
||||
const qList = component.query;
|
||||
@ -1224,7 +1236,7 @@ describe('query', () => {
|
||||
'cmpt',
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
ɵɵelement(0, 'div', ['child', ''], ['foo', '']);
|
||||
ɵɵelement(0, 'div', 0, ['foo', '']);
|
||||
}
|
||||
},
|
||||
2, 0, [Child], [],
|
||||
@ -1237,7 +1249,8 @@ describe('query', () => {
|
||||
ɵɵqueryRefresh(tmp = ɵɵloadQuery<QueryList<any>>()) &&
|
||||
(ctx.query = tmp as QueryList<any>);
|
||||
}
|
||||
});
|
||||
},
|
||||
[], [], undefined, [['child', '']]);
|
||||
|
||||
const {component} = new ComponentFixture(Cmpt);
|
||||
const qList = component.query;
|
||||
@ -1258,7 +1271,7 @@ describe('query', () => {
|
||||
'cmpt',
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
ɵɵelement(0, 'div', ['child', '']);
|
||||
ɵɵelement(0, 'div', 0);
|
||||
}
|
||||
},
|
||||
1, 0, [Child], [],
|
||||
@ -1271,7 +1284,8 @@ describe('query', () => {
|
||||
ɵɵqueryRefresh(tmp = ɵɵloadQuery<QueryList<any>>()) &&
|
||||
(ctx.query = tmp as QueryList<any>);
|
||||
}
|
||||
});
|
||||
},
|
||||
[], [], undefined, [['child', '']]);
|
||||
|
||||
const {component} = new ComponentFixture(Cmpt);
|
||||
const qList = component.query;
|
||||
@ -1429,8 +1443,7 @@ describe('query', () => {
|
||||
'app',
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
ɵɵtemplate(
|
||||
0, AppComponent_Template_1, 1, 0, 'div', [AttributeMarker.Template, 'someDir']);
|
||||
ɵɵtemplate(0, AppComponent_Template_1, 1, 0, 'div', 0);
|
||||
ɵɵelement(1, 'div', null, ['foo', '']);
|
||||
}
|
||||
},
|
||||
@ -1444,7 +1457,8 @@ describe('query', () => {
|
||||
ɵɵqueryRefresh(tmp = ɵɵloadQuery<QueryList<any>>()) &&
|
||||
(ctx.query = tmp as QueryList<any>);
|
||||
}
|
||||
});
|
||||
},
|
||||
[], [], undefined, [[AttributeMarker.Template, 'someDir']]);
|
||||
|
||||
const fixture = new ComponentFixture(AppComponent);
|
||||
expect(fixture.component.query.length).toBe(1);
|
||||
@ -1489,13 +1503,17 @@ describe('query', () => {
|
||||
* <span #foo></span>
|
||||
* </div>
|
||||
*/
|
||||
const AppComponent = createComponent('app-component', function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
ɵɵelementStart(0, 'div', [AttributeMarker.Bindings, 'with-content']);
|
||||
{ ɵɵelement(1, 'span', null, ['foo', '']); }
|
||||
ɵɵelementEnd();
|
||||
}
|
||||
}, 3, 0, [WithContentDirective]);
|
||||
const AppComponent = createComponent(
|
||||
'app-component',
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
ɵɵelementStart(0, 'div', 0);
|
||||
{ ɵɵelement(1, 'span', null, ['foo', '']); }
|
||||
ɵɵelementEnd();
|
||||
}
|
||||
},
|
||||
3, 0, [WithContentDirective], [], null, [], [], undefined,
|
||||
[[AttributeMarker.Bindings, 'with-content']]);
|
||||
|
||||
const fixture = new ComponentFixture(AppComponent);
|
||||
expect(withContentInstance !.foos.length)
|
||||
@ -1520,27 +1538,31 @@ describe('query', () => {
|
||||
* </div>
|
||||
* % }
|
||||
*/
|
||||
const AppComponent = createComponent('app-component', function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
ɵɵcontainer(0);
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
ɵɵcontainerRefreshStart(0);
|
||||
{
|
||||
for (let i = 0; i < 3; i++) {
|
||||
let rf = ɵɵembeddedViewStart(1, 3, 0);
|
||||
if (rf & RenderFlags.Create) {
|
||||
ɵɵelementStart(0, 'div', [AttributeMarker.Bindings, 'with-content']);
|
||||
{ ɵɵelement(1, 'span', null, ['foo', '']); }
|
||||
ɵɵelementEnd();
|
||||
}
|
||||
ɵɵembeddedViewEnd();
|
||||
const AppComponent = createComponent(
|
||||
'app-component',
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
ɵɵcontainer(0);
|
||||
}
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
ɵɵcontainerRefreshStart(0);
|
||||
{
|
||||
for (let i = 0; i < 3; i++) {
|
||||
let rf = ɵɵembeddedViewStart(1, 3, 0);
|
||||
if (rf & RenderFlags.Create) {
|
||||
ɵɵelementStart(0, 'div', 0);
|
||||
{ ɵɵelement(1, 'span', null, ['foo', '']); }
|
||||
ɵɵelementEnd();
|
||||
}
|
||||
ɵɵembeddedViewEnd();
|
||||
}
|
||||
}
|
||||
|
||||
ɵɵcontainerRefreshEnd();
|
||||
}
|
||||
}, 1, 0, [WithContentDirective]);
|
||||
ɵɵcontainerRefreshEnd();
|
||||
}
|
||||
},
|
||||
1, 0, [WithContentDirective], [], null, [], [], undefined,
|
||||
[[AttributeMarker.Bindings, 'with-content']]);
|
||||
|
||||
const fixture = new ComponentFixture(AppComponent);
|
||||
expect(withContentInstance !.foos.length)
|
||||
@ -1564,9 +1586,9 @@ describe('query', () => {
|
||||
*/
|
||||
const AppComponent = createComponent('app-component', function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
ɵɵelement(0, 'div', ['with-content', ''], ['foo', '']);
|
||||
ɵɵelement(0, 'div', 0, ['foo', '']);
|
||||
}
|
||||
}, 2, 0, [WithContentDirective]);
|
||||
}, 2, 0, [WithContentDirective], [], null, [], [], undefined, [['with-content', '']]);
|
||||
|
||||
const fixture = new ComponentFixture(AppComponent);
|
||||
expect(withContentInstance !.foos.length)
|
||||
@ -1588,10 +1610,10 @@ describe('query', () => {
|
||||
'app-component',
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
ɵɵelementStart(0, 'div', ['with-content', '']);
|
||||
ɵɵelementStart(0, 'div', 0);
|
||||
{ ɵɵelement(1, 'div', null, ['foo', '']); }
|
||||
ɵɵelementEnd();
|
||||
ɵɵelement(3, 'div', ['id', 'after'], ['bar', '']);
|
||||
ɵɵelement(3, 'div', 1, ['bar', '']);
|
||||
}
|
||||
},
|
||||
5, 0, [WithContentDirective], [],
|
||||
@ -1604,7 +1626,8 @@ describe('query', () => {
|
||||
ɵɵqueryRefresh(tmp = ɵɵloadQuery<QueryList<any>>()) &&
|
||||
(ctx.foos = tmp as QueryList<any>);
|
||||
}
|
||||
});
|
||||
},
|
||||
[], [], undefined, [['with-content', ''], ['id', 'after']]);
|
||||
|
||||
const fixture = new ComponentFixture(AppComponent);
|
||||
const viewQList = fixture.component.foos;
|
||||
@ -1629,8 +1652,8 @@ describe('query', () => {
|
||||
'app-component',
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
ɵɵelementStart(0, 'div', ['with-content', '']);
|
||||
{ ɵɵelement(1, 'div', ['id', 'yes'], ['foo', '']); }
|
||||
ɵɵelementStart(0, 'div', 0);
|
||||
{ ɵɵelement(1, 'div', 1, ['foo', '']); }
|
||||
ɵɵelementEnd();
|
||||
ɵɵelement(3, 'div', null, ['foo', '']);
|
||||
}
|
||||
@ -1645,7 +1668,8 @@ describe('query', () => {
|
||||
ɵɵqueryRefresh(tmp = ɵɵloadQuery<QueryList<any>>()) &&
|
||||
(ctx.bars = tmp as QueryList<any>);
|
||||
}
|
||||
});
|
||||
},
|
||||
[], [], undefined, [['with-content', ''], ['id', 'yes']]);
|
||||
|
||||
const fixture = new ComponentFixture(AppComponent);
|
||||
expect(withContentInstance !.foos.length).toBe(1);
|
||||
@ -1690,13 +1714,13 @@ describe('query', () => {
|
||||
*/
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
ɵɵelementStart(0, 'div', [AttributeMarker.Bindings, 'query'], ['out', 'query']);
|
||||
ɵɵelementStart(0, 'div', 0, ['out', 'query']);
|
||||
{
|
||||
ɵɵelement(2, 'span', ['id', 'foo'], ['foo', '']);
|
||||
ɵɵelementStart(4, 'div', [AttributeMarker.Bindings, 'query'], ['in', 'query']);
|
||||
{ ɵɵelement(6, 'span', ['id', 'bar'], ['bar', '']); }
|
||||
ɵɵelement(2, 'span', 1, ['foo', '']);
|
||||
ɵɵelementStart(4, 'div', 0, ['in', 'query']);
|
||||
{ ɵɵelement(6, 'span', 2, ['bar', '']); }
|
||||
ɵɵelementEnd();
|
||||
ɵɵelement(8, 'span', ['id', 'baz'], ['baz', '']);
|
||||
ɵɵelement(8, 'span', 3, ['baz', '']);
|
||||
}
|
||||
ɵɵelementEnd();
|
||||
}
|
||||
@ -1706,7 +1730,8 @@ describe('query', () => {
|
||||
inInstance = load<QueryDirective>(lView, 5);
|
||||
}
|
||||
},
|
||||
10, 0, [QueryDirective]);
|
||||
10, 0, [QueryDirective], [], null, [], [], undefined,
|
||||
[[AttributeMarker.Bindings, 'query'], ['id', 'foo'], ['id', 'bar'], ['id', 'baz']]);
|
||||
|
||||
const fixture = new ComponentFixture(AppComponent);
|
||||
expect(outInstance !.fooBars.length).toBe(3);
|
||||
@ -1750,10 +1775,10 @@ describe('query', () => {
|
||||
*/
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
ɵɵelementStart(0, 'div', ['query', ''], ['out', 'query']);
|
||||
ɵɵelementStart(0, 'div', 0, ['out', 'query']);
|
||||
{
|
||||
ɵɵelementStart(2, 'div', ['query', ''], ['in', 'query', 'foo', '']);
|
||||
{ ɵɵelement(5, 'span', ['id', 'bar'], ['foo', '']); }
|
||||
ɵɵelementStart(2, 'div', 0, ['in', 'query', 'foo', '']);
|
||||
{ ɵɵelement(5, 'span', 1, ['foo', '']); }
|
||||
ɵɵelementEnd();
|
||||
}
|
||||
ɵɵelementEnd();
|
||||
@ -1764,7 +1789,7 @@ describe('query', () => {
|
||||
inInstance = load<QueryDirective>(lView, 3);
|
||||
}
|
||||
},
|
||||
7, 0, [QueryDirective]);
|
||||
7, 0, [QueryDirective], [], null, [], [], undefined, [['query', ''], ['id', 'bar']]);
|
||||
|
||||
const fixture = new ComponentFixture(AppComponent);
|
||||
expect(outInstance !.fooBars.length).toBe(1);
|
||||
@ -1807,10 +1832,10 @@ describe('query', () => {
|
||||
*/
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
ɵɵelementStart(0, 'div', ['query', ''], ['out', 'query']);
|
||||
ɵɵelementStart(0, 'div', 0, ['out', 'query']);
|
||||
{
|
||||
ɵɵelementStart(2, 'div', ['query', ''], ['in', 'query', 'foo', '']);
|
||||
{ ɵɵelement(5, 'span', ['id', 'bar'], ['foo', '']); }
|
||||
ɵɵelementStart(2, 'div', 0, ['in', 'query', 'foo', '']);
|
||||
{ ɵɵelement(5, 'span', 1, ['foo', '']); }
|
||||
ɵɵelementEnd();
|
||||
}
|
||||
ɵɵelementEnd();
|
||||
@ -1821,7 +1846,7 @@ describe('query', () => {
|
||||
inInstance = load<QueryDirective>(lView, 3);
|
||||
}
|
||||
},
|
||||
7, 0, [QueryDirective]);
|
||||
7, 0, [QueryDirective], [], null, [], [], undefined, [['query', ''], ['id', 'bar']]);
|
||||
|
||||
const fixture1 = new ComponentFixture(AppComponent);
|
||||
expect(outInstance !.fooBars.length).toBe(1);
|
||||
@ -1893,9 +1918,7 @@ describe('query', () => {
|
||||
*/
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
ɵɵelementStart(
|
||||
0, 'div', [AttributeMarker.Bindings, 'shallow-query', 'deep-query'],
|
||||
['shallow', 'shallow-query', 'deep', 'deep-query']);
|
||||
ɵɵelementStart(0, 'div', 0, ['shallow', 'shallow-query', 'deep', 'deep-query']);
|
||||
{
|
||||
ɵɵelement(3, 'span', null, ['foo', '']);
|
||||
ɵɵelementStart(5, 'div');
|
||||
@ -1910,7 +1933,8 @@ describe('query', () => {
|
||||
deepInstance = load<DeepQueryDirective>(lView, 2);
|
||||
}
|
||||
},
|
||||
8, 0, [ShallowQueryDirective, DeepQueryDirective]);
|
||||
8, 0, [ShallowQueryDirective, DeepQueryDirective], [], null, [], [], undefined,
|
||||
[[AttributeMarker.Bindings, 'shallow-query', 'deep-query']]);
|
||||
|
||||
const fixture = new ComponentFixture(AppComponent);
|
||||
expect(shallowInstance !.foos.length).toBe(1);
|
||||
@ -1967,20 +1991,23 @@ describe('query', () => {
|
||||
*/
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
ɵɵelementStart(0, 'div', ['content-query']);
|
||||
ɵɵelementStart(0, 'div', 0);
|
||||
{
|
||||
ɵɵelement(1, 'span', ['text', 'A']);
|
||||
ɵɵelementStart(2, 'div', ['text', 'B']);
|
||||
ɵɵelementStart(3, 'span', ['text', 'C']);
|
||||
{ ɵɵelement(4, 'span', ['text', 'D']); }
|
||||
ɵɵelement(1, 'span', 1);
|
||||
ɵɵelementStart(2, 'div', 2);
|
||||
ɵɵelementStart(3, 'span', 3);
|
||||
{ ɵɵelement(4, 'span', 4); }
|
||||
ɵɵelementEnd();
|
||||
ɵɵelementEnd();
|
||||
ɵɵelement(5, 'span', ['text', 'E']);
|
||||
ɵɵelement(5, 'span', 5);
|
||||
}
|
||||
ɵɵelementEnd();
|
||||
}
|
||||
},
|
||||
6, 0, [TextDirective, ContentQueryDirective]);
|
||||
6, 0, [TextDirective, ContentQueryDirective], [], null, [], [], undefined, [
|
||||
['content-query'], ['text', 'A'], ['text', 'B'], ['text', 'C'], ['text', 'D'],
|
||||
['text', 'E']
|
||||
]);
|
||||
|
||||
new ComponentFixture(AppComponent);
|
||||
expect(contentQueryDirective !.texts.map(item => item.value)).toEqual([
|
||||
@ -2006,18 +2033,19 @@ describe('query', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: ViewQueryComponent,
|
||||
selectors: [['view-query']],
|
||||
consts: [['text', 'A'], ['text', 'B'], ['text', 'C'], ['text', 'D'], ['text', 'E']],
|
||||
template: function(rf: RenderFlags, ctx: ViewQueryComponent) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
ɵɵelement(0, 'span', ['text', 'A']);
|
||||
ɵɵelementStart(1, 'div', ['text', 'B']);
|
||||
ɵɵelementStart(2, 'span', ['text', 'C']);
|
||||
{ ɵɵelement(3, 'span', ['text', 'D']); }
|
||||
ɵɵelement(0, 'span', 0);
|
||||
ɵɵelementStart(1, 'div', 1);
|
||||
ɵɵelementStart(2, 'span', 2);
|
||||
{ ɵɵelement(3, 'span', 3); }
|
||||
ɵɵelementEnd();
|
||||
ɵɵelementEnd();
|
||||
ɵɵelement(4, 'span', ['text', 'E']);
|
||||
ɵɵelement(4, 'span', 4);
|
||||
}
|
||||
},
|
||||
consts: 5,
|
||||
decls: 5,
|
||||
vars: 0,
|
||||
viewQuery: function(rf: RenderFlags, ctx: ViewQueryComponent) {
|
||||
let tmp: any;
|
||||
|
@ -13,7 +13,7 @@ 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 {createLView, createTView, getOrCreateTNode, getOrCreateTView, renderComponentOrTemplate} from '@angular/core/src/render3/instructions/shared';
|
||||
import {TNodeType} from '@angular/core/src/render3/interfaces/node';
|
||||
import {TAttributes, TNodeType} from '@angular/core/src/render3/interfaces/node';
|
||||
import {getLView, resetComponentState, selectView} from '@angular/core/src/render3/state';
|
||||
import {stringifyElement} from '@angular/platform-browser/testing/src/browser_util';
|
||||
|
||||
@ -100,10 +100,10 @@ export class TemplateFixture extends BaseFixture {
|
||||
* `if (rf & RenderFlags.Update) { __here__ }`.
|
||||
*/
|
||||
constructor(
|
||||
private createBlock: () => void, private updateBlock: () => void = noop, consts: number = 0,
|
||||
private createBlock: () => void, private updateBlock: () => void = noop, decls: number = 0,
|
||||
private vars: number = 0, directives?: DirectiveTypesOrFactory|null,
|
||||
pipes?: PipeTypesOrFactory|null, sanitizer?: Sanitizer|null,
|
||||
rendererFactory?: RendererFactory3) {
|
||||
rendererFactory?: RendererFactory3, private _consts?: TAttributes[]) {
|
||||
super();
|
||||
this._directiveDefs = toDefs(directives, extractDirectiveDef);
|
||||
this._pipeDefs = toDefs(pipes, extractPipeDef);
|
||||
@ -119,8 +119,8 @@ export class TemplateFixture extends BaseFixture {
|
||||
this.updateBlock();
|
||||
}
|
||||
},
|
||||
consts, vars, null !, this._rendererFactory, null, this._directiveDefs, this._pipeDefs,
|
||||
sanitizer);
|
||||
decls, vars, null !, this._rendererFactory, null, this._directiveDefs, this._pipeDefs,
|
||||
sanitizer, this._consts);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -131,7 +131,8 @@ export class TemplateFixture extends BaseFixture {
|
||||
update(updateBlock?: () => void): void {
|
||||
renderTemplate(
|
||||
this.hostElement, updateBlock || this.updateBlock, 0, this.vars, null !,
|
||||
this._rendererFactory, this.hostView, this._directiveDefs, this._pipeDefs, this._sanitizer);
|
||||
this._rendererFactory, this.hostView, this._directiveDefs, this._pipeDefs, this._sanitizer,
|
||||
this._consts);
|
||||
}
|
||||
|
||||
destroy(): void {
|
||||
@ -236,24 +237,25 @@ export function resetDOM() {
|
||||
*
|
||||
* @param hostNode Existing node to render into.
|
||||
* @param templateFn Template function with the instructions.
|
||||
* @param consts The number of nodes, local refs, and pipes in this template
|
||||
* @param decls The number of nodes, local refs, and pipes in this template
|
||||
* @param context to pass into the template.
|
||||
* @param providedRendererFactory renderer factory to use
|
||||
* @param host The host element node to use
|
||||
* @param directives Directive defs that should be used for matching
|
||||
* @param pipes Pipe defs that should be used for matching
|
||||
* @param consts Constants associated with the template.
|
||||
*/
|
||||
export function renderTemplate<T>(
|
||||
hostNode: RElement, templateFn: ComponentTemplate<T>, consts: number, vars: number, context: T,
|
||||
hostNode: RElement, templateFn: ComponentTemplate<T>, decls: number, vars: number, context: T,
|
||||
providedRendererFactory: RendererFactory3, componentView: LView | null,
|
||||
directives?: DirectiveDefListOrFactory | null, pipes?: PipeDefListOrFactory | null,
|
||||
sanitizer?: Sanitizer | null): LView {
|
||||
sanitizer?: Sanitizer | null, consts?: TAttributes[]): LView {
|
||||
if (componentView === null) {
|
||||
resetComponentState();
|
||||
const renderer = providedRendererFactory.createRenderer(null, null);
|
||||
|
||||
// We need to create a root view so it's possible to look up the host element through its index
|
||||
const tView = createTView(-1, null, 1, 0, null, null, null, null);
|
||||
const tView = createTView(-1, null, 1, 0, null, null, null, null, null);
|
||||
const hostLView = createLView(
|
||||
null, tView, {}, LViewFlags.CheckAlways | LViewFlags.IsRoot, null, null,
|
||||
providedRendererFactory, renderer);
|
||||
@ -263,8 +265,9 @@ export function renderTemplate<T>(
|
||||
selectors: [],
|
||||
type: Object,
|
||||
template: templateFn,
|
||||
consts: consts,
|
||||
decls: decls,
|
||||
vars: vars,
|
||||
consts: consts,
|
||||
});
|
||||
def.directiveDefs = directives || null;
|
||||
def.pipeDefs = pipes || null;
|
||||
@ -285,12 +288,14 @@ export function renderTemplate<T>(
|
||||
* @deprecated use `TemplateFixture` or `ComponentFixture`
|
||||
*/
|
||||
export function renderToHtml(
|
||||
template: ComponentTemplate<any>, ctx: any, consts: number = 0, vars: number = 0,
|
||||
template: ComponentTemplate<any>, ctx: any, decls: number = 0, vars: number = 0,
|
||||
directives?: DirectiveTypesOrFactory | null, pipes?: PipeTypesOrFactory | null,
|
||||
providedRendererFactory?: RendererFactory3 | null, keepNgReflect = false) {
|
||||
providedRendererFactory?: RendererFactory3 | null, keepNgReflect = false,
|
||||
consts?: TAttributes[]) {
|
||||
hostView = renderTemplate(
|
||||
containerEl, template, consts, vars, ctx, providedRendererFactory || testRendererFactory,
|
||||
hostView, toDefs(directives, extractDirectiveDef), toDefs(pipes, extractPipeDef));
|
||||
containerEl, template, decls, vars, ctx, providedRendererFactory || testRendererFactory,
|
||||
hostView, toDefs(directives, extractDirectiveDef), toDefs(pipes, extractPipeDef), null,
|
||||
consts);
|
||||
return toHtml(containerEl, keepNgReflect);
|
||||
}
|
||||
|
||||
@ -362,24 +367,26 @@ export function toHtml<T>(componentOrElement: T | RElement, keepNgReflect = fals
|
||||
}
|
||||
|
||||
export function createComponent(
|
||||
name: string, template: ComponentTemplate<any>, consts: number = 0, vars: number = 0,
|
||||
name: string, template: ComponentTemplate<any>, decls: number = 0, vars: number = 0,
|
||||
directives: DirectiveTypesOrFactory = [], pipes: PipeTypesOrFactory = [],
|
||||
viewQuery: ComponentTemplate<any>| null = null, providers: Provider[] = [],
|
||||
viewProviders: Provider[] = [], hostBindings?: HostBindingsFunction<any>): ComponentType<any> {
|
||||
viewProviders: Provider[] = [], hostBindings?: HostBindingsFunction<any>,
|
||||
consts: TAttributes[] = []): ComponentType<any> {
|
||||
return class Component {
|
||||
value: any;
|
||||
static ngFactoryDef = () => new Component;
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: Component,
|
||||
selectors: [[name]],
|
||||
consts: consts,
|
||||
decls: decls,
|
||||
vars: vars,
|
||||
template: template,
|
||||
viewQuery: viewQuery,
|
||||
directives: directives, hostBindings,
|
||||
pipes: pipes,
|
||||
features: (providers.length > 0 || viewProviders.length > 0)?
|
||||
[ɵɵProvidersFeature(providers || [], viewProviders || [])]: []
|
||||
[ɵɵProvidersFeature(providers || [], viewProviders || [])]: [],
|
||||
consts: consts,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ describe('renderer factory lifecycle', () => {
|
||||
type: SomeComponent,
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
selectors: [['some-component']],
|
||||
consts: 1,
|
||||
decls: 1,
|
||||
vars: 0,
|
||||
template: function(rf: RenderFlags, ctx: SomeComponent) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
@ -51,7 +51,7 @@ describe('renderer factory lifecycle', () => {
|
||||
type: SomeComponentWhichThrows,
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
selectors: [['some-component-with-Error']],
|
||||
consts: 0,
|
||||
decls: 0,
|
||||
vars: 0,
|
||||
template: function(rf: RenderFlags, ctx: SomeComponentWhichThrows) {
|
||||
throw(new Error('SomeComponentWhichThrows threw'));
|
||||
@ -155,7 +155,7 @@ describe('Renderer2 destruction hooks', () => {
|
||||
type: SimpleComponent,
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
selectors: [['simple']],
|
||||
consts: 1,
|
||||
decls: 1,
|
||||
vars: 0,
|
||||
template: function(rf: RenderFlags, ctx: SimpleComponent) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
|
@ -106,13 +106,14 @@ describe('ViewContainerRef', () => {
|
||||
type: TestComponent,
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
selectors: [['test-cmp']],
|
||||
consts: 4,
|
||||
decls: 4,
|
||||
vars: 0,
|
||||
consts: [['testdir', '']],
|
||||
template: (rf: RenderFlags, cmp: TestComponent) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
ɵɵtext(0, 'before|');
|
||||
ɵɵtemplate(1, EmbeddedTemplateA, 1, 0, 'ng-template', ['testdir', '']);
|
||||
ɵɵtemplate(2, EmbeddedTemplateB, 1, 0, 'ng-template', ['testdir', '']);
|
||||
ɵɵtemplate(1, EmbeddedTemplateA, 1, 0, 'ng-template', 0);
|
||||
ɵɵtemplate(2, EmbeddedTemplateB, 1, 0, 'ng-template', 0);
|
||||
ɵɵtext(3, '|after');
|
||||
}
|
||||
},
|
||||
@ -177,12 +178,13 @@ describe('ViewContainerRef', () => {
|
||||
type: TestComponent,
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
selectors: [['test-cmp']],
|
||||
consts: 4,
|
||||
decls: 4,
|
||||
vars: 0,
|
||||
consts: [['testdir', '']],
|
||||
template: (rf: RenderFlags, cmp: TestComponent) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
ɵɵtext(0, 'before|');
|
||||
ɵɵtemplate(1, EmbeddedTemplateA, 1, 0, 'ng-template', ['testdir', '']);
|
||||
ɵɵtemplate(1, EmbeddedTemplateA, 1, 0, 'ng-template', 0);
|
||||
ɵɵcontainer(2);
|
||||
ɵɵtext(3, '|after');
|
||||
}
|
||||
@ -248,7 +250,7 @@ describe('ViewContainerRef', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: AppComp,
|
||||
selectors: [['app-comp']],
|
||||
consts: 0,
|
||||
decls: 0,
|
||||
vars: 0,
|
||||
template: (rf: RenderFlags, cmp: AppComp) => {}
|
||||
});
|
||||
@ -264,7 +266,7 @@ describe('ViewContainerRef', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: DynamicComp,
|
||||
selectors: [['dynamic-comp']],
|
||||
consts: 0,
|
||||
decls: 0,
|
||||
vars: 0,
|
||||
template: (rf: RenderFlags, cmp: DynamicComp) => {}
|
||||
});
|
||||
@ -320,11 +322,13 @@ describe('ViewContainerRef', () => {
|
||||
describe('getters', () => {
|
||||
it('should work on elements', () => {
|
||||
function createTemplate() {
|
||||
ɵɵelement(0, 'header', ['vcref', '']);
|
||||
ɵɵelement(0, 'header', 0);
|
||||
ɵɵelement(1, 'footer');
|
||||
}
|
||||
|
||||
new TemplateFixture(createTemplate, undefined, 2, 0, [DirectiveWithVCRef]);
|
||||
new TemplateFixture(
|
||||
createTemplate, undefined, 2, 0, [DirectiveWithVCRef], null, null, undefined,
|
||||
[['vcref', '']]);
|
||||
|
||||
expect(directiveInstance !.vcref.element.nativeElement.tagName.toLowerCase())
|
||||
.toEqual('header');
|
||||
@ -339,11 +343,13 @@ describe('ViewContainerRef', () => {
|
||||
createComponent('header-cmp', function(rf: RenderFlags, ctx: any) {});
|
||||
|
||||
function createTemplate() {
|
||||
ɵɵelement(0, 'header-cmp', ['vcref', '']);
|
||||
ɵɵelement(0, 'header-cmp', 0);
|
||||
ɵɵelement(1, 'footer');
|
||||
}
|
||||
|
||||
new TemplateFixture(createTemplate, undefined, 2, 0, [HeaderComponent, DirectiveWithVCRef]);
|
||||
new TemplateFixture(
|
||||
createTemplate, undefined, 2, 0, [HeaderComponent, DirectiveWithVCRef], null, null,
|
||||
undefined, [['vcref', '']]);
|
||||
|
||||
expect(directiveInstance !.vcref.element.nativeElement.tagName.toLowerCase())
|
||||
.toEqual('header-cmp');
|
||||
@ -365,7 +371,7 @@ describe('ViewContainerRef', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: AppCmpt,
|
||||
selectors: [['app']],
|
||||
consts: 0,
|
||||
decls: 0,
|
||||
vars: 0,
|
||||
template: (rf: RenderFlags, cmp: AppCmpt) => {}
|
||||
});
|
||||
@ -433,11 +439,12 @@ describe('ViewContainerRef', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: DynamicCompWithViewQueries,
|
||||
selectors: [['dynamic-cmpt-with-view-queries']],
|
||||
consts: 2,
|
||||
decls: 2,
|
||||
vars: 0,
|
||||
consts: [['bar', '']],
|
||||
template: (rf: RenderFlags, ctx: DynamicCompWithViewQueries) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
ɵɵelement(0, 'div', ['bar', ''], ['foo', '']);
|
||||
ɵɵelement(0, 'div', 0, ['foo', '']);
|
||||
}
|
||||
// testing only
|
||||
fooEl = getNativeByIndex(0, getLView()) as RElement;
|
||||
@ -481,7 +488,7 @@ describe('ViewContainerRef', () => {
|
||||
static ngComponentDef = ɵɵdefineComponent({
|
||||
type: CompWithListenerThatDestroysItself,
|
||||
selectors: [['comp-with-listener-and-on-destroy']],
|
||||
consts: 2,
|
||||
decls: 2,
|
||||
vars: 0,
|
||||
/** <button (click)="onClick()"> Click me </button> */
|
||||
template: function CompTemplate(rf: RenderFlags, ctx: any) {
|
||||
|
@ -12,7 +12,7 @@ import {isLContainer, isLView} from '@angular/core/src/render3/interfaces/type_c
|
||||
describe('view_utils', () => {
|
||||
it('should verify unwrap methods', () => {
|
||||
const div = document.createElement('div');
|
||||
const tView = createTView(0, null, 0, 0, null, null, null, null);
|
||||
const tView = createTView(0, null, 0, 0, null, null, null, null, null);
|
||||
const lView = createLView(null, tView, {}, 0, div, null, {} as any, {} as any, null, null);
|
||||
const tNode = createTNode(null !, null, 3, 0, 'div', []);
|
||||
const lContainer = createLContainer(lView, lView, div, tNode, true);
|
||||
|
@ -509,7 +509,7 @@ describe('TestBed', () => {
|
||||
static ngComponentDef = defineComponent({
|
||||
type: ComponentClass,
|
||||
selectors: [['comp']],
|
||||
consts: 1,
|
||||
decls: 1,
|
||||
vars: 0,
|
||||
template: (rf: any, ctx: any) => {
|
||||
if (rf & 1) {
|
||||
|
Reference in New Issue
Block a user