feat(ivy): add ɵɵtextInterpolateX instructions (#30011)
- `ɵɵtextBinding(..., ɵɵinterpolationX())` instructions will now just be `ɵɵtextInterpolate(...)` instructions PR Close #30011
This commit is contained in:
		
							parent
							
								
									48093823cb
								
							
						
					
					
						commit
						dd0815095f
					
				| @ -168,7 +168,7 @@ describe('Renderer', () => { | ||||
|         ɵngcc0.ɵɵtext(0); | ||||
|     } if (rf & 2) { | ||||
|         ɵngcc0.ɵɵselect(0); | ||||
|         ɵngcc0.ɵɵtextBinding(0, ɵngcc0.ɵɵinterpolation1("", ctx.person.name, "")); | ||||
|         ɵngcc0.ɵɵtextInterpolate(ctx.person.name); | ||||
|     } }, encapsulation: 2 }); | ||||
| /*@__PURE__*/ ɵngcc0.ɵsetClassMetadata(A, [{ | ||||
|         type: Component, | ||||
|  | ||||
| @ -810,7 +810,7 @@ describe('compiler compliance', () => { | ||||
|             const $myComp$ = $r3$.ɵɵnextContext(); | ||||
|             const $foo$ = $r3$.ɵɵreference(1); | ||||
|             $r3$.ɵɵselect(1); | ||||
|             $r3$.ɵɵtextBinding(1, $r3$.ɵɵinterpolation2("", $myComp$.salutation, " ", $foo$, "")); | ||||
|             $r3$.ɵɵtextInterpolate2("", $myComp$.salutation, " ", $foo$, ""); | ||||
|           } | ||||
|         } | ||||
|         … | ||||
| @ -2074,9 +2074,9 @@ describe('compiler compliance', () => { | ||||
|                 } | ||||
|                 if (rf & 2) { | ||||
|                   $r3$.ɵɵselect(0); | ||||
|                   $r3$.ɵɵtextBinding(0, $r3$.ɵɵinterpolation1("", $r3$.ɵɵpipeBind2(1, 3, $r3$.ɵɵpipeBind2(2, 6, ctx.name, ctx.size), ctx.size), "")); | ||||
|                   $r3$.ɵɵtextInterpolate($r3$.ɵɵpipeBind2(1, 3, $r3$.ɵɵpipeBind2(2, 6, ctx.name, ctx.size), ctx.size)); | ||||
|                   $r3$.ɵɵselect(4); | ||||
|                   $r3$.ɵɵtextBinding(4, $r3$.ɵɵinterpolation2("", $r3$.ɵɵpipeBindV(5, 9, $r3$.ɵɵpureFunction1(18, $c0$, ctx.name)), " ", ctx.name ? 1 : $r3$.ɵɵpipeBind1(6, 16, 2), "")); | ||||
|                   $r3$.ɵɵtextInterpolate2("", $r3$.ɵɵpipeBindV(5, 9, $r3$.ɵɵpureFunction1(18, $c0$, ctx.name)), " ", ctx.name ? 1 : $r3$.ɵɵpipeBind1(6, 16, 2), ""); | ||||
|                 } | ||||
|               }, | ||||
|               pipes: [MyPurePipe, MyPipe], | ||||
| @ -2139,14 +2139,14 @@ describe('compiler compliance', () => { | ||||
|                 } | ||||
|                 if (rf & 2) { | ||||
|                   $r3$.ɵɵselect(0); | ||||
|                   $r3$.ɵɵtextBinding(0, $r3$.ɵɵinterpolation5( | ||||
|                   $r3$.ɵɵtextInterpolate5( | ||||
|                     "0:", i0.ɵɵpipeBind1(1, 5, ctx.name), | ||||
|                     "1:", i0.ɵɵpipeBind2(2, 7, ctx.name, 1), | ||||
|                     "2:", i0.ɵɵpipeBind3(3, 10, ctx.name, 1, 2), | ||||
|                     "3:", i0.ɵɵpipeBind4(4, 14, ctx.name, 1, 2, 3), | ||||
|                     "4:", i0.ɵɵpipeBindV(5, 19, $r3$.ɵɵpureFunction1(25, $c0$, ctx.name)), | ||||
|                     "" | ||||
|                   )); | ||||
|                   ); | ||||
|                 } | ||||
|               }, | ||||
|               pipes: [MyPipe], | ||||
| @ -2192,7 +2192,7 @@ describe('compiler compliance', () => { | ||||
|             if (rf & 2) { | ||||
|               const $user$ = $r3$.ɵɵreference(1); | ||||
|               $r3$.ɵɵselect(2); | ||||
|               $r3$.ɵɵtextBinding(2, $r3$.ɵɵinterpolation1("Hello ", $user$.value, "!")); | ||||
|               $r3$.ɵɵtextInterpolate1("Hello ", $user$.value, "!"); | ||||
|             } | ||||
|           }, | ||||
|           encapsulation: 2 | ||||
| @ -2255,7 +2255,7 @@ describe('compiler compliance', () => { | ||||
|             const $foo$ = $r3$.ɵɵreference(1); | ||||
|             const $baz$ = $r3$.ɵɵreference(5); | ||||
|             $r3$.ɵɵselect(1); | ||||
|             $r3$.ɵɵtextBinding(1, $r3$.ɵɵinterpolation3("", $foo$, "-", $bar$, "-", $baz$, "")); | ||||
|             $r3$.ɵɵtextInterpolate3("", $foo$, "-", $bar$, "-", $baz$, ""); | ||||
|           } | ||||
|         } | ||||
|         function MyComponent_div_3_Template(rf, ctx) { | ||||
| @ -2271,7 +2271,7 @@ describe('compiler compliance', () => { | ||||
|             $r3$.ɵɵnextContext(); | ||||
|             const $foo$ = $r3$.ɵɵreference(1); | ||||
|             $r3$.ɵɵselect(1); | ||||
|             $r3$.ɵɵtextBinding(1, $r3$.ɵɵinterpolation2(" ", $foo$, "-", $bar$, " ")); | ||||
|             $r3$.ɵɵtextInterpolate2(" ", $foo$, "-", $bar$, " "); | ||||
|           } | ||||
|         } | ||||
|         … | ||||
| @ -2291,7 +2291,7 @@ describe('compiler compliance', () => { | ||||
|             if (rf & 2) { | ||||
|               const $foo$ = $r3$.ɵɵreference(1); | ||||
|               $r3$.ɵɵselect(2); | ||||
|               $r3$.ɵɵtextBinding(2, $r3$.ɵɵinterpolation1(" ", $foo$, " ")); | ||||
|               $r3$.ɵɵtextInterpolate1(" ", $foo$, " "); | ||||
|             } | ||||
|           }, | ||||
|           directives:[IfDirective], | ||||
| @ -2300,9 +2300,7 @@ describe('compiler compliance', () => { | ||||
| 
 | ||||
|       const result = compile(files, angularFiles); | ||||
|       const source = result.source; | ||||
| 
 | ||||
|       expectEmit(source, MyComponentDefinition, 'Incorrect MyComponent.ngComponentDef'); | ||||
| 
 | ||||
|     }); | ||||
| 
 | ||||
|     it('should support local refs mixed with context assignments', () => { | ||||
| @ -2344,7 +2342,7 @@ describe('compiler compliance', () => { | ||||
|           const $item$ = $i0$.ɵɵnextContext().$implicit; | ||||
|           const $foo$ = $i0$.ɵɵreference(2); | ||||
|           $r3$.ɵɵselect(1); | ||||
|           $i0$.ɵɵtextBinding(1, $i0$.ɵɵinterpolation2(" ", $foo$, " - ", $item$, " ")); | ||||
|           $i0$.ɵɵtextInterpolate2(" ", $foo$, " - ", $item$, " "); | ||||
|         } | ||||
|       } | ||||
| 
 | ||||
| @ -2648,7 +2646,7 @@ describe('compiler compliance', () => { | ||||
|             if (rf & 2) { | ||||
|               const $item$ = ctx.$implicit; | ||||
|               $r3$.ɵɵselect(1); | ||||
|               $r3$.ɵɵtextBinding(1, $r3$.ɵɵinterpolation1("", $item$.name, "")); | ||||
|               $r3$.ɵɵtextInterpolate($item$.name); | ||||
|             } | ||||
|           } | ||||
|           … | ||||
| @ -2731,7 +2729,7 @@ describe('compiler compliance', () => { | ||||
|               const $info$ = ctx.$implicit; | ||||
|               const $item$ = $r3$.ɵɵnextContext().$implicit; | ||||
|               $r3$.ɵɵselect(1); | ||||
|               $r3$.ɵɵtextBinding(1, $r3$.ɵɵinterpolation2(" ", $item$.name, ": ", $info$.description, " ")); | ||||
|               $r3$.ɵɵtextInterpolate2(" ", $item$.name, ": ", $info$.description, " "); | ||||
|             } | ||||
|           } | ||||
| 
 | ||||
| @ -2749,7 +2747,7 @@ describe('compiler compliance', () => { | ||||
|             if (rf & 2) { | ||||
|               const $item$ = ctx.$implicit; | ||||
|               $r3$.ɵɵselect(2); | ||||
|               $r3$.ɵɵtextBinding(2, $r3$.ɵɵinterpolation1("", IDENT.name, "")); | ||||
|               $r3$.ɵɵtextInterpolate(IDENT.name); | ||||
|               $r3$.ɵɵselect(4); | ||||
|               $r3$.ɵɵproperty("forOf", IDENT.infos); | ||||
|             } | ||||
|  | ||||
| @ -45,7 +45,7 @@ describe('compiler compliance: bindings', () => { | ||||
|         } | ||||
|         if (rf & 2) { | ||||
|           $r3$.ɵɵselect(1); | ||||
|           $i0$.ɵɵtextBinding(1, $i0$.ɵɵinterpolation1("Hello ", $ctx$.name, "")); | ||||
|           $i0$.ɵɵtextInterpolate1("Hello ", $ctx$.name, ""); | ||||
|         } | ||||
|       }`;
 | ||||
|       const result = compile(files, angularFiles); | ||||
| @ -567,7 +567,7 @@ describe('compiler compliance: bindings', () => { | ||||
|           if (rf & 2) { | ||||
|             const $_r0$ = $i0$.ɵɵreference(1); | ||||
|             $r3$.ɵɵselect(4); | ||||
|             $i0$.ɵɵtextBinding(4, $i0$.ɵɵinterpolation1(" ", $_r0$.id, " ")); | ||||
|             $i0$.ɵɵtextInterpolate1(" ", $_r0$.id, " "); | ||||
|           } | ||||
|         } | ||||
|       `;
 | ||||
|  | ||||
| @ -93,7 +93,7 @@ describe('r3_view_compiler', () => { | ||||
| 
 | ||||
|   describe('interpolations', () => { | ||||
|     // Regression #21927
 | ||||
|     it('should generate a correct call to bV with more than 8 interpolations', () => { | ||||
|     it('should generate a correct call to textInterpolateV with more than 8 interpolations', () => { | ||||
|       const files: MockDirectory = { | ||||
|         app: { | ||||
|           'example.ts': ` | ||||
| @ -112,10 +112,19 @@ describe('r3_view_compiler', () => { | ||||
|         } | ||||
|       }; | ||||
| 
 | ||||
|       const bV_call = | ||||
|           `$r3$.ɵɵinterpolationV([" ",ctx.list[0]," ",ctx.list[1]," ",ctx.list[2]," ",ctx.list[3],
 | ||||
|         " ",ctx.list[4]," ",ctx.list[5]," ",ctx.list[6]," ",ctx.list[7]," ",ctx.list[8], | ||||
|         " "])`;
 | ||||
|       const bV_call = ` | ||||
|       … | ||||
|       function MyApp_Template(rf, ctx) { | ||||
|         if (rf & 1) { | ||||
|           $i0$.ɵɵtext(0); | ||||
|         } | ||||
|         if (rf & 2) { | ||||
|           $i0$.ɵɵselect(0); | ||||
|           $i0$.ɵɵtextInterpolateV([" ", ctx.list[0], " ", ctx.list[1], " ", ctx.list[2], " ", ctx.list[3], " ", ctx.list[4], " ", ctx.list[5], " ", ctx.list[6], " ", ctx.list[7], " ", ctx.list[8], " "]); | ||||
|         } | ||||
|       } | ||||
|       … | ||||
|       `;
 | ||||
|       const result = compile(files, angularFiles); | ||||
|       expectEmit(result.source, bV_call, 'Incorrect bV call'); | ||||
|     }); | ||||
|  | ||||
| @ -999,7 +999,7 @@ describe('compiler compliance: styling', () => { | ||||
|               $r3$.ɵɵclassProp(0, $r3$.ɵɵpipeBind2(4, 10, $ctx$.fooExp, 2000)); | ||||
|               $r3$.ɵɵstylingApply(); | ||||
|               $r3$.ɵɵselect(5); | ||||
|               $r3$.ɵɵtextBinding(5, $r3$.ɵɵinterpolation1(" ", $ctx$.item, "")); | ||||
|               $r3$.ɵɵtextInterpolate1(" ", $ctx$.item, ""); | ||||
|             } | ||||
|           } | ||||
|           `;
 | ||||
|  | ||||
| @ -78,7 +78,7 @@ describe('compiler compliance: template', () => { | ||||
|           $i0$.ɵɵselect(0); | ||||
|           $i0$.ɵɵproperty("title", $myComp1$.format($outer1$, $middle1$, $inner1$, $myComp1$.component)); | ||||
|           $r3$.ɵɵselect(1); | ||||
|           $i0$.ɵɵtextBinding(1, $i0$.ɵɵinterpolation1(" ", $myComp1$.format($outer1$, $middle1$, $inner1$, $myComp1$.component), " ")); | ||||
|           $i0$.ɵɵtextInterpolate1(" ", $myComp1$.format($outer1$, $middle1$, $inner1$, $myComp1$.component), " "); | ||||
|         } | ||||
|       } | ||||
| 
 | ||||
| @ -215,7 +215,7 @@ describe('compiler compliance: template', () => { | ||||
|           const $item$ = ctx.$implicit; | ||||
|           const $i$ = ctx.index; | ||||
|           $r3$.ɵɵselect(1); | ||||
|           $i0$.ɵɵtextBinding(1, $i0$.ɵɵinterpolation2(" ", $i$, " - ", $item$, " ")); | ||||
|           $i0$.ɵɵtextInterpolate2(" ", $i$, " - ", $item$, " "); | ||||
|         } | ||||
|       } | ||||
|       // ...
 | ||||
| @ -272,7 +272,7 @@ describe('compiler compliance: template', () => { | ||||
|           const $i$ = $div$.index; | ||||
|           const $item$ = $div$.$implicit; | ||||
|           $r3$.ɵɵselect(1); | ||||
|           $i0$.ɵɵtextBinding(1, $i0$.ɵɵinterpolation2(" ", $i$, " - ", $item$, " ")); | ||||
|           $i0$.ɵɵtextInterpolate2(" ", $i$, " - ", $item$, " "); | ||||
|         } | ||||
|       } | ||||
| 
 | ||||
| @ -343,7 +343,7 @@ describe('compiler compliance: template', () => { | ||||
|           const $middle$ = $i0$.ɵɵnextContext().$implicit; | ||||
|           const $myComp$ = $i0$.ɵɵnextContext(2); | ||||
|           $r3$.ɵɵselect(1); | ||||
|           $i0$.ɵɵtextBinding(1, $i0$.ɵɵinterpolation2(" ", $middle$.value, " - ", $myComp$.name, " ")); | ||||
|           $i0$.ɵɵtextInterpolate2(" ", $middle$.value, " - ", $myComp$.name, " "); | ||||
|         } | ||||
|       } | ||||
| 
 | ||||
|  | ||||
| @ -1961,7 +1961,7 @@ describe('ngtsc behavioral tests', () => { | ||||
| 
 | ||||
|     env.driveMain(); | ||||
|     const jsContents = env.getContents('test.js'); | ||||
|     expect(jsContents).toContain('interpolation1("", ctx.text, "")'); | ||||
|     expect(jsContents).toContain('ɵɵtextInterpolate(ctx.text)'); | ||||
|   }); | ||||
| 
 | ||||
|   it('should handle `encapsulation` field', () => { | ||||
|  | ||||
| @ -44,7 +44,7 @@ describe('template source-mapping', () => { | ||||
|             {source: '<h3>', generated: 'i0.ɵɵelementStart(0, "h3")', sourceUrl: '../test.ts'}); | ||||
|         expect(mappings).toContain({ | ||||
|           source: 'Hello {{ name }}', | ||||
|           generated: 'i0.ɵɵtextBinding(1, i0.ɵɵinterpolation1("Hello ", ctx.name, ""))', | ||||
|           generated: 'i0.ɵɵtextInterpolate1("Hello ", ctx.name, "")', | ||||
|           sourceUrl: '../test.ts' | ||||
|         }); | ||||
|         expect(mappings).toContain( | ||||
| @ -57,8 +57,7 @@ describe('template source-mapping', () => { | ||||
|             {source: '<h2>', generated: 'i0.ɵɵelementStart(0, "h2")', sourceUrl: '../test.ts'}); | ||||
|         expect(mappings).toContain({ | ||||
|           source: '{{ greeting + " " + name }}', | ||||
|           generated: | ||||
|               'i0.ɵɵtextBinding(1, i0.ɵɵinterpolation1("", ctx.greeting + " " + ctx.name, ""))', | ||||
|           generated: 'i0.ɵɵtextInterpolate(ctx.greeting + " " + ctx.name)', | ||||
|           sourceUrl: '../test.ts' | ||||
|         }); | ||||
|         expect(mappings).toContain( | ||||
| @ -85,8 +84,7 @@ describe('template source-mapping', () => { | ||||
|             {source: '<div>', generated: 'i0.ɵɵelementStart(0, "div")', sourceUrl: '../test.ts'}); | ||||
|         expect(mappings).toContain({ | ||||
|           source: '{{200.3 | percent : 2 }}', | ||||
|           generated: | ||||
|               'i0.ɵɵtextBinding(1, i0.ɵɵinterpolation1("", i0.ɵɵpipeBind2(2, 1, 200.3, 2), ""))', | ||||
|           generated: 'i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(2, 1, 200.3, 2))', | ||||
|           sourceUrl: '../test.ts' | ||||
|         }); | ||||
|         expect(mappings).toContain( | ||||
| @ -270,7 +268,7 @@ describe('template source-mapping', () => { | ||||
| 
 | ||||
|         // expect(mappings).toContain({
 | ||||
|         //   source: '{{ name }}',
 | ||||
|         //   generated: 'i0.ɵɵtextBinding(1, i0.ɵɵinterpolation1("", ctx_r0.name, ""))',
 | ||||
|         //   generated: 'i0.ɵɵtextInterpolate(ctx_r0.name)',
 | ||||
|         //   sourceUrl: '../test.ts'
 | ||||
|         // });
 | ||||
|       }); | ||||
| @ -294,7 +292,7 @@ describe('template source-mapping', () => { | ||||
| 
 | ||||
|         // expect(mappings).toContain({
 | ||||
|         //   source: '{{ name }}',
 | ||||
|         //   generated: 'i0.ɵɵtextBinding(1, i0.ɵɵinterpolation1("", ctx_r0.name, ""))',
 | ||||
|         //   generated: 'i0.ɵɵtextInterpolate(ctx_r0.name)',
 | ||||
|         //   sourceUrl: '../test.ts'
 | ||||
|         // });
 | ||||
|       }); | ||||
| @ -370,7 +368,7 @@ describe('template source-mapping', () => { | ||||
| 
 | ||||
|       // Update mode
 | ||||
|       expect(mappings).toContain({ | ||||
|         generated: 'i0.ɵɵtextBinding(3, i0.ɵɵinterpolation1("", 1 + 2, ""))', | ||||
|         generated: 'i0.ɵɵtextInterpolate(1 + 2)', | ||||
|         source: '{{ 1 + 2 }}', | ||||
|         sourceUrl: '../test.ts' | ||||
|       }); | ||||
| @ -396,9 +394,10 @@ describe('template source-mapping', () => { | ||||
|       expect(mappings).toContain( | ||||
|           {generated: 'i0.ɵɵelementEnd()', source: '</div>', sourceUrl: '../test.ts'}); | ||||
| 
 | ||||
|       // TODO(benlesh): We need to circle back and prevent the extra parens from being generated.
 | ||||
|       // Update mode
 | ||||
|       expect(mappings).toContain({ | ||||
|         generated: 'i0.ɵɵtextBinding(3, i0.ɵɵinterpolation1("", 1 + 2, ""))', | ||||
|         generated: 'i0.ɵɵtextInterpolate(1 + 2)', | ||||
|         source: '{{ 1 + 2 }}', | ||||
|         sourceUrl: '../test.ts' | ||||
|       }); | ||||
| @ -452,7 +451,7 @@ describe('template source-mapping', () => { | ||||
| 
 | ||||
|         // Update mode
 | ||||
|         expect(mappings).toContain({ | ||||
|           generated: 'i0.ɵɵtextBinding(3, i0.ɵɵinterpolation1("", 1 + 2, ""))', | ||||
|           generated: 'i0.ɵɵtextInterpolate(1 + 2)', | ||||
|           source: '{{ 1 + 2 }}', | ||||
|           sourceUrl: '../dir/test.html' | ||||
|         }); | ||||
| @ -496,7 +495,7 @@ describe('template source-mapping', () => { | ||||
| 
 | ||||
|         // Update mode
 | ||||
|         expect(mappings).toContain({ | ||||
|           generated: 'i0.ɵɵtextBinding(3, i0.ɵɵinterpolation1("", 1 + 2, ""))', | ||||
|           generated: 'i0.ɵɵtextInterpolate(1 + 2)', | ||||
|           source: '{{ 1 + 2 }}', | ||||
|           sourceUrl: '../extraRootDir/test.html' | ||||
|         }); | ||||
|  | ||||
| @ -56,7 +56,7 @@ export class JitEvaluator { | ||||
|   evaluateCode( | ||||
|       sourceUrl: string, ctx: EmitterVisitorContext, vars: {[key: string]: any}, | ||||
|       createSourceMap: boolean): any { | ||||
|     let fnBody = `${ctx.toSource()}\n//# sourceURL=${sourceUrl}`; | ||||
|     let fnBody = `"use strict";${ctx.toSource()}\n//# sourceURL=${sourceUrl}`; | ||||
|     const fnArgNames: string[] = []; | ||||
|     const fnArgValues: any[] = []; | ||||
|     for (const argName in vars) { | ||||
|  | ||||
| @ -102,6 +102,17 @@ export class Identifiers { | ||||
| 
 | ||||
|   static getCurrentView: o.ExternalReference = {name: 'ɵɵgetCurrentView', moduleName: CORE}; | ||||
| 
 | ||||
|   static textInterpolate: o.ExternalReference = {name: 'ɵɵtextInterpolate', moduleName: CORE}; | ||||
|   static textInterpolate1: o.ExternalReference = {name: 'ɵɵtextInterpolate1', moduleName: CORE}; | ||||
|   static textInterpolate2: o.ExternalReference = {name: 'ɵɵtextInterpolate2', moduleName: CORE}; | ||||
|   static textInterpolate3: o.ExternalReference = {name: 'ɵɵtextInterpolate3', moduleName: CORE}; | ||||
|   static textInterpolate4: o.ExternalReference = {name: 'ɵɵtextInterpolate4', moduleName: CORE}; | ||||
|   static textInterpolate5: o.ExternalReference = {name: 'ɵɵtextInterpolate5', moduleName: CORE}; | ||||
|   static textInterpolate6: o.ExternalReference = {name: 'ɵɵtextInterpolate6', moduleName: CORE}; | ||||
|   static textInterpolate7: o.ExternalReference = {name: 'ɵɵtextInterpolate7', moduleName: CORE}; | ||||
|   static textInterpolate8: o.ExternalReference = {name: 'ɵɵtextInterpolate8', moduleName: CORE}; | ||||
|   static textInterpolateV: o.ExternalReference = {name: 'ɵɵtextInterpolateV', moduleName: CORE}; | ||||
| 
 | ||||
|   static restoreView: o.ExternalReference = {name: 'ɵɵrestoreView', moduleName: CORE}; | ||||
| 
 | ||||
|   static interpolation1: o.ExternalReference = {name: 'ɵɵinterpolation1', moduleName: CORE}; | ||||
|  | ||||
| @ -941,9 +941,17 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver | ||||
| 
 | ||||
|     const value = text.value.visit(this._valueConverter); | ||||
|     this.allocateBindingSlots(value); | ||||
| 
 | ||||
|     if (value instanceof Interpolation) { | ||||
|       this.updateInstruction( | ||||
|           nodeIndex, text.sourceSpan, getTextInterpolationExpression(value), | ||||
|           () => this.getUpdateInstructionArguments(o.variable(CONTEXT_NAME), value)); | ||||
|     } else { | ||||
|       this.updateInstruction( | ||||
|           nodeIndex, text.sourceSpan, R3.textBinding, | ||||
|         () => [o.literal(nodeIndex), this.convertPropertyBinding(o.variable(CONTEXT_NAME), value)]); | ||||
|           () => | ||||
|               [o.literal(nodeIndex), this.convertPropertyBinding(o.variable(CONTEXT_NAME), value)]); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   visitText(text: t.Text) { | ||||
| @ -1736,6 +1744,35 @@ function getAttributeInterpolationExpression(interpolation: Interpolation) { | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Gets the instruction to generate for interpolated text. | ||||
|  * @param interpolation An Interpolation AST | ||||
|  */ | ||||
| function getTextInterpolationExpression(interpolation: Interpolation): o.ExternalReference { | ||||
|   switch (getInterpolationArgsLength(interpolation)) { | ||||
|     case 1: | ||||
|       return R3.textInterpolate; | ||||
|     case 3: | ||||
|       return R3.textInterpolate1; | ||||
|     case 5: | ||||
|       return R3.textInterpolate2; | ||||
|     case 7: | ||||
|       return R3.textInterpolate3; | ||||
|     case 9: | ||||
|       return R3.textInterpolate4; | ||||
|     case 11: | ||||
|       return R3.textInterpolate5; | ||||
|     case 13: | ||||
|       return R3.textInterpolate6; | ||||
|     case 15: | ||||
|       return R3.textInterpolate7; | ||||
|     case 17: | ||||
|       return R3.textInterpolate8; | ||||
|     default: | ||||
|       return R3.textInterpolateV; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Gets the number of arguments expected to be passed to a generated instruction in the case of | ||||
|  * interpolation instructions. | ||||
|  | ||||
| @ -57,6 +57,16 @@ export { | ||||
|   ɵɵelement, | ||||
|   ɵɵlistener, | ||||
|   ɵɵtext, | ||||
|   ɵɵtextInterpolate, | ||||
|   ɵɵtextInterpolate1, | ||||
|   ɵɵtextInterpolate2, | ||||
|   ɵɵtextInterpolate3, | ||||
|   ɵɵtextInterpolate4, | ||||
|   ɵɵtextInterpolate5, | ||||
|   ɵɵtextInterpolate6, | ||||
|   ɵɵtextInterpolate7, | ||||
|   ɵɵtextInterpolate8, | ||||
|   ɵɵtextInterpolateV, | ||||
|   ɵɵembeddedViewStart, | ||||
|   ɵɵprojection, | ||||
|   ɵɵbind, | ||||
|  | ||||
| @ -107,7 +107,18 @@ export { | ||||
|   ɵɵtemplate, | ||||
| 
 | ||||
|   ɵɵtext, | ||||
|   ɵɵtextBinding} from './instructions/all'; | ||||
|   ɵɵtextBinding, | ||||
|   ɵɵtextInterpolate, | ||||
|   ɵɵtextInterpolate1, | ||||
|   ɵɵtextInterpolate2, | ||||
|   ɵɵtextInterpolate3, | ||||
|   ɵɵtextInterpolate4, | ||||
|   ɵɵtextInterpolate5, | ||||
|   ɵɵtextInterpolate6, | ||||
|   ɵɵtextInterpolate7, | ||||
|   ɵɵtextInterpolate8, | ||||
|   ɵɵtextInterpolateV, | ||||
| } from './instructions/all'; | ||||
| export {RenderFlags} from './interfaces/definition'; | ||||
| export {CssSelectorList} from './interfaces/projection'; | ||||
| 
 | ||||
|  | ||||
| @ -36,6 +36,7 @@ export * from './element'; | ||||
| export * from './element_container'; | ||||
| export * from './embedded_view'; | ||||
| export * from './get_current_view'; | ||||
| export * from './interpolation'; | ||||
| export * from './listener'; | ||||
| export * from './namespace'; | ||||
| export * from './next_context'; | ||||
| @ -45,3 +46,4 @@ export * from './property_interpolation'; | ||||
| export * from './select'; | ||||
| export * from './styling'; | ||||
| export * from './text'; | ||||
| export * from './text_interpolation'; | ||||
|  | ||||
| @ -8,7 +8,7 @@ | ||||
| import {SanitizerFn} from '../interfaces/sanitization'; | ||||
| import {getSelectedIndex} from '../state'; | ||||
| import {ɵɵelementAttribute} from './element'; | ||||
| import {ɵɵinterpolation1, ɵɵinterpolation2, ɵɵinterpolation3, ɵɵinterpolation4, ɵɵinterpolation5, ɵɵinterpolation6, ɵɵinterpolation7, ɵɵinterpolation8, ɵɵinterpolationV} from './property_interpolation'; | ||||
| import {ɵɵinterpolation1, ɵɵinterpolation2, ɵɵinterpolation3, ɵɵinterpolation4, ɵɵinterpolation5, ɵɵinterpolation6, ɵɵinterpolation7, ɵɵinterpolation8, ɵɵinterpolationV} from './interpolation'; | ||||
| import {TsickleIssue1009} from './shared'; | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										289
									
								
								packages/core/src/render3/instructions/interpolation.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										289
									
								
								packages/core/src/render3/instructions/interpolation.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,289 @@ | ||||
| /** | ||||
|  * @license | ||||
|  * Copyright Google Inc. All Rights Reserved. | ||||
|  * | ||||
|  * Use of this source code is governed by an MIT-style license that can be | ||||
|  * found in the LICENSE file at https://angular.io/license
 | ||||
|  */ | ||||
| 
 | ||||
| import {assertEqual, assertLessThan} from '../../util/assert'; | ||||
| import {bindingUpdated, bindingUpdated2, bindingUpdated3, bindingUpdated4} from '../bindings'; | ||||
| import {BINDING_INDEX, TVIEW} from '../interfaces/view'; | ||||
| import {getLView} from '../state'; | ||||
| import {NO_CHANGE} from '../tokens'; | ||||
| import {renderStringify} from '../util/misc_utils'; | ||||
| 
 | ||||
| import {storeBindingMetadata} from './shared'; | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| /** | ||||
|  * Create interpolation bindings with a variable number of expressions. | ||||
|  * | ||||
|  * If there are 1 to 8 expressions `interpolation1()` to `interpolation8()` should be used instead. | ||||
|  * Those are faster because there is no need to create an array of expressions and iterate over it. | ||||
|  * | ||||
|  * `values`: | ||||
|  * - has static text at even indexes, | ||||
|  * - has evaluated expressions at odd indexes. | ||||
|  * | ||||
|  * Returns the concatenated string when any of the arguments changes, `NO_CHANGE` otherwise. | ||||
|  * | ||||
|  * @codeGenApi | ||||
|  */ | ||||
| export function ɵɵinterpolationV(values: any[]): string|NO_CHANGE { | ||||
|   ngDevMode && assertLessThan(2, values.length, 'should have at least 3 values'); | ||||
|   ngDevMode && assertEqual(values.length % 2, 1, 'should have an odd number of values'); | ||||
|   let isBindingUpdated = false; | ||||
|   const lView = getLView(); | ||||
|   const tData = lView[TVIEW].data; | ||||
|   let bindingIndex = lView[BINDING_INDEX]; | ||||
| 
 | ||||
|   if (tData[bindingIndex] == null) { | ||||
|     // 2 is the index of the first static interstitial value (ie. not prefix)
 | ||||
|     for (let i = 2; i < values.length; i += 2) { | ||||
|       tData[bindingIndex++] = values[i]; | ||||
|     } | ||||
|     bindingIndex = lView[BINDING_INDEX]; | ||||
|   } | ||||
| 
 | ||||
|   for (let i = 1; i < values.length; i += 2) { | ||||
|     // Check if bindings (odd indexes) have changed
 | ||||
|     isBindingUpdated = bindingUpdated(lView, bindingIndex++, values[i]) || isBindingUpdated; | ||||
|   } | ||||
|   lView[BINDING_INDEX] = bindingIndex; | ||||
|   storeBindingMetadata(lView, values[0], values[values.length - 1]); | ||||
| 
 | ||||
|   if (!isBindingUpdated) { | ||||
|     return NO_CHANGE; | ||||
|   } | ||||
| 
 | ||||
|   // Build the updated content
 | ||||
|   let content = values[0]; | ||||
|   for (let i = 1; i < values.length; i += 2) { | ||||
|     content += renderStringify(values[i]) + values[i + 1]; | ||||
|   } | ||||
| 
 | ||||
|   return content; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Creates an interpolation binding with 1 expression. | ||||
|  * | ||||
|  * @param prefix static value used for concatenation only. | ||||
|  * @param v0 value checked for change. | ||||
|  * @param suffix static value used for concatenation only. | ||||
|  * | ||||
|  * @codeGenApi | ||||
|  */ | ||||
| export function ɵɵinterpolation1(prefix: string, v0: any, suffix: string): string|NO_CHANGE { | ||||
|   const lView = getLView(); | ||||
|   const different = bindingUpdated(lView, lView[BINDING_INDEX]++, v0); | ||||
|   storeBindingMetadata(lView, prefix, suffix); | ||||
|   return different ? prefix + renderStringify(v0) + suffix : NO_CHANGE; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Creates an interpolation binding with 2 expressions. | ||||
|  * | ||||
|  * @codeGenApi | ||||
|  */ | ||||
| export function ɵɵinterpolation2( | ||||
|     prefix: string, v0: any, i0: string, v1: any, suffix: string): string|NO_CHANGE { | ||||
|   const lView = getLView(); | ||||
|   const bindingIndex = lView[BINDING_INDEX]; | ||||
|   const different = bindingUpdated2(lView, bindingIndex, v0, v1); | ||||
|   lView[BINDING_INDEX] += 2; | ||||
| 
 | ||||
|   // Only set static strings the first time (data will be null subsequent runs).
 | ||||
|   const data = storeBindingMetadata(lView, prefix, suffix); | ||||
|   if (data) { | ||||
|     lView[TVIEW].data[bindingIndex] = i0; | ||||
|   } | ||||
| 
 | ||||
|   return different ? prefix + renderStringify(v0) + i0 + renderStringify(v1) + suffix : NO_CHANGE; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Creates an interpolation binding with 3 expressions. | ||||
|  * | ||||
|  * @codeGenApi | ||||
|  */ | ||||
| export function ɵɵinterpolation3( | ||||
|     prefix: string, v0: any, i0: string, v1: any, i1: string, v2: any, suffix: string): string| | ||||
|     NO_CHANGE { | ||||
|   const lView = getLView(); | ||||
|   const bindingIndex = lView[BINDING_INDEX]; | ||||
|   const different = bindingUpdated3(lView, bindingIndex, v0, v1, v2); | ||||
|   lView[BINDING_INDEX] += 3; | ||||
| 
 | ||||
|   // Only set static strings the first time (data will be null subsequent runs).
 | ||||
|   const data = storeBindingMetadata(lView, prefix, suffix); | ||||
|   if (data) { | ||||
|     const tData = lView[TVIEW].data; | ||||
|     tData[bindingIndex] = i0; | ||||
|     tData[bindingIndex + 1] = i1; | ||||
|   } | ||||
| 
 | ||||
|   return different ? | ||||
|       prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 + renderStringify(v2) + suffix : | ||||
|       NO_CHANGE; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Create an interpolation binding with 4 expressions. | ||||
|  * | ||||
|  * @codeGenApi | ||||
|  */ | ||||
| export function ɵɵinterpolation4( | ||||
|     prefix: string, v0: any, i0: string, v1: any, i1: string, v2: any, i2: string, v3: any, | ||||
|     suffix: string): string|NO_CHANGE { | ||||
|   const lView = getLView(); | ||||
|   const bindingIndex = lView[BINDING_INDEX]; | ||||
|   const different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3); | ||||
|   lView[BINDING_INDEX] += 4; | ||||
| 
 | ||||
|   // Only set static strings the first time (data will be null subsequent runs).
 | ||||
|   const data = storeBindingMetadata(lView, prefix, suffix); | ||||
|   if (data) { | ||||
|     const tData = lView[TVIEW].data; | ||||
|     tData[bindingIndex] = i0; | ||||
|     tData[bindingIndex + 1] = i1; | ||||
|     tData[bindingIndex + 2] = i2; | ||||
|   } | ||||
| 
 | ||||
|   return different ? | ||||
|       prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 + renderStringify(v2) + i2 + | ||||
|           renderStringify(v3) + suffix : | ||||
|       NO_CHANGE; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Creates an interpolation binding with 5 expressions. | ||||
|  * | ||||
|  * @codeGenApi | ||||
|  */ | ||||
| export function ɵɵinterpolation5( | ||||
|     prefix: string, v0: any, i0: string, v1: any, i1: string, v2: any, i2: string, v3: any, | ||||
|     i3: string, v4: any, suffix: string): string|NO_CHANGE { | ||||
|   const lView = getLView(); | ||||
|   const bindingIndex = lView[BINDING_INDEX]; | ||||
|   let different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3); | ||||
|   different = bindingUpdated(lView, bindingIndex + 4, v4) || different; | ||||
|   lView[BINDING_INDEX] += 5; | ||||
| 
 | ||||
|   // Only set static strings the first time (data will be null subsequent runs).
 | ||||
|   const data = storeBindingMetadata(lView, prefix, suffix); | ||||
|   if (data) { | ||||
|     const tData = lView[TVIEW].data; | ||||
|     tData[bindingIndex] = i0; | ||||
|     tData[bindingIndex + 1] = i1; | ||||
|     tData[bindingIndex + 2] = i2; | ||||
|     tData[bindingIndex + 3] = i3; | ||||
|   } | ||||
| 
 | ||||
|   return different ? | ||||
|       prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 + renderStringify(v2) + i2 + | ||||
|           renderStringify(v3) + i3 + renderStringify(v4) + suffix : | ||||
|       NO_CHANGE; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Creates an interpolation binding with 6 expressions. | ||||
|  * | ||||
|  * @codeGenApi | ||||
|  */ | ||||
| export function ɵɵinterpolation6( | ||||
|     prefix: string, v0: any, i0: string, v1: any, i1: string, v2: any, i2: string, v3: any, | ||||
|     i3: string, v4: any, i4: string, v5: any, suffix: string): string|NO_CHANGE { | ||||
|   const lView = getLView(); | ||||
|   const bindingIndex = lView[BINDING_INDEX]; | ||||
|   let different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3); | ||||
|   different = bindingUpdated2(lView, bindingIndex + 4, v4, v5) || different; | ||||
|   lView[BINDING_INDEX] += 6; | ||||
| 
 | ||||
|   // Only set static strings the first time (data will be null subsequent runs).
 | ||||
|   const data = storeBindingMetadata(lView, prefix, suffix); | ||||
|   if (data) { | ||||
|     const tData = lView[TVIEW].data; | ||||
|     tData[bindingIndex] = i0; | ||||
|     tData[bindingIndex + 1] = i1; | ||||
|     tData[bindingIndex + 2] = i2; | ||||
|     tData[bindingIndex + 3] = i3; | ||||
|     tData[bindingIndex + 4] = i4; | ||||
|   } | ||||
| 
 | ||||
|   return different ? | ||||
|       prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 + renderStringify(v2) + i2 + | ||||
|           renderStringify(v3) + i3 + renderStringify(v4) + i4 + renderStringify(v5) + suffix : | ||||
|       NO_CHANGE; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Creates an interpolation binding with 7 expressions. | ||||
|  * | ||||
|  * @codeGenApi | ||||
|  */ | ||||
| export function ɵɵinterpolation7( | ||||
|     prefix: string, v0: any, i0: string, v1: any, i1: string, v2: any, i2: string, v3: any, | ||||
|     i3: string, v4: any, i4: string, v5: any, i5: string, v6: any, suffix: string): string| | ||||
|     NO_CHANGE { | ||||
|   const lView = getLView(); | ||||
|   const bindingIndex = lView[BINDING_INDEX]; | ||||
|   let different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3); | ||||
|   different = bindingUpdated3(lView, bindingIndex + 4, v4, v5, v6) || different; | ||||
|   lView[BINDING_INDEX] += 7; | ||||
| 
 | ||||
|   // Only set static strings the first time (data will be null subsequent runs).
 | ||||
|   const data = storeBindingMetadata(lView, prefix, suffix); | ||||
|   if (data) { | ||||
|     const tData = lView[TVIEW].data; | ||||
|     tData[bindingIndex] = i0; | ||||
|     tData[bindingIndex + 1] = i1; | ||||
|     tData[bindingIndex + 2] = i2; | ||||
|     tData[bindingIndex + 3] = i3; | ||||
|     tData[bindingIndex + 4] = i4; | ||||
|     tData[bindingIndex + 5] = i5; | ||||
|   } | ||||
| 
 | ||||
|   return different ? | ||||
|       prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 + renderStringify(v2) + i2 + | ||||
|           renderStringify(v3) + i3 + renderStringify(v4) + i4 + renderStringify(v5) + i5 + | ||||
|           renderStringify(v6) + suffix : | ||||
|       NO_CHANGE; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Creates an interpolation binding with 8 expressions. | ||||
|  * | ||||
|  * @codeGenApi | ||||
|  */ | ||||
| export function ɵɵinterpolation8( | ||||
|     prefix: string, v0: any, i0: string, v1: any, i1: string, v2: any, i2: string, v3: any, | ||||
|     i3: string, v4: any, i4: string, v5: any, i5: string, v6: any, i6: string, v7: any, | ||||
|     suffix: string): string|NO_CHANGE { | ||||
|   const lView = getLView(); | ||||
|   const bindingIndex = lView[BINDING_INDEX]; | ||||
|   let different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3); | ||||
|   different = bindingUpdated4(lView, bindingIndex + 4, v4, v5, v6, v7) || different; | ||||
|   lView[BINDING_INDEX] += 8; | ||||
| 
 | ||||
|   // Only set static strings the first time (data will be null subsequent runs).
 | ||||
|   const data = storeBindingMetadata(lView, prefix, suffix); | ||||
|   if (data) { | ||||
|     const tData = lView[TVIEW].data; | ||||
|     tData[bindingIndex] = i0; | ||||
|     tData[bindingIndex + 1] = i1; | ||||
|     tData[bindingIndex + 2] = i2; | ||||
|     tData[bindingIndex + 3] = i3; | ||||
|     tData[bindingIndex + 4] = i4; | ||||
|     tData[bindingIndex + 5] = i5; | ||||
|     tData[bindingIndex + 6] = i6; | ||||
|   } | ||||
| 
 | ||||
|   return different ? | ||||
|       prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 + renderStringify(v2) + i2 + | ||||
|           renderStringify(v3) + i3 + renderStringify(v4) + i4 + renderStringify(v5) + i5 + | ||||
|           renderStringify(v6) + i6 + renderStringify(v7) + suffix : | ||||
|       NO_CHANGE; | ||||
| } | ||||
| @ -5,293 +5,14 @@ | ||||
|  * Use of this source code is governed by an MIT-style license that can be | ||||
|  * found in the LICENSE file at https://angular.io/license
 | ||||
|  */ | ||||
| import {assertEqual, assertLessThan} from '../../util/assert'; | ||||
| import {bindingUpdated, bindingUpdated2, bindingUpdated3, bindingUpdated4} from '../bindings'; | ||||
| import {SanitizerFn} from '../interfaces/sanitization'; | ||||
| import {BINDING_INDEX, TVIEW} from '../interfaces/view'; | ||||
| import {getLView, getSelectedIndex} from '../state'; | ||||
| import {getSelectedIndex} from '../state'; | ||||
| import {NO_CHANGE} from '../tokens'; | ||||
| import {renderStringify} from '../util/misc_utils'; | ||||
| 
 | ||||
| import {TsickleIssue1009, elementPropertyInternal, storeBindingMetadata} from './shared'; | ||||
| import {ɵɵinterpolation1, ɵɵinterpolation2, ɵɵinterpolation3, ɵɵinterpolation4, ɵɵinterpolation5, ɵɵinterpolation6, ɵɵinterpolation7, ɵɵinterpolation8, ɵɵinterpolationV} from './interpolation'; | ||||
| import {TsickleIssue1009, elementPropertyInternal} from './shared'; | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| /** | ||||
|  * Create interpolation bindings with a variable number of expressions. | ||||
|  * | ||||
|  * If there are 1 to 8 expressions `interpolation1()` to `interpolation8()` should be used instead. | ||||
|  * Those are faster because there is no need to create an array of expressions and iterate over it. | ||||
|  * | ||||
|  * `values`: | ||||
|  * - has static text at even indexes, | ||||
|  * - has evaluated expressions at odd indexes. | ||||
|  * | ||||
|  * Returns the concatenated string when any of the arguments changes, `NO_CHANGE` otherwise. | ||||
|  * | ||||
|  * @codeGenApi | ||||
|  */ | ||||
| export function ɵɵinterpolationV(values: any[]): string|NO_CHANGE { | ||||
|   ngDevMode && assertLessThan(2, values.length, 'should have at least 3 values'); | ||||
|   ngDevMode && assertEqual(values.length % 2, 1, 'should have an odd number of values'); | ||||
|   let different = false; | ||||
|   const lView = getLView(); | ||||
|   const tData = lView[TVIEW].data; | ||||
|   let bindingIndex = lView[BINDING_INDEX]; | ||||
| 
 | ||||
|   if (tData[bindingIndex] == null) { | ||||
|     // 2 is the index of the first static interstitial value (ie. not prefix)
 | ||||
|     for (let i = 2; i < values.length; i += 2) { | ||||
|       tData[bindingIndex++] = values[i]; | ||||
|     } | ||||
|     bindingIndex = lView[BINDING_INDEX]; | ||||
|   } | ||||
| 
 | ||||
|   for (let i = 1; i < values.length; i += 2) { | ||||
|     // Check if bindings (odd indexes) have changed
 | ||||
|     bindingUpdated(lView, bindingIndex++, values[i]) && (different = true); | ||||
|   } | ||||
|   lView[BINDING_INDEX] = bindingIndex; | ||||
|   storeBindingMetadata(lView, values[0], values[values.length - 1]); | ||||
| 
 | ||||
|   if (!different) { | ||||
|     return NO_CHANGE; | ||||
|   } | ||||
| 
 | ||||
|   // Build the updated content
 | ||||
|   let content = values[0]; | ||||
|   for (let i = 1; i < values.length; i += 2) { | ||||
|     content += renderStringify(values[i]) + values[i + 1]; | ||||
|   } | ||||
| 
 | ||||
|   return content; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Creates an interpolation binding with 1 expression. | ||||
|  * | ||||
|  * @param prefix static value used for concatenation only. | ||||
|  * @param v0 value checked for change. | ||||
|  * @param suffix static value used for concatenation only. | ||||
|  * | ||||
|  * @codeGenApi | ||||
|  */ | ||||
| export function ɵɵinterpolation1(prefix: string, v0: any, suffix: string): string|NO_CHANGE { | ||||
|   const lView = getLView(); | ||||
|   const different = bindingUpdated(lView, lView[BINDING_INDEX]++, v0); | ||||
|   storeBindingMetadata(lView, prefix, suffix); | ||||
|   return different ? prefix + renderStringify(v0) + suffix : NO_CHANGE; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Creates an interpolation binding with 2 expressions. | ||||
|  * | ||||
|  * @codeGenApi | ||||
|  */ | ||||
| export function ɵɵinterpolation2( | ||||
|     prefix: string, v0: any, i0: string, v1: any, suffix: string): string|NO_CHANGE { | ||||
|   const lView = getLView(); | ||||
|   const bindingIndex = lView[BINDING_INDEX]; | ||||
|   const different = bindingUpdated2(lView, bindingIndex, v0, v1); | ||||
|   lView[BINDING_INDEX] += 2; | ||||
| 
 | ||||
|   // Only set static strings the first time (data will be null subsequent runs).
 | ||||
|   const data = storeBindingMetadata(lView, prefix, suffix); | ||||
|   if (data) { | ||||
|     lView[TVIEW].data[bindingIndex] = i0; | ||||
|   } | ||||
| 
 | ||||
|   return different ? prefix + renderStringify(v0) + i0 + renderStringify(v1) + suffix : NO_CHANGE; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Creates an interpolation binding with 3 expressions. | ||||
|  * | ||||
|  * @codeGenApi | ||||
|  */ | ||||
| export function ɵɵinterpolation3( | ||||
|     prefix: string, v0: any, i0: string, v1: any, i1: string, v2: any, suffix: string): string| | ||||
|     NO_CHANGE { | ||||
|   const lView = getLView(); | ||||
|   const bindingIndex = lView[BINDING_INDEX]; | ||||
|   const different = bindingUpdated3(lView, bindingIndex, v0, v1, v2); | ||||
|   lView[BINDING_INDEX] += 3; | ||||
| 
 | ||||
|   // Only set static strings the first time (data will be null subsequent runs).
 | ||||
|   const data = storeBindingMetadata(lView, prefix, suffix); | ||||
|   if (data) { | ||||
|     const tData = lView[TVIEW].data; | ||||
|     tData[bindingIndex] = i0; | ||||
|     tData[bindingIndex + 1] = i1; | ||||
|   } | ||||
| 
 | ||||
|   return different ? | ||||
|       prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 + renderStringify(v2) + suffix : | ||||
|       NO_CHANGE; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Create an interpolation binding with 4 expressions. | ||||
|  * | ||||
|  * @codeGenApi | ||||
|  */ | ||||
| export function ɵɵinterpolation4( | ||||
|     prefix: string, v0: any, i0: string, v1: any, i1: string, v2: any, i2: string, v3: any, | ||||
|     suffix: string): string|NO_CHANGE { | ||||
|   const lView = getLView(); | ||||
|   const bindingIndex = lView[BINDING_INDEX]; | ||||
|   const different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3); | ||||
|   lView[BINDING_INDEX] += 4; | ||||
| 
 | ||||
|   // Only set static strings the first time (data will be null subsequent runs).
 | ||||
|   const data = storeBindingMetadata(lView, prefix, suffix); | ||||
|   if (data) { | ||||
|     const tData = lView[TVIEW].data; | ||||
|     tData[bindingIndex] = i0; | ||||
|     tData[bindingIndex + 1] = i1; | ||||
|     tData[bindingIndex + 2] = i2; | ||||
|   } | ||||
| 
 | ||||
|   return different ? | ||||
|       prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 + renderStringify(v2) + i2 + | ||||
|           renderStringify(v3) + suffix : | ||||
|       NO_CHANGE; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Creates an interpolation binding with 5 expressions. | ||||
|  * | ||||
|  * @codeGenApi | ||||
|  */ | ||||
| export function ɵɵinterpolation5( | ||||
|     prefix: string, v0: any, i0: string, v1: any, i1: string, v2: any, i2: string, v3: any, | ||||
|     i3: string, v4: any, suffix: string): string|NO_CHANGE { | ||||
|   const lView = getLView(); | ||||
|   const bindingIndex = lView[BINDING_INDEX]; | ||||
|   let different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3); | ||||
|   different = bindingUpdated(lView, bindingIndex + 4, v4) || different; | ||||
|   lView[BINDING_INDEX] += 5; | ||||
| 
 | ||||
|   // Only set static strings the first time (data will be null subsequent runs).
 | ||||
|   const data = storeBindingMetadata(lView, prefix, suffix); | ||||
|   if (data) { | ||||
|     const tData = lView[TVIEW].data; | ||||
|     tData[bindingIndex] = i0; | ||||
|     tData[bindingIndex + 1] = i1; | ||||
|     tData[bindingIndex + 2] = i2; | ||||
|     tData[bindingIndex + 3] = i3; | ||||
|   } | ||||
| 
 | ||||
|   return different ? | ||||
|       prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 + renderStringify(v2) + i2 + | ||||
|           renderStringify(v3) + i3 + renderStringify(v4) + suffix : | ||||
|       NO_CHANGE; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Creates an interpolation binding with 6 expressions. | ||||
|  * | ||||
|  * @codeGenApi | ||||
|  */ | ||||
| export function ɵɵinterpolation6( | ||||
|     prefix: string, v0: any, i0: string, v1: any, i1: string, v2: any, i2: string, v3: any, | ||||
|     i3: string, v4: any, i4: string, v5: any, suffix: string): string|NO_CHANGE { | ||||
|   const lView = getLView(); | ||||
|   const bindingIndex = lView[BINDING_INDEX]; | ||||
|   let different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3); | ||||
|   different = bindingUpdated2(lView, bindingIndex + 4, v4, v5) || different; | ||||
|   lView[BINDING_INDEX] += 6; | ||||
| 
 | ||||
|   // Only set static strings the first time (data will be null subsequent runs).
 | ||||
|   const data = storeBindingMetadata(lView, prefix, suffix); | ||||
|   if (data) { | ||||
|     const tData = lView[TVIEW].data; | ||||
|     tData[bindingIndex] = i0; | ||||
|     tData[bindingIndex + 1] = i1; | ||||
|     tData[bindingIndex + 2] = i2; | ||||
|     tData[bindingIndex + 3] = i3; | ||||
|     tData[bindingIndex + 4] = i4; | ||||
|   } | ||||
| 
 | ||||
|   return different ? | ||||
|       prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 + renderStringify(v2) + i2 + | ||||
|           renderStringify(v3) + i3 + renderStringify(v4) + i4 + renderStringify(v5) + suffix : | ||||
|       NO_CHANGE; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Creates an interpolation binding with 7 expressions. | ||||
|  * | ||||
|  * @codeGenApi | ||||
|  */ | ||||
| export function ɵɵinterpolation7( | ||||
|     prefix: string, v0: any, i0: string, v1: any, i1: string, v2: any, i2: string, v3: any, | ||||
|     i3: string, v4: any, i4: string, v5: any, i5: string, v6: any, suffix: string): string| | ||||
|     NO_CHANGE { | ||||
|   const lView = getLView(); | ||||
|   const bindingIndex = lView[BINDING_INDEX]; | ||||
|   let different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3); | ||||
|   different = bindingUpdated3(lView, bindingIndex + 4, v4, v5, v6) || different; | ||||
|   lView[BINDING_INDEX] += 7; | ||||
| 
 | ||||
|   // Only set static strings the first time (data will be null subsequent runs).
 | ||||
|   const data = storeBindingMetadata(lView, prefix, suffix); | ||||
|   if (data) { | ||||
|     const tData = lView[TVIEW].data; | ||||
|     tData[bindingIndex] = i0; | ||||
|     tData[bindingIndex + 1] = i1; | ||||
|     tData[bindingIndex + 2] = i2; | ||||
|     tData[bindingIndex + 3] = i3; | ||||
|     tData[bindingIndex + 4] = i4; | ||||
|     tData[bindingIndex + 5] = i5; | ||||
|   } | ||||
| 
 | ||||
|   return different ? | ||||
|       prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 + renderStringify(v2) + i2 + | ||||
|           renderStringify(v3) + i3 + renderStringify(v4) + i4 + renderStringify(v5) + i5 + | ||||
|           renderStringify(v6) + suffix : | ||||
|       NO_CHANGE; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Creates an interpolation binding with 8 expressions. | ||||
|  * | ||||
|  * @codeGenApi | ||||
|  */ | ||||
| export function ɵɵinterpolation8( | ||||
|     prefix: string, v0: any, i0: string, v1: any, i1: string, v2: any, i2: string, v3: any, | ||||
|     i3: string, v4: any, i4: string, v5: any, i5: string, v6: any, i6: string, v7: any, | ||||
|     suffix: string): string|NO_CHANGE { | ||||
|   const lView = getLView(); | ||||
|   const bindingIndex = lView[BINDING_INDEX]; | ||||
|   let different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3); | ||||
|   different = bindingUpdated4(lView, bindingIndex + 4, v4, v5, v6, v7) || different; | ||||
|   lView[BINDING_INDEX] += 8; | ||||
| 
 | ||||
|   // Only set static strings the first time (data will be null subsequent runs).
 | ||||
|   const data = storeBindingMetadata(lView, prefix, suffix); | ||||
|   if (data) { | ||||
|     const tData = lView[TVIEW].data; | ||||
|     tData[bindingIndex] = i0; | ||||
|     tData[bindingIndex + 1] = i1; | ||||
|     tData[bindingIndex + 2] = i2; | ||||
|     tData[bindingIndex + 3] = i3; | ||||
|     tData[bindingIndex + 4] = i4; | ||||
|     tData[bindingIndex + 5] = i5; | ||||
|     tData[bindingIndex + 6] = i6; | ||||
|   } | ||||
| 
 | ||||
|   return different ? | ||||
|       prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 + renderStringify(v2) + i2 + | ||||
|           renderStringify(v3) + i3 + renderStringify(v4) + i4 + renderStringify(v5) + i5 + | ||||
|           renderStringify(v6) + i6 + renderStringify(v7) + suffix : | ||||
|       NO_CHANGE; | ||||
| } | ||||
| 
 | ||||
| /////////////////////////////////////////////////////////////////////
 | ||||
| /// NEW INSTRUCTIONS
 | ||||
| /////////////////////////////////////////////////////////////////////
 | ||||
| 
 | ||||
| /** | ||||
|  * | ||||
|  * Update an interpolated property on an element with a lone bound value | ||||
|  | ||||
							
								
								
									
										298
									
								
								packages/core/src/render3/instructions/text_interpolation.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										298
									
								
								packages/core/src/render3/instructions/text_interpolation.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,298 @@ | ||||
| /** | ||||
|  * @license | ||||
|  * Copyright Google Inc. All Rights Reserved. | ||||
|  * | ||||
|  * Use of this source code is governed by an MIT-style license that can be | ||||
|  * found in the LICENSE file at https://angular.io/license
 | ||||
|  */ | ||||
| import {getSelectedIndex} from '../state'; | ||||
| 
 | ||||
| import {ɵɵinterpolation1, ɵɵinterpolation2, ɵɵinterpolation3, ɵɵinterpolation4, ɵɵinterpolation5, ɵɵinterpolation6, ɵɵinterpolation7, ɵɵinterpolation8, ɵɵinterpolationV} from './interpolation'; | ||||
| import {TsickleIssue1009} from './shared'; | ||||
| import {ɵɵtextBinding} from './text'; | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| /** | ||||
|  * | ||||
|  * Update text content with a lone bound value | ||||
|  * | ||||
|  * Used when a text node has 1 interpolated value in it, an no additional text | ||||
|  * surrounds that interpolated value: | ||||
|  * | ||||
|  * ```html
 | ||||
|  * <div>{{v0}}</div> | ||||
|  * ``` | ||||
|  * | ||||
|  * Its compiled representation is: | ||||
|  * | ||||
|  * ```ts
 | ||||
|  * ɵɵtextInterpolate(v0); | ||||
|  * ``` | ||||
|  * @returns itself, so that it may be chained. | ||||
|  * @see textInterpolateV | ||||
|  * @codeGenApi | ||||
|  */ | ||||
| export function ɵɵtextInterpolate(v0: any): TsickleIssue1009 { | ||||
|   ɵɵtextInterpolate1('', v0, ''); | ||||
|   return ɵɵtextInterpolate; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /** | ||||
|  * | ||||
|  * Update text content with single bound value surrounded by other text. | ||||
|  * | ||||
|  * Used when a text node has 1 interpolated value in it: | ||||
|  * | ||||
|  * ```html
 | ||||
|  * <div>prefix{{v0}}suffix</div> | ||||
|  * ``` | ||||
|  * | ||||
|  * Its compiled representation is: | ||||
|  * | ||||
|  * ```ts
 | ||||
|  * ɵɵtextInterpolate1('prefix', v0, 'suffix'); | ||||
|  * ``` | ||||
|  * @returns itself, so that it may be chained. | ||||
|  * @see textInterpolateV | ||||
|  * @codeGenApi | ||||
|  */ | ||||
| export function ɵɵtextInterpolate1(prefix: string, v0: any, suffix: string): TsickleIssue1009 { | ||||
|   const index = getSelectedIndex(); | ||||
|   ɵɵtextBinding(index, ɵɵinterpolation1(prefix, v0, suffix)); | ||||
|   return ɵɵtextInterpolate1; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * | ||||
|  * Update text content with 2 bound values surrounded by other text. | ||||
|  * | ||||
|  * Used when a text node has 2 interpolated values in it: | ||||
|  * | ||||
|  * ```html
 | ||||
|  * <div>prefix{{v0}}-{{v1}}suffix</div> | ||||
|  * ``` | ||||
|  * | ||||
|  * Its compiled representation is: | ||||
|  * | ||||
|  * ```ts
 | ||||
|  * ɵɵtextInterpolate2('prefix', v0, '-', v1, 'suffix'); | ||||
|  * ``` | ||||
|  * @returns itself, so that it may be chained. | ||||
|  * @see textInterpolateV | ||||
|  * @codeGenApi | ||||
|  */ | ||||
| export function ɵɵtextInterpolate2( | ||||
|     prefix: string, v0: any, i0: string, v1: any, suffix: string): TsickleIssue1009 { | ||||
|   const index = getSelectedIndex(); | ||||
|   ɵɵtextBinding(index, ɵɵinterpolation2(prefix, v0, i0, v1, suffix)); | ||||
|   return ɵɵtextInterpolate2; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * | ||||
|  * Update text content with 3 bound values surrounded by other text. | ||||
|  * | ||||
|  * Used when a text node has 3 interpolated values in it: | ||||
|  * | ||||
|  * ```html
 | ||||
|  * <div>prefix{{v0}}-{{v1}}-{{v2}}suffix</div> | ||||
|  * ``` | ||||
|  * | ||||
|  * Its compiled representation is: | ||||
|  * | ||||
|  * ```ts
 | ||||
|  * ɵɵtextInterpolate3( | ||||
|  * 'prefix', v0, '-', v1, '-', v2, 'suffix'); | ||||
|  * ``` | ||||
|  * @returns itself, so that it may be chained. | ||||
|  * @see textInterpolateV | ||||
|  * @codeGenApi | ||||
|  */ | ||||
| export function ɵɵtextInterpolate3( | ||||
|     prefix: string, v0: any, i0: string, v1: any, i1: string, v2: any, | ||||
|     suffix: string): TsickleIssue1009 { | ||||
|   const index = getSelectedIndex(); | ||||
|   ɵɵtextBinding(index, ɵɵinterpolation3(prefix, v0, i0, v1, i1, v2, suffix)); | ||||
|   return ɵɵtextInterpolate3; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * | ||||
|  * Update text content with 4 bound values surrounded by other text. | ||||
|  * | ||||
|  * Used when a text node has 4 interpolated values in it: | ||||
|  * | ||||
|  * ```html
 | ||||
|  * <div>prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}suffix</div> | ||||
|  * ``` | ||||
|  * | ||||
|  * Its compiled representation is: | ||||
|  * | ||||
|  * ```ts
 | ||||
|  * ɵɵtextInterpolate4( | ||||
|  * 'prefix', v0, '-', v1, '-', v2, '-', v3, 'suffix'); | ||||
|  * ``` | ||||
|  * @returns itself, so that it may be chained. | ||||
|  * @see ɵɵtextInterpolateV | ||||
|  * @codeGenApi | ||||
|  */ | ||||
| export function ɵɵtextInterpolate4( | ||||
|     prefix: string, v0: any, i0: string, v1: any, i1: string, v2: any, i2: string, v3: any, | ||||
|     suffix: string): TsickleIssue1009 { | ||||
|   const index = getSelectedIndex(); | ||||
|   ɵɵtextBinding(index, ɵɵinterpolation4(prefix, v0, i0, v1, i1, v2, i2, v3, suffix)); | ||||
|   return ɵɵtextInterpolate4; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * | ||||
|  * Update text content with 5 bound values surrounded by other text. | ||||
|  * | ||||
|  * Used when a text node has 5 interpolated values in it: | ||||
|  * | ||||
|  * ```html
 | ||||
|  * <div>prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}suffix</div> | ||||
|  * ``` | ||||
|  * | ||||
|  * Its compiled representation is: | ||||
|  * | ||||
|  * ```ts
 | ||||
|  * ɵɵtextInterpolate5( | ||||
|  * 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, 'suffix'); | ||||
|  * ``` | ||||
|  * @returns itself, so that it may be chained. | ||||
|  * @see textInterpolateV | ||||
|  * @codeGenApi | ||||
|  */ | ||||
| export function ɵɵtextInterpolate5( | ||||
|     prefix: string, v0: any, i0: string, v1: any, i1: string, v2: any, i2: string, v3: any, | ||||
|     i3: string, v4: any, suffix: string): TsickleIssue1009 { | ||||
|   const index = getSelectedIndex(); | ||||
|   ɵɵtextBinding(index, ɵɵinterpolation5(prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix)); | ||||
|   return ɵɵtextInterpolate5; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * | ||||
|  * Update text content with 6 bound values surrounded by other text. | ||||
|  * | ||||
|  * Used when a text node has 6 interpolated values in it: | ||||
|  * | ||||
|  * ```html
 | ||||
|  * <div>prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}suffix</div> | ||||
|  * ``` | ||||
|  * | ||||
|  * Its compiled representation is: | ||||
|  * | ||||
|  * ```ts
 | ||||
|  * ɵɵtextInterpolate6( | ||||
|  *    'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, 'suffix'); | ||||
|  * ``` | ||||
|  * | ||||
|  * @param i4 Static value used for concatenation only. | ||||
|  * @param v5 Value checked for change. @returns itself, so that it may be chained. | ||||
|  * @see textInterpolateV | ||||
|  * @codeGenApi | ||||
|  */ | ||||
| export function ɵɵtextInterpolate6( | ||||
|     prefix: string, v0: any, i0: string, v1: any, i1: string, v2: any, i2: string, v3: any, | ||||
|     i3: string, v4: any, i4: string, v5: any, suffix: string): TsickleIssue1009 { | ||||
|   const index = getSelectedIndex(); | ||||
|   ɵɵtextBinding( | ||||
|       index, ɵɵinterpolation6(prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix)); | ||||
|   return ɵɵtextInterpolate6; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * | ||||
|  * Update text content with 7 bound values surrounded by other text. | ||||
|  * | ||||
|  * Used when a text node has 7 interpolated values in it: | ||||
|  * | ||||
|  * ```html
 | ||||
|  * <div>prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}suffix</div> | ||||
|  * ``` | ||||
|  * | ||||
|  * Its compiled representation is: | ||||
|  * | ||||
|  * ```ts
 | ||||
|  * ɵɵtextInterpolate7( | ||||
|  *    'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, 'suffix'); | ||||
|  * ``` | ||||
|  * @returns itself, so that it may be chained. | ||||
|  * @see textInterpolateV | ||||
|  * @codeGenApi | ||||
|  */ | ||||
| export function ɵɵtextInterpolate7( | ||||
|     prefix: string, v0: any, i0: string, v1: any, i1: string, v2: any, i2: string, v3: any, | ||||
|     i3: string, v4: any, i4: string, v5: any, i5: string, v6: any, | ||||
|     suffix: string): TsickleIssue1009 { | ||||
|   const index = getSelectedIndex(); | ||||
|   ɵɵtextBinding( | ||||
|       index, ɵɵinterpolation7(prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix)); | ||||
|   return ɵɵtextInterpolate7; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * | ||||
|  * Update text content with 8 bound values surrounded by other text. | ||||
|  * | ||||
|  * Used when a text node has 8 interpolated values in it: | ||||
|  * | ||||
|  * ```html
 | ||||
|  * <div>prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}-{{v7}}suffix</div> | ||||
|  * ``` | ||||
|  * | ||||
|  * Its compiled representation is: | ||||
|  * | ||||
|  * ```ts
 | ||||
|  * ɵɵtextInterpolate8( | ||||
|  *  'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, '-', v7, 'suffix'); | ||||
|  * ``` | ||||
|  * @returns itself, so that it may be chained. | ||||
|  * @see textInterpolateV | ||||
|  * @codeGenApi | ||||
|  */ | ||||
| export function ɵɵtextInterpolate8( | ||||
|     prefix: string, v0: any, i0: string, v1: any, i1: string, v2: any, i2: string, v3: any, | ||||
|     i3: string, v4: any, i4: string, v5: any, i5: string, v6: any, i6: string, v7: any, | ||||
|     suffix: string): TsickleIssue1009 { | ||||
|   const index = getSelectedIndex(); | ||||
|   ɵɵtextBinding( | ||||
|       index, | ||||
|       ɵɵinterpolation8(prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix)); | ||||
|   return ɵɵtextInterpolate8; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Update text content with 9 or more bound values other surrounded by text. | ||||
|  * | ||||
|  * Used when the number of interpolated values exceeds 8. | ||||
|  * | ||||
|  * ```html
 | ||||
|  * <div>prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}-{{v7}}-{{v8}}-{{v9}}suffix</div> | ||||
|  * ``` | ||||
|  * | ||||
|  * Its compiled representation is: | ||||
|  * | ||||
|  * ```ts
 | ||||
|  * ɵɵtextInterpolateV( | ||||
|  *  ['prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, '-', v7, '-', v9, | ||||
|  *  'suffix']); | ||||
|  * ``` | ||||
|  *. | ||||
|  * @param values The a collection of values and the strings in between those values, beginning with | ||||
|  * a string prefix and ending with a string suffix. | ||||
|  * (e.g. `['prefix', value0, '-', value1, '-', value2, ..., value99, 'suffix']`) | ||||
|  * | ||||
|  * @returns itself, so that it may be chained. | ||||
|  * @codeGenApi | ||||
|  */ | ||||
| export function ɵɵtextInterpolateV(values: any[]): TsickleIssue1009 { | ||||
|   const index = getSelectedIndex(); | ||||
| 
 | ||||
|   ɵɵtextBinding(index, ɵɵinterpolationV(values)); | ||||
|   return ɵɵtextInterpolateV; | ||||
| } | ||||
| @ -127,6 +127,16 @@ export const angularCoreEnv: {[name: string]: Function} = | ||||
|        'ɵɵtemplate': r3.ɵɵtemplate, | ||||
|        'ɵɵtext': r3.ɵɵtext, | ||||
|        'ɵɵtextBinding': r3.ɵɵtextBinding, | ||||
|        'ɵɵtextInterpolate': r3.ɵɵtextInterpolate, | ||||
|        'ɵɵtextInterpolate1': r3.ɵɵtextInterpolate1, | ||||
|        'ɵɵtextInterpolate2': r3.ɵɵtextInterpolate2, | ||||
|        'ɵɵtextInterpolate3': r3.ɵɵtextInterpolate3, | ||||
|        'ɵɵtextInterpolate4': r3.ɵɵtextInterpolate4, | ||||
|        'ɵɵtextInterpolate5': r3.ɵɵtextInterpolate5, | ||||
|        'ɵɵtextInterpolate6': r3.ɵɵtextInterpolate6, | ||||
|        'ɵɵtextInterpolate7': r3.ɵɵtextInterpolate7, | ||||
|        'ɵɵtextInterpolate8': r3.ɵɵtextInterpolate8, | ||||
|        'ɵɵtextInterpolateV': r3.ɵɵtextInterpolateV, | ||||
|        'ɵɵembeddedViewStart': r3.ɵɵembeddedViewStart, | ||||
|        'ɵɵembeddedViewEnd': r3.ɵɵembeddedViewEnd, | ||||
|        'ɵɵi18n': r3.ɵɵi18n, | ||||
|  | ||||
							
								
								
									
										115
									
								
								packages/core/test/acceptance/text_spec.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										115
									
								
								packages/core/test/acceptance/text_spec.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,115 @@ | ||||
| /** | ||||
|  * @license | ||||
|  * Copyright Google Inc. All Rights Reserved. | ||||
|  * | ||||
|  * Use of this source code is governed by an MIT-style license that can be | ||||
|  * found in the LICENSE file at https://angular.io/license
 | ||||
|  */ | ||||
| import {Component} from '@angular/core'; | ||||
| import {TestBed} from '@angular/core/testing'; | ||||
| import {of } from 'rxjs'; | ||||
| 
 | ||||
| describe('text instructions', () => { | ||||
|   it('should handle all flavors of interpolated text', () => { | ||||
|     @Component({ | ||||
|       template: ` | ||||
|         <div>a{{one}}b{{two}}c{{three}}d{{four}}e{{five}}f{{six}}g{{seven}}h{{eight}}i{{nine}}j</div> | ||||
|         <div>a{{one}}b{{two}}c{{three}}d{{four}}e{{five}}f{{six}}g{{seven}}h{{eight}}i</div> | ||||
|         <div>a{{one}}b{{two}}c{{three}}d{{four}}e{{five}}f{{six}}g{{seven}}h</div> | ||||
|         <div>a{{one}}b{{two}}c{{three}}d{{four}}e{{five}}f{{six}}g</div> | ||||
|         <div>a{{one}}b{{two}}c{{three}}d{{four}}e{{five}}f</div> | ||||
|         <div>a{{one}}b{{two}}c{{three}}d{{four}}e</div> | ||||
|         <div>a{{one}}b{{two}}c{{three}}d</div> | ||||
|         <div>a{{one}}b{{two}}c</div> | ||||
|         <div>a{{one}}b</div> | ||||
|         <div>{{one}}</div> | ||||
|       ` | ||||
|     }) | ||||
|     class App { | ||||
|       one = 1; | ||||
|       two = 2; | ||||
|       three = 3; | ||||
|       four = 4; | ||||
|       five = 5; | ||||
|       six = 6; | ||||
|       seven = 7; | ||||
|       eight = 8; | ||||
|       nine = 9; | ||||
|     } | ||||
| 
 | ||||
|     TestBed.configureTestingModule({declarations: [App]}); | ||||
|     const fixture = TestBed.createComponent(App); | ||||
|     fixture.detectChanges(); | ||||
| 
 | ||||
|     const allTextContent = Array.from(fixture.nativeElement.querySelectorAll('div')) | ||||
|                                .map((div: HTMLDivElement) => div.textContent); | ||||
| 
 | ||||
|     expect(allTextContent).toEqual([ | ||||
|       'a1b2c3d4e5f6g7h8i9j', | ||||
|       'a1b2c3d4e5f6g7h8i', | ||||
|       'a1b2c3d4e5f6g7h', | ||||
|       'a1b2c3d4e5f6g', | ||||
|       'a1b2c3d4e5f', | ||||
|       'a1b2c3d4e', | ||||
|       'a1b2c3d', | ||||
|       'a1b2c', | ||||
|       'a1b', | ||||
|       '1', | ||||
|     ]); | ||||
|   }); | ||||
| 
 | ||||
|   it('should handle piped values in interpolated text', () => { | ||||
|     @Component({ | ||||
|       template: ` | ||||
|         <p>{{who | async}} sells {{(item | async)?.what}} down by the {{(item | async)?.where}}.</p> | ||||
|       ` | ||||
|     }) | ||||
|     class App { | ||||
|       who = of ('Sally'); | ||||
|       item = of ({ | ||||
|         what: 'seashells', | ||||
|         where: 'seashore', | ||||
|       }); | ||||
|     } | ||||
| 
 | ||||
|     TestBed.configureTestingModule({declarations: [App]}); | ||||
|     const fixture = TestBed.createComponent(App); | ||||
|     fixture.detectChanges(); | ||||
| 
 | ||||
|     const p = fixture.nativeElement.querySelector('p') as HTMLDivElement; | ||||
|     expect(p.textContent).toBe('Sally sells seashells down by the seashore.'); | ||||
|   }); | ||||
| 
 | ||||
|   it('should not sanitize urls in interpolated text', () => { | ||||
|     @Component({ | ||||
|       template: '<p>{{thisisfine}}</p>', | ||||
|     }) | ||||
|     class App { | ||||
|       thisisfine = 'javascript:alert("image_of_dog_with_coffee_in_burning_building.gif")'; | ||||
|     } | ||||
| 
 | ||||
|     TestBed.configureTestingModule({declarations: [App]}); | ||||
|     const fixture = TestBed.createComponent(App); | ||||
|     fixture.detectChanges(); | ||||
|     const p = fixture.nativeElement.querySelector('p'); | ||||
| 
 | ||||
|     expect(p.textContent) | ||||
|         .toBe('javascript:alert("image_of_dog_with_coffee_in_burning_building.gif")'); | ||||
|   }); | ||||
| 
 | ||||
|   it('should not allow writing HTML in interpolated text', () => { | ||||
|     @Component({ | ||||
|       template: '<div>{{test}}</div>', | ||||
|     }) | ||||
|     class App { | ||||
|       test = '<h1>LOL, big text</h1>'; | ||||
|     } | ||||
| 
 | ||||
|     TestBed.configureTestingModule({declarations: [App]}); | ||||
|     const fixture = TestBed.createComponent(App); | ||||
|     fixture.detectChanges(); | ||||
|     const div = fixture.nativeElement.querySelector('div'); | ||||
| 
 | ||||
|     expect(div.innerHTML).toBe('<h1>LOL, big text</h1>'); | ||||
|   }); | ||||
| }); | ||||
| @ -1603,5 +1603,11 @@ | ||||
|   }, | ||||
|   { | ||||
|     "name": "ɵɵtextBinding" | ||||
|   }, | ||||
|   { | ||||
|     "name": "ɵɵtextInterpolate" | ||||
|   }, | ||||
|   { | ||||
|     "name": "ɵɵtextInterpolate1" | ||||
|   } | ||||
| ] | ||||
							
								
								
									
										20
									
								
								tools/public_api_guard/core/core.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										20
									
								
								tools/public_api_guard/core/core.d.ts
									
									
									
									
										vendored
									
									
								
							| @ -1057,6 +1057,26 @@ export declare function ɵɵtext(index: number, value?: any): void; | ||||
| 
 | ||||
| export declare function ɵɵtextBinding<T>(index: number, value: T | NO_CHANGE): void; | ||||
| 
 | ||||
| export declare function ɵɵtextInterpolate(v0: any): TsickleIssue1009; | ||||
| 
 | ||||
| export declare function ɵɵtextInterpolate1(prefix: string, v0: any, suffix: string): TsickleIssue1009; | ||||
| 
 | ||||
| export declare function ɵɵtextInterpolate2(prefix: string, v0: any, i0: string, v1: any, suffix: string): TsickleIssue1009; | ||||
| 
 | ||||
| export declare function ɵɵtextInterpolate3(prefix: string, v0: any, i0: string, v1: any, i1: string, v2: any, suffix: string): TsickleIssue1009; | ||||
| 
 | ||||
| export declare function ɵɵtextInterpolate4(prefix: string, v0: any, i0: string, v1: any, i1: string, v2: any, i2: string, v3: any, suffix: string): TsickleIssue1009; | ||||
| 
 | ||||
| export declare function ɵɵtextInterpolate5(prefix: string, v0: any, i0: string, v1: any, i1: string, v2: any, i2: string, v3: any, i3: string, v4: any, suffix: string): TsickleIssue1009; | ||||
| 
 | ||||
| export declare function ɵɵtextInterpolate6(prefix: string, v0: any, i0: string, v1: any, i1: string, v2: any, i2: string, v3: any, i3: string, v4: any, i4: string, v5: any, suffix: string): TsickleIssue1009; | ||||
| 
 | ||||
| export declare function ɵɵtextInterpolate7(prefix: string, v0: any, i0: string, v1: any, i1: string, v2: any, i2: string, v3: any, i3: string, v4: any, i4: string, v5: any, i5: string, v6: any, suffix: string): TsickleIssue1009; | ||||
| 
 | ||||
| export declare function ɵɵtextInterpolate8(prefix: string, v0: any, i0: string, v1: any, i1: string, v2: any, i2: string, v3: any, i3: string, v4: any, i4: string, v5: any, i5: string, v6: any, i6: string, v7: any, suffix: string): TsickleIssue1009; | ||||
| 
 | ||||
| export declare function ɵɵtextInterpolateV(values: any[]): TsickleIssue1009; | ||||
| 
 | ||||
| export declare function ɵɵviewQuery<T>(predicate: Type<any> | string[], descend: boolean, read: any): QueryList<T>; | ||||
| 
 | ||||
| export declare const PACKAGE_ROOT_URL: InjectionToken<string>; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user