Revert "feat(ivy): support for i18n & ICU expressions (#26275)"
This reverts commit a63fd2d0f5f867ee17bf991a72ccbe6d6fa76566.
This commit is contained in:
		
							parent
							
								
									a752971bca
								
							
						
					
					
						commit
						f8f1168fa6
					
				| @ -83,23 +83,23 @@ describe('i18n support in the view compiler', () => { | ||||
|             $r3$.ɵi18nEnd(); | ||||
|             $r3$.ɵelementEnd(); | ||||
|             $r3$.ɵelementStart(2, "div"); | ||||
|             $r3$.ɵi18nAttributes(3, $_c2$); | ||||
|             $r3$.ɵi18nAttribute(3, $_c2$); | ||||
|             $r3$.ɵtext(4, "Content B"); | ||||
|             $r3$.ɵelementEnd(); | ||||
|             $r3$.ɵelementStart(5, "div"); | ||||
|             $r3$.ɵi18nAttributes(6, $_c4$); | ||||
|             $r3$.ɵi18nAttribute(6, $_c4$); | ||||
|             $r3$.ɵtext(7, "Content C"); | ||||
|             $r3$.ɵelementEnd(); | ||||
|             $r3$.ɵelementStart(8, "div"); | ||||
|             $r3$.ɵi18nAttributes(9, $_c6$); | ||||
|             $r3$.ɵi18nAttribute(9, $_c6$); | ||||
|             $r3$.ɵtext(10, "Content D"); | ||||
|             $r3$.ɵelementEnd(); | ||||
|             $r3$.ɵelementStart(11, "div"); | ||||
|             $r3$.ɵi18nAttributes(12, $_c8$); | ||||
|             $r3$.ɵi18nAttribute(12, $_c8$); | ||||
|             $r3$.ɵtext(13, "Content E"); | ||||
|             $r3$.ɵelementEnd(); | ||||
|             $r3$.ɵelementStart(14, "div"); | ||||
|             $r3$.ɵi18nAttributes(15, $_c10$); | ||||
|             $r3$.ɵi18nAttribute(15, $_c10$); | ||||
|             $r3$.ɵtext(16, "Content F"); | ||||
|             $r3$.ɵelementEnd(); | ||||
|           } | ||||
| @ -142,7 +142,7 @@ describe('i18n support in the view compiler', () => { | ||||
|         template: function MyComponent_Template(rf, ctx) { | ||||
|           if (rf & 1) { | ||||
|             $r3$.ɵelementStart(0, "div", $_c0$); | ||||
|             $r3$.ɵi18nAttributes(1, $_c2$); | ||||
|             $r3$.ɵi18nAttribute(1, $_c2$); | ||||
|             $r3$.ɵelementEnd(); | ||||
|           } | ||||
|         } | ||||
| @ -207,10 +207,10 @@ describe('i18n support in the view compiler', () => { | ||||
|           if (rf & 1) { | ||||
|             $r3$.ɵelementStart(0, "div", $_c0$); | ||||
|             $r3$.ɵpipe(1, "uppercase"); | ||||
|             $r3$.ɵi18nAttributes(2, $_c4$); | ||||
|             $r3$.ɵi18nAttribute(2, $_c4$); | ||||
|             $r3$.ɵelementEnd(); | ||||
|             $r3$.ɵelementStart(3, "div", $_c5$); | ||||
|             $r3$.ɵi18nAttributes(4, $_c8$); | ||||
|             $r3$.ɵi18nAttribute(4, $_c8$); | ||||
|             $r3$.ɵelementEnd(); | ||||
|           } | ||||
|           if (rf & 2) { | ||||
| @ -265,7 +265,7 @@ describe('i18n support in the view compiler', () => { | ||||
|             $r3$.ɵelementStart(0, "div"); | ||||
|             $r3$.ɵelementStart(1, "div"); | ||||
|             $r3$.ɵpipe(2, "uppercase"); | ||||
|             $r3$.ɵi18nAttributes(3, $_c2$); | ||||
|             $r3$.ɵi18nAttribute(3, $_c2$); | ||||
|             $r3$.ɵelementEnd(); | ||||
|             $r3$.ɵelementEnd(); | ||||
|           } | ||||
| @ -345,10 +345,10 @@ describe('i18n support in the view compiler', () => { | ||||
|           if (rf & 1) { | ||||
|             $r3$.ɵelementStart(0, "div", $_c0$); | ||||
|             $r3$.ɵpipe(1, "uppercase"); | ||||
|             $r3$.ɵi18nAttributes(2, $_c4$); | ||||
|             $r3$.ɵi18nAttribute(2, $_c4$); | ||||
|             $r3$.ɵelementEnd(); | ||||
|             $r3$.ɵelementStart(3, "div", $_c5$); | ||||
|             $r3$.ɵi18nAttributes(4, $_c8$); | ||||
|             $r3$.ɵi18nAttribute(4, $_c8$); | ||||
|             $r3$.ɵelementEnd(); | ||||
|           } | ||||
|           if (rf & 2) { | ||||
| @ -403,7 +403,7 @@ describe('i18n support in the view compiler', () => { | ||||
|             $r3$.ɵelementStart(0, "div"); | ||||
|             $r3$.ɵelementStart(1, "div"); | ||||
|             $r3$.ɵpipe(2, "uppercase"); | ||||
|             $r3$.ɵi18nAttributes(3, $_c2$); | ||||
|             $r3$.ɵi18nAttribute(3, $_c2$); | ||||
|             $r3$.ɵelementEnd(); | ||||
|             $r3$.ɵelementEnd(); | ||||
|           } | ||||
| @ -693,7 +693,7 @@ describe('i18n support in the view compiler', () => { | ||||
|             $r3$.ɵelementStart(0, "div"); | ||||
|             $r3$.ɵi18nStart(1, $MSG_APP_SPEC_TS_0$); | ||||
|             $r3$.ɵelementStart(2, "span"); | ||||
|             $r3$.ɵi18nAttributes(3, $_c2$); | ||||
|             $r3$.ɵi18nAttribute(3, $_c2$); | ||||
|             $r3$.ɵelementEnd(); | ||||
|             $r3$.ɵi18nEnd(); | ||||
|             $r3$.ɵelementEnd(); | ||||
| @ -701,7 +701,7 @@ describe('i18n support in the view compiler', () => { | ||||
|             $r3$.ɵi18nStart(5, $MSG_APP_SPEC_TS_3$); | ||||
|             $r3$.ɵpipe(6, "uppercase"); | ||||
|             $r3$.ɵelementStart(7, "span"); | ||||
|             $r3$.ɵi18nAttributes(8, $_c5$); | ||||
|             $r3$.ɵi18nAttribute(8, $_c5$); | ||||
|             $r3$.ɵelementEnd(); | ||||
|             $r3$.ɵi18nEnd(); | ||||
|             $r3$.ɵelementEnd(); | ||||
|  | ||||
| @ -95,7 +95,7 @@ export class Identifiers { | ||||
|   static pipeBind4: o.ExternalReference = {name: 'ɵpipeBind4', moduleName: CORE}; | ||||
|   static pipeBindV: o.ExternalReference = {name: 'ɵpipeBindV', moduleName: CORE}; | ||||
| 
 | ||||
|   static i18nAttributes: o.ExternalReference = {name: 'ɵi18nAttributes', moduleName: CORE}; | ||||
|   static i18nAttribute: o.ExternalReference = {name: 'ɵi18nAttribute', moduleName: CORE}; | ||||
|   static i18nExp: o.ExternalReference = {name: 'ɵi18nExp', moduleName: CORE}; | ||||
|   static i18nStart: o.ExternalReference = {name: 'ɵi18nStart', moduleName: CORE}; | ||||
|   static i18nEnd: o.ExternalReference = {name: 'ɵi18nEnd', moduleName: CORE}; | ||||
|  | ||||
| @ -490,7 +490,7 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver | ||||
|         if (i18nAttrArgs.length) { | ||||
|           const index: o.Expression = o.literal(this.allocateDataSlot()); | ||||
|           const args = this.constantPool.getConstLiteral(o.literalArr(i18nAttrArgs), true); | ||||
|           this.creationInstruction(element.sourceSpan, R3.i18nAttributes, [index, args]); | ||||
|           this.creationInstruction(element.sourceSpan, R3.i18nAttribute, [index, args]); | ||||
|           if (hasBindings) { | ||||
|             this.updateInstruction(element.sourceSpan, R3.i18nApply, [index]); | ||||
|           } | ||||
|  | ||||
| @ -108,12 +108,24 @@ export { | ||||
|   PipeDef as ɵPipeDef, | ||||
|   PipeDefWithMeta as ɵPipeDefWithMeta, | ||||
|   whenRendered as ɵwhenRendered, | ||||
|   i18nAttributes as ɵi18nAttributes, | ||||
|   i18nAttribute as ɵi18nAttribute, | ||||
|   i18nExp as ɵi18nExp, | ||||
|   i18nStart as ɵi18nStart, | ||||
|   i18nEnd as ɵi18nEnd, | ||||
|   i18nApply as ɵi18nApply, | ||||
|   i18nIcuReplaceVars as ɵi18nIcuReplaceVars, | ||||
|   i18nExpMapping as ɵi18nExpMapping, | ||||
|   i18nInterpolation1 as ɵi18nInterpolation1, | ||||
|   i18nInterpolation2 as ɵi18nInterpolation2, | ||||
|   i18nInterpolation3 as ɵi18nInterpolation3, | ||||
|   i18nInterpolation4 as ɵi18nInterpolation4, | ||||
|   i18nInterpolation5 as ɵi18nInterpolation5, | ||||
|   i18nInterpolation6 as ɵi18nInterpolation6, | ||||
|   i18nInterpolation7 as ɵi18nInterpolation7, | ||||
|   i18nInterpolation8 as ɵi18nInterpolation8, | ||||
|   i18nInterpolationV as ɵi18nInterpolationV, | ||||
|   i18nMapping as ɵi18nMapping, | ||||
|   I18nInstruction as ɵI18nInstruction, | ||||
|   I18nExpInstruction as ɵI18nExpInstruction, | ||||
|   WRAP_RENDERER_FACTORY2 as ɵWRAP_RENDERER_FACTORY2, | ||||
|   setClassMetadata as ɵsetClassMetadata, | ||||
| } from './render3/index'; | ||||
|  | ||||
| @ -205,12 +205,12 @@ The goal is for the `@Component` (and friends) to be the compiler of template. S | ||||
| ### I18N | ||||
| | Feature                             | Runtime | Spec     | Compiler | | ||||
| | ----------------------------------- | ------- | -------- | -------- | | ||||
| | i18nStart                           |  ✅     |  ✅       |  ✅      | | ||||
| | i18nEnd                             |  ✅     |  ✅       |  ✅      | | ||||
| | i18nAttributes                      |  ✅     |  ✅       |  ✅      | | ||||
| | i18nExp                             |  ✅     |  ✅       |  ✅     | | ||||
| | i18nApply                           |  ✅     |  ✅       |  ✅      | | ||||
| | ICU expressions                     |  ✅     |  ✅       |  ❌      | | ||||
| | i18nStart                           |  ❌     |  ✅       |  ✅      | | ||||
| | i18nEnd                             |  ❌     |  ✅       |  ✅      | | ||||
| | i18nAttributes                      |  ❌     |  ✅       |  ✅      | | ||||
| | i18nExp                             |  ❌     |  ✅       |  ✅     | | ||||
| | i18nApply                           |  ❌     |  ✅       |  ✅      | | ||||
| | ICU expressions                     |  ❌     |  ✅       |  ❌      | | ||||
| | closure support for g3              |  ✅     |  ✅       |  ❌      | | ||||
| | runtime service for external world  |  ❌     |  ❌       |  ❌      | | ||||
| | migration tool                      |  ❌     |  ❌       |  ❌      | | ||||
|  | ||||
| @ -11,12 +11,12 @@ For example index `123` may point to a component instance in the `LViewData` but | ||||
| 
 | ||||
| The layout is as such: | ||||
| 
 | ||||
| | Section    | `LViewData`                                                  | `TView.data` | ||||
| | ---------- | ------------------------------------------------------------ | -------------------------------------------------- | ||||
| | `HEADER`   | contextual data                                              |  mostly `null` | ||||
| | `CONSTS`   | DOM, pipe, and local ref instances                           | | ||||
| | `VARS`     | binding values                                               |  property names | ||||
| | `EXPANDO`  | host bindings; directive instances; providers; dynamic nodes | host prop names; directive tokens; provider tokens; `null` | ||||
| | Section    | `LViewData`                                   | `TView.data` | ||||
| | ---------- | --------------------------------------------- | -------------------------------------------------- | ||||
| | `HEADER`   | contextual data                               |  mostly `null` | ||||
| | `CONSTS`   | DOM, pipe, and local ref instances            | | ||||
| | `VARS`     | binding values                                |  property names | ||||
| | `EXPANDO`  | host bindings; directive instances; providers | host prop names; directive tokens; provider tokens | ||||
| 
 | ||||
| 
 | ||||
| ## `HEADER` | ||||
|  | ||||
| @ -23,7 +23,7 @@ class MyComponent { | ||||
| ``` | ||||
| NOTE: | ||||
| - There really is only two kinds of i18n text. | ||||
|   1. In attribute as in `title` (with `i18n-title` present). | ||||
|   1. In attribute as in `i18n-title`. | ||||
|   2. In element body marked as as `<div i18n>`. | ||||
| - The element body i18n can have internal DOM structure which may consist of sub-templates. | ||||
| 
 | ||||
| @ -160,8 +160,8 @@ i18nAttributes(1, MSG_div_attr); | ||||
| ``` | ||||
| The above instruction checks the `TView.data` cache at position `1` and if empty will create `I18nUpdateOpCodes` like so: | ||||
| ```typescript | ||||
| const i18nUpdateOpCodes = <I18nUpdateOpCodes>[ | ||||
|   // The following OpCodes represent: `<div i18n-title title="Hello <20>0<EFBFBD>!">` | ||||
| <I18nUpdateOpCodes>[ | ||||
|   // The following OpCodes represent: `<div i18n-title="Hello <20>0<EFBFBD>!">` | ||||
|   // If `changeMask & 0b11` | ||||
|   //        has changed then execute update OpCodes. | ||||
|   //        has NOT changed then skip `7` values and start processing next OpCodes. | ||||
| @ -170,13 +170,12 @@ const i18nUpdateOpCodes = <I18nUpdateOpCodes>[ | ||||
|   'Hello ',   // accumulate('Hello '); | ||||
|   -1,         // accumulate(-1); | ||||
|   '!',        // accumulate('!'); | ||||
|   // Update attribute: `elementAttribute(0, 'title', accumulatorFlush(null));` | ||||
|   // Update attribute: `elementAttribute(1, 'title', accumulatorFlush(null));` | ||||
|   // NOTE: `null` means don't sanitize | ||||
|   0 << SHIFT_REF | Attr, 'title', null, | ||||
|   1 << SHIFT_REF | Attr, 'title', null, | ||||
| ] | ||||
| ``` | ||||
| NOTE: | ||||
| - `i18nAttributes` updates the attributes of the previous element. | ||||
| - If there is more than one attribute which needs to be internationalized it is added to the array as `[attributeName, translation]` tuple.  | ||||
| - Even attributes which don't have bindings must go through `i18nAttributes` so that they correctly work with i18n in server environment. | ||||
| 
 | ||||
| @ -217,7 +216,7 @@ will generate | ||||
| ```typescript | ||||
| // Text broken down to allow addition of comments (Generated code will not have comments) | ||||
| const MSG_div = | ||||
|   'List: ' + | ||||
|   'List: ' | ||||
|   '<27>*2:1<>' +        // template(2, MyComponent_NgIf_Template_0, ...); | ||||
|     '<27>#1:1<EFBFBD>' +      // elementStart(1, 'ul'); | ||||
|       '<27>*2:2<>' +    // template(2, MyComponent_NgIf_NgFor_Template_1, ...); | ||||
| @ -299,7 +298,7 @@ i18nEnd();       // The instruction which is responsible for inserting text node | ||||
| The `i18nStart` generates these instructions which are cached in the `TView` and then processed by `i18nEnd`. | ||||
| 
 | ||||
| ```typescript | ||||
| const tI18n = <TI18n>{ | ||||
| <TI18n>{ | ||||
|   vars: 2,                               // Number of slots to allocate in EXPANDO.  | ||||
|   expandoStartIndex: 100,                // Assume in this example EXPANDO starts at 100 | ||||
|   create: <I18nMutateOpCodes>[           // Processed by `i18nEnd` | ||||
| @ -363,7 +362,7 @@ This case is more complex because it contains an ICU. | ||||
| ICUs are pre-parsed and then stored in the `TVIEW.data` as follows. | ||||
| 
 | ||||
| ```typescript | ||||
| const tI18n = <TI18n>{ | ||||
| <TI18n>{ | ||||
|   vars: 3 + Math.max(4, 3, 3),           // Number of slots to allocate in EXPANDO. (Max of all ICUs + fixed) | ||||
|   expandoStartIndex: 200,                // Assume in this example EXPANDO starts at 200 | ||||
|   create: <I18nMutateOpCodes>[ | ||||
| @ -380,16 +379,16 @@ const tI18n = <TI18n>{ | ||||
|     //        has NOT changed then skip `2` values and start processing next OpCodes. | ||||
|     0b1, 2, | ||||
|     -1,       // accumulate(-1); | ||||
|     // Switch ICU: `icuSwitchCase(lViewData[200 /*SHIFT_REF*/], 0 /*SHIFT_ICU*/, accumulatorFlush());` | ||||
|     200 << SHIFT_REF | 0 << SHIFT_ICU | IcuSwitch, | ||||
|     // Switch ICU: `icuSwitchCase(lViewData[0 /*SHIFT_ICU*/], 0 /*SHIFT_REF*/, accumulatorFlush());` | ||||
|     0 << SHIFT_ICU | 0 << SHIFT_REF | IcuSwitch, | ||||
| 
 | ||||
|     // NOTE: the bit mask here is the logical OR of all of the masks in the ICU. | ||||
|     0b1, 1, | ||||
|     // Update ICU: `icuUpdateCase(lViewData[200 /*SHIFT_REF*/], 0 /*SHIFT_ICU*/);` | ||||
|     // SHIFT_REF: points to: `i18nStart(0, MSG_div, 1);` | ||||
|     // SHIFT_ICU: is an index into which ICU is being updated. In our example we only have | ||||
|     // Update ICU: `icuUpdateCase(lViewData[0 /*SHIFT_ICU*/], 0 /*SHIFT_REF*/);` | ||||
|     // SHIFT_ICU: points to: `i18nStart(0, MSG_div, 1);` | ||||
|     // SHIFT_REF: is an index into which ICU is being updated. In our example we only have | ||||
|     //            one ICU so it is 0-th ICU to update. | ||||
|     200 << SHIFT_REF | 0 << SHIFT_ICU | IcuUpdate, | ||||
|     0 << SHIFT_ICU | 0 << SHIFT_REF | IcuUpdate, | ||||
|   ], | ||||
|   icus: [ | ||||
|     <TIcu>{ | ||||
| @ -545,7 +544,7 @@ The OpCodes require that offsets for the EXPANDO index for the reference. | ||||
| The question is how do we compute this: | ||||
| 
 | ||||
| ```typescript | ||||
| const tI18n = <TI18n>{ | ||||
| <TI18n>{ | ||||
|   vars: 1, | ||||
|   expandoStartIndex: 100, // Retrieved from `tView.blueprint.length` at i18nStart invocation. | ||||
|   create: <I18nMutateOpCodes>[ | ||||
| @ -624,7 +623,7 @@ The rules for attribute ICUs should be the same as for normal ICUs. | ||||
| For this reason we would like to reuse as much code as possible for parsing and processing of the ICU for simplicity and consistency. | ||||
| 
 | ||||
| ```typescript | ||||
| const tI18n = <TI18n>{ | ||||
| <TI18n>{ | ||||
|   vars: 0,                               // Number of slots to allocate in EXPANDO. (Max of all ICUs + fixed) | ||||
|   expandoStartIndex: 200,                // Assume in this example EXPANDO starts at 200 | ||||
|   create: <I18nMutateOpCodes>[ | ||||
| @ -636,18 +635,18 @@ const tI18n = <TI18n>{ | ||||
|     //        has NOT changed then skip `2` values and start processing next OpCodes. | ||||
|     0b1, 2, | ||||
|     -1,       // accumulate(-1) | ||||
|     // Switch ICU: `icuSwitchCase(lViewData[200 /*SHIFT_REF*/], 0 /*SHIFT_ICU*/, accumulatorFlush());` | ||||
|     200 << SHIFT_REF | 0 << SHIFT_ICU | IcuSwitch, | ||||
|     // Switch ICU: `icuSwitchCase(lViewData[0 /*SHIFT_ICU*/], 0 /*SHIFT_REF*/, accumulatorFlush());` | ||||
|     0 << SHIFT_ICU | 0 << SHIFT_REF | IcuSwitch, | ||||
| 
 | ||||
|     // NOTE: the bit mask here is the logical OR of all of the masks in the ICU. | ||||
|     0b1, 4, | ||||
|     'You have ',  // accumulate('You have '); | ||||
| 
 | ||||
|     // Update ICU: `icuUpdateCase(lViewData[200 /*SHIFT_REF*/], 0 /*SHIFT_ICU*/);` | ||||
|     // SHIFT_REF: points to: `i18nStart(0, MSG_div, 1);` | ||||
|     // SHIFT_ICU: is an index into which ICU is being updated. In our example we only have | ||||
|     // Update ICU: `icuUpdateCase(lViewData[0 /*SHIFT_ICU*/], 0 /*SHIFT_REF*/);` | ||||
|     // SHIFT_ICU: points to: `i18nStart(0, MSG_div, 1);` | ||||
|     // SHIFT_REF: is an index into which ICU is being updated. In our example we only have | ||||
|     //            one ICU so it is 0-th ICU to update. | ||||
|     200 << SHIFT_REF | 0 << SHIFT_ICU | IcuUpdate, | ||||
|     0 << SHIFT_ICU | 0 << SHIFT_REF | IcuUpdate, | ||||
|      | ||||
|     '.',  // accumulate('.'); | ||||
| 
 | ||||
| @ -700,7 +699,7 @@ const tI18n = <TI18n>{ | ||||
|           //        has changed then execute update OpCodes. | ||||
|           //        has NOT changed then skip `1` values and start processing next OpCodes. | ||||
|           -1, 2, | ||||
|           -1,        // accumulate(lViewData[bindIndex-1]); | ||||
|           -1,        // accumulate(lviewData[bindIndex-1]); | ||||
|           'emails',  // accumulate('no emails'); | ||||
|          ] | ||||
|       ] | ||||
| @ -725,7 +724,7 @@ Given | ||||
| ``` | ||||
| The above needs to be parsed into: | ||||
| ```TypeScript | ||||
| const icu = { | ||||
| { | ||||
|   type: 'plural',             // or 'select' | ||||
|   expressionBindingIndex: 0,  // from <20>0<EFBFBD>, | ||||
|   cases: [ | ||||
| @ -758,7 +757,7 @@ NOTE: The updates to attributes with placeholders require that we go through san | ||||
| 
 | ||||
| ## Translation without top level element | ||||
| 
 | ||||
| Placing `i18n` attribute on an existing elements is easy because the element defines parent and the translated element can be inserted synchronously.  | ||||
| Placing `i18n` attribute on an existing elements is easy because the element defines parent and the translated element can be insert synchronously.  | ||||
| For virtual elements such as `<ng-container>` or `<ng-template>` this is more complicated because there is no common root element to insert into. | ||||
| In such a case the `i18nStart` acts as the element to insert into. | ||||
| This is similar to `<ng-container>` behavior. | ||||
| @ -784,7 +783,7 @@ function MyComponent_Template_0(rf: RenderFlags, ctx: any) { | ||||
| 
 | ||||
| Which would get parsed into: | ||||
| ```typescript | ||||
| const tI18n = <TI18n>{ | ||||
| <TI18n>{ | ||||
|   vars: 2,                               // Number of slots to allocate in EXPANDO.  | ||||
|   expandoStartIndex: 100,                // Assume in this example EXPANDO starts at 100 | ||||
|   create: <I18nMutateOpCodes>[           // Processed by `i18nEnd` | ||||
| @ -870,7 +869,7 @@ NOTE: | ||||
| 
 | ||||
| The internal data structure will be: | ||||
| ```typescript | ||||
| const tI18n = <TI18n>{ | ||||
| <TI18n>{ | ||||
|   vars: 2,                               // Number of slots to allocate in EXPANDO.  | ||||
|   expandoStartIndex: 100,                // Assume in this example EXPANDO starts at 100 | ||||
|   create: <I18nMutateOpCodes>[           // Processed by `i18nEnd` | ||||
| @ -882,16 +881,16 @@ const tI18n = <TI18n>{ | ||||
|     //        has NOT changed then skip `2` values and start processing next OpCodes. | ||||
|     0b1, 2, | ||||
|     -1,       // accumulate(-1); | ||||
|     // Switch ICU: `icuSwitchCase(lViewData[100 /*SHIFT_REF*/], 0 /*SHIFT_ICU*/, accumulatorFlush());` | ||||
|     100 << SHIFT_REF | 0 << SHIFT_ICU | IcuSwitch, | ||||
|     // Switch ICU: `icuSwitchCase(lViewData[0 /*SHIFT_ICU*/], 0 /*SHIFT_REF*/, accumulatorFlush());` | ||||
|     0 << SHIFT_ICU | 0 << SHIFT_REF | IcuSwitch, | ||||
| 
 | ||||
|     // NOTE: the bit mask here is the logical OR of all of the masks in the ICU. | ||||
|     0b1, 1, | ||||
|     // Update ICU: `icuUpdateCase(lViewData[100 /*SHIFT_REF*/], 0 /*SHIFT_ICU*/);` | ||||
|     // SHIFT_REF: points to: `i18nStart(0, MSG_div, 1);` | ||||
|     // SHIFT_ICU: is an index into which ICU is being updated. In our example we only have | ||||
|     // Update ICU: `icuUpdateCase(lViewData[0 /*SHIFT_ICU*/], 0 /*SHIFT_REF*/);` | ||||
|     // SHIFT_ICU: points to: `i18nStart(0, MSG_div, 1);` | ||||
|     // SHIFT_REF: is an index into which ICU is being updated. In our example we only have | ||||
|     //            one ICU so it is 0-th ICU to update. | ||||
|     100 << SHIFT_REF | 0 << SHIFT_ICU | IcuUpdate, | ||||
|     0 << SHIFT_ICU | 0 << SHIFT_REF | IcuUpdate, | ||||
|   ], | ||||
|   icus: [ | ||||
|     <TIcu>{                                  // {<7B>0<EFBFBD>, plural, =0 {zero} other {<7B>0<EFBFBD> <!--subICU-->}} | ||||
| @ -907,7 +906,7 @@ const tI18n = <TI18n>{ | ||||
|           '', 1 << SHIFT_PARENT | AppendChild,       // Expando location: 100 | ||||
|           COMMENT_MARKER, '', 0 << SHIFT_PARENT | AppendChild,    // Expando location: 101 | ||||
|         ], | ||||
|       ], | ||||
|       ] | ||||
|       remove: [  | ||||
|         <I18nMutateOpCodes>[                         // Case: `0`: `{zero}` | ||||
|           1 << SHIFT_PARENT | 100 << SHIFT_REF | Remove, | ||||
| @ -922,16 +921,16 @@ const tI18n = <TI18n>{ | ||||
|         ], | ||||
|         <I18nMutateOpCodes>[                         // Case: `other`: `{<7B>0<EFBFBD> <!--subICU-->}` | ||||
|           0b1, 3, | ||||
|           -2, ' ', 100 << SHIFT_REF | Text,           // Case: `<60>0<EFBFBD> ` | ||||
|           -2, ' ', 100 << SHIFT_REF | Text           // Case: `<60>0<EFBFBD> ` | ||||
|           0b10, 5, | ||||
|           -1, | ||||
|           // Switch ICU: `icuSwitchCase(lViewData[101 /*SHIFT_REF*/], 0 /*SHIFT_ICU*/, accumulatorFlush());` | ||||
|           101 << SHIFT_REF | 0 << SHIFT_ICU | IcuSwitch, | ||||
|           -1 | ||||
|           // Switch ICU: `icuSwitchCase(lViewData[0 /*SHIFT_ICU*/], 1 /*SHIFT_REF*/, accumulatorFlush());` | ||||
|           0 << SHIFT_ICU | 1 << SHIFT_REF | IcuSwitch, | ||||
| 
 | ||||
|           // NOTE: the bit mask here is the logical OR of all of the masks int the ICU. | ||||
|           0b10, 1, | ||||
|           // Update ICU: `icuUpdateCase(lViewData[101 /*SHIFT_REF*/], 0 /*SHIFT_ICU*/);` | ||||
|           101 << SHIFT_REF | 0 << SHIFT_ICU | IcuUpdate, | ||||
|           // Update ICU: `icuUpdateCase(lViewData[0 /*SHIFT_ICU*/], 1 /*SHIFT_REF*/);` | ||||
|           0 << SHIFT_ICU | 1 << SHIFT_REF | IcuUpdate, | ||||
|         ], | ||||
|       ] | ||||
|     }, | ||||
| @ -1058,7 +1057,7 @@ Here is a more complete example. | ||||
| 
 | ||||
| Given this Angular's template: | ||||
| ```HTML | ||||
| <div i18n-title title="Hello {{name}}!" i18n="Some description."> | ||||
| <div i18n-title="Hello {{name}}!" i18n="Some description."> | ||||
|   {{count}} is rendered as: | ||||
|   <b *ngIf="true"> | ||||
|     { count, plural, | ||||
| @ -1112,7 +1111,7 @@ To generate code where the extracted i18n messages have the same ids, the `ngtsc | ||||
| 
 | ||||
| Given this Angular's template: | ||||
| ```HTML | ||||
| <div i18n-title title="Hello {{name}}!" i18n="Some description."> | ||||
| <div i18n-title="Hello {{name}}!" i18n="Some description."> | ||||
|   {{count}} is rendered as: | ||||
|   <b *ngIf="true"> | ||||
|     { count, plural, | ||||
|  | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -87,12 +87,24 @@ export { | ||||
| } from './state'; | ||||
| 
 | ||||
| export { | ||||
|   i18nAttributes, | ||||
|   i18nAttribute, | ||||
|   i18nExp, | ||||
|   i18nStart, | ||||
|   i18nEnd, | ||||
|   i18nApply, | ||||
|   i18nIcuReplaceVars, | ||||
|   i18nMapping, | ||||
|   i18nInterpolation1, | ||||
|   i18nInterpolation2, | ||||
|   i18nInterpolation3, | ||||
|   i18nInterpolation4, | ||||
|   i18nInterpolation5, | ||||
|   i18nInterpolation6, | ||||
|   i18nInterpolation7, | ||||
|   i18nInterpolation8, | ||||
|   i18nInterpolationV, | ||||
|   i18nExpMapping, | ||||
|   I18nInstruction, | ||||
|   I18nExpInstruction | ||||
| } from './i18n'; | ||||
| 
 | ||||
| export {NgModuleFactory, NgModuleRef, NgModuleType} from './ng_module_ref'; | ||||
|  | ||||
| @ -7,6 +7,7 @@ | ||||
|  */ | ||||
| 
 | ||||
| import './ng_dev_mode'; | ||||
| 
 | ||||
| import {resolveForwardRef} from '../di/forward_ref'; | ||||
| import {InjectionToken} from '../di/injection_token'; | ||||
| import {InjectFlags} from '../di/injector_compatibility'; | ||||
| @ -15,6 +16,7 @@ import {Sanitizer} from '../sanitization/security'; | ||||
| import {StyleSanitizeFn} from '../sanitization/style_sanitizer'; | ||||
| import {Type} from '../type'; | ||||
| import {noop} from '../util/noop'; | ||||
| 
 | ||||
| import {assertDefined, assertEqual, assertLessThan, assertNotEqual} from './assert'; | ||||
| import {attachPatchData, getComponentViewByInstance} from './context_discovery'; | ||||
| import {diPublicInInjector, getNodeInjectable, getOrCreateInjectable, getOrCreateNodeInjectorForNode, injectAttributeImpl} from './di'; | ||||
| @ -23,12 +25,11 @@ import {executeHooks, executeInitHooks, queueInitHooks, queueLifecycleHooks} fro | ||||
| import {ACTIVE_INDEX, LContainer, VIEWS} from './interfaces/container'; | ||||
| import {ComponentDef, ComponentQuery, ComponentTemplate, DirectiveDef, DirectiveDefListOrFactory, InitialStylingFlags, PipeDefListOrFactory, RenderFlags} from './interfaces/definition'; | ||||
| import {INJECTOR_SIZE, NodeInjectorFactory} from './interfaces/injector'; | ||||
| import {AttributeMarker, InitialInputData, InitialInputs, LocalRefExtractor, PropertyAliasValue, PropertyAliases, TAttributes, TContainerNode, TElementContainerNode, TElementNode, TIcuContainerNode, TNode, TNodeFlags, TNodeProviderIndexes, TNodeType, TProjectionNode, TViewNode} from './interfaces/node'; | ||||
| import {AttributeMarker, InitialInputData, InitialInputs, LocalRefExtractor, PropertyAliasValue, PropertyAliases, TAttributes, TContainerNode, TElementContainerNode, TElementNode, TNode, TNodeFlags, TNodeProviderIndexes, TNodeType, TProjectionNode, TViewNode} from './interfaces/node'; | ||||
| import {PlayerFactory} from './interfaces/player'; | ||||
| import {CssSelectorList, NG_PROJECT_AS_ATTR_NAME} from './interfaces/projection'; | ||||
| import {LQueries} from './interfaces/query'; | ||||
| import {ProceduralRenderer3, RComment, RElement, RNode, RText, Renderer3, RendererFactory3, isProceduralRenderer} from './interfaces/renderer'; | ||||
| import {SanitizerFn} from './interfaces/sanitization'; | ||||
| import {StylingIndex} from './interfaces/styling'; | ||||
| import {BINDING_INDEX, CLEANUP, CONTAINER_INDEX, CONTENT_QUERIES, CONTEXT, DECLARATION_VIEW, FLAGS, HEADER_OFFSET, HOST, HOST_NODE, INJECTOR, LViewData, LViewFlags, NEXT, OpaqueViewState, PARENT, QUERIES, RENDERER, RootContext, RootContextFlags, SANITIZER, TAIL, TVIEW, TView} from './interfaces/view'; | ||||
| import {assertNodeOfPossibleTypes, assertNodeType} from './node_assert'; | ||||
| @ -41,6 +42,7 @@ import {getStylingContext} from './styling/util'; | ||||
| import {NO_CHANGE} from './tokens'; | ||||
| import {getComponentViewByIndex, getNativeByIndex, getNativeByTNode, getRootContext, getRootView, getTNode, isComponent, isComponentDef, isDifferent, loadInternal, readPatchedLViewData, stringify} from './util'; | ||||
| 
 | ||||
| 
 | ||||
| /** | ||||
|  * A permanent marker promise which signifies that the current CD tree is | ||||
|  * clean. | ||||
| @ -52,6 +54,11 @@ const enum BindingDirection { | ||||
|   Output, | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Function used to sanitize the value before writing it into the renderer. | ||||
|  */ | ||||
| type SanitizerFn = (value: any) => string; | ||||
| 
 | ||||
| /** | ||||
|  * Refreshes the view, executing the following steps in that order: | ||||
|  * triggers init hooks, refreshes dynamic embedded views, triggers content hooks, sets host | ||||
| @ -190,13 +197,9 @@ export function createNodeAtIndex( | ||||
| export function createNodeAtIndex( | ||||
|     index: number, type: TNodeType.ElementContainer, native: RComment, name: null, | ||||
|     attrs: TAttributes | null): TElementContainerNode; | ||||
| export function createNodeAtIndex( | ||||
|     index: number, type: TNodeType.IcuContainer, native: RComment, name: null, | ||||
|     attrs: TAttributes | null): TElementContainerNode; | ||||
| export function createNodeAtIndex( | ||||
|     index: number, type: TNodeType, native: RText | RElement | RComment | null, name: string | null, | ||||
|     attrs: TAttributes | null): TElementNode&TContainerNode&TElementContainerNode&TProjectionNode& | ||||
|     TIcuContainerNode { | ||||
|     attrs: TAttributes | null): TElementNode&TContainerNode&TElementContainerNode&TProjectionNode { | ||||
|   const viewData = getViewData(); | ||||
|   const tView = getTView(); | ||||
|   const adjustedIndex = index + HEADER_OFFSET; | ||||
| @ -230,7 +233,7 @@ export function createNodeAtIndex( | ||||
|   setPreviousOrParentTNode(tNode); | ||||
|   setIsParent(true); | ||||
|   return tNode as TElementNode & TViewNode & TContainerNode & TElementContainerNode & | ||||
|       TProjectionNode & TIcuContainerNode; | ||||
|       TProjectionNode; | ||||
| } | ||||
| 
 | ||||
| export function createViewNode(index: number, view: LViewData) { | ||||
| @ -252,12 +255,11 @@ export function createViewNode(index: number, view: LViewData) { | ||||
|  * i18nApply() or ComponentFactory.create), we need to adjust the blueprint for future | ||||
|  * template passes. | ||||
|  */ | ||||
| export function allocExpando(view: LViewData) { | ||||
| export function adjustBlueprintForNewNode(view: LViewData) { | ||||
|   const tView = view[TVIEW]; | ||||
|   if (tView.firstTemplatePass) { | ||||
|     tView.expandoStartIndex++; | ||||
|     tView.blueprint.push(null); | ||||
|     tView.data.push(null); | ||||
|     view.push(null); | ||||
|   } | ||||
| } | ||||
| @ -912,7 +914,7 @@ export function elementEnd(): void { | ||||
|  * @param sanitizer An optional function used to sanitize the value. | ||||
|  */ | ||||
| export function elementAttribute( | ||||
|     index: number, name: string, value: any, sanitizer?: SanitizerFn | null): void { | ||||
|     index: number, name: string, value: any, sanitizer?: SanitizerFn): void { | ||||
|   if (value !== NO_CHANGE) { | ||||
|     const viewData = getViewData(); | ||||
|     const renderer = getRenderer(); | ||||
| @ -945,7 +947,7 @@ export function elementAttribute( | ||||
|  */ | ||||
| 
 | ||||
| export function elementProperty<T>( | ||||
|     index: number, propName: string, value: T | NO_CHANGE, sanitizer?: SanitizerFn | null): void { | ||||
|     index: number, propName: string, value: T | NO_CHANGE, sanitizer?: SanitizerFn): void { | ||||
|   if (value === NO_CHANGE) return; | ||||
|   const viewData = getViewData(); | ||||
|   const element = getNativeByIndex(index, viewData) as RElement | RComment; | ||||
|  | ||||
| @ -16,32 +16,24 @@ | ||||
|  * | ||||
|  * See: `I18nCreateOpCodes` for example of usage. | ||||
|  */ | ||||
| import {SanitizerFn} from './sanitization'; | ||||
| 
 | ||||
| export const enum I18nMutateOpCode { | ||||
|   /// Stores shift amount for bits 17-3 that contain reference index.
 | ||||
|   SHIFT_REF = 3, | ||||
|   /// Stores shift amount for bits 17-2 that contain reference index.
 | ||||
|   SHIFT_REF = 2, | ||||
|   /// Stores shift amount for bits 31-17 that contain parent index.
 | ||||
|   SHIFT_PARENT = 17, | ||||
|   /// Mask for OpCode
 | ||||
|   MASK_OPCODE = 0b111, | ||||
|   MASK_OPCODE = 0b11, | ||||
|   /// Mask for reference index.
 | ||||
|   MASK_REF = ((2 ^ 16) - 1) << SHIFT_REF, | ||||
| 
 | ||||
|   /// OpCode to select a node. (next OpCode will contain the operation.)
 | ||||
|   Select = 0b000, | ||||
|   Select = 0b00, | ||||
|   /// OpCode to append the current node to `PARENT`.
 | ||||
|   AppendChild = 0b001, | ||||
|   AppendChild = 0b01, | ||||
|   /// OpCode to insert the current node to `PARENT` before `REF`.
 | ||||
|   InsertBefore = 0b010, | ||||
|   InsertBefore = 0b10, | ||||
|   /// OpCode to remove the `REF` node from `PARENT`.
 | ||||
|   Remove = 0b011, | ||||
|   /// OpCode to set the attribute of a node.
 | ||||
|   Attr = 0b100, | ||||
|   /// OpCode to simulate elementEnd()
 | ||||
|   ElementEnd = 0b101, | ||||
|   /// OpCode to read the remove OpCodes for the nested ICU
 | ||||
|   RemoveNestedIcu = 0b110, | ||||
|   Remove = 0b11, | ||||
| } | ||||
| 
 | ||||
| /** | ||||
| @ -122,8 +114,8 @@ export interface COMMENT_MARKER { marker: 'comment'; } | ||||
|  *   // For removing existing nodes
 | ||||
|  *   // --------------------------------------------------
 | ||||
|  *   //   const node = lViewData[1];
 | ||||
|  *   //   removeChild(tView.data(1), node, lViewData);
 | ||||
|  *   1 << SHIFT_REF | Remove, | ||||
|  *   //   lViewData[2].remove(node);
 | ||||
|  *   2 << SHIFT_PARENT | 1 << SHIFT_REF | Remove, | ||||
|  * | ||||
|  *   // For writing attributes
 | ||||
|  *   // --------------------------------------------------
 | ||||
| @ -186,7 +178,7 @@ export const enum I18nUpdateOpCode { | ||||
|  *  } | ||||
|  * ``` | ||||
|  * We can assume that each call to `i18nExp` sets an internal `changeMask` bit depending on the | ||||
|  * index of `i18nExp`. | ||||
|  * index of `i18nExp` index. | ||||
|  * | ||||
|  * OpCodes | ||||
|  * ``` | ||||
| @ -230,7 +222,7 @@ export const enum I18nUpdateOpCode { | ||||
|  * ``` | ||||
|  * | ||||
|  */ | ||||
| export interface I18nUpdateOpCodes extends Array<string|number|SanitizerFn|null> {} | ||||
| export interface I18nUpdateOpCodes extends Array<string|number|((text: string) => string | null)> {} | ||||
| 
 | ||||
| /** | ||||
|  * Store information for the i18n translation block. | ||||
| @ -363,6 +355,10 @@ export interface TIcu { | ||||
|   update: I18nUpdateOpCodes[]; | ||||
| } | ||||
| 
 | ||||
| // Note: This hack is necessary so we don't erroneously get a circular dependency
 | ||||
| // failure based on types.
 | ||||
| export const unusedValueExportToPlacateAjd = 1; | ||||
| /** | ||||
|  * Stores currently selected case in each ICU. | ||||
|  * | ||||
|  * For each ICU in translation, the `Li18n` stores the currently selected case for the current | ||||
|  * `LView`. For perf reasons this array is only created if a translation block has an ICU. | ||||
|  */ | ||||
| export interface LI18n extends Array<number> {} | ||||
|  | ||||
| @ -21,7 +21,6 @@ export const enum TNodeType { | ||||
|   Element = 0b011, | ||||
|   ViewOrElement = 0b010, | ||||
|   ElementContainer = 0b100, | ||||
|   IcuContainer = 0b101, | ||||
| } | ||||
| 
 | ||||
| /** | ||||
| @ -256,7 +255,7 @@ export interface TNode { | ||||
|   parent: TElementNode|TContainerNode|null; | ||||
| 
 | ||||
|   /** | ||||
|    * If this node is part of an i18n block, it indicates whether this node is part of the DOM. | ||||
|    * If this node is part of an i18n block, it indicates whether this container is part of the DOM | ||||
|    * If this node is not part of an i18n block, this field is null. | ||||
|    */ | ||||
|   detached: boolean|null; | ||||
| @ -359,6 +358,7 @@ export interface TContainerNode extends TNode { | ||||
|   projection: null; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /** Static data for an <ng-container> */ | ||||
| export interface TElementContainerNode extends TNode { | ||||
|   /** Index in the LViewData[] array. */ | ||||
| @ -369,21 +369,6 @@ export interface TElementContainerNode extends TNode { | ||||
|   projection: null; | ||||
| } | ||||
| 
 | ||||
| /** Static data for an ICU expression */ | ||||
| export interface TIcuContainerNode extends TNode { | ||||
|   /** Index in the LViewData[] array. */ | ||||
|   index: number; | ||||
|   child: TElementNode|TTextNode|null; | ||||
|   parent: TElementNode|TElementContainerNode|null; | ||||
|   tViews: null; | ||||
|   projection: null; | ||||
|   /** | ||||
|    * Indicates the current active case for an ICU expression. | ||||
|    * It is null when there is no active case. | ||||
|    */ | ||||
|   activeCaseIndex: number|null; | ||||
| } | ||||
| 
 | ||||
| /** Static data for a view  */ | ||||
| export interface TViewNode extends TNode { | ||||
|   /** If -1, it's a dynamically created view. Otherwise, it is the view block ID. */ | ||||
|  | ||||
| @ -1,12 +0,0 @@ | ||||
| /** | ||||
|  * @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
 | ||||
|  */ | ||||
| 
 | ||||
| /** | ||||
|  * Function used to sanitize the value before writing it into the renderer. | ||||
|  */ | ||||
| export type SanitizerFn = (value: any) => string; | ||||
| @ -11,9 +11,9 @@ import {Injector} from '../../di/injector'; | ||||
| import {QueryList} from '../../linker'; | ||||
| import {Sanitizer} from '../../sanitization/security'; | ||||
| import {Type} from '../../type'; | ||||
| 
 | ||||
| import {LContainer} from './container'; | ||||
| import {ComponentDef, ComponentQuery, ComponentTemplate, DirectiveDef, DirectiveDefList, HostBindingsFunction, PipeDef, PipeDefList} from './definition'; | ||||
| import {I18nUpdateOpCodes, TI18n} from './i18n'; | ||||
| import {TElementNode, TNode, TViewNode} from './node'; | ||||
| import {PlayerHandler} from './player'; | ||||
| import {LQueries} from './query'; | ||||
| @ -297,7 +297,7 @@ export interface TView { | ||||
|   /** Whether or not this template has been processed. */ | ||||
|   firstTemplatePass: boolean; | ||||
| 
 | ||||
|   /** Static data equivalent of LView.data[]. Contains TNodes, PipeDefInternal or TI18n. */ | ||||
|   /** Static data equivalent of LView.data[]. Contains TNodes. */ | ||||
|   data: TData; | ||||
| 
 | ||||
|   /** | ||||
| @ -535,7 +535,7 @@ export type HookData = (number | (() => void))[]; | ||||
|  */ | ||||
| export type TData = | ||||
|     (TNode | PipeDef<any>| DirectiveDef<any>| ComponentDef<any>| number | Type<any>| | ||||
|      InjectionToken<any>| TI18n | I18nUpdateOpCodes | null)[]; | ||||
|      InjectionToken<any>| null)[]; | ||||
| 
 | ||||
| // Note: This hack is necessary so we don't erroneously get a circular dependency
 | ||||
| // failure based on types.
 | ||||
|  | ||||
| @ -97,7 +97,7 @@ export const angularCoreEnv: {[name: string]: Function} = { | ||||
|   'ɵtextBinding': r3.textBinding, | ||||
|   'ɵembeddedViewStart': r3.embeddedViewStart, | ||||
|   'ɵembeddedViewEnd': r3.embeddedViewEnd, | ||||
|   'ɵi18nAttributes': r3.i18nAttributes, | ||||
|   'ɵi18nAttribute': r3.i18nAttribute, | ||||
|   'ɵi18nExp': r3.i18nExp, | ||||
|   'ɵi18nStart': r3.i18nStart, | ||||
|   'ɵi18nEnd': r3.i18nEnd, | ||||
|  | ||||
| @ -21,23 +21,8 @@ const unusedValueToPlacateAjd = unused1 + unused2 + unused3 + unused4 + unused5; | ||||
| 
 | ||||
| /** Retrieves the parent element of a given node. */ | ||||
| export function getParentNative(tNode: TNode, currentView: LViewData): RElement|RComment|null { | ||||
|   if (tNode.parent == null) { | ||||
|     return getHostNative(currentView); | ||||
|   } else { | ||||
|     const parentTNode = getFirstParentNative(tNode); | ||||
|     return getNativeByTNode(parentTNode, currentView); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Get the first parent of a node that isn't an IcuContainer TNode | ||||
|  */ | ||||
| function getFirstParentNative(tNode: TNode): TNode { | ||||
|   let parent = tNode.parent; | ||||
|   while (parent && parent.type === TNodeType.IcuContainer) { | ||||
|     parent = parent.parent; | ||||
|   } | ||||
|   return parent !; | ||||
|   return tNode.parent == null ? getHostNative(currentView) : | ||||
|                                 getNativeByTNode(tNode.parent, currentView); | ||||
| } | ||||
| 
 | ||||
| /** | ||||
| @ -593,22 +578,17 @@ function canInsertNativeChildOfView(viewTNode: TViewNode, view: LViewData): bool | ||||
|  * | ||||
| 
 | ||||
|  * | ||||
|  * @param tNode The tNode of the node that we want to insert. | ||||
|  * @param parent The parent where the child will be inserted into. | ||||
|  * @param currentView Current LView being processed. | ||||
|  * @return boolean Whether the node should be inserted now (or delayed until later). | ||||
|  * @return boolean Whether the child should be inserted now (or delayed until later). | ||||
|  */ | ||||
| export function canInsertNativeNode(tNode: TNode, currentView: LViewData): boolean { | ||||
|   let currentNode = tNode; | ||||
|   let parent: TNode|null = tNode.parent; | ||||
| 
 | ||||
|   if (tNode.parent) { | ||||
|     if (tNode.parent.type === TNodeType.ElementContainer) { | ||||
|       currentNode = getHighestElementContainer(tNode); | ||||
|       parent = currentNode.parent; | ||||
|     } else if (tNode.parent.type === TNodeType.IcuContainer) { | ||||
|       currentNode = getFirstParentNative(currentNode); | ||||
|       parent = currentNode.parent; | ||||
|     } | ||||
|   if (tNode.parent && tNode.parent.type === TNodeType.ElementContainer) { | ||||
|     currentNode = getHighestElementContainer(tNode); | ||||
|     parent = currentNode.parent; | ||||
|   } | ||||
|   if (parent === null) parent = currentView[HOST_NODE]; | ||||
| 
 | ||||
| @ -659,7 +639,7 @@ export function nativeNextSibling(renderer: Renderer3, node: RNode): RNode|null | ||||
|  * @returns Whether or not the child was appended | ||||
|  */ | ||||
| export function appendChild( | ||||
|     childEl: RNode | null = null, childTNode: TNode, currentView: LViewData): boolean { | ||||
|     childEl: RNode | null, childTNode: TNode, currentView: LViewData): boolean { | ||||
|   if (childEl !== null && canInsertNativeNode(childTNode, currentView)) { | ||||
|     const renderer = currentView[RENDERER]; | ||||
|     const parentEl = getParentNative(childTNode, currentView); | ||||
| @ -675,9 +655,6 @@ export function appendChild( | ||||
|     } else if (parentTNode.type === TNodeType.ElementContainer) { | ||||
|       const renderParent = getRenderParent(childTNode, currentView) !; | ||||
|       nativeInsertBefore(renderer, renderParent, childEl, parentEl); | ||||
|     } else if (parentTNode.type === TNodeType.IcuContainer) { | ||||
|       const icuAnchorNode = getNativeByTNode(childTNode.parent !, currentView) !as RElement; | ||||
|       nativeInsertBefore(renderer, parentEl as RElement, childEl, icuAnchorNode); | ||||
|     } else { | ||||
|       isProceduralRenderer(renderer) ? renderer.appendChild(parentEl !as RElement, childEl) : | ||||
|                                        parentEl !.appendChild(childEl); | ||||
|  | ||||
| @ -157,10 +157,6 @@ export function getCurrentView(): OpaqueViewState { | ||||
|   return viewData as any as OpaqueViewState; | ||||
| } | ||||
| 
 | ||||
| export function _getViewData(): LViewData { | ||||
|   return viewData; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Restores `contextViewData` to the given OpaqueViewState instance. | ||||
|  * | ||||
|  | ||||
| @ -249,16 +249,4 @@ export function getParentInjectorTNode( | ||||
| export const defaultScheduler = | ||||
|     (typeof requestAnimationFrame !== 'undefined' && requestAnimationFrame ||  // browser only
 | ||||
|      setTimeout                                                                // everything else
 | ||||
|      ).bind(global); | ||||
| 
 | ||||
| /** | ||||
|  * Equivalent to ES6 spread, add each item to an array. | ||||
|  * | ||||
|  * @param items The items to add | ||||
|  * @param arr The array to which you want to add the items | ||||
|  */ | ||||
| export function addAllToArray(items: any[], arr: any[]) { | ||||
|   for (let i = 0; i < items.length; i++) { | ||||
|     arr.push(items[i]); | ||||
|   } | ||||
| } | ||||
|      ).bind(global); | ||||
| @ -57,14 +57,14 @@ const INLINE_ELEMENTS = merge( | ||||
|         'bdi,bdo,big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,picture,q,ruby,rp,rt,s,' + | ||||
|         'samp,small,source,span,strike,strong,sub,sup,time,track,tt,u,var,video')); | ||||
| 
 | ||||
| export const VALID_ELEMENTS = | ||||
| const VALID_ELEMENTS = | ||||
|     merge(VOID_ELEMENTS, BLOCK_ELEMENTS, INLINE_ELEMENTS, OPTIONAL_END_TAG_ELEMENTS); | ||||
| 
 | ||||
| // Attributes that have href and hence need to be sanitized
 | ||||
| export const URI_ATTRS = tagSet('background,cite,href,itemtype,longdesc,poster,src,xlink:href'); | ||||
| const URI_ATTRS = tagSet('background,cite,href,itemtype,longdesc,poster,src,xlink:href'); | ||||
| 
 | ||||
| // Attributes that have special href set hence need to be sanitized
 | ||||
| export const SRCSET_ATTRS = tagSet('srcset'); | ||||
| const SRCSET_ATTRS = tagSet('srcset'); | ||||
| 
 | ||||
| const HTML_ATTRS = tagSet( | ||||
|     'abbr,accesskey,align,alt,autoplay,axis,bgcolor,border,cellpadding,cellspacing,class,clear,color,cols,colspan,' + | ||||
| @ -81,7 +81,7 @@ const HTML_ATTRS = tagSet( | ||||
| // can be sanitized, but they increase security surface area without a legitimate use case, so they
 | ||||
| // are left out here.
 | ||||
| 
 | ||||
| export const VALID_ATTRS = merge(URI_ATTRS, SRCSET_ATTRS, HTML_ATTRS); | ||||
| const VALID_ATTRS = merge(URI_ATTRS, SRCSET_ATTRS, HTML_ATTRS); | ||||
| 
 | ||||
| /** | ||||
|  * SanitizingHtmlSerializer serializes a DOM fragment, stripping out any unsafe elements and unsafe | ||||
| @ -265,7 +265,7 @@ export function _sanitizeHtml(defaultDoc: any, unsafeHtmlInput: string): string | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export function getTemplateContent(el: Node): Node|null { | ||||
| function getTemplateContent(el: Node): Node|null { | ||||
|   return 'content' in (el as any /** Microsoft/TypeScript#21517 */) && isTemplateElement(el) ? | ||||
|       el.content : | ||||
|       null; | ||||
|  | ||||
| @ -623,9 +623,6 @@ | ||||
|   { | ||||
|     "name": "getElementDepthCount" | ||||
|   }, | ||||
|   { | ||||
|     "name": "getFirstParentNative" | ||||
|   }, | ||||
|   { | ||||
|     "name": "getFirstTemplatePass" | ||||
|   }, | ||||
|  | ||||
| @ -260,9 +260,6 @@ | ||||
|   { | ||||
|     "name": "getDirectiveDef" | ||||
|   }, | ||||
|   { | ||||
|     "name": "getFirstParentNative" | ||||
|   }, | ||||
|   { | ||||
|     "name": "getFirstTemplatePass" | ||||
|   }, | ||||
|  | ||||
| @ -845,9 +845,6 @@ | ||||
|   { | ||||
|     "name": "getErrorLogger" | ||||
|   }, | ||||
|   { | ||||
|     "name": "getFirstParentNative" | ||||
|   }, | ||||
|   { | ||||
|     "name": "getFirstTemplatePass" | ||||
|   }, | ||||
| @ -1107,7 +1104,7 @@ | ||||
|     "name": "markViewDirty" | ||||
|   }, | ||||
|   { | ||||
|     "name": "merge$1" | ||||
|     "name": "merge" | ||||
|   }, | ||||
|   { | ||||
|     "name": "mergeAll" | ||||
|  | ||||
| @ -665,9 +665,6 @@ | ||||
|   { | ||||
|     "name": "getElementDepthCount" | ||||
|   }, | ||||
|   { | ||||
|     "name": "getFirstParentNative" | ||||
|   }, | ||||
|   { | ||||
|     "name": "getFirstTemplatePass" | ||||
|   }, | ||||
|  | ||||
| @ -678,7 +678,7 @@ | ||||
|     "name": "PlatformRef" | ||||
|   }, | ||||
|   { | ||||
|     "name": "Plural$1" | ||||
|     "name": "Plural" | ||||
|   }, | ||||
|   { | ||||
|     "name": "QUERIES" | ||||
| @ -1688,9 +1688,6 @@ | ||||
|   { | ||||
|     "name": "getErrorLogger" | ||||
|   }, | ||||
|   { | ||||
|     "name": "getFirstParentNative" | ||||
|   }, | ||||
|   { | ||||
|     "name": "getFirstTemplatePass" | ||||
|   }, | ||||
| @ -1854,7 +1851,7 @@ | ||||
|     "name": "getPlayerContext" | ||||
|   }, | ||||
|   { | ||||
|     "name": "getPluralCategory$1" | ||||
|     "name": "getPluralCategory" | ||||
|   }, | ||||
|   { | ||||
|     "name": "getPointers" | ||||
|  | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user