feat(ivy): add element instruction (#23899)

Adds a simplified element instruction that can be used if an element
has no children.

PR Close #23899
This commit is contained in:
Ben Lesh 2018-05-25 16:23:00 -07:00 committed by Victor Berchet
parent d6989c80d3
commit b415010222
13 changed files with 117 additions and 78 deletions

View File

@ -17,10 +17,12 @@ export class Identifiers {
static PATCH_DEPS = 'patchedDeps'; static PATCH_DEPS = 'patchedDeps';
/* Instructions */ /* Instructions */
static createElement: o.ExternalReference = {name: 'ɵE', moduleName: CORE}; static elementStart: o.ExternalReference = {name: 'ɵE', moduleName: CORE};
static elementEnd: o.ExternalReference = {name: 'ɵe', moduleName: CORE}; static elementEnd: o.ExternalReference = {name: 'ɵe', moduleName: CORE};
static element: o.ExternalReference = {name: 'ɵEe', moduleName: CORE};
static elementProperty: o.ExternalReference = {name: 'ɵp', moduleName: CORE}; static elementProperty: o.ExternalReference = {name: 'ɵp', moduleName: CORE};
static elementAttribute: o.ExternalReference = {name: 'ɵa', moduleName: CORE}; static elementAttribute: o.ExternalReference = {name: 'ɵa', moduleName: CORE};

View File

@ -314,32 +314,42 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver
if (i18nMessages.length > 0) { if (i18nMessages.length > 0) {
this._creationCode.push(...i18nMessages); this._creationCode.push(...i18nMessages);
} }
this.instruction(
this._creationCode, element.sourceSpan, R3.createElement, ...trimTrailingNulls(parameters)); let isSelfClosingElement = element.outputs.length === 0 && element.children.length === 0;
const implicit = o.variable(CONTEXT_NAME); const implicit = o.variable(CONTEXT_NAME);
// Generate Listeners (outputs) if (isSelfClosingElement) {
element.outputs.forEach((outputAst: t.BoundEvent) => {
const elName = sanitizeIdentifier(element.name);
const evName = sanitizeIdentifier(outputAst.name);
const functionName = `${this.templateName}_${elName}_${evName}_listener`;
const localVars: o.Statement[] = [];
const bindingScope =
this._bindingScope.nestedScope((lhsVar: o.ReadVarExpr, rhsExpression: o.Expression) => {
localVars.push(
lhsVar.set(rhsExpression).toDeclStmt(o.INFERRED_TYPE, [o.StmtModifier.Final]));
});
const bindingExpr = convertActionBinding(
bindingScope, implicit, outputAst.handler, 'b', () => error('Unexpected interpolation'));
const handler = o.fn(
[new o.FnParam('$event', o.DYNAMIC_TYPE)], [...localVars, ...bindingExpr.render3Stmts],
o.INFERRED_TYPE, null, functionName);
this.instruction( this.instruction(
this._creationCode, outputAst.sourceSpan, R3.listener, o.literal(outputAst.name), this._creationCode, element.sourceSpan, R3.element, ...trimTrailingNulls(parameters));
handler); } else {
}); this.instruction(
this._creationCode, element.sourceSpan, R3.elementStart,
...trimTrailingNulls(parameters));
// Generate Listeners (outputs)
element.outputs.forEach((outputAst: t.BoundEvent) => {
const elName = sanitizeIdentifier(element.name);
const evName = sanitizeIdentifier(outputAst.name);
const functionName = `${this.templateName}_${elName}_${evName}_listener`;
const localVars: o.Statement[] = [];
const bindingScope =
this._bindingScope.nestedScope((lhsVar: o.ReadVarExpr, rhsExpression: o.Expression) => {
localVars.push(
lhsVar.set(rhsExpression).toDeclStmt(o.INFERRED_TYPE, [o.StmtModifier.Final]));
});
const bindingExpr = convertActionBinding(
bindingScope, implicit, outputAst.handler, 'b',
() => error('Unexpected interpolation'));
const handler = o.fn(
[new o.FnParam('$event', o.DYNAMIC_TYPE)], [...localVars, ...bindingExpr.render3Stmts],
o.INFERRED_TYPE, null, functionName);
this.instruction(
this._creationCode, outputAst.sourceSpan, R3.listener, o.literal(outputAst.name),
handler);
});
}
// Generate element input bindings // Generate element input bindings
element.inputs.forEach((input: t.BoundAttribute) => { element.inputs.forEach((input: t.BoundAttribute) => {
@ -367,10 +377,11 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver
t.visitAll(this, element.children); t.visitAll(this, element.children);
} }
// Finish element construction mode. if (!isSelfClosingElement) {
this.instruction( // Finish element construction mode.
this._creationCode, element.endSourceSpan || element.sourceSpan, R3.elementEnd); this.instruction(
this._creationCode, element.endSourceSpan || element.sourceSpan, R3.elementEnd);
}
// Restore the state before exiting this node // Restore the state before exiting this node
this._inI18nSection = wasInI18nSection; this._inI18nSection = wasInI18nSection;
} }

View File

@ -90,8 +90,7 @@ describe('compiler compliance', () => {
const template = ` const template = `
template: function MyComponent_Template(rf: IDENT, ctx: IDENT) { template: function MyComponent_Template(rf: IDENT, ctx: IDENT) {
if (rf & 1) { if (rf & 1) {
$r3$.ɵE(0, 'div'); $r3$.ɵEe(0, 'div');
$r3$.ɵe();
} }
if (rf & 2) { if (rf & 2) {
$r3$.ɵp(0, 'id', $r3$.ɵb(ctx.id)); $r3$.ɵp(0, 'id', $r3$.ɵb(ctx.id));
@ -135,9 +134,8 @@ describe('compiler compliance', () => {
const template = ` const template = `
template: function MyComponent_Template(rf: IDENT, ctx: IDENT) { template: function MyComponent_Template(rf: IDENT, ctx: IDENT) {
if (rf & 1) { if (rf & 1) {
$r3$.ɵE(0, 'div'); $r3$.ɵEe(0, 'div');
$r3$.ɵPp(1,'pipe'); $r3$.ɵPp(1,'pipe');
$r3$.ɵe();
$r3$.ɵrS(10); $r3$.ɵrS(10);
} }
if (rf & 2) { if (rf & 2) {
@ -181,8 +179,7 @@ describe('compiler compliance', () => {
const template = ` const template = `
template: function MyComponent_Template(rf: IDENT, ctx: IDENT) { template: function MyComponent_Template(rf: IDENT, ctx: IDENT) {
if (rf & 1) { if (rf & 1) {
$r3$.ɵE(0, 'div'); $r3$.ɵEe(0, 'div');
$r3$.ɵe();
} }
if (rf & 2) { if (rf & 2) {
$r3$.ɵkn(0, 'error', $r3$.ɵb(ctx.error)); $r3$.ɵkn(0, 'error', $r3$.ɵb(ctx.error));
@ -254,8 +251,7 @@ describe('compiler compliance', () => {
factory: function MyComponent_Factory() { return new MyComponent(); }, factory: function MyComponent_Factory() { return new MyComponent(); },
template: function MyComponent_Template(rf: IDENT, ctx: IDENT) { template: function MyComponent_Template(rf: IDENT, ctx: IDENT) {
if (rf & 1) { if (rf & 1) {
$r3$.ɵE(0, 'child', $c1$); $r3$.ɵEe(0, 'child', $c1$);
$r3$.ɵe();
$r3$.ɵT(1, '!'); $r3$.ɵT(1, '!');
} }
}, },
@ -461,8 +457,7 @@ describe('compiler compliance', () => {
factory: function MyApp_Factory() { return new MyApp(); }, factory: function MyApp_Factory() { return new MyApp(); },
template: function MyApp_Template(rf: $RenderFlags$, ctx: $MyApp$) { template: function MyApp_Template(rf: $RenderFlags$, ctx: $MyApp$) {
if (rf & 1) { if (rf & 1) {
$r3$.ɵE(0, 'my-comp'); $r3$.ɵEe(0, 'my-comp');
$r3$.ɵe();
$r3$.ɵrS(2); $r3$.ɵrS(2);
} }
if (rf & 2) { if (rf & 2) {
@ -541,8 +536,7 @@ describe('compiler compliance', () => {
factory: function MyApp_Factory() { return new MyApp(); }, factory: function MyApp_Factory() { return new MyApp(); },
template: function MyApp_Template(rf: $RenderFlags$, ctx: $MyApp$) { template: function MyApp_Template(rf: $RenderFlags$, ctx: $MyApp$) {
if (rf & 1) { if (rf & 1) {
$r3$.ɵE(0, 'my-comp'); $r3$.ɵEe(0, 'my-comp');
$r3$.ɵe();
$r3$.ɵrS(10); $r3$.ɵrS(10);
} }
if (rf & 2) { if (rf & 2) {
@ -603,8 +597,7 @@ describe('compiler compliance', () => {
factory: function MyApp_Factory() { return new MyApp(); }, factory: function MyApp_Factory() { return new MyApp(); },
template: function MyApp_Template(rf: $RenderFlags$, ctx: $MyApp$) { template: function MyApp_Template(rf: $RenderFlags$, ctx: $MyApp$) {
if (rf & 1) { if (rf & 1) {
$r3$.ɵE(0, 'object-comp'); $r3$.ɵEe(0, 'object-comp');
$r3$.ɵe();
$r3$.ɵrS(2); $r3$.ɵrS(2);
} }
if (rf & 2) { if (rf & 2) {
@ -669,8 +662,7 @@ describe('compiler compliance', () => {
factory: function MyApp_Factory() { return new MyApp(); }, factory: function MyApp_Factory() { return new MyApp(); },
template: function MyApp_Template(rf: $RenderFlags$, ctx: $MyApp$) { template: function MyApp_Template(rf: $RenderFlags$, ctx: $MyApp$) {
if (rf & 1) { if (rf & 1) {
$r3$.ɵE(0, 'nested-comp'); $r3$.ɵEe(0, 'nested-comp');
$r3$.ɵe();
$r3$.ɵrS(7); $r3$.ɵrS(7);
} }
if (rf & 2) { if (rf & 2) {
@ -814,8 +806,7 @@ describe('compiler compliance', () => {
var $tmp$: $any$; var $tmp$: $any$;
if (rf & 1) { if (rf & 1) {
$r3$.ɵQ(0, SomeDirective, true); $r3$.ɵQ(0, SomeDirective, true);
$r3$.ɵE(1, 'div', $e0_attrs$); $r3$.ɵEe(1, 'div', $e0_attrs$);
$r3$.ɵe();
} }
if (rf & 2) { if (rf & 2) {
($r3$.ɵqR(($tmp$ = $r3$.ɵld(0))) && (ctx.someDir = $tmp$.first)); ($r3$.ɵqR(($tmp$ = $r3$.ɵld(0))) && (ctx.someDir = $tmp$.first));
@ -1009,8 +1000,7 @@ describe('compiler compliance', () => {
factory: function MyComponent_Factory() { return new MyComponent(); }, factory: function MyComponent_Factory() { return new MyComponent(); },
template: function MyComponent_Template(rf: IDENT, ctx: IDENT) { template: function MyComponent_Template(rf: IDENT, ctx: IDENT) {
if (rf & 1) { if (rf & 1) {
$r3$.ɵE(0, 'input', null, $c1$); $r3$.ɵEe(0, 'input', null, $c1$);
$r3$.ɵe();
$r3$.ɵT(2); $r3$.ɵT(2);
} }
const $user$ = $r3$.ɵld(1); const $user$ = $r3$.ɵld(1);
@ -1089,10 +1079,8 @@ describe('compiler compliance', () => {
factory: function SimpleLayout_Factory() { return new SimpleLayout(); }, factory: function SimpleLayout_Factory() { return new SimpleLayout(); },
template: function SimpleLayout_Template(rf: IDENT, ctx: IDENT) { template: function SimpleLayout_Template(rf: IDENT, ctx: IDENT) {
if (rf & 1) { if (rf & 1) {
$r3$.ɵE(0, 'lifecycle-comp'); $r3$.ɵEe(0, 'lifecycle-comp');
$r3$.ɵe(); $r3$.ɵEe(1, 'lifecycle-comp');
$r3$.ɵE(1, 'lifecycle-comp');
$r3$.ɵe();
} }
if (rf & 2) { if (rf & 2) {
$r3$.ɵp(0, 'name', $r3$.ɵb(ctx.name1)); $r3$.ɵp(0, 'name', $r3$.ɵb(ctx.name1));

View File

@ -75,8 +75,7 @@ describe('compiler compliance: bindings', () => {
const template = ` const template = `
template:function MyComponent_Template(rf: IDENT, $ctx$: IDENT){ template:function MyComponent_Template(rf: IDENT, $ctx$: IDENT){
if (rf & 1) { if (rf & 1) {
$i0$.ɵE(0, 'a'); $i0$.ɵEe(0, 'a');
$i0$.ɵe();
} }
if (rf & 2) { if (rf & 2) {
$i0$.ɵp(0, 'title', $i0$.ɵb($ctx$.title)); $i0$.ɵp(0, 'title', $i0$.ɵb($ctx$.title));
@ -108,8 +107,7 @@ describe('compiler compliance: bindings', () => {
const template = ` const template = `
template:function MyComponent_Template(rf: IDENT, $ctx$: IDENT){ template:function MyComponent_Template(rf: IDENT, $ctx$: IDENT){
if (rf & 1) { if (rf & 1) {
$i0$.ɵE(0, 'a'); $i0$.ɵEe(0, 'a');
$i0$.ɵe();
} }
if (rf & 2) { if (rf & 2) {
$i0$.ɵp(0, 'title', $i0$.ɵi1('Hello ', $ctx$.name, '')); $i0$.ɵp(0, 'title', $i0$.ɵi1('Hello ', $ctx$.name, ''));

View File

@ -148,8 +148,7 @@ describe('i18n support in the view compiler', () => {
template: function MyComponent_Template(rf: IDENT, ctx: IDENT) { template: function MyComponent_Template(rf: IDENT, ctx: IDENT) {
if (rf & 1) { if (rf & 1) {
$r3$.ɵE(0, 'div', $c1$); $r3$.ɵEe(0, 'div', $c1$);
$r3$.ɵe();
} }
} }
`; `;

View File

@ -109,4 +109,43 @@ describe('compiler compliance: template', () => {
expectEmit(result.source, template, 'Incorrect template'); expectEmit(result.source, template, 'Incorrect template');
}); });
// tslint:disable-next-line:ban
describe('element with no children', () => {
it('should just use the element instruction', () => {
const files = {
app: {
'spec.ts': `
import {Component, NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
@Component({
selector: 'my-component',
template: \`
<div></div>\`
})
export class MyComponent {
}
@NgModule({declarations: [MyComponent], imports: [CommonModule]})
export class MyModule {}
`
}
};
const template = `
// ...
template:function MyComponent_Template(rf: IDENT, $ctx$: IDENT){
if (rf & 1) {
$i0$.ɵEe(0,'div');
}
}`;
debugger;
const result = compile(files, angularFiles);
expectEmit(result.source, template, 'Incorrect template');
});
});
}); });

View File

@ -28,6 +28,7 @@ export {
NC as ɵNC, NC as ɵNC,
C as ɵC, C as ɵC,
E as ɵE, E as ɵE,
Ee as ɵEe,
L as ɵL, L as ɵL,
T as ɵT, T as ɵT,
V as ɵV, V as ɵV,

View File

@ -50,6 +50,7 @@ export {
elementEnd as e, elementEnd as e,
elementProperty as p, elementProperty as p,
elementStart as E, elementStart as E,
element as Ee,
elementStyle as s, elementStyle as s,
elementStyleNamed as sn, elementStyleNamed as sn,

View File

@ -1032,6 +1032,15 @@ export function elementEnd() {
queueLifecycleHooks(previousOrParentNode.tNode.flags, currentView); queueLifecycleHooks(previousOrParentNode.tNode.flags, currentView);
} }
/** Marks the beginning and end of an element in one call. */
export function element(
index: number, name: string, attrs?: TAttributes | null | undefined,
localRefs?: string[] | null | undefined): RElement {
const relement = elementStart(index, name, attrs, localRefs);
elementEnd();
return relement;
}
/** /**
* Updates the value of removes an attribute on an Element. * Updates the value of removes an attribute on an Element.
* *

View File

@ -12,6 +12,7 @@ import {assertNotNull} from './assert';
import {AttributeMarker, TAttributes, TNode, unusedValueExportToPlacateAjd as unused1} from './interfaces/node'; import {AttributeMarker, TAttributes, TNode, unusedValueExportToPlacateAjd as unused1} from './interfaces/node';
import {CssSelector, CssSelectorList, NG_PROJECT_AS_ATTR_NAME, SelectorFlags, unusedValueExportToPlacateAjd as unused2} from './interfaces/projection'; import {CssSelector, CssSelectorList, NG_PROJECT_AS_ATTR_NAME, SelectorFlags, unusedValueExportToPlacateAjd as unused2} from './interfaces/projection';
const unusedValueToPlacateAjd = unused1 + unused2; const unusedValueToPlacateAjd = unused1 + unused2;
function isCssClassMatching(nodeClassAttrVal: string, cssClassToMatch: string): boolean { function isCssClassMatching(nodeClassAttrVal: string, cssClassToMatch: string): boolean {

View File

@ -69,8 +69,7 @@ describe('components & directives', () => {
factory: () => new MyComponent(), factory: () => new MyComponent(),
template: function(rf: $RenderFlags$, ctx: $MyComponent$) { template: function(rf: $RenderFlags$, ctx: $MyComponent$) {
if (rf & 1) { if (rf & 1) {
$r3$.ɵE(0, 'child', $e0_attrs$); $r3$.ɵEe(0, 'child', $e0_attrs$);
$r3$.ɵe();
$r3$.ɵT(1, '!'); $r3$.ɵT(1, '!');
} }
} }
@ -455,8 +454,7 @@ describe('components & directives', () => {
factory: function MyApp_Factory() { return new MyApp(); }, factory: function MyApp_Factory() { return new MyApp(); },
template: function MyApp_Template(rf: $RenderFlags$, ctx: $MyApp$) { template: function MyApp_Template(rf: $RenderFlags$, ctx: $MyApp$) {
if (rf & 1) { if (rf & 1) {
$r3$.ɵE(0, 'my-array-comp'); $r3$.ɵEe(0, 'my-array-comp');
$r3$.ɵe();
} }
if (rf & 2) { if (rf & 2) {
$r3$.ɵp(0, 'names', rf & 1 ? $e0_arr$ : $r3$.ɵNC); $r3$.ɵp(0, 'names', rf & 1 ? $e0_arr$ : $r3$.ɵNC);
@ -500,8 +498,7 @@ describe('components & directives', () => {
factory: function MyApp_Factory() { return new MyApp(); }, factory: function MyApp_Factory() { return new MyApp(); },
template: function MyApp_Template(rf: $RenderFlags$, ctx: $MyApp$) { template: function MyApp_Template(rf: $RenderFlags$, ctx: $MyApp$) {
if (rf & 1) { if (rf & 1) {
$r3$.ɵE(0, 'my-array-comp'); $r3$.ɵEe(0, 'my-array-comp');
$r3$.ɵe();
$r3$.ɵrS(1); $r3$.ɵrS(1);
} }
if (rf & 2) { if (rf & 2) {
@ -606,8 +603,7 @@ describe('components & directives', () => {
factory: function MyApp_Factory() { return new MyApp(); }, factory: function MyApp_Factory() { return new MyApp(); },
template: function MyApp_Template(rf: $RenderFlags$, ctx: $MyApp$) { template: function MyApp_Template(rf: $RenderFlags$, ctx: $MyApp$) {
if (rf & 1) { if (rf & 1) {
$r3$.ɵE(0, 'my-array-comp'); $r3$.ɵEe(0, 'my-array-comp');
$r3$.ɵe();
$r3$.ɵrS(2); $r3$.ɵrS(2);
} }
if (rf & 2) { if (rf & 2) {
@ -717,8 +713,7 @@ describe('components & directives', () => {
factory: function MyApp_Factory() { return new MyApp(); }, factory: function MyApp_Factory() { return new MyApp(); },
template: function MyApp_Template(rf: $RenderFlags$, c: $any$) { template: function MyApp_Template(rf: $RenderFlags$, c: $any$) {
if (rf & 1) { if (rf & 1) {
$r3$.ɵE(0, 'my-comp'); $r3$.ɵEe(0, 'my-comp');
$r3$.ɵe();
$r3$.ɵrS(10); $r3$.ɵrS(10);
} }
if (rf & 2) { if (rf & 2) {

View File

@ -58,8 +58,7 @@ describe('queries', () => {
if (rf & 1) { if (rf & 1) {
$r3$.ɵQ(0, SomeDirective, false); $r3$.ɵQ(0, SomeDirective, false);
$r3$.ɵQ(1, SomeDirective, false); $r3$.ɵQ(1, SomeDirective, false);
$r3$.ɵE(2, 'div', $e1_attrs$); $r3$.ɵEe(2, 'div', $e1_attrs$);
$r3$.ɵe();
} }
if (rf & 2) { if (rf & 2) {
$r3$.ɵqR($tmp$ = $r3$.ɵld<QueryList<any>>(0)) && (ctx.someDir = $tmp$.first); $r3$.ɵqR($tmp$ = $r3$.ɵld<QueryList<any>>(0)) && (ctx.someDir = $tmp$.first);

View File

@ -10,14 +10,14 @@ import {NgForOfContext} from '@angular/common';
import {RenderFlags, directiveInject} from '../../src/render3'; import {RenderFlags, directiveInject} from '../../src/render3';
import {defineComponent} from '../../src/render3/definition'; import {defineComponent} from '../../src/render3/definition';
import {bind, container, elementAttribute, elementClass, elementEnd, elementProperty, elementStart, elementStyle, elementStyleNamed, interpolation1, renderTemplate, setHtmlNS, setSvgNS, text, textBinding} from '../../src/render3/instructions'; import {bind, container, element, elementAttribute, elementClass, elementEnd, elementProperty, elementStart, elementStyle, elementStyleNamed, interpolation1, renderTemplate, setHtmlNS, setSvgNS, text, textBinding} from '../../src/render3/instructions';
import {LElementNode, LNode, NS} from '../../src/render3/interfaces/node'; import {LElementNode, LNode, NS} from '../../src/render3/interfaces/node';
import {RElement, domRendererFactory3} from '../../src/render3/interfaces/renderer'; import {RElement, domRendererFactory3} from '../../src/render3/interfaces/renderer';
import {TrustedString, bypassSanitizationTrustHtml, bypassSanitizationTrustResourceUrl, bypassSanitizationTrustScript, bypassSanitizationTrustStyle, bypassSanitizationTrustUrl, sanitizeHtml, sanitizeResourceUrl, sanitizeScript, sanitizeStyle, sanitizeUrl} from '../../src/sanitization/sanitization'; import {TrustedString, bypassSanitizationTrustHtml, bypassSanitizationTrustResourceUrl, bypassSanitizationTrustScript, bypassSanitizationTrustStyle, bypassSanitizationTrustUrl, sanitizeHtml, sanitizeResourceUrl, sanitizeScript, sanitizeStyle, sanitizeUrl} from '../../src/sanitization/sanitization';
import {Sanitizer, SecurityContext} from '../../src/sanitization/security'; import {Sanitizer, SecurityContext} from '../../src/sanitization/security';
import {NgForOf} from './common_with_def'; import {NgForOf} from './common_with_def';
import {ComponentFixture, TemplateFixture} from './render_util'; import {ComponentFixture, TemplateFixture, toHtml} from './render_util';
describe('instructions', () => { describe('instructions', () => {
function createAnchor() { function createAnchor() {
@ -94,13 +94,12 @@ describe('instructions', () => {
it('should use sanitizer function even on elements with namespaced attributes', () => { it('should use sanitizer function even on elements with namespaced attributes', () => {
const t = new TemplateFixture(() => { const t = new TemplateFixture(() => {
elementStart(0, 'div', [ element(0, 'div', [
NS.FULL, NS.FULL,
'http://www.example.com/2004/test', 'http://www.example.com/2004/test',
'whatever', 'whatever',
'abc', 'abc',
]); ]);
elementEnd();
}); });
t.update(() => elementAttribute(0, 'title', 'javascript:true', sanitizeUrl)); t.update(() => elementAttribute(0, 'title', 'javascript:true', sanitizeUrl));
@ -451,8 +450,7 @@ describe('instructions', () => {
'title', 'title',
'abc', 'abc',
]); ]);
elementStart(2, 'circle', ['cx', '200', 'cy', '150', 'fill', '#0000ff']); element(2, 'circle', ['cx', '200', 'cy', '150', 'fill', '#0000ff']);
elementEnd();
elementEnd(); elementEnd();
setHtmlNS(); setHtmlNS();
elementEnd(); elementEnd();
@ -470,7 +468,7 @@ describe('instructions', () => {
it('should set an attribute with a namespace', () => { it('should set an attribute with a namespace', () => {
const t = new TemplateFixture(() => { const t = new TemplateFixture(() => {
elementStart(0, 'div', [ element(0, 'div', [
'id', 'id',
'container', 'container',
// test:title="abc" // test:title="abc"
@ -479,7 +477,6 @@ describe('instructions', () => {
'title', 'title',
'abc', 'abc',
]); ]);
elementEnd();
}); });
const standardHTML = '<div id="container" title="abc"></div>'; const standardHTML = '<div id="container" title="abc"></div>';
@ -490,7 +487,7 @@ describe('instructions', () => {
it('should set attributes including more than one namespaced attribute', () => { it('should set attributes including more than one namespaced attribute', () => {
const t = new TemplateFixture(() => { const t = new TemplateFixture(() => {
elementStart(0, 'div', [ element(0, 'div', [
'id', 'id',
'container', 'container',
@ -516,7 +513,6 @@ describe('instructions', () => {
'shazbot', 'shazbot',
'wocka wocka', 'wocka wocka',
]); ]);
elementEnd();
}); });
const standardHTML = const standardHTML =