feat(ivy): added new namespace and element instructions to JIT environment (#23899)
PR Close #23899
This commit is contained in:
		
							parent
							
								
									1007d1ad27
								
							
						
					
					
						commit
						acf270d724
					
				| @ -136,7 +136,8 @@ export function compileComponentFromMetadata( | ||||
|   const templateFunctionExpression = | ||||
|       new TemplateDefinitionBuilder( | ||||
|           constantPool, CONTEXT_NAME, BindingScope.ROOT_SCOPE, 0, templateTypeName, templateName, | ||||
|           meta.viewQueries, directiveMatcher, directivesUsed, meta.pipes, pipesUsed) | ||||
|           meta.viewQueries, directiveMatcher, directivesUsed, meta.pipes, pipesUsed, | ||||
|           R3.namespaceHTML) | ||||
|           .buildTemplateFunction( | ||||
|               template.nodes, [], template.hasNgContent, template.ngContentSelectors); | ||||
| 
 | ||||
|  | ||||
| @ -18,8 +18,8 @@ import * as html from '../../ml_parser/ast'; | ||||
| import {HtmlParser} from '../../ml_parser/html_parser'; | ||||
| import {WhitespaceVisitor} from '../../ml_parser/html_whitespaces'; | ||||
| import {DEFAULT_INTERPOLATION_CONFIG} from '../../ml_parser/interpolation_config'; | ||||
| import {splitNsName} from '../../ml_parser/tags'; | ||||
| import * as o from '../../output/output_ast'; | ||||
| import {ExternalReference} from '../../output/output_ast'; | ||||
| import {ParseError, ParseSourceSpan} from '../../parse_util'; | ||||
| import {DomElementSchemaRegistry} from '../../schema/dom_element_schema_registry'; | ||||
| import {CssSelector, SelectorMatcher} from '../../selector'; | ||||
| @ -52,7 +52,6 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver | ||||
|   private _valueConverter: ValueConverter; | ||||
|   private _unsupported = unsupported; | ||||
|   private _bindingScope: BindingScope; | ||||
|   private _namespace = R3.namespaceHTML; | ||||
| 
 | ||||
|   // Whether we are inside a translatable element (`<p i18n>... somewhere here ... </p>)
 | ||||
|   private _inI18nSection: boolean = false; | ||||
| @ -68,7 +67,8 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver | ||||
|       parentBindingScope: BindingScope, private level = 0, private contextName: string|null, | ||||
|       private templateName: string|null, private viewQueries: R3QueryMetadata[], | ||||
|       private directiveMatcher: SelectorMatcher|null, private directives: Set<o.Expression>, | ||||
|       private pipeTypeByName: Map<string, o.Expression>, private pipes: Set<o.Expression>) { | ||||
|       private pipeTypeByName: Map<string, o.Expression>, private pipes: Set<o.Expression>, | ||||
|       private _namespace: o.ExternalReference) { | ||||
|     this._bindingScope = | ||||
|         parentBindingScope.nestedScope((lhsVar: o.ReadVarExpr, expression: o.Expression) => { | ||||
|           this._bindingCode.push( | ||||
| @ -91,6 +91,10 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver | ||||
|   buildTemplateFunction( | ||||
|       nodes: t.Node[], variables: t.Variable[], hasNgContent: boolean = false, | ||||
|       ngContentSelectors: string[] = []): o.FunctionExpr { | ||||
|     if (this._namespace !== R3.namespaceHTML) { | ||||
|       this.instruction(this._creationCode, null, this._namespace); | ||||
|     } | ||||
| 
 | ||||
|     // Create variable bindings
 | ||||
|     for (const variable of variables) { | ||||
|       const variableName = variable.name; | ||||
| @ -224,20 +228,20 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver | ||||
| 
 | ||||
|   /** | ||||
|    * Gets the namespace instruction function based on the current element | ||||
|    * @param ivyElementName An system element name, can include colons like :svg:svg | ||||
|    * @param namespaceKey A system key for a namespace (e.g. 'svg' or 'math') | ||||
|    */ | ||||
|   getNamespaceInstruction(ivyElementName: string) { | ||||
|     switch (ivyElementName) { | ||||
|       case ':svg:svg': | ||||
|   getNamespaceInstruction(namespaceKey: string|null) { | ||||
|     switch (namespaceKey) { | ||||
|       case 'svg': | ||||
|         return R3.namespaceSVG; | ||||
|       case ':math:math': | ||||
|       case 'math': | ||||
|         return R3.namespaceMathML; | ||||
|       default: | ||||
|         return this._namespace; | ||||
|         return R3.namespaceHTML; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   addNamespaceInstruction(nsInstruction: ExternalReference, element: t.Element) { | ||||
|   addNamespaceInstruction(nsInstruction: o.ExternalReference, element: t.Element) { | ||||
|     this._namespace = nsInstruction; | ||||
|     this.instruction(this._creationCode, element.sourceSpan, nsInstruction); | ||||
|   } | ||||
| @ -249,7 +253,9 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver | ||||
| 
 | ||||
|     const outputAttrs: {[name: string]: string} = {}; | ||||
|     const attrI18nMetas: {[name: string]: string} = {}; | ||||
|     let i18nMeta: string = ''; | ||||
|     let i18nMeta = ''; | ||||
| 
 | ||||
|     const [namespaceKey, elementName] = splitNsName(element.name); | ||||
| 
 | ||||
|     // Elements inside i18n sections are replaced with placeholders
 | ||||
|     // TODO(vicb): nested elements are a WIP in this phase
 | ||||
| @ -291,7 +297,7 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver | ||||
|     // Element creation mode
 | ||||
|     const parameters: o.Expression[] = [ | ||||
|       o.literal(elementIndex), | ||||
|       o.literal(element.name), | ||||
|       o.literal(elementName), | ||||
|     ]; | ||||
| 
 | ||||
|     // Add the attributes
 | ||||
| @ -343,7 +349,8 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver | ||||
|     const implicit = o.variable(CONTEXT_NAME); | ||||
| 
 | ||||
|     const wasInNamespace = this._namespace; | ||||
|     const currentNamespace = this.getNamespaceInstruction(element.name); | ||||
|     const currentNamespace = this.getNamespaceInstruction(namespaceKey); | ||||
| 
 | ||||
|     // If the namespace is changing now, include an instruction to change it
 | ||||
|     // during element creation.
 | ||||
|     if (currentNamespace !== wasInNamespace) { | ||||
| @ -359,14 +366,6 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver | ||||
|           this._creationCode, element.sourceSpan, R3.elementStart, | ||||
|           ...trimTrailingNulls(parameters)); | ||||
| 
 | ||||
|       // If the element happens to be an SVG <foreignObject>, we need to switch
 | ||||
|       // to the HTML namespace inside of it
 | ||||
|       if (element.name === ':svg:foreignObject') { | ||||
|         // NOTE(benlesh): this may cause extremem corner-case bugs if someone was to do something
 | ||||
|         //   like <math>...<foreignObject></foreignObject>...</math>.
 | ||||
|         this.addNamespaceInstruction(R3.namespaceHTML, element); | ||||
|       } | ||||
| 
 | ||||
|       // Generate Listeners (outputs)
 | ||||
|       element.outputs.forEach((outputAst: t.BoundEvent) => { | ||||
|         const elName = sanitizeIdentifier(element.name); | ||||
| @ -423,7 +422,6 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver | ||||
|     } | ||||
|     // Restore the state before exiting this node
 | ||||
|     this._inI18nSection = wasInI18nSection; | ||||
|     this._namespace = wasInNamespace; | ||||
|   } | ||||
| 
 | ||||
|   visitTemplate(template: t.Template) { | ||||
| @ -484,7 +482,8 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver | ||||
|     // Create the template function
 | ||||
|     const templateVisitor = new TemplateDefinitionBuilder( | ||||
|         this.constantPool, templateContext, this._bindingScope, this.level + 1, contextName, | ||||
|         templateName, [], this.directiveMatcher, this.directives, this.pipeTypeByName, this.pipes); | ||||
|         templateName, [], this.directiveMatcher, this.directives, this.pipeTypeByName, this.pipes, | ||||
|         this._namespace); | ||||
|     const templateFunctionExpr = | ||||
|         templateVisitor.buildTemplateFunction(template.children, template.variables); | ||||
|     this._postfixCode.push(templateFunctionExpr.toDeclStmt(templateName, null)); | ||||
|  | ||||
| @ -95,8 +95,56 @@ describe('compiler compliance', () => { | ||||
|           if (rf & 1) { | ||||
|             $r3$.ɵE(0, 'div', $e0_attrs$); | ||||
|             $r3$.ɵNS(); | ||||
|             $r3$.ɵE(1, ':svg:svg'); | ||||
|             $r3$.ɵEe(2, ':svg:circle', $e2_attrs$); | ||||
|             $r3$.ɵE(1, 'svg'); | ||||
|             $r3$.ɵEe(2, 'circle', $e2_attrs$); | ||||
|             $r3$.ɵe(); | ||||
|             $r3$.ɵe(); | ||||
|           } | ||||
|         } | ||||
|       `;
 | ||||
| 
 | ||||
| 
 | ||||
|       const result = compile(files, angularFiles); | ||||
| 
 | ||||
|       expectEmit(result.source, factory, 'Incorrect factory'); | ||||
|       expectEmit(result.source, template, 'Incorrect template'); | ||||
|     }); | ||||
| 
 | ||||
|     it('should enter and leave the SVG namespace appropriately', () => { | ||||
|       const files = { | ||||
|         app: { | ||||
|           'spec.ts': ` | ||||
|               import {Component, NgModule} from '@angular/core'; | ||||
| 
 | ||||
|               @Component({ | ||||
|                 selector: 'my-component', | ||||
|                 template: \`<div class="my-app" title="Hello"><svg><circle cx="50" cy="100" r="25"/></svg><p>TEST 2</p></div>\` | ||||
|               }) | ||||
|               export class MyComponent {} | ||||
| 
 | ||||
|               @NgModule({declarations: [MyComponent]}) | ||||
|               export class MyModule {} | ||||
|           ` | ||||
|         } | ||||
|       }; | ||||
| 
 | ||||
|       // The factory should look like this:
 | ||||
|       const factory = 'factory: function MyComponent_Factory() { return new MyComponent(); }'; | ||||
| 
 | ||||
|       // The template should look like this (where IDENT is a wild card for an identifier):
 | ||||
|       const template = ` | ||||
|         const $c1$ = ['class', 'my-app', 'title', 'Hello']; | ||||
|         … | ||||
|         template: function MyComponent_Template(rf: IDENT, ctx: IDENT) { | ||||
|           if (rf & 1) { | ||||
|             $r3$.ɵE(0, 'div', $e0_attrs$); | ||||
|               $r3$.ɵNS(); | ||||
|               $r3$.ɵE(1, 'svg'); | ||||
|                 $r3$.ɵEe(2, 'circle', $e2_attrs$); | ||||
|               $r3$.ɵe(); | ||||
|               $r3$.ɵNH(); | ||||
|               $r3$.ɵE(3, 'p'); | ||||
|                 $r3$.ɵT(4, 'TEST 2'); | ||||
|               $r3$.ɵe(); | ||||
|             $r3$.ɵe(); | ||||
|           } | ||||
| @ -1274,7 +1322,7 @@ describe('compiler compliance', () => { | ||||
|         expectEmit(source, MyComponentDefinition, 'Invalid component definition'); | ||||
|       }); | ||||
| 
 | ||||
|       it('should support a let variable and reference for SVG', () => { | ||||
|       it('should support embedded views in the SVG namespace', () => { | ||||
|         const files = { | ||||
|           app: { | ||||
|             ...shared, | ||||
| @ -1321,15 +1369,16 @@ describe('compiler compliance', () => { | ||||
|             template: function MyComponent_Template(rf:IDENT,ctx:IDENT){ | ||||
|               if (rf & 1) { | ||||
|                 $r3$.ɵNS(); | ||||
|                 $r3$.ɵE(0,':svg:svg'); | ||||
|                 $r3$.ɵE(0,'svg'); | ||||
|                 $r3$.ɵC(1,MyComponent__svg_g_Template_1,null,$_c0$); | ||||
|                 $r3$.ɵe(); | ||||
|               } | ||||
|               if (rf & 2) { $r3$.ɵp(1,'forOf',$r3$.ɵb(ctx.items)); } | ||||
|               function MyComponent__svg_g_Template_1(rf:IDENT,ctx0:IDENT) { | ||||
|                 if (rf & 1) { | ||||
|                   $r3$.ɵE(0,':svg:g'); | ||||
|                   $r3$.ɵEe(1,':svg:circle'); | ||||
|                   $r3$.ɵNS(); | ||||
|                   $r3$.ɵE(0,'g'); | ||||
|                   $r3$.ɵEe(1,'circle'); | ||||
|                   $r3$.ɵe(); | ||||
|                 } | ||||
|               } | ||||
|  | ||||
| @ -45,7 +45,6 @@ export { | ||||
|   i7 as ɵi7, | ||||
|   i8 as ɵi8, | ||||
|   iV as ɵiV, | ||||
|   N as ɵN, | ||||
|   NH as ɵNH, | ||||
|   NM as ɵNM, | ||||
|   NS as ɵNS, | ||||
|  | ||||
| @ -150,7 +150,7 @@ The goal is for the `@Component` (and friends) to be the compiler of template. S | ||||
| | `{{ ['literal', exp ] }}`                   |  ✅     |  ✅      |  ✅      | | ||||
| | `{{ { a: 'literal', b: exp } }}`            |  ✅     |  ✅      |  ✅      | | ||||
| | `{{ exp \| pipe: arg }}`                    |  ✅     |  ✅      |  ✅      | | ||||
| | `<svg:g svg:p>`                             |  ✅     |  ✅      |  ❌      | | ||||
| | `<svg:g svg:p>`                             |  ✅     |  ✅      |  ✅      | | ||||
| | `<img src=[userData]>` sanitization         |  ❌     |  ❌      |  ❌      | | ||||
| | `<div (nocd.click)>`                        |  ❌     |  ❌      |  ❌      | | ||||
| | `<div (bubble.click)>`                      |  ❌     |  ❌      |  ❌      | | ||||
|  | ||||
| @ -261,8 +261,8 @@ export function injectAttribute(attrNameToInject: string): string|undefined { | ||||
|   if (attrs) { | ||||
|     for (let i = 0; i < attrs.length; i = i + 2) { | ||||
|       let attrName = attrs[i]; | ||||
|       if (attrName === AttributeMarker.SELECT_ONLY) break; | ||||
|       if (attrName === AttributeMarker.NAMESPACE_URI) { | ||||
|       if (attrName === AttributeMarker.SelectOnly) break; | ||||
|       if (attrName === AttributeMarker.NamespaceUri) { | ||||
|         attrName = attrs[i += 2]; | ||||
|       } | ||||
|       if (attrName == attrNameToInject) { | ||||
|  | ||||
| @ -54,7 +54,6 @@ export { | ||||
|   elementStyle as s, | ||||
|   elementStyleNamed as sn, | ||||
| 
 | ||||
|   namespace as N, | ||||
|   namespaceHTML as NH, | ||||
|   namespaceMathML as NM, | ||||
|   namespaceSVG as NS, | ||||
|  | ||||
| @ -560,15 +560,6 @@ function getRenderFlags(view: LView): RenderFlags { | ||||
| //////////////////////////
 | ||||
| let _currentNamespace: string|null = null; | ||||
| 
 | ||||
| /** | ||||
|  * Sets the namespace URI that will be used to create elements in {@link element} | ||||
|  * and {@link elementStart} | ||||
|  * @param uri the full namespaceUri | ||||
|  */ | ||||
| export function namespace(uri: string | null) { | ||||
|   _currentNamespace = uri; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Sets the current namespace URI to null, meaning createElement (not createElementNS) | ||||
|  * will be used to create elements in {@link element} and {@link elementStart} | ||||
| @ -617,9 +608,17 @@ export function elementStart( | ||||
| 
 | ||||
|   ngDevMode && ngDevMode.rendererCreateElement++; | ||||
| 
 | ||||
|   const native: RElement = _currentNamespace === null || isProceduralRenderer(renderer) ? | ||||
|       renderer.createElement(name) : | ||||
|       (renderer as ObjectOrientedRenderer3).createElementNS(_currentNamespace, name); | ||||
|   let native: RElement; | ||||
| 
 | ||||
|   if (isProceduralRenderer(renderer)) { | ||||
|     native = renderer.createElement(name, _currentNamespace); | ||||
|   } else { | ||||
|     if (_currentNamespace === null) { | ||||
|       native = renderer.createElement(name); | ||||
|     } else { | ||||
|       native = renderer.createElementNS(_currentNamespace, name); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   ngDevMode && assertDataInRange(index - 1); | ||||
| 
 | ||||
| @ -861,7 +860,7 @@ function setUpAttributes(native: RElement, attrs: TAttributes): void { | ||||
|   const isProc = isProceduralRenderer(renderer); | ||||
|   for (let i = 0; i < attrs.length; i += 2) { | ||||
|     let attrName = attrs[i]; | ||||
|     if (attrName === AttributeMarker.NAMESPACE_URI) { | ||||
|     if (attrName === AttributeMarker.NamespaceUri) { | ||||
|       const attrNS = attrs[i + 1] as string; | ||||
|       attrName = attrs[i + 2] as string; | ||||
|       const attrVal = attrs[i + 3] as string; | ||||
| @ -872,7 +871,7 @@ function setUpAttributes(native: RElement, attrs: TAttributes): void { | ||||
|         native.setAttributeNS(attrNS, attrName, attrVal); | ||||
|       } | ||||
|     } else { | ||||
|       if (attrName === AttributeMarker.SELECT_ONLY) break; | ||||
|       if (attrName === AttributeMarker.SelectOnly) break; | ||||
|       if (attrName !== NG_PROJECT_AS_ATTR_NAME) { | ||||
|         const attrVal = attrs[i + 1]; | ||||
|         ngDevMode && ngDevMode.rendererSetAttribute++; | ||||
| @ -1533,11 +1532,11 @@ function generateInitialInputs( | ||||
|   const attrs = tNode.attrs !; | ||||
|   for (let i = 0; i < attrs.length; i += 2) { | ||||
|     const first = attrs[i]; | ||||
|     const attrName = first === AttributeMarker.NAMESPACE_URI ? attrs[i += 2] : first; | ||||
|     const attrName = first === AttributeMarker.NamespaceUri ? attrs[i += 2] : first; | ||||
|     const minifiedInputName = inputs[attrName]; | ||||
|     const attrValue = attrs[i + 1]; | ||||
| 
 | ||||
|     if (attrName === AttributeMarker.SELECT_ONLY) break; | ||||
|     if (attrName === AttributeMarker.SelectOnly) break; | ||||
|     if (minifiedInputName !== undefined) { | ||||
|       const inputsToStore: InitialInputs = | ||||
|           initialInputData[directiveIndex] || (initialInputData[directiveIndex] = []); | ||||
|  | ||||
| @ -164,7 +164,7 @@ export const enum AttributeMarker { | ||||
|    * Use the next value as the full namespaces URI, the values after that | ||||
|    * are then the name and the value, respectively. | ||||
|    */ | ||||
|   NAMESPACE_URI = 0,  // namespace. Has to be repeated.
 | ||||
|   NamespaceUri = 0,  // namespace. Has to be repeated.
 | ||||
| 
 | ||||
|   /** | ||||
|    * This marker indicates that the following attribute names were extracted from bindings (ex.: | ||||
| @ -172,7 +172,7 @@ export const enum AttributeMarker { | ||||
|    * Taking the above bindings and outputs as an example an attributes array could look as follows: | ||||
|    * ['class', 'fade in', AttributeMarker.SELECT_ONLY, 'foo', 'bar'] | ||||
|    */ | ||||
|   SELECT_ONLY = 1 | ||||
|   SelectOnly = 1 | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  | ||||
| @ -37,6 +37,7 @@ export const angularCoreEnv: {[name: string]: Function} = { | ||||
|   'ɵcr': r3.cr, | ||||
|   'ɵd': r3.d, | ||||
|   'ɵE': r3.E, | ||||
|   'ɵEe': r3.Ee, | ||||
|   'ɵe': r3.e, | ||||
|   'ɵf0': r3.f0, | ||||
|   'ɵf1': r3.f1, | ||||
| @ -60,6 +61,9 @@ export const angularCoreEnv: {[name: string]: Function} = { | ||||
|   'ɵkn': r3.kn, | ||||
|   'ɵL': r3.L, | ||||
|   'ɵld': r3.ld, | ||||
|   'ɵNH': r3.NH, | ||||
|   'ɵNM': r3.NM, | ||||
|   'ɵNS': r3.NS, | ||||
|   'ɵp': r3.p, | ||||
|   'ɵpb1': r3.pb1, | ||||
|   'ɵpb2': r3.pb2, | ||||
|  | ||||
| @ -41,7 +41,7 @@ export function isNodeMatchingSelector(tNode: TNode, selector: CssSelector): boo | ||||
| 
 | ||||
|   let mode: SelectorFlags = SelectorFlags.ELEMENT; | ||||
|   const nodeAttrs = tNode.attrs !; | ||||
|   const selectOnlyMarkerIdx = nodeAttrs ? nodeAttrs.indexOf(AttributeMarker.SELECT_ONLY) : -1; | ||||
|   const selectOnlyMarkerIdx = nodeAttrs ? nodeAttrs.indexOf(AttributeMarker.SelectOnly) : -1; | ||||
| 
 | ||||
|   // When processing ":not" selectors, we skip to the next ":not" if the
 | ||||
|   // current one doesn't match
 | ||||
| @ -107,11 +107,11 @@ function findAttrIndexInNode(name: string, attrs: TAttributes | null): number { | ||||
|   if (attrs === null) return -1; | ||||
|   for (let i = 0; i < attrs.length; i += step) { | ||||
|     const attrName = attrs[i]; | ||||
|     if (attrName === AttributeMarker.NAMESPACE_URI) { | ||||
|     if (attrName === AttributeMarker.NamespaceUri) { | ||||
|       step = 2; | ||||
|     } else if (attrName === name) { | ||||
|       return i; | ||||
|     } else if (attrName === AttributeMarker.SELECT_ONLY) { | ||||
|     } else if (attrName === AttributeMarker.SelectOnly) { | ||||
|       step = 1; | ||||
|     } | ||||
|   } | ||||
|  | ||||
| @ -165,6 +165,7 @@ describe('template variables', () => { | ||||
|           } | ||||
|           function MyComponent__svg_g_Template_1(rf: $RenderFlags$, ctx0: $MyComponent$) { | ||||
|             if (rf & 1) { | ||||
|               $r3$.ɵNS(); | ||||
|               $r3$.ɵE(0, 'g'); | ||||
|               $r3$.ɵEe(1, 'circle'); | ||||
|               $r3$.ɵe(); | ||||
| @ -180,7 +181,7 @@ describe('template variables', () => { | ||||
|         [ForOfDirective.ngDirectiveDef]; | ||||
|     // /NON-NORMATIVE
 | ||||
| 
 | ||||
|     // TODO(chuckj): update when the changes to enable ngForOf lands.
 | ||||
|     // TODO(benlesh): update when the changes to enable ngForOf lands.
 | ||||
|     expect(toHtml(renderComponent(MyComponent))).toEqual('<svg></svg>'); | ||||
|   }); | ||||
| 
 | ||||
|  | ||||
| @ -605,7 +605,7 @@ describe('content projection', () => { | ||||
|         if (rf & RenderFlags.Create) { | ||||
|           elementStart(0, 'child'); | ||||
|           { | ||||
|             elementStart(1, 'span', [AttributeMarker.SELECT_ONLY, 'title']); | ||||
|             elementStart(1, 'span', [AttributeMarker.SelectOnly, 'title']); | ||||
|             { text(2, 'Has title'); } | ||||
|             elementEnd(); | ||||
|           } | ||||
|  | ||||
| @ -1225,7 +1225,7 @@ describe('di', () => { | ||||
| 
 | ||||
|       const MyApp = createComponent('my-app', function(rf: RenderFlags, ctx: any) { | ||||
|         if (rf & RenderFlags.Create) { | ||||
|           elementStart(0, 'div', ['exist', 'existValue', AttributeMarker.SELECT_ONLY, 'nonExist']); | ||||
|           elementStart(0, 'div', ['exist', 'existValue', AttributeMarker.SelectOnly, 'nonExist']); | ||||
|           exist = injectAttribute('exist'); | ||||
|           nonExist = injectAttribute('nonExist'); | ||||
|         } | ||||
| @ -1243,7 +1243,7 @@ describe('di', () => { | ||||
|       const MyApp = createComponent('my-app', function(rf: RenderFlags, ctx: any) { | ||||
|         if (rf & RenderFlags.Create) { | ||||
|           elementStart(0, 'div', [ | ||||
|             'exist', 'existValue', AttributeMarker.SELECT_ONLY, 'binding1', 'nonExist', 'binding2' | ||||
|             'exist', 'existValue', AttributeMarker.SelectOnly, 'binding1', 'nonExist', 'binding2' | ||||
|           ]); | ||||
|           exist = injectAttribute('exist'); | ||||
|           nonExist = injectAttribute('nonExist'); | ||||
|  | ||||
| @ -34,7 +34,7 @@ describe('directive', () => { | ||||
|       } | ||||
| 
 | ||||
|       function Template() { | ||||
|         elementStart(0, 'span', [AttributeMarker.SELECT_ONLY, 'dir']); | ||||
|         elementStart(0, 'span', [AttributeMarker.SelectOnly, 'dir']); | ||||
|         elementEnd(); | ||||
|       } | ||||
| 
 | ||||
| @ -82,7 +82,7 @@ describe('directive', () => { | ||||
|        */ | ||||
|       function createTemplate() { | ||||
|         // using 2 bindings to show example shape of attributes array
 | ||||
|         elementStart(0, 'span', ['class', 'fade', AttributeMarker.SELECT_ONLY, 'test', 'other']); | ||||
|         elementStart(0, 'span', ['class', 'fade', AttributeMarker.SelectOnly, 'test', 'other']); | ||||
|         elementEnd(); | ||||
|       } | ||||
| 
 | ||||
| @ -132,7 +132,7 @@ describe('directive', () => { | ||||
|          function createTemplate() { | ||||
|            // putting name (test) in the "usual" value position
 | ||||
|            elementStart( | ||||
|                0, 'span', ['class', 'fade', AttributeMarker.SELECT_ONLY, 'prop1', 'test', 'prop2']); | ||||
|                0, 'span', ['class', 'fade', AttributeMarker.SelectOnly, 'prop1', 'test', 'prop2']); | ||||
|            elementEnd(); | ||||
|          } | ||||
| 
 | ||||
| @ -168,7 +168,7 @@ describe('directive', () => { | ||||
|        * <span (out)="someVar = true"></span> | ||||
|        */ | ||||
|       function createTemplate() { | ||||
|         elementStart(0, 'span', [AttributeMarker.SELECT_ONLY, 'out']); | ||||
|         elementStart(0, 'span', [AttributeMarker.SelectOnly, 'out']); | ||||
|         { listener('out', () => {}); } | ||||
|         elementEnd(); | ||||
|       } | ||||
|  | ||||
| @ -95,7 +95,7 @@ describe('instructions', () => { | ||||
|     it('should use sanitizer function even on elements with namespaced attributes', () => { | ||||
|       const t = new TemplateFixture(() => { | ||||
|         element(0, 'div', [ | ||||
|           AttributeMarker.NAMESPACE_URI, | ||||
|           AttributeMarker.NamespaceUri, | ||||
|           'http://www.example.com/2004/test', | ||||
|           'whatever', | ||||
|           'abc', | ||||
| @ -445,7 +445,7 @@ describe('instructions', () => { | ||||
|           'height', | ||||
|           '300', | ||||
|           // test:title="abc"
 | ||||
|           AttributeMarker.NAMESPACE_URI, | ||||
|           AttributeMarker.NamespaceUri, | ||||
|           'http://www.example.com/2014/test', | ||||
|           'title', | ||||
|           'abc', | ||||
| @ -472,7 +472,7 @@ describe('instructions', () => { | ||||
|           'id', | ||||
|           'container', | ||||
|           // test:title="abc"
 | ||||
|           AttributeMarker.NAMESPACE_URI, | ||||
|           AttributeMarker.NamespaceUri, | ||||
|           'http://www.example.com/2014/test', | ||||
|           'title', | ||||
|           'abc', | ||||
| @ -492,19 +492,19 @@ describe('instructions', () => { | ||||
|           'container', | ||||
| 
 | ||||
|           // NS1:title="abc"
 | ||||
|           AttributeMarker.NAMESPACE_URI, | ||||
|           AttributeMarker.NamespaceUri, | ||||
|           'http://www.example.com/2014/test', | ||||
|           'title', | ||||
|           'abc', | ||||
| 
 | ||||
|           // NS1:whatever="wee"
 | ||||
|           AttributeMarker.NAMESPACE_URI, | ||||
|           AttributeMarker.NamespaceUri, | ||||
|           'http://www.example.com/2014/test', | ||||
|           'whatever', | ||||
|           'wee', | ||||
| 
 | ||||
|           // NS2:shazbot="wocka wocka"
 | ||||
|           AttributeMarker.NAMESPACE_URI, | ||||
|           AttributeMarker.NamespaceUri, | ||||
|           'http://www.whatever.com/2016/blah', | ||||
|           'shazbot', | ||||
|           'wocka wocka', | ||||
|  | ||||
| @ -179,14 +179,14 @@ describe('css selector matching', () => { | ||||
|       }); | ||||
| 
 | ||||
|       it('should take optional binding attribute names into account', () => { | ||||
|         expect(isMatching('span', [AttributeMarker.SELECT_ONLY, 'directive'], [ | ||||
|         expect(isMatching('span', [AttributeMarker.SelectOnly, 'directive'], [ | ||||
|           '', 'directive', '' | ||||
|         ])).toBeTruthy(`Selector '[directive]' should match <span [directive]="exp">`); | ||||
|       }); | ||||
| 
 | ||||
|       it('should not match optional binding attribute names if attribute selector has value', | ||||
|          () => { | ||||
|            expect(isMatching('span', [AttributeMarker.SELECT_ONLY, 'directive'], [ | ||||
|            expect(isMatching('span', [AttributeMarker.SelectOnly, 'directive'], [ | ||||
|              '', 'directive', 'value' | ||||
|            ])).toBeFalsy(`Selector '[directive=value]' should not match <span [directive]="exp">`); | ||||
|          }); | ||||
| @ -194,7 +194,7 @@ describe('css selector matching', () => { | ||||
|       it('should not match optional binding attribute names if attribute selector has value and next name equals to value', | ||||
|          () => { | ||||
|            expect(isMatching( | ||||
|                       'span', [AttributeMarker.SELECT_ONLY, 'directive', 'value'], | ||||
|                       'span', [AttributeMarker.SelectOnly, 'directive', 'value'], | ||||
|                       ['', 'directive', 'value'])) | ||||
|                .toBeFalsy( | ||||
|                    `Selector '[directive=value]' should not match <span [directive]="exp" [value]="otherExp">`); | ||||
|  | ||||
| @ -856,7 +856,7 @@ describe('query', () => { | ||||
|                  } | ||||
|                }, null, []); | ||||
| 
 | ||||
|                container(5, undefined, null, [AttributeMarker.SELECT_ONLY, 'vc']); | ||||
|                container(5, undefined, null, [AttributeMarker.SelectOnly, 'vc']); | ||||
|              } | ||||
| 
 | ||||
|              if (rf & RenderFlags.Update) { | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user