refactor(core): extract `icuSwitchCase`, `icuUpdateCase`, `removeNestedIcu` (#38154)
Extract `icuSwitchCase`, `icuUpdateCase`, `removeNestedIcu` into separate functions to align them with the `.debug` property text. PR Close #38154
This commit is contained in:
parent
3821dc5f6c
commit
26be5b4994
|
@ -758,6 +758,7 @@ function createDynamicNodeAtIndex(
|
||||||
const previousOrParentTNode = getPreviousOrParentTNode();
|
const previousOrParentTNode = getPreviousOrParentTNode();
|
||||||
ngDevMode && assertDataInRange(lView, index + HEADER_OFFSET);
|
ngDevMode && assertDataInRange(lView, index + HEADER_OFFSET);
|
||||||
lView[index + HEADER_OFFSET] = native;
|
lView[index + HEADER_OFFSET] = native;
|
||||||
|
// FIXME(misko): Why does this create A TNode??? I would not expect this to be here.
|
||||||
const tNode = getOrCreateTNode(tView, lView[T_HOST], index, type as any, name, null);
|
const tNode = getOrCreateTNode(tView, lView[T_HOST], index, type as any, name, null);
|
||||||
|
|
||||||
// We are creating a dynamic node, the previous tNode might not be pointing at this node.
|
// We are creating a dynamic node, the previous tNode might not be pointing at this node.
|
||||||
|
@ -882,7 +883,7 @@ function readCreateOpCodes(
|
||||||
|
|
||||||
function readUpdateOpCodes(
|
function readUpdateOpCodes(
|
||||||
updateOpCodes: I18nUpdateOpCodes, icus: TIcu[]|null, bindingsStartIndex: number,
|
updateOpCodes: I18nUpdateOpCodes, icus: TIcu[]|null, bindingsStartIndex: number,
|
||||||
changeMask: number, tView: TView, lView: LView, bypassCheckBit = false) {
|
changeMask: number, tView: TView, lView: LView, bypassCheckBit: boolean) {
|
||||||
let caseCreated = false;
|
let caseCreated = false;
|
||||||
for (let i = 0; i < updateOpCodes.length; i++) {
|
for (let i = 0; i < updateOpCodes.length; i++) {
|
||||||
// bit code to check if we should apply the next update
|
// bit code to check if we should apply the next update
|
||||||
|
@ -898,12 +899,10 @@ function readUpdateOpCodes(
|
||||||
value += opCode;
|
value += opCode;
|
||||||
} else if (typeof opCode == 'number') {
|
} else if (typeof opCode == 'number') {
|
||||||
if (opCode < 0) {
|
if (opCode < 0) {
|
||||||
|
// Negative opCode represent `i18nExp` values offset.
|
||||||
value += renderStringify(lView[bindingsStartIndex - opCode]);
|
value += renderStringify(lView[bindingsStartIndex - opCode]);
|
||||||
} else {
|
} else {
|
||||||
const nodeIndex = opCode >>> I18nUpdateOpCode.SHIFT_REF;
|
const nodeIndex = opCode >>> I18nUpdateOpCode.SHIFT_REF;
|
||||||
let tIcuIndex: number;
|
|
||||||
let tIcu: TIcu;
|
|
||||||
let icuTNode: TIcuContainerNode;
|
|
||||||
switch (opCode & I18nUpdateOpCode.MASK_OPCODE) {
|
switch (opCode & I18nUpdateOpCode.MASK_OPCODE) {
|
||||||
case I18nUpdateOpCode.Attr:
|
case I18nUpdateOpCode.Attr:
|
||||||
const propName = updateOpCodes[++j] as string;
|
const propName = updateOpCodes[++j] as string;
|
||||||
|
@ -916,58 +915,13 @@ function readUpdateOpCodes(
|
||||||
textBindingInternal(lView, nodeIndex, value);
|
textBindingInternal(lView, nodeIndex, value);
|
||||||
break;
|
break;
|
||||||
case I18nUpdateOpCode.IcuSwitch:
|
case I18nUpdateOpCode.IcuSwitch:
|
||||||
// FIXME(misko): Pull to a new function `icuSwitchCase`
|
caseCreated = icuSwitchCase(
|
||||||
tIcuIndex = updateOpCodes[++j] as number;
|
tView, updateOpCodes[++j] as number, nodeIndex, icus!, lView, value);
|
||||||
tIcu = icus![tIcuIndex];
|
|
||||||
icuTNode = getTNode(tView, nodeIndex) as TIcuContainerNode;
|
|
||||||
// If there is an active case, delete the old nodes
|
|
||||||
if (icuTNode.activeCaseIndex !== null) {
|
|
||||||
const removeCodes = tIcu.remove[icuTNode.activeCaseIndex];
|
|
||||||
for (let k = 0; k < removeCodes.length; k++) {
|
|
||||||
const removeOpCode = removeCodes[k] as number;
|
|
||||||
switch (removeOpCode & I18nMutateOpCode.MASK_INSTRUCTION) {
|
|
||||||
case I18nMutateOpCode.Remove:
|
|
||||||
const nodeIndex = removeOpCode >>> I18nMutateOpCode.SHIFT_REF;
|
|
||||||
// Remove DOM element, but do *not* mark TNode as detached, since we are
|
|
||||||
// just switching ICU cases (while keeping the same TNode), so a DOM element
|
|
||||||
// representing a new ICU case will be re-created.
|
|
||||||
removeNode(tView, lView, nodeIndex, /* markAsDetached */ false);
|
|
||||||
break;
|
|
||||||
case I18nMutateOpCode.RemoveNestedIcu:
|
|
||||||
const nestedIcuNodeIndex =
|
|
||||||
removeCodes[k + 1] as number >>> I18nMutateOpCode.SHIFT_REF;
|
|
||||||
const nestedIcuTNode =
|
|
||||||
getTNode(tView, nestedIcuNodeIndex) as TIcuContainerNode;
|
|
||||||
const activeIndex = nestedIcuTNode.activeCaseIndex;
|
|
||||||
if (activeIndex !== null) {
|
|
||||||
const nestedIcuTIndex = removeOpCode >>> I18nMutateOpCode.SHIFT_REF;
|
|
||||||
const nestedTIcu = icus![nestedIcuTIndex];
|
|
||||||
addAllToArray(nestedTIcu.remove[activeIndex], removeCodes);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the active caseIndex
|
|
||||||
const caseIndex = getCaseIndex(tIcu, value);
|
|
||||||
icuTNode.activeCaseIndex = caseIndex !== -1 ? caseIndex : null;
|
|
||||||
if (caseIndex > -1) {
|
|
||||||
// Add the nodes for the new case
|
|
||||||
readCreateOpCodes(-1, tIcu.create[caseIndex], tView, lView);
|
|
||||||
caseCreated = true;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case I18nUpdateOpCode.IcuUpdate:
|
case I18nUpdateOpCode.IcuUpdate:
|
||||||
// FIXME(misko): Pull to a new function `icuUpdateCase`
|
icuUpdateCase(
|
||||||
tIcuIndex = updateOpCodes[++j] as number;
|
tView, lView, updateOpCodes[++j] as number, nodeIndex, bindingsStartIndex,
|
||||||
tIcu = icus![tIcuIndex];
|
icus!, caseCreated);
|
||||||
icuTNode = getTNode(tView, nodeIndex) as TIcuContainerNode;
|
|
||||||
if (icuTNode.activeCaseIndex !== null) {
|
|
||||||
readUpdateOpCodes(
|
|
||||||
tIcu.update[icuTNode.activeCaseIndex], icus, bindingsStartIndex, changeMask,
|
|
||||||
tView, lView, caseCreated);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -978,6 +932,70 @@ function readUpdateOpCodes(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function icuUpdateCase(
|
||||||
|
tView: TView, lView: LView, tIcuIndex: number, nodeIndex: number, bindingsStartIndex: number,
|
||||||
|
tIcus: TIcu[], caseCreated: boolean) {
|
||||||
|
const tIcu = tIcus[tIcuIndex];
|
||||||
|
const icuTNode = getTNode(tView, nodeIndex) as TIcuContainerNode;
|
||||||
|
if (icuTNode.activeCaseIndex !== null) {
|
||||||
|
readUpdateOpCodes(
|
||||||
|
tIcu.update[icuTNode.activeCaseIndex], tIcus, bindingsStartIndex, changeMask, tView, lView,
|
||||||
|
caseCreated);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function icuSwitchCase(
|
||||||
|
tView: TView, tIcuIndex: number, nodeIndex: number, tIcus: TIcu[], lView: LView,
|
||||||
|
value: string): boolean {
|
||||||
|
const tIcu = tIcus[tIcuIndex];
|
||||||
|
const icuTNode = getTNode(tView, nodeIndex) as TIcuContainerNode;
|
||||||
|
let caseCreated = false;
|
||||||
|
// If there is an active case, delete the old nodes
|
||||||
|
if (icuTNode.activeCaseIndex !== null) {
|
||||||
|
const removeCodes = tIcu.remove[icuTNode.activeCaseIndex];
|
||||||
|
for (let k = 0; k < removeCodes.length; k++) {
|
||||||
|
const removeOpCode = removeCodes[k] as number;
|
||||||
|
const nodeOrIcuIndex = removeOpCode >>> I18nMutateOpCode.SHIFT_REF;
|
||||||
|
switch (removeOpCode & I18nMutateOpCode.MASK_INSTRUCTION) {
|
||||||
|
case I18nMutateOpCode.Remove:
|
||||||
|
// Remove DOM element, but do *not* mark TNode as detached, since we are
|
||||||
|
// just switching ICU cases (while keeping the same TNode), so a DOM element
|
||||||
|
// representing a new ICU case will be re-created.
|
||||||
|
removeNode(tView, lView, nodeOrIcuIndex, /* markAsDetached */ false);
|
||||||
|
break;
|
||||||
|
case I18nMutateOpCode.RemoveNestedIcu:
|
||||||
|
removeNestedIcu(
|
||||||
|
tView, tIcus, removeCodes, nodeOrIcuIndex,
|
||||||
|
removeCodes[k + 1] as number >>> I18nMutateOpCode.SHIFT_REF);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the active caseIndex
|
||||||
|
const caseIndex = getCaseIndex(tIcu, value);
|
||||||
|
icuTNode.activeCaseIndex = caseIndex !== -1 ? caseIndex : null;
|
||||||
|
if (caseIndex > -1) {
|
||||||
|
// Add the nodes for the new case
|
||||||
|
readCreateOpCodes(
|
||||||
|
-1 /* -1 means we don't have parent node */, tIcu.create[caseIndex], tView, lView);
|
||||||
|
caseCreated = true;
|
||||||
|
}
|
||||||
|
return caseCreated;
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeNestedIcu(
|
||||||
|
tView: TView, tIcus: TIcu[], removeCodes: I18nMutateOpCodes, nodeIndex: number,
|
||||||
|
nestedIcuNodeIndex: number) {
|
||||||
|
const nestedIcuTNode = getTNode(tView, nestedIcuNodeIndex) as TIcuContainerNode;
|
||||||
|
const activeIndex = nestedIcuTNode.activeCaseIndex;
|
||||||
|
if (activeIndex !== null) {
|
||||||
|
const nestedTIcu = tIcus[nodeIndex];
|
||||||
|
// FIXME(misko): the fact that we are adding items to parent list looks very suspect!
|
||||||
|
addAllToArray(nestedTIcu.remove[activeIndex], removeCodes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function removeNode(tView: TView, lView: LView, index: number, markAsDetached: boolean) {
|
function removeNode(tView: TView, lView: LView, index: number, markAsDetached: boolean) {
|
||||||
const removedPhTNode = getTNode(tView, index);
|
const removedPhTNode = getTNode(tView, index);
|
||||||
const removedPhRNode = getNativeByIndex(index, lView);
|
const removedPhRNode = getNativeByIndex(index, lView);
|
||||||
|
@ -1146,7 +1164,7 @@ export function ɵɵi18nApply(index: number) {
|
||||||
}
|
}
|
||||||
const bindingsStartIndex = getBindingIndex() - shiftsCounter - 1;
|
const bindingsStartIndex = getBindingIndex() - shiftsCounter - 1;
|
||||||
const lView = getLView();
|
const lView = getLView();
|
||||||
readUpdateOpCodes(updateOpCodes, icus, bindingsStartIndex, changeMask, tView, lView);
|
readUpdateOpCodes(updateOpCodes, icus, bindingsStartIndex, changeMask, tView, lView, false);
|
||||||
|
|
||||||
// Reset changeMask & maskBit to default for the next update cycle
|
// Reset changeMask & maskBit to default for the next update cycle
|
||||||
changeMask = 0b0;
|
changeMask = 0b0;
|
||||||
|
|
|
@ -102,7 +102,6 @@ export function i18nMutateOpCodesToString(
|
||||||
case I18nMutateOpCode.ElementEnd:
|
case I18nMutateOpCode.ElementEnd:
|
||||||
return `setPreviousOrParentTNode(tView.data[${ref}] as TNode)`;
|
return `setPreviousOrParentTNode(tView.data[${ref}] as TNode)`;
|
||||||
case I18nMutateOpCode.RemoveNestedIcu:
|
case I18nMutateOpCode.RemoveNestedIcu:
|
||||||
// FIXME(misko): refactor to have a real method in i18n.ts.
|
|
||||||
return `removeNestedICU(${ref})`;
|
return `removeNestedICU(${ref})`;
|
||||||
}
|
}
|
||||||
throw new Error('Unexpected OpCode');
|
throw new Error('Unexpected OpCode');
|
||||||
|
|
Loading…
Reference in New Issue