( ast: I18nNode[], tView: TView, tIcu: TIcu, lView: LView, sharedUpdateOpCodes: I18nUpdateOpCodes, create: IcuCreateOpCodes, remove: I18nRemoveOpCodes, update: I18nUpdateOpCodes, parentNode: Element, parentIdx: number, nestedIcus: IcuExpression[], depth: number, )
| 785 | } |
| 786 | |
| 787 | function walkIcuTree( |
| 788 | ast: I18nNode[], |
| 789 | tView: TView, |
| 790 | tIcu: TIcu, |
| 791 | lView: LView, |
| 792 | sharedUpdateOpCodes: I18nUpdateOpCodes, |
| 793 | create: IcuCreateOpCodes, |
| 794 | remove: I18nRemoveOpCodes, |
| 795 | update: I18nUpdateOpCodes, |
| 796 | parentNode: Element, |
| 797 | parentIdx: number, |
| 798 | nestedIcus: IcuExpression[], |
| 799 | depth: number, |
| 800 | ): number { |
| 801 | let bindingMask = 0; |
| 802 | let currentNode = parentNode.firstChild; |
| 803 | while (currentNode) { |
| 804 | const newIndex = allocExpando(tView, lView, 1, null); |
| 805 | switch (currentNode.nodeType) { |
| 806 | case Node.ELEMENT_NODE: |
| 807 | const element = currentNode as Element; |
| 808 | const tagName = element.tagName.toLowerCase(); |
| 809 | if (VALID_ELEMENTS.hasOwnProperty(tagName)) { |
| 810 | addCreateNodeAndAppend(create, ELEMENT_MARKER, tagName, parentIdx, newIndex); |
| 811 | tView.data[newIndex] = tagName; |
| 812 | const elAttrs = element.attributes; |
| 813 | for (let i = 0; i < elAttrs.length; i++) { |
| 814 | const attr = elAttrs.item(i)!; |
| 815 | const lowerAttrName = attr.name.toLowerCase(); |
| 816 | const hasBinding = !!attr.value.match(BINDING_REGEXP); |
| 817 | const elementNS = element.namespaceURI; |
| 818 | const tagNameWithNamespace = |
| 819 | elementNS === 'http://www.w3.org/2000/svg' |
| 820 | ? `:svg:${tagName}` |
| 821 | : elementNS === 'http://www.w3.org/1998/Math/MathML' |
| 822 | ? `:math:${tagName}` |
| 823 | : tagName; |
| 824 | if (hasBinding) { |
| 825 | if (VALID_ATTRS.hasOwnProperty(lowerAttrName)) { |
| 826 | generateBindingUpdateOpCodes( |
| 827 | update, |
| 828 | attr.value, |
| 829 | newIndex, |
| 830 | attr.name, |
| 831 | 0, |
| 832 | i18nResolveSanitizer(lowerAttrName, tagNameWithNamespace), |
| 833 | ); |
| 834 | } else { |
| 835 | ngDevMode && |
| 836 | console.warn( |
| 837 | `WARNING: ignoring unsafe attribute value ` + |
| 838 | `${lowerAttrName} on element ${tagName} ` + |
| 839 | `(see ${XSS_SECURITY_URL})`, |
| 840 | ); |
| 841 | } |
| 842 | } else if (VALID_ATTRS[lowerAttrName]) { |
| 843 | let val = attr.value; |
| 844 | const sanitizer = i18nResolveSanitizer(lowerAttrName, tagNameWithNamespace); |
no test coverage detected
searching dependent graphs…