fix(ivy): provide an ability to match <ng-template> tags (#27636)
Prior to this change, we were unable to match directives using `ng-template` tags (for example the following selector would not work even though there might be some <ng-template>s in a template: `ng-template[directiveA]`. As a result, that broke some components that relies on such selectors to work. In order to resolve the problem, we now pass tag name to the `template` instruction (where we passed `null` before) and this tag name is used for matching at runtime. This update should also help support projecting containers, because the tag name is required to properly match such elements. PR Close #27636
This commit is contained in:

committed by
Miško Hevery

parent
ea10a3abe5
commit
dfbf6d72b0
@ -194,7 +194,7 @@ export function createNodeAtIndex(
|
||||
index: number, type: TNodeType.Projection, native: null, name: null,
|
||||
attrs: TAttributes | null): TProjectionNode;
|
||||
export function createNodeAtIndex(
|
||||
index: number, type: TNodeType.ElementContainer, native: RComment, name: null,
|
||||
index: number, type: TNodeType.ElementContainer, native: RComment, name: string | null,
|
||||
attrs: TAttributes | null): TElementContainerNode;
|
||||
export function createNodeAtIndex(
|
||||
index: number, type: TNodeType.IcuContainer, native: RComment, name: null,
|
||||
@ -490,15 +490,17 @@ export function elementContainerStart(
|
||||
const lView = getLView();
|
||||
const tView = lView[TVIEW];
|
||||
const renderer = lView[RENDERER];
|
||||
const tagName = 'ng-container';
|
||||
ngDevMode && assertEqual(
|
||||
lView[BINDING_INDEX], tView.bindingStartIndex,
|
||||
'element containers should be created before any bindings');
|
||||
|
||||
ngDevMode && ngDevMode.rendererCreateComment++;
|
||||
const native = renderer.createComment(ngDevMode ? 'ng-container' : '');
|
||||
const native = renderer.createComment(ngDevMode ? tagName : '');
|
||||
|
||||
ngDevMode && assertDataInRange(lView, index - 1);
|
||||
const tNode = createNodeAtIndex(index, TNodeType.ElementContainer, native, null, attrs || null);
|
||||
const tNode =
|
||||
createNodeAtIndex(index, TNodeType.ElementContainer, native, tagName, attrs || null);
|
||||
|
||||
appendChild(native, tNode, lView);
|
||||
createDirectivesAndLocals(tView, lView, localRefs);
|
||||
@ -1646,7 +1648,7 @@ function findDirectiveMatches(tView: TView, viewData: LView, tNode: TNode): Dire
|
||||
if (registry) {
|
||||
for (let i = 0; i < registry.length; i++) {
|
||||
const def = registry[i] as ComponentDef<any>| DirectiveDef<any>;
|
||||
if (isNodeMatchingSelectorList(tNode, def.selectors !)) {
|
||||
if (isNodeMatchingSelectorList(tNode, def.selectors !, /* isProjectionMode */ false)) {
|
||||
matches || (matches = []);
|
||||
diPublicInInjector(
|
||||
getOrCreateNodeInjectorForNode(
|
||||
|
@ -9,11 +9,13 @@
|
||||
import './ng_dev_mode';
|
||||
|
||||
import {assertDefined, assertNotEqual} from './assert';
|
||||
import {AttributeMarker, TAttributes, TNode, unusedValueExportToPlacateAjd as unused1} from './interfaces/node';
|
||||
import {AttributeMarker, TAttributes, TNode, TNodeType, unusedValueExportToPlacateAjd as unused1} from './interfaces/node';
|
||||
import {CssSelector, CssSelectorList, NG_PROJECT_AS_ATTR_NAME, SelectorFlags, unusedValueExportToPlacateAjd as unused2} from './interfaces/projection';
|
||||
|
||||
const unusedValueToPlacateAjd = unused1 + unused2;
|
||||
|
||||
const NG_TEMPLATE_SELECTOR = 'ng-template';
|
||||
|
||||
function isCssClassMatching(nodeClassAttrVal: string, cssClassToMatch: string): boolean {
|
||||
const nodeClassesLen = nodeClassAttrVal.length;
|
||||
const matchIndex = nodeClassAttrVal !.indexOf(cssClassToMatch);
|
||||
@ -28,6 +30,24 @@ function isCssClassMatching(nodeClassAttrVal: string, cssClassToMatch: string):
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function that checks whether a given tNode matches tag-based selector and has a valid type.
|
||||
*
|
||||
* Matching can be perfomed in 2 modes: projection mode (when we project nodes) and regular
|
||||
* directive matching mode. In "projection" mode, we do not need to check types, so if tag name
|
||||
* matches selector, we declare a match. In "directive matching" mode, we also check whether tNode
|
||||
* is of expected type:
|
||||
* - whether tNode has either Element or ElementContainer type
|
||||
* - or if we want to match "ng-template" tag, we check for Container type
|
||||
*/
|
||||
function hasTagAndTypeMatch(
|
||||
tNode: TNode, currentSelector: string, isProjectionMode: boolean): boolean {
|
||||
return currentSelector === tNode.tagName &&
|
||||
(isProjectionMode ||
|
||||
(tNode.type === TNodeType.Element || tNode.type === TNodeType.ElementContainer) ||
|
||||
(tNode.type === TNodeType.Container && currentSelector === NG_TEMPLATE_SELECTOR));
|
||||
}
|
||||
|
||||
/**
|
||||
* A utility function to match an Ivy node static data against a simple CSS selector
|
||||
*
|
||||
@ -35,7 +55,8 @@ function isCssClassMatching(nodeClassAttrVal: string, cssClassToMatch: string):
|
||||
* @param selector
|
||||
* @returns true if node matches the selector.
|
||||
*/
|
||||
export function isNodeMatchingSelector(tNode: TNode, selector: CssSelector): boolean {
|
||||
export function isNodeMatchingSelector(
|
||||
tNode: TNode, selector: CssSelector, isProjectionMode: boolean): boolean {
|
||||
ngDevMode && assertDefined(selector[0], 'Selector should have a tag name');
|
||||
|
||||
let mode: SelectorFlags = SelectorFlags.ELEMENT;
|
||||
@ -65,7 +86,8 @@ export function isNodeMatchingSelector(tNode: TNode, selector: CssSelector): boo
|
||||
|
||||
if (mode & SelectorFlags.ELEMENT) {
|
||||
mode = SelectorFlags.ATTRIBUTE | mode & SelectorFlags.NOT;
|
||||
if (current !== '' && current !== tNode.tagName || current === '' && selector.length === 1) {
|
||||
if (current !== '' && !hasTagAndTypeMatch(tNode, current, isProjectionMode) ||
|
||||
current === '' && selector.length === 1) {
|
||||
if (isPositive(mode)) return false;
|
||||
skipToNextSelector = true;
|
||||
}
|
||||
@ -139,9 +161,10 @@ function findAttrIndexInNode(name: string, attrs: TAttributes | null): number {
|
||||
return -1;
|
||||
}
|
||||
|
||||
export function isNodeMatchingSelectorList(tNode: TNode, selector: CssSelectorList): boolean {
|
||||
export function isNodeMatchingSelectorList(
|
||||
tNode: TNode, selector: CssSelectorList, isProjectionMode: boolean = false): boolean {
|
||||
for (let i = 0; i < selector.length; i++) {
|
||||
if (isNodeMatchingSelector(tNode, selector[i])) {
|
||||
if (isNodeMatchingSelector(tNode, selector[i], isProjectionMode)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -176,7 +199,8 @@ export function matchingSelectorIndex(
|
||||
// if a node has the ngProjectAs attribute match it against unparsed selector
|
||||
// match a node against a parsed selector only if ngProjectAs attribute is not present
|
||||
if (ngProjectAsAttrVal === textSelectors[i] ||
|
||||
ngProjectAsAttrVal === null && isNodeMatchingSelectorList(tNode, selectors[i])) {
|
||||
ngProjectAsAttrVal === null &&
|
||||
isNodeMatchingSelectorList(tNode, selectors[i], /* isProjectionMode */ true)) {
|
||||
return i + 1; // first matching selector "captures" a given node
|
||||
}
|
||||
}
|
||||
|
@ -113,6 +113,9 @@
|
||||
{
|
||||
"name": "NG_PROJECT_AS_ATTR_NAME"
|
||||
},
|
||||
{
|
||||
"name": "NG_TEMPLATE_SELECTOR"
|
||||
},
|
||||
{
|
||||
"name": "NOT_FOUND"
|
||||
},
|
||||
@ -830,6 +833,9 @@
|
||||
{
|
||||
"name": "hasPlayerBuilderChanged"
|
||||
},
|
||||
{
|
||||
"name": "hasTagAndTypeMatch"
|
||||
},
|
||||
{
|
||||
"name": "hasValueChanged"
|
||||
},
|
||||
|
@ -126,7 +126,7 @@ describe('change detection', () => {
|
||||
*/
|
||||
const App = createComponent('app', function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(0, FooTemplate, 2, 1, '', null, ['foo', ''], templateRefExtractor);
|
||||
template(0, FooTemplate, 2, 1, 'ng-template', null, ['foo', ''], templateRefExtractor);
|
||||
element(2, 'structural-comp');
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
|
@ -48,7 +48,7 @@ describe('@angular/common integration', () => {
|
||||
template: (rf: RenderFlags, ctx: MyApp) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
elementStart(0, 'ul');
|
||||
{ template(1, liTemplate, 2, 1, undefined, ['ngForOf', '']); }
|
||||
{ template(1, liTemplate, 2, 1, 'li', ['ngForOf', '']); }
|
||||
elementEnd();
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
@ -111,7 +111,7 @@ describe('@angular/common integration', () => {
|
||||
template: (rf: RenderFlags, ctx: MyApp) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
elementStart(0, 'ul');
|
||||
{ template(1, liTemplate, 2, 3, undefined, ['ngForOf', '']); }
|
||||
{ template(1, liTemplate, 2, 3, 'li', ['ngForOf', '']); }
|
||||
elementEnd();
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
@ -175,7 +175,7 @@ describe('@angular/common integration', () => {
|
||||
vars: 1,
|
||||
template: (rf: RenderFlags, ctx: MyApp) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(0, ngForTemplate, 1, 0, undefined, ['ngForOf', '']);
|
||||
template(0, ngForTemplate, 1, 0, 'comp', ['ngForOf', '']);
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
elementProperty(0, 'ngForOf', bind(ctx.rows));
|
||||
@ -247,7 +247,7 @@ describe('@angular/common integration', () => {
|
||||
}
|
||||
elementEnd();
|
||||
elementStart(2, 'ul');
|
||||
{ template(3, liTemplate, 2, 1, undefined, ['ngForOf', '']); }
|
||||
{ template(3, liTemplate, 2, 1, 'li', ['ngForOf', '']); }
|
||||
elementEnd();
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
@ -302,7 +302,7 @@ describe('@angular/common integration', () => {
|
||||
template: (rf: RenderFlags, ctx: MyApp) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
elementStart(0, 'ul');
|
||||
{ template(1, liTemplate, 2, 1, null, ['ngForOf', '']); }
|
||||
{ template(1, liTemplate, 2, 1, 'li', ['ngForOf', '']); }
|
||||
elementEnd();
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
@ -317,7 +317,7 @@ describe('@angular/common integration', () => {
|
||||
function liTemplate(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
elementStart(0, 'li');
|
||||
{ template(1, spanTemplate, 2, 3, null, ['ngForOf', '']); }
|
||||
{ template(1, spanTemplate, 2, 3, 'span', ['ngForOf', '']); }
|
||||
elementEnd();
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
@ -392,7 +392,7 @@ describe('@angular/common integration', () => {
|
||||
vars: 1,
|
||||
template: (rf: RenderFlags, ctx: MyApp) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(0, divTemplate, 2, 1, null, ['ngForOf', '']);
|
||||
template(0, divTemplate, 2, 1, 'div', ['ngForOf', '']);
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
elementProperty(0, 'ngForOf', bind(ctx.items));
|
||||
@ -406,7 +406,7 @@ describe('@angular/common integration', () => {
|
||||
function divTemplate(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
elementStart(0, 'div');
|
||||
{ template(1, pTemplate, 3, 2, null, ['ngForOf', '']); }
|
||||
{ template(1, pTemplate, 3, 2, 'p', ['ngForOf', '']); }
|
||||
elementEnd();
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
@ -486,7 +486,7 @@ describe('@angular/common integration', () => {
|
||||
vars: 1,
|
||||
template: (rf: RenderFlags, ctx: MyApp) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(0, divTemplate, 2, 1, null, ['ngForOf', '']);
|
||||
template(0, divTemplate, 2, 1, 'div', ['ngForOf', '']);
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
elementProperty(0, 'ngForOf', bind(ctx.items));
|
||||
@ -500,7 +500,7 @@ describe('@angular/common integration', () => {
|
||||
function divTemplate(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
elementStart(0, 'div');
|
||||
{ template(1, innerDivTemplate, 2, 1, null, ['ngForOf', '']); }
|
||||
{ template(1, innerDivTemplate, 2, 1, 'div', ['ngForOf', '']); }
|
||||
elementEnd();
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
@ -512,7 +512,7 @@ describe('@angular/common integration', () => {
|
||||
function innerDivTemplate(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
elementStart(0, 'div');
|
||||
{ template(1, spanTemplate, 2, 2, null, ['ngForOf', '']); }
|
||||
{ template(1, spanTemplate, 2, 2, 'span', ['ngForOf', '']); }
|
||||
elementEnd();
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
@ -654,7 +654,7 @@ describe('@angular/common integration', () => {
|
||||
vars: 1,
|
||||
template: (rf: RenderFlags, ctx: MyApp) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(0, itemTemplate0, 2, 1, null, ['ngForOf', '']);
|
||||
template(0, itemTemplate0, 2, 1, 'span', ['ngForOf', '']);
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
elementProperty(0, 'ngForOf', bind(ctx.items));
|
||||
@ -668,7 +668,7 @@ describe('@angular/common integration', () => {
|
||||
function itemTemplate0(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
elementStart(0, 'span');
|
||||
{ template(1, itemTemplate1, 2, 1, null, ['ngForOf', '']); }
|
||||
{ template(1, itemTemplate1, 2, 1, 'span', ['ngForOf', '']); }
|
||||
elementEnd();
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
@ -680,7 +680,7 @@ describe('@angular/common integration', () => {
|
||||
function itemTemplate1(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
elementStart(0, 'span');
|
||||
{ template(1, itemTemplate2, 2, 1, null, ['ngForOf', '']); }
|
||||
{ template(1, itemTemplate2, 2, 1, 'span', ['ngForOf', '']); }
|
||||
elementEnd();
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
@ -692,7 +692,7 @@ describe('@angular/common integration', () => {
|
||||
function itemTemplate2(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
elementStart(0, 'span');
|
||||
{ template(1, itemTemplate3, 2, 1, null, ['ngForOf', '']); }
|
||||
{ template(1, itemTemplate3, 2, 1, 'span', ['ngForOf', '']); }
|
||||
elementEnd();
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
@ -704,7 +704,7 @@ describe('@angular/common integration', () => {
|
||||
function itemTemplate3(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
elementStart(0, 'span');
|
||||
{ template(1, itemTemplate4, 2, 1, null, ['ngForOf', '']); }
|
||||
{ template(1, itemTemplate4, 2, 1, 'span', ['ngForOf', '']); }
|
||||
elementEnd();
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
@ -716,7 +716,7 @@ describe('@angular/common integration', () => {
|
||||
function itemTemplate4(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
elementStart(0, 'span');
|
||||
{ template(1, itemTemplate5, 2, 1, null, ['ngForOf', '']); }
|
||||
{ template(1, itemTemplate5, 2, 1, 'span', ['ngForOf', '']); }
|
||||
elementEnd();
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
@ -728,7 +728,7 @@ describe('@angular/common integration', () => {
|
||||
function itemTemplate5(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
elementStart(0, 'span');
|
||||
{ template(1, itemTemplate6, 2, 1, null, ['ngForOf', '']); }
|
||||
{ template(1, itemTemplate6, 2, 1, 'span', ['ngForOf', '']); }
|
||||
elementEnd();
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
@ -740,7 +740,7 @@ describe('@angular/common integration', () => {
|
||||
function itemTemplate6(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
elementStart(0, 'span');
|
||||
{ template(1, itemTemplate7, 2, 1, null, ['ngForOf', '']); }
|
||||
{ template(1, itemTemplate7, 2, 1, 'span', ['ngForOf', '']); }
|
||||
elementEnd();
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
@ -752,7 +752,7 @@ describe('@angular/common integration', () => {
|
||||
function itemTemplate7(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
elementStart(0, 'span');
|
||||
{ template(1, itemTemplate8, 2, 10, null, ['ngForOf', '']); }
|
||||
{ template(1, itemTemplate8, 2, 10, 'span', ['ngForOf', '']); }
|
||||
elementEnd();
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
@ -822,8 +822,8 @@ describe('@angular/common integration', () => {
|
||||
*/
|
||||
template: (rf: RenderFlags, ctx: MyApp) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(0, templateOne, 2, 1, undefined, ['ngIf', '']);
|
||||
template(1, templateTwo, 2, 1, undefined, ['ngIf', '']);
|
||||
template(0, templateOne, 2, 1, 'div', ['ngIf', '']);
|
||||
template(1, templateTwo, 2, 1, 'div', ['ngIf', '']);
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
elementProperty(0, 'ngIf', bind(ctx.showing));
|
||||
@ -892,7 +892,7 @@ describe('@angular/common integration', () => {
|
||||
vars: 1,
|
||||
template: (rf: RenderFlags, ctx: AppComponent) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(0, divTemplate, 2, 1, undefined, ['ngIf', '']);
|
||||
template(0, divTemplate, 2, 1, 'div', ['ngIf', '']);
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
elementProperty(0, 'ngIf', bind(ctx.showing));
|
||||
@ -906,7 +906,7 @@ describe('@angular/common integration', () => {
|
||||
function divTemplate(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
elementStart(0, 'div');
|
||||
{ template(1, outerDivTemplate, 2, 1, undefined, ['ngIf', '']); }
|
||||
{ template(1, outerDivTemplate, 2, 1, 'div', ['ngIf', '']); }
|
||||
elementEnd();
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
@ -918,7 +918,7 @@ describe('@angular/common integration', () => {
|
||||
function outerDivTemplate(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
elementStart(0, 'div');
|
||||
{ template(1, innerDivTemplate, 2, 1, undefined, ['ngIf', '']); }
|
||||
{ template(1, innerDivTemplate, 2, 1, 'div', ['ngIf', '']); }
|
||||
elementEnd();
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
@ -971,8 +971,9 @@ describe('@angular/common integration', () => {
|
||||
if (rf1 & RenderFlags.Create) {
|
||||
text(0, 'from tpl');
|
||||
}
|
||||
}, 1, 0, undefined, undefined, ['tpl', ''], templateRefExtractor);
|
||||
template(2, null, 0, 0, null, [AttributeMarker.SelectOnly, 'ngTemplateOutlet']);
|
||||
}, 1, 0, 'ng-template', undefined, ['tpl', ''], templateRefExtractor);
|
||||
template(
|
||||
2, null, 0, 0, 'ng-template', [AttributeMarker.SelectOnly, 'ngTemplateOutlet']);
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
const tplRef = load(1);
|
||||
@ -1014,7 +1015,7 @@ describe('@angular/common integration', () => {
|
||||
if (rf1 & RenderFlags.Create) {
|
||||
text(0, 'from tpl');
|
||||
}
|
||||
}, 1, 0, undefined, undefined, ['tpl', ''], templateRefExtractor);
|
||||
}, 1, 0, 'ng-template', undefined, ['tpl', ''], templateRefExtractor);
|
||||
elementContainerStart(2, [AttributeMarker.SelectOnly, 'ngTemplateOutlet']);
|
||||
elementContainerEnd();
|
||||
}
|
||||
|
@ -185,7 +185,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, null, [1, 'ngIf']);
|
||||
template(2, MyComponent_div_Template_2, 2, 0, null, [AttributeMarker.SelectOnly, 'ngIf']);
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
elementProperty(2, 'ngIf', bind(ctx.visible));
|
||||
@ -511,8 +511,8 @@ describe('recursive components', () => {
|
||||
|
||||
if (rf & RenderFlags.Create) {
|
||||
text(0);
|
||||
template(1, IfTemplate, 1, 1, '', [AttributeMarker.SelectOnly, 'ngIf']);
|
||||
template(2, IfTemplate2, 1, 1, '', [AttributeMarker.SelectOnly, 'ngIf']);
|
||||
template(1, IfTemplate, 1, 1, 'ng-if-tree', [AttributeMarker.SelectOnly, 'ngIf']);
|
||||
template(2, IfTemplate2, 1, 1, 'ng-if-tree', [AttributeMarker.SelectOnly, 'ngIf']);
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
textBinding(0, bind(ctx.data.value));
|
||||
|
@ -813,7 +813,7 @@ describe('content projection', () => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
projectionDef();
|
||||
text(0, 'Before-');
|
||||
template(1, IfTemplate, 1, 0, '', [AttributeMarker.SelectOnly, 'ngIf']);
|
||||
template(1, IfTemplate, 1, 0, 'ng-template', [AttributeMarker.SelectOnly, 'ngIf']);
|
||||
text(2, '-After');
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
@ -878,7 +878,7 @@ describe('content projection', () => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
projectionDef();
|
||||
text(0, 'Before-');
|
||||
template(1, IfTemplate, 1, 0, '', [AttributeMarker.SelectOnly, 'ngIf']);
|
||||
template(1, IfTemplate, 1, 0, 'ng-template', [AttributeMarker.SelectOnly, 'ngIf']);
|
||||
text(2, '-After');
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
|
@ -489,7 +489,7 @@ describe('di', () => {
|
||||
const App = createComponent('app', (rf: RenderFlags, ctx: any) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
elementStart(0, 'div', ['dirB', '']);
|
||||
{ template(1, IfTemplate, 4, 1, '', [AttributeMarker.SelectOnly, 'ngIf', '']); }
|
||||
{ template(1, IfTemplate, 4, 1, 'div', [AttributeMarker.SelectOnly, 'ngIf', '']); }
|
||||
elementEnd();
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
@ -609,7 +609,10 @@ describe('di', () => {
|
||||
const App = createComponent('app', (rf: RenderFlags, ctx: any) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
elementStart(0, 'div', ['dirB', '', 'value', 'declaration']);
|
||||
{ template(1, FooTemplate, 3, 1, '', null, ['foo', ''], templateRefExtractor); }
|
||||
{
|
||||
template(
|
||||
1, FooTemplate, 3, 1, 'ng-template', null, ['foo', ''], templateRefExtractor);
|
||||
}
|
||||
elementEnd();
|
||||
elementStart(3, 'div', ['dirB', '', 'value', 'insertion']);
|
||||
{ element(4, 'div', ['structuralDir', '']); }
|
||||
@ -1157,7 +1160,7 @@ describe('di', () => {
|
||||
const App = createComponent('app', function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
elementStart(0, 'div', ['dirB', '']);
|
||||
{ template(1, IfTemplate, 1, 0, '', ['ngIf', '']); }
|
||||
{ template(1, IfTemplate, 1, 0, 'div', ['ngIf', '']); }
|
||||
elementEnd();
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
@ -1300,7 +1303,7 @@ describe('di', () => {
|
||||
/** <ng-template dir></ng-template> */
|
||||
const App = createComponent('app', function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(0, () => {}, 0, 0, null, ['dir', '']);
|
||||
template(0, () => {}, 0, 0, 'ng-template', ['dir', '']);
|
||||
lContainer = load(0) as any;
|
||||
}
|
||||
}, 1, 0, [Directive]);
|
||||
@ -1347,8 +1350,9 @@ describe('di', () => {
|
||||
*/
|
||||
const App = createComponent('app', function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(0, function() {
|
||||
}, 0, 0, undefined, ['dir', '', 'dirSame', ''], ['dir', 'dir', 'dirSame', 'dirSame']);
|
||||
template(
|
||||
0, function() {}, 0, 0, 'ng-template', ['dir', '', 'dirSame', ''],
|
||||
['dir', 'dir', 'dirSame', 'dirSame']);
|
||||
text(3);
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
@ -1703,7 +1707,7 @@ describe('di', () => {
|
||||
/** <div *ngIf="showing" dir dirSameInstance #dir="dir"> {{ dir.value }} </div> */
|
||||
template: function(rf: RenderFlags, ctx: MyApp) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(0, C1, 3, 1, null, ['ngIf', 'showing']);
|
||||
template(0, C1, 3, 1, 'div', ['ngIf', 'showing']);
|
||||
}
|
||||
},
|
||||
directives: directives
|
||||
@ -1827,7 +1831,7 @@ describe('di', () => {
|
||||
const MyApp = createComponent('my-app', function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(
|
||||
0, null, 0, 0, null,
|
||||
0, null, 0, 0, 'ng-template',
|
||||
['myDirective', 'initial', 'exist', 'existValue', 'other', 'ignore']);
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
|
@ -6,13 +6,14 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {EventEmitter} from '@angular/core';
|
||||
import {EventEmitter, TemplateRef, ViewContainerRef} from '@angular/core';
|
||||
|
||||
import {AttributeMarker, RenderFlags, defineDirective} from '../../src/render3/index';
|
||||
import {AttributeMarker, RenderFlags, defineComponent, defineDirective, directiveInject} from '../../src/render3/index';
|
||||
|
||||
import {bind, element, elementEnd, elementProperty, elementStart, listener, template, elementContainerStart, elementContainerEnd} from '../../src/render3/instructions';
|
||||
import {bind, element, elementEnd, elementProperty, elementStart, listener, template, elementContainerStart, elementContainerEnd, text} from '../../src/render3/instructions';
|
||||
|
||||
import {ComponentFixture, TemplateFixture, createComponent} from './render_util';
|
||||
import {NgIf} from './common_with_def';
|
||||
|
||||
describe('directive', () => {
|
||||
|
||||
@ -121,6 +122,106 @@ describe('directive', () => {
|
||||
expect(directiveInstance !.testValue).toBe(false);
|
||||
});
|
||||
|
||||
it('should match directives on <ng-template>', () => {
|
||||
/**
|
||||
* @Directive({
|
||||
* selector: 'ng-template[directiveA]'
|
||||
* })
|
||||
* export class DirectiveA {
|
||||
* constructor(public templateRef: TemplateRef<any>) {}
|
||||
* }
|
||||
*/
|
||||
let tmplRef: any;
|
||||
class DirectiveA {
|
||||
constructor(public templateRef: any) { tmplRef = templateRef; }
|
||||
static ngDirectiveDef = defineDirective({
|
||||
type: DirectiveA,
|
||||
selectors: [['ng-template', 'directiveA', '']],
|
||||
factory: () => new DirectiveA(directiveInject(TemplateRef as any))
|
||||
});
|
||||
}
|
||||
|
||||
function MyComponent_ng_template_Template_0(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
text(0, 'Some content');
|
||||
}
|
||||
}
|
||||
class MyComponent {
|
||||
static ngComponentDef = defineComponent({
|
||||
type: MyComponent,
|
||||
selectors: [['my-component']],
|
||||
factory: () => new MyComponent(),
|
||||
consts: 1,
|
||||
vars: 0,
|
||||
// <ng-template directiveA>Some content</ng-template>
|
||||
template: function MyComponent_Template(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(
|
||||
0, MyComponent_ng_template_Template_0, 1, 0, 'ng-template', ['directiveA', '']);
|
||||
}
|
||||
},
|
||||
directives: [DirectiveA]
|
||||
});
|
||||
}
|
||||
|
||||
new ComponentFixture(MyComponent);
|
||||
expect(tmplRef instanceof TemplateRef).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should match directives on <ng-container>', () => {
|
||||
/**
|
||||
* @Directive({
|
||||
* selector: 'ng-container[directiveA]'
|
||||
* })
|
||||
* export class DirectiveA {
|
||||
* constructor(public vcRef: ViewContainerRef<any>) {}
|
||||
* }
|
||||
*/
|
||||
let vcRef: any;
|
||||
class DirectiveA {
|
||||
constructor(public viewContainerRef: any) { vcRef = viewContainerRef; }
|
||||
static ngDirectiveDef = defineDirective({
|
||||
type: DirectiveA,
|
||||
selectors: [['ng-container', 'directiveA', '']],
|
||||
factory: () => new DirectiveA(directiveInject(ViewContainerRef as any))
|
||||
});
|
||||
}
|
||||
|
||||
function MyComponent_ng_container_Template_0(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
elementContainerStart(0, ['directiveA', '']);
|
||||
text(1, 'Some content');
|
||||
elementContainerEnd();
|
||||
}
|
||||
}
|
||||
class MyComponent {
|
||||
visible = true;
|
||||
|
||||
static ngComponentDef = defineComponent({
|
||||
type: MyComponent,
|
||||
selectors: [['my-component']],
|
||||
factory: () => new MyComponent(),
|
||||
consts: 1,
|
||||
vars: 1,
|
||||
// <ng-container *ngIf="visible" directiveA>Some content</ng-container>
|
||||
template: function MyComponent_Template(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(
|
||||
0, MyComponent_ng_container_Template_0, 2, 0, 'ng-container',
|
||||
[AttributeMarker.SelectOnly, 'ngIf']);
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
elementProperty(0, 'ngIf', bind(ctx.visible));
|
||||
}
|
||||
},
|
||||
directives: [DirectiveA, NgIf]
|
||||
});
|
||||
}
|
||||
|
||||
new ComponentFixture(MyComponent);
|
||||
expect(vcRef instanceof ViewContainerRef).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should match directives with attribute selectors on outputs', () => {
|
||||
let directiveInstance: Directive;
|
||||
|
||||
@ -173,7 +274,7 @@ describe('directive', () => {
|
||||
*/
|
||||
const Cmpt = createComponent('Cmpt', function(rf: RenderFlags, ctx: {value: any}) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(0, null, 0, 0, null, [AttributeMarker.SelectOnly, 'out']);
|
||||
template(0, null, 0, 0, 'ng-template', [AttributeMarker.SelectOnly, 'out']);
|
||||
listener('out', () => { ctx.value = true; });
|
||||
}
|
||||
}, 1, 0, [Directive]);
|
||||
|
@ -120,7 +120,7 @@ describe('discovery utils', () => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
element(0, 'child');
|
||||
}
|
||||
}, 1, 0, null, ['ngIf', '']);
|
||||
}, 1, 0, 'child', ['ngIf', '']);
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
textBinding(1, bind(ctx.text));
|
||||
|
@ -365,7 +365,7 @@ describe('exports', () => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
elementStart(0, 'input', ['value', 'one'], ['outerInput', '']);
|
||||
elementEnd();
|
||||
template(2, outerTemplate, 5, 2, '', [AttributeMarker.SelectOnly, 'ngIf']);
|
||||
template(2, outerTemplate, 5, 2, 'div', [AttributeMarker.SelectOnly, 'ngIf']);
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
elementProperty(2, 'ngIf', bind(app.outer));
|
||||
@ -379,7 +379,7 @@ describe('exports', () => {
|
||||
text(1);
|
||||
elementStart(2, 'input', ['value', 'two'], ['innerInput', '']);
|
||||
elementEnd();
|
||||
template(4, innerTemplate, 2, 2, '', [AttributeMarker.SelectOnly, 'ngIf']);
|
||||
template(4, innerTemplate, 2, 2, 'div', [AttributeMarker.SelectOnly, 'ngIf']);
|
||||
}
|
||||
elementEnd();
|
||||
}
|
||||
|
@ -472,7 +472,7 @@ describe('host bindings', () => {
|
||||
*/
|
||||
const App = createComponent('parent', (rf: RenderFlags, ctx: any) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(0, NgForTemplate, 2, 0, null, ['ngForOf', '']);
|
||||
template(0, NgForTemplate, 2, 0, 'div', ['ngForOf', '']);
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
elementProperty(0, 'ngForOf', bind(ctx.rows));
|
||||
|
@ -595,7 +595,7 @@ describe('Runtime i18n', () => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
i18nStart(0, MSG_DIV, 1);
|
||||
elementStart(1, 'div');
|
||||
template(2, subTemplate_2, 2, 0, null, ['ngIf', '']);
|
||||
template(2, subTemplate_2, 2, 0, 'span', ['ngIf', '']);
|
||||
elementEnd();
|
||||
i18nEnd();
|
||||
}
|
||||
@ -624,7 +624,7 @@ describe('Runtime i18n', () => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
elementStart(0, 'div');
|
||||
i18nStart(1, MSG_DIV);
|
||||
template(2, subTemplate_1, 3, 1, null, ['ngIf', '']);
|
||||
template(2, subTemplate_1, 3, 1, 'div', ['ngIf', '']);
|
||||
i18nEnd();
|
||||
elementEnd();
|
||||
}
|
||||
|
@ -297,7 +297,7 @@ describe('instructions', () => {
|
||||
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, null, _c0);
|
||||
template(1, ToDoAppComponent_NgForOf_NgForOf_Template_1, 2, 1, 'li', _c0);
|
||||
elementEnd();
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
@ -335,7 +335,7 @@ describe('instructions', () => {
|
||||
vars: 1,
|
||||
template: function ToDoAppComponent_Template(rf: RenderFlags, ctx: NestedLoops) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(0, ToDoAppComponent_NgForOf_Template_0, 2, 1, null, _c0);
|
||||
template(0, ToDoAppComponent_NgForOf_Template_0, 2, 1, 'ul', _c0);
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
elementProperty(0, 'ngForOf', bind(ctx.rows));
|
||||
|
@ -719,7 +719,8 @@ describe('render3 integration test', () => {
|
||||
const TestCmpt =
|
||||
createComponent('test-cmpt', function(rf: RenderFlags, ctx: {value: any}) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(0, ngIfTemplate, 2, 0, null, [AttributeMarker.SelectOnly, 'ngIf']);
|
||||
template(
|
||||
0, ngIfTemplate, 2, 0, 'ng-template', [AttributeMarker.SelectOnly, 'ngIf']);
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
elementProperty(0, 'ngIf', bind(ctx.value));
|
||||
@ -778,7 +779,8 @@ describe('render3 integration test', () => {
|
||||
const TestCmpt = createComponent('test-cmpt', function(rf: RenderFlags) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(
|
||||
0, embeddedTemplate, 2, 0, null, [AttributeMarker.SelectOnly, 'testDirective']);
|
||||
0, embeddedTemplate, 2, 0, 'ng-template',
|
||||
[AttributeMarker.SelectOnly, 'testDirective']);
|
||||
}
|
||||
}, 1, 0, [TestDirective]);
|
||||
|
||||
@ -893,7 +895,9 @@ describe('render3 integration test', () => {
|
||||
*/
|
||||
const TestCmpt = createComponent('test-cmpt', function(rf: RenderFlags) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(0, embeddedTemplate, 4, 0, null, [AttributeMarker.SelectOnly, 'testDirective']);
|
||||
template(
|
||||
0, embeddedTemplate, 4, 0, 'ng-template',
|
||||
[AttributeMarker.SelectOnly, 'testDirective']);
|
||||
}
|
||||
}, 1, 0, [TestDirective]);
|
||||
|
||||
@ -981,7 +985,8 @@ describe('render3 integration test', () => {
|
||||
const App = createComponent('app', function(rf: RenderFlags) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
elementContainerStart(0, [AttributeMarker.SelectOnly, 'dir']);
|
||||
template(1, ContentTemplate, 1, 0, '', null, ['content', ''], templateRefExtractor);
|
||||
template(
|
||||
1, ContentTemplate, 1, 0, 'ng-template', null, ['content', ''], templateRefExtractor);
|
||||
elementContainerEnd();
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
@ -1037,7 +1042,7 @@ describe('render3 integration test', () => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
elementContainerStart(0);
|
||||
template(
|
||||
1, ContentTemplate, 1, 0, '', [AttributeMarker.SelectOnly, 'dir'], [],
|
||||
1, ContentTemplate, 1, 0, 'ng-template', [AttributeMarker.SelectOnly, 'dir'], [],
|
||||
templateRefExtractor);
|
||||
elementContainerEnd();
|
||||
}
|
||||
@ -1610,7 +1615,7 @@ describe('render3 integration test', () => {
|
||||
*/
|
||||
const App = createComponent('app', function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(0, FooTemplate, 1, 0, '', null, ['foo', ''], templateRefExtractor);
|
||||
template(0, FooTemplate, 1, 0, 'ng-template', null, ['foo', ''], templateRefExtractor);
|
||||
elementStart(2, 'structural-comp');
|
||||
elementStyling(['active']);
|
||||
elementEnd();
|
||||
@ -1990,7 +1995,7 @@ describe('render3 integration test', () => {
|
||||
elementEnd();
|
||||
element(2, 'div');
|
||||
}
|
||||
}, 3, 0, null, ['ngIf', '']);
|
||||
}, 3, 0, 'ng-template', ['ngIf', '']);
|
||||
elementEnd();
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
|
@ -196,7 +196,7 @@ describe('lifecycles', () => {
|
||||
/** <comp *ngIf="showing"></comp> */
|
||||
const App = createComponent('app', function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(0, IfTemplate, 1, 0, '', ['ngIf', '']);
|
||||
template(0, IfTemplate, 1, 0, 'comp', ['ngIf', '']);
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
elementProperty(0, 'ngIf', bind(ctx.showing));
|
||||
@ -2586,7 +2586,8 @@ describe('lifecycles', () => {
|
||||
|
||||
function conditionTpl(rf: RenderFlags, ctx: Cmpt) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(0, null, 0, 1, null, [AttributeMarker.SelectOnly, 'onDestroyDirective']);
|
||||
template(
|
||||
0, null, 0, 1, 'ng-template', [AttributeMarker.SelectOnly, 'onDestroyDirective']);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2597,7 +2598,7 @@ describe('lifecycles', () => {
|
||||
*/
|
||||
function cmptTpl(rf: RenderFlags, cmpt: Cmpt) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(0, conditionTpl, 1, 1, null, [AttributeMarker.SelectOnly, 'ngIf']);
|
||||
template(0, conditionTpl, 1, 1, 'ng-template', [AttributeMarker.SelectOnly, 'ngIf']);
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
elementProperty(0, 'ngIf', bind(cmpt.showing));
|
||||
|
@ -20,7 +20,7 @@ function testLStaticData(tagName: string, attrs: TAttributes | null): TNode {
|
||||
describe('css selector matching', () => {
|
||||
function isMatching(tagName: string, attrs: TAttributes | null, selector: CssSelector): boolean {
|
||||
return isNodeMatchingSelector(
|
||||
createTNode(getLView(), TNodeType.Element, 0, tagName, attrs, null), selector);
|
||||
createTNode(getLView(), TNodeType.Element, 0, tagName, attrs, null), selector, false);
|
||||
}
|
||||
|
||||
describe('isNodeMatchingSimpleSelector', () => {
|
||||
@ -417,7 +417,7 @@ describe('css selector matching', () => {
|
||||
|
||||
function isAnyMatching(
|
||||
tagName: string, attrs: string[] | null, selector: CssSelectorList): boolean {
|
||||
return isNodeMatchingSelectorList(testLStaticData(tagName, attrs), selector);
|
||||
return isNodeMatchingSelectorList(testLStaticData(tagName, attrs), selector, false);
|
||||
}
|
||||
|
||||
it('should match when there is only one simple selector without negations', () => {
|
||||
|
@ -87,7 +87,7 @@ describe('array literals', () => {
|
||||
*/
|
||||
const App = createComponent('app', function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(0, IfTemplate, 1, 3, null, [AttributeMarker.SelectOnly, 'ngIf']);
|
||||
template(0, IfTemplate, 1, 3, 'my-comp', [AttributeMarker.SelectOnly, 'ngIf']);
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
elementProperty(0, 'ngIf', bind(ctx.showing));
|
||||
|
@ -661,7 +661,7 @@ describe('query', () => {
|
||||
'cmpt',
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(1, null, 0, 0, null, null, ['foo', '']);
|
||||
template(1, null, 0, 0, 'ng-template', null, ['foo', '']);
|
||||
}
|
||||
},
|
||||
3, 0, [], [],
|
||||
@ -693,7 +693,7 @@ describe('query', () => {
|
||||
'cmpt',
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(1, null, 0, 0, null, null, ['foo', '']);
|
||||
template(1, null, 0, 0, 'ng-template', null, ['foo', '']);
|
||||
}
|
||||
},
|
||||
3, 0, [], [],
|
||||
@ -728,7 +728,7 @@ describe('query', () => {
|
||||
'cmpt',
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(1, null, 0, 0, null, null, ['foo', '']);
|
||||
template(1, null, 0, 0, 'ng-template', null, ['foo', '']);
|
||||
}
|
||||
},
|
||||
3, 0, [], [],
|
||||
@ -760,7 +760,7 @@ describe('query', () => {
|
||||
'cmpt',
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(1, null, 0, 0, null, null, ['foo', '']);
|
||||
template(1, null, 0, 0, 'ng-template', null, ['foo', '']);
|
||||
}
|
||||
},
|
||||
3, 0, [], [],
|
||||
@ -1276,9 +1276,15 @@ describe('query', () => {
|
||||
'cmpt',
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(2, Cmpt_Template_1, 2, 0, null, null, ['foo', ''], templateRefExtractor);
|
||||
template(3, Cmpt_Template_1, 2, 0, null, null, ['bar', ''], templateRefExtractor);
|
||||
template(4, Cmpt_Template_1, 2, 0, null, null, ['baz', ''], templateRefExtractor);
|
||||
template(
|
||||
2, Cmpt_Template_1, 2, 0, 'ng-template', null, ['foo', ''],
|
||||
templateRefExtractor);
|
||||
template(
|
||||
3, Cmpt_Template_1, 2, 0, 'ng-template', null, ['bar', ''],
|
||||
templateRefExtractor);
|
||||
template(
|
||||
4, Cmpt_Template_1, 2, 0, 'ng-template', null, ['baz', ''],
|
||||
templateRefExtractor);
|
||||
}
|
||||
},
|
||||
5, 0, [], [],
|
||||
@ -1361,7 +1367,7 @@ describe('query', () => {
|
||||
'cmpt',
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(1, Cmpt_Template_1, 2, 0, null, ['ngIf', '']);
|
||||
template(1, Cmpt_Template_1, 2, 0, 'ng-template', ['ngIf', '']);
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
elementProperty(1, 'ngIf', bind(ctx.value));
|
||||
@ -1422,7 +1428,7 @@ describe('query', () => {
|
||||
vars: 1,
|
||||
template: function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(1, Cmpt_Template_1, 2, 1, null, ['ngForOf', '']);
|
||||
template(1, Cmpt_Template_1, 2, 1, 'ng-template', ['ngForOf', '']);
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
elementProperty(1, 'ngForOf', bind(ctx.value));
|
||||
@ -1501,11 +1507,13 @@ describe('query', () => {
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(
|
||||
1, Cmpt_Template_1, 2, 1, null, null, ['tpl1', ''], templateRefExtractor);
|
||||
1, Cmpt_Template_1, 2, 1, 'ng-template', null, ['tpl1', ''],
|
||||
templateRefExtractor);
|
||||
element(3, 'div', ['id', 'middle'], ['foo', '']);
|
||||
template(
|
||||
5, Cmpt_Template_5, 2, 1, null, null, ['tpl2', ''], templateRefExtractor);
|
||||
template(7, null, 0, 0, null, [AttributeMarker.SelectOnly, 'vc']);
|
||||
5, Cmpt_Template_5, 2, 1, 'ng-template', null, ['tpl2', ''],
|
||||
templateRefExtractor);
|
||||
template(7, null, 0, 0, 'ng-template', [AttributeMarker.SelectOnly, 'vc']);
|
||||
}
|
||||
|
||||
if (rf & RenderFlags.Update) {
|
||||
@ -1599,9 +1607,11 @@ describe('query', () => {
|
||||
template: function(rf: RenderFlags, ctx: any) {
|
||||
let tmp: any;
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(1, Cmpt_Template_1, 2, 1, null, [], ['tpl', ''], templateRefExtractor);
|
||||
template(3, null, 0, 0, null, [AttributeMarker.SelectOnly, 'vc']);
|
||||
template(4, null, 0, 0, null, [AttributeMarker.SelectOnly, 'vc']);
|
||||
template(
|
||||
1, Cmpt_Template_1, 2, 1, 'ng-template', [], ['tpl', ''],
|
||||
templateRefExtractor);
|
||||
template(3, null, 0, 0, 'ng-template', [AttributeMarker.SelectOnly, 'vc']);
|
||||
template(4, null, 0, 0, 'ng-template', [AttributeMarker.SelectOnly, 'vc']);
|
||||
}
|
||||
|
||||
if (rf & RenderFlags.Update) {
|
||||
@ -1671,9 +1681,10 @@ describe('query', () => {
|
||||
template: (rf: RenderFlags, myApp: MyApp) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(
|
||||
1, MyApp_Template_1, 2, 0, undefined, undefined, ['tpl', ''],
|
||||
1, MyApp_Template_1, 2, 0, 'ng-template', undefined, ['tpl', ''],
|
||||
templateRefExtractor);
|
||||
template(3, null, 0, 0, null, [AttributeMarker.SelectOnly, 'ngTemplateOutlet']);
|
||||
template(
|
||||
3, null, 0, 0, 'ng-template', [AttributeMarker.SelectOnly, 'ngTemplateOutlet']);
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
const tplRef = reference(2);
|
||||
@ -2195,7 +2206,7 @@ describe('query', () => {
|
||||
function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(
|
||||
1, AppComponent_Template_1, 1, 0, null, [AttributeMarker.SelectOnly, 'someDir']);
|
||||
1, AppComponent_Template_1, 1, 0, 'div', [AttributeMarker.SelectOnly, 'someDir']);
|
||||
element(2, 'div', null, ['foo', '']);
|
||||
}
|
||||
},
|
||||
@ -2377,7 +2388,7 @@ describe('query', () => {
|
||||
const AppComponent = createComponent('app-component', function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
elementStart(0, 'shallow-comp');
|
||||
{ template(1, IfTemplate, 2, 0, null, [AttributeMarker.SelectOnly, 'ngIf', '']); }
|
||||
{ template(1, IfTemplate, 2, 0, 'div', [AttributeMarker.SelectOnly, 'ngIf', '']); }
|
||||
elementEnd();
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
|
@ -50,7 +50,7 @@ describe('TemplateRef', () => {
|
||||
*/
|
||||
const AppComponent = createComponent('app-cmp', function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(0, embeddedTemplate, 3, 0, null, ['tplRef', '']);
|
||||
template(0, embeddedTemplate, 3, 0, 'ng-template', ['tplRef', '']);
|
||||
directiveWithTplRef = getDirectiveOnNode(0, 0);
|
||||
}
|
||||
}, 1, 0, [DirectiveWithTplRef]);
|
||||
@ -79,7 +79,7 @@ describe('TemplateRef', () => {
|
||||
*/
|
||||
const AppComponent = createComponent('app-cmp', function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(0, () => {}, 0, 0, null, ['tplRef', '']);
|
||||
template(0, () => {}, 0, 0, 'ng-template', ['tplRef', '']);
|
||||
directiveWithTplRef = getDirectiveOnNode(0, 0);
|
||||
}
|
||||
}, 1, 0, [DirectiveWithTplRef]);
|
||||
@ -108,7 +108,7 @@ describe('TemplateRef', () => {
|
||||
|
||||
function embeddedTemplate(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(0, ngIfTemplate, 1, 0, null, [AttributeMarker.SelectOnly, 'ngIf']);
|
||||
template(0, ngIfTemplate, 1, 0, 'ng-template', [AttributeMarker.SelectOnly, 'ngIf']);
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
elementProperty(0, 'ngIf', bind(ctx.showing));
|
||||
@ -120,7 +120,7 @@ describe('TemplateRef', () => {
|
||||
*/
|
||||
const AppComponent = createComponent('app-cmp', function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(0, embeddedTemplate, 1, 1, null, ['tplRef', '']);
|
||||
template(0, embeddedTemplate, 1, 1, 'ng-template', ['tplRef', '']);
|
||||
directiveWithTplRef = getDirectiveOnNode(0, 0);
|
||||
}
|
||||
}, 1, 0, [DirectiveWithTplRef, NgIf]);
|
||||
@ -158,7 +158,7 @@ describe('TemplateRef', () => {
|
||||
*/
|
||||
const AppComponent = createComponent('app-cmp', function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(0, embeddedTemplate, 2, 0, null, ['tplRef', '']);
|
||||
template(0, embeddedTemplate, 2, 0, 'ng-template', ['tplRef', '']);
|
||||
directiveWithTplRef = getDirectiveOnNode(0, 0);
|
||||
}
|
||||
}, 1, 0, [DirectiveWithTplRef]);
|
||||
|
@ -75,7 +75,8 @@ describe('ViewContainerRef', () => {
|
||||
* <p vcref [tplRef]="tplRef"></p>
|
||||
*/
|
||||
function createTemplate() {
|
||||
template(0, embeddedTemplate, 1, 1, null, null, ['tplRef', ''], templateRefExtractor);
|
||||
template(
|
||||
0, embeddedTemplate, 1, 1, 'ng-template', null, ['tplRef', ''], templateRefExtractor);
|
||||
element(2, 'p', ['vcref', '']);
|
||||
}
|
||||
|
||||
@ -92,7 +93,8 @@ describe('ViewContainerRef', () => {
|
||||
* <footer></footer>
|
||||
*/
|
||||
function createTemplate() {
|
||||
template(0, embeddedTemplate, 1, 1, null, null, ['tplRef', ''], templateRefExtractor);
|
||||
template(
|
||||
0, embeddedTemplate, 1, 1, 'ng-template', null, ['tplRef', ''], templateRefExtractor);
|
||||
element(2, 'header', ['vcref', '']);
|
||||
element(3, 'footer');
|
||||
}
|
||||
@ -128,7 +130,8 @@ describe('ViewContainerRef', () => {
|
||||
* <footer></footer>
|
||||
*/
|
||||
function createTemplate() {
|
||||
template(0, embeddedTemplate, 1, 1, null, [], ['tplRef', ''], templateRefExtractor);
|
||||
template(
|
||||
0, embeddedTemplate, 1, 1, 'ng-template', [], ['tplRef', ''], templateRefExtractor);
|
||||
element(2, 'header-cmp', ['vcref', '']);
|
||||
element(3, 'footer');
|
||||
}
|
||||
@ -164,7 +167,8 @@ describe('ViewContainerRef', () => {
|
||||
* <div vcref [tplRef]="tplRef"></div>
|
||||
*/
|
||||
function createTemplate() {
|
||||
template(0, embeddedTemplate, 1, 1, null, null, ['tplRef', ''], templateRefExtractor);
|
||||
template(
|
||||
0, embeddedTemplate, 1, 1, 'ng-template', null, ['tplRef', ''], templateRefExtractor);
|
||||
element(2, 'div', ['vcref', '']);
|
||||
element(3, 'div', ['vcref', '']);
|
||||
|
||||
@ -195,7 +199,8 @@ describe('ViewContainerRef', () => {
|
||||
*/
|
||||
function createTemplate() {
|
||||
template(
|
||||
0, embeddedTemplate, 1, 1, null, ['vcref', ''], ['tplRef', ''], templateRefExtractor);
|
||||
0, embeddedTemplate, 1, 1, 'ng-template', ['vcref', ''], ['tplRef', ''],
|
||||
templateRefExtractor);
|
||||
element(2, 'footer');
|
||||
}
|
||||
|
||||
@ -281,8 +286,8 @@ describe('ViewContainerRef', () => {
|
||||
template: (rf: RenderFlags, cmp: TestComponent) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
text(0, 'before|');
|
||||
template(1, EmbeddedTemplateA, 1, 0, null, ['testdir', '']);
|
||||
template(2, EmbeddedTemplateB, 1, 0, null, ['testdir', '']);
|
||||
template(1, EmbeddedTemplateA, 1, 0, 'ng-template', ['testdir', '']);
|
||||
template(2, EmbeddedTemplateB, 1, 0, 'ng-template', ['testdir', '']);
|
||||
text(3, '|after');
|
||||
}
|
||||
},
|
||||
@ -354,7 +359,7 @@ describe('ViewContainerRef', () => {
|
||||
template: (rf: RenderFlags, cmp: TestComponent) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
text(0, 'before|');
|
||||
template(1, EmbeddedTemplateA, 1, 0, null, ['testdir', '']);
|
||||
template(1, EmbeddedTemplateA, 1, 0, 'ng-template', ['testdir', '']);
|
||||
container(2);
|
||||
text(3, '|after');
|
||||
}
|
||||
@ -466,7 +471,8 @@ describe('ViewContainerRef', () => {
|
||||
template: (rf: RenderFlags, cmp: SomeComponent) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(
|
||||
0, SomeComponent_Template_0, 2, 3, null, [], ['foo', ''], templateRefExtractor);
|
||||
0, SomeComponent_Template_0, 2, 3, 'ng-template', [], ['foo', ''],
|
||||
templateRefExtractor);
|
||||
pipe(2, 'starPipe');
|
||||
element(3, 'child', ['vcref', '']);
|
||||
pipe(4, 'starPipe');
|
||||
@ -557,7 +563,8 @@ describe('ViewContainerRef', () => {
|
||||
*/
|
||||
const Parent = createComponent('parent', function(rf: RenderFlags, parent: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(0, fooTemplate, 2, 1, null, null, ['foo', ''], templateRefExtractor);
|
||||
template(
|
||||
0, fooTemplate, 2, 1, 'ng-template', null, ['foo', ''], templateRefExtractor);
|
||||
element(2, 'child');
|
||||
}
|
||||
|
||||
@ -618,7 +625,7 @@ describe('ViewContainerRef', () => {
|
||||
vars: 2,
|
||||
template: function(rf: RenderFlags, loop: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(0, null, 0, 0, null, [AttributeMarker.SelectOnly, 'ngForOf']);
|
||||
template(0, null, 0, 0, 'ng-template', [AttributeMarker.SelectOnly, 'ngForOf']);
|
||||
}
|
||||
|
||||
if (rf & RenderFlags.Update) {
|
||||
@ -648,7 +655,9 @@ describe('ViewContainerRef', () => {
|
||||
*/
|
||||
const Parent = createComponent('parent', function(rf: RenderFlags, parent: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(0, rowTemplate, 3, 2, null, null, ['rowTemplate', ''], templateRefExtractor);
|
||||
template(
|
||||
0, rowTemplate, 3, 2, 'ng-template', null, ['rowTemplate', ''],
|
||||
templateRefExtractor);
|
||||
element(2, 'loop-comp');
|
||||
}
|
||||
|
||||
@ -662,7 +671,9 @@ describe('ViewContainerRef', () => {
|
||||
|
||||
function rowTemplate(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(0, cellTemplate, 2, 3, null, null, ['cellTemplate', ''], templateRefExtractor);
|
||||
template(
|
||||
0, cellTemplate, 2, 3, 'ng-template', null, ['cellTemplate', ''],
|
||||
templateRefExtractor);
|
||||
element(2, 'loop-comp');
|
||||
}
|
||||
|
||||
@ -1247,7 +1258,7 @@ describe('ViewContainerRef', () => {
|
||||
|
||||
it('should work on templates', () => {
|
||||
function createTemplate() {
|
||||
template(0, embeddedTemplate, 1, 1, null, ['vcref', '']);
|
||||
template(0, embeddedTemplate, 1, 1, 'ng-template', ['vcref', '']);
|
||||
element(1, 'footer');
|
||||
}
|
||||
|
||||
@ -1312,7 +1323,9 @@ describe('ViewContainerRef', () => {
|
||||
vars: 2,
|
||||
template: (rf: RenderFlags, cmp: Parent) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(0, embeddedTemplate, 2, 1, null, null, ['foo', ''], templateRefExtractor);
|
||||
template(
|
||||
0, embeddedTemplate, 2, 1, 'ng-template', null, ['foo', ''],
|
||||
templateRefExtractor);
|
||||
elementStart(2, 'child');
|
||||
{
|
||||
elementStart(3, 'header', ['vcref', '']);
|
||||
@ -1407,7 +1420,8 @@ describe('ViewContainerRef', () => {
|
||||
template: (rf: RenderFlags, cmp: Parent) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(
|
||||
0, embeddedTemplate, 2, 1, null, undefined, ['foo', ''], templateRefExtractor);
|
||||
0, embeddedTemplate, 2, 1, 'ng-template', undefined, ['foo', ''],
|
||||
templateRefExtractor);
|
||||
elementStart(2, 'child-with-view');
|
||||
text(3, 'Before projected');
|
||||
elementStart(4, 'header', ['vcref', '']);
|
||||
@ -1491,7 +1505,8 @@ describe('ViewContainerRef', () => {
|
||||
let tplRef: any;
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(
|
||||
0, embeddedTemplate, 2, 1, null, null, ['foo', ''], templateRefExtractor);
|
||||
0, embeddedTemplate, 2, 1, 'ng-template', null, ['foo', ''],
|
||||
templateRefExtractor);
|
||||
elementStart(2, 'child-with-selector');
|
||||
elementStart(3, 'header', ['vcref', '']);
|
||||
text(4, 'blah');
|
||||
@ -1544,7 +1559,8 @@ describe('ViewContainerRef', () => {
|
||||
let tplRef: any;
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(
|
||||
0, embeddedTemplate, 2, 1, null, null, ['foo', ''], templateRefExtractor);
|
||||
0, embeddedTemplate, 2, 1, 'ng-template', null, ['foo', ''],
|
||||
templateRefExtractor);
|
||||
elementStart(2, 'child-with-selector');
|
||||
elementStart(3, 'footer', ['vcref', '']);
|
||||
text(4, 'blah');
|
||||
@ -1649,7 +1665,8 @@ describe('ViewContainerRef', () => {
|
||||
template: (rf: RenderFlags, cmp: SomeComponent) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(
|
||||
0, SomeComponent_Template_0, 1, 1, null, [], ['foo', ''], templateRefExtractor);
|
||||
0, SomeComponent_Template_0, 1, 1, 'ng-template', [], ['foo', ''],
|
||||
templateRefExtractor);
|
||||
element(2, 'hooks', ['vcref', '']);
|
||||
element(3, 'hooks');
|
||||
}
|
||||
@ -1864,7 +1881,7 @@ describe('ViewContainerRef', () => {
|
||||
vars: 0,
|
||||
template: (rf: RenderFlags, cmp: AppCmpt) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(0, null, 0, 0, null, ['vcref', '']);
|
||||
template(0, null, 0, 0, 'ng-template', ['vcref', '']);
|
||||
}
|
||||
},
|
||||
directives: [HostBindingCmpt, DirectiveWithVCRef]
|
||||
|
Reference in New Issue
Block a user