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