happy-dom 15.11.7 → 16.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cjs/PropertySymbol.cjs +12 -9
- package/cjs/PropertySymbol.cjs.map +1 -1
- package/cjs/PropertySymbol.d.ts +4 -1
- package/cjs/PropertySymbol.d.ts.map +1 -1
- package/cjs/config/HTMLElementConfig.cjs +42 -16
- package/cjs/config/HTMLElementConfig.cjs.map +1 -1
- package/cjs/config/HTMLElementConfig.d.ts +7 -0
- package/cjs/config/HTMLElementConfig.d.ts.map +1 -1
- package/cjs/config/HTMLElementConfigContentModelEnum.cjs +3 -0
- package/cjs/config/HTMLElementConfigContentModelEnum.cjs.map +1 -1
- package/cjs/config/HTMLElementConfigContentModelEnum.d.ts +3 -0
- package/cjs/config/HTMLElementConfigContentModelEnum.d.ts.map +1 -1
- package/cjs/config/NamespaceURI.cjs +2 -0
- package/cjs/config/NamespaceURI.cjs.map +1 -1
- package/cjs/config/NamespaceURI.d.ts +2 -0
- package/cjs/config/NamespaceURI.d.ts.map +1 -1
- package/cjs/css/declaration/CSSStyleDeclaration.cjs +1 -1
- package/cjs/css/declaration/CSSStyleDeclaration.cjs.map +1 -1
- package/cjs/css/declaration/CSSStyleDeclaration.d.ts.map +1 -1
- package/cjs/css/declaration/computed-style/CSSStyleDeclarationComputedStyle.cjs +2 -2
- package/cjs/css/declaration/computed-style/CSSStyleDeclarationComputedStyle.cjs.map +1 -1
- package/cjs/css/declaration/computed-style/CSSStyleDeclarationComputedStyle.d.ts.map +1 -1
- package/cjs/css/rules/CSSStyleRule.cjs +1 -1
- package/cjs/css/rules/CSSStyleRule.cjs.map +1 -1
- package/cjs/css/rules/CSSStyleRule.d.ts +1 -1
- package/cjs/css/rules/CSSStyleRule.d.ts.map +1 -1
- package/cjs/custom-element/CustomElementReactionStack.cjs +104 -0
- package/cjs/custom-element/CustomElementReactionStack.cjs.map +1 -0
- package/cjs/custom-element/CustomElementReactionStack.d.ts +27 -0
- package/cjs/custom-element/CustomElementReactionStack.d.ts.map +1 -0
- package/cjs/custom-element/CustomElementRegistry.cjs +32 -45
- package/cjs/custom-element/CustomElementRegistry.cjs.map +1 -1
- package/cjs/custom-element/CustomElementRegistry.d.ts +2 -6
- package/cjs/custom-element/CustomElementRegistry.d.ts.map +1 -1
- package/cjs/custom-element/CustomElementUtility.cjs +35 -0
- package/cjs/custom-element/CustomElementUtility.cjs.map +1 -0
- package/cjs/custom-element/CustomElementUtility.d.ts +14 -0
- package/cjs/custom-element/CustomElementUtility.d.ts.map +1 -0
- package/cjs/custom-element/ICustomElementDefinition.cjs +3 -0
- package/cjs/custom-element/ICustomElementDefinition.cjs.map +1 -0
- package/cjs/custom-element/ICustomElementDefinition.d.ts +12 -0
- package/cjs/custom-element/ICustomElementDefinition.d.ts.map +1 -0
- package/cjs/dom/DOMStringMap.cjs +8 -8
- package/cjs/dom/DOMStringMap.cjs.map +1 -1
- package/cjs/dom/DOMStringMap.d.ts.map +1 -1
- package/cjs/dom/DOMTokenList.cjs +1 -1
- package/cjs/dom/DOMTokenList.cjs.map +1 -1
- package/cjs/dom-parser/DOMParser.cjs +5 -67
- package/cjs/dom-parser/DOMParser.cjs.map +1 -1
- package/cjs/dom-parser/DOMParser.d.ts +0 -1
- package/cjs/dom-parser/DOMParser.d.ts.map +1 -1
- package/cjs/exception/DOMExceptionNameEnum.cjs +1 -0
- package/cjs/exception/DOMExceptionNameEnum.cjs.map +1 -1
- package/cjs/exception/DOMExceptionNameEnum.d.ts +2 -1
- package/cjs/exception/DOMExceptionNameEnum.d.ts.map +1 -1
- package/cjs/history/History.cjs +6 -6
- package/cjs/history/History.cjs.map +1 -1
- package/cjs/html-parser/HTMLParser.cjs +726 -0
- package/cjs/html-parser/HTMLParser.cjs.map +1 -0
- package/cjs/html-parser/HTMLParser.d.ts +91 -0
- package/cjs/html-parser/HTMLParser.d.ts.map +1 -0
- package/cjs/html-serializer/HTMLSerializer.cjs +152 -0
- package/cjs/html-serializer/HTMLSerializer.cjs.map +1 -0
- package/cjs/html-serializer/HTMLSerializer.d.ts +36 -0
- package/cjs/html-serializer/HTMLSerializer.d.ts.map +1 -0
- package/cjs/nodes/document/Document.cjs +104 -120
- package/cjs/nodes/document/Document.cjs.map +1 -1
- package/cjs/nodes/document/Document.d.ts +8 -0
- package/cjs/nodes/document/Document.d.ts.map +1 -1
- package/cjs/nodes/element/Element.cjs +35 -53
- package/cjs/nodes/element/Element.cjs.map +1 -1
- package/cjs/nodes/element/Element.d.ts +2 -12
- package/cjs/nodes/element/Element.d.ts.map +1 -1
- package/cjs/nodes/element/HTMLCollection.cjs +5 -9
- package/cjs/nodes/element/HTMLCollection.cjs.map +1 -1
- package/cjs/nodes/element/HTMLCollection.d.ts.map +1 -1
- package/cjs/nodes/element/NamedNodeMap.cjs +39 -52
- package/cjs/nodes/element/NamedNodeMap.cjs.map +1 -1
- package/cjs/nodes/element/NamedNodeMap.d.ts +1 -16
- package/cjs/nodes/element/NamedNodeMap.d.ts.map +1 -1
- package/cjs/nodes/element/NamedNodeMapProxyFactory.cjs +12 -14
- package/cjs/nodes/element/NamedNodeMapProxyFactory.cjs.map +1 -1
- package/cjs/nodes/element/NamedNodeMapProxyFactory.d.ts.map +1 -1
- package/cjs/nodes/html-button-element/HTMLButtonElement.cjs +1 -1
- package/cjs/nodes/html-button-element/HTMLButtonElement.cjs.map +1 -1
- package/cjs/nodes/html-button-element/HTMLButtonElement.d.ts.map +1 -1
- package/cjs/nodes/html-document/HTMLDocument.cjs +33 -2
- package/cjs/nodes/html-document/HTMLDocument.cjs.map +1 -1
- package/cjs/nodes/html-document/HTMLDocument.d.ts +10 -0
- package/cjs/nodes/html-document/HTMLDocument.d.ts.map +1 -1
- package/cjs/nodes/html-element/HTMLElement.cjs +58 -22
- package/cjs/nodes/html-element/HTMLElement.cjs.map +1 -1
- package/cjs/nodes/html-element/HTMLElement.d.ts +34 -0
- package/cjs/nodes/html-element/HTMLElement.d.ts.map +1 -1
- package/cjs/nodes/html-field-set-element/HTMLFieldSetElement.cjs +1 -1
- package/cjs/nodes/html-field-set-element/HTMLFieldSetElement.cjs.map +1 -1
- package/cjs/nodes/html-field-set-element/HTMLFieldSetElement.d.ts.map +1 -1
- package/cjs/nodes/html-form-element/HTMLFormElement.cjs +5 -8
- package/cjs/nodes/html-form-element/HTMLFormElement.cjs.map +1 -1
- package/cjs/nodes/html-form-element/HTMLFormElement.d.ts.map +1 -1
- package/cjs/nodes/html-iframe-element/HTMLIFrameElement.cjs +1 -1
- package/cjs/nodes/html-iframe-element/HTMLIFrameElement.cjs.map +1 -1
- package/cjs/nodes/html-input-element/HTMLInputElement.cjs +1 -1
- package/cjs/nodes/html-input-element/HTMLInputElement.cjs.map +1 -1
- package/cjs/nodes/html-input-element/HTMLInputElement.d.ts.map +1 -1
- package/cjs/nodes/html-media-element/TextTrackList.cjs +1 -1
- package/cjs/nodes/html-media-element/TextTrackList.cjs.map +1 -1
- package/cjs/nodes/html-object-element/HTMLObjectElement.cjs +1 -1
- package/cjs/nodes/html-object-element/HTMLObjectElement.cjs.map +1 -1
- package/cjs/nodes/html-object-element/HTMLObjectElement.d.ts.map +1 -1
- package/cjs/nodes/html-output-element/HTMLOutputElement.cjs +1 -1
- package/cjs/nodes/html-output-element/HTMLOutputElement.cjs.map +1 -1
- package/cjs/nodes/html-output-element/HTMLOutputElement.d.ts.map +1 -1
- package/cjs/nodes/html-script-element/HTMLScriptElement.cjs +3 -1
- package/cjs/nodes/html-script-element/HTMLScriptElement.cjs.map +1 -1
- package/cjs/nodes/html-script-element/HTMLScriptElement.d.ts.map +1 -1
- package/cjs/nodes/html-select-element/HTMLSelectElement.cjs +2 -2
- package/cjs/nodes/html-select-element/HTMLSelectElement.cjs.map +1 -1
- package/cjs/nodes/html-select-element/HTMLSelectElement.d.ts.map +1 -1
- package/cjs/nodes/html-table-element/HTMLTableElement.cjs +9 -1
- package/cjs/nodes/html-table-element/HTMLTableElement.cjs.map +1 -1
- package/cjs/nodes/html-table-element/HTMLTableElement.d.ts.map +1 -1
- package/cjs/nodes/html-table-row-element/HTMLTableRowElement.cjs +1 -1
- package/cjs/nodes/html-template-element/HTMLTemplateElement.cjs +15 -17
- package/cjs/nodes/html-template-element/HTMLTemplateElement.cjs.map +1 -1
- package/cjs/nodes/html-template-element/HTMLTemplateElement.d.ts +2 -2
- package/cjs/nodes/html-template-element/HTMLTemplateElement.d.ts.map +1 -1
- package/cjs/nodes/html-text-area-element/HTMLTextAreaElement.cjs +1 -1
- package/cjs/nodes/html-text-area-element/HTMLTextAreaElement.cjs.map +1 -1
- package/cjs/nodes/html-text-area-element/HTMLTextAreaElement.d.ts.map +1 -1
- package/cjs/nodes/node/Node.cjs +44 -48
- package/cjs/nodes/node/Node.cjs.map +1 -1
- package/cjs/nodes/node/Node.d.ts +2 -10
- package/cjs/nodes/node/Node.d.ts.map +1 -1
- package/cjs/nodes/node/NodeList.cjs +1 -1
- package/cjs/nodes/node/NodeList.cjs.map +1 -1
- package/cjs/nodes/node/NodeUtility.cjs +4 -3
- package/cjs/nodes/node/NodeUtility.cjs.map +1 -1
- package/cjs/nodes/node/NodeUtility.d.ts.map +1 -1
- package/cjs/nodes/parent-node/ParentNodeUtility.cjs +5 -2
- package/cjs/nodes/parent-node/ParentNodeUtility.cjs.map +1 -1
- package/cjs/nodes/parent-node/ParentNodeUtility.d.ts.map +1 -1
- package/cjs/nodes/shadow-root/ShadowRoot.cjs +8 -8
- package/cjs/nodes/shadow-root/ShadowRoot.cjs.map +1 -1
- package/cjs/nodes/shadow-root/ShadowRoot.d.ts.map +1 -1
- package/cjs/nodes/xml-document/XMLDocument.cjs +26 -0
- package/cjs/nodes/xml-document/XMLDocument.cjs.map +1 -1
- package/cjs/nodes/xml-document/XMLDocument.d.ts +2 -0
- package/cjs/nodes/xml-document/XMLDocument.d.ts.map +1 -1
- package/cjs/query-selector/SelectorItem.cjs +1 -2
- package/cjs/query-selector/SelectorItem.cjs.map +1 -1
- package/cjs/query-selector/SelectorItem.d.ts.map +1 -1
- package/cjs/range/Range.cjs +3 -3
- package/cjs/range/Range.cjs.map +1 -1
- package/cjs/range/Range.d.ts.map +1 -1
- package/cjs/storage/Storage.cjs +1 -1
- package/cjs/storage/Storage.cjs.map +1 -1
- package/cjs/svg/SVGLengthList.cjs +1 -1
- package/cjs/svg/SVGLengthList.cjs.map +1 -1
- package/cjs/svg/SVGNumberList.cjs +1 -1
- package/cjs/svg/SVGNumberList.cjs.map +1 -1
- package/cjs/svg/SVGPointList.cjs +1 -1
- package/cjs/svg/SVGPointList.cjs.map +1 -1
- package/cjs/svg/SVGStringList.cjs +1 -1
- package/cjs/svg/SVGStringList.cjs.map +1 -1
- package/cjs/svg/SVGTransformList.cjs +1 -1
- package/cjs/svg/SVGTransformList.cjs.map +1 -1
- package/cjs/tree-walker/NodeIterator.cjs +63 -6
- package/cjs/tree-walker/NodeIterator.cjs.map +1 -1
- package/cjs/tree-walker/NodeIterator.d.ts +18 -3
- package/cjs/tree-walker/NodeIterator.d.ts.map +1 -1
- package/cjs/tree-walker/TreeWalker.cjs +6 -6
- package/cjs/tree-walker/TreeWalker.cjs.map +1 -1
- package/cjs/tree-walker/TreeWalker.d.ts +2 -1
- package/cjs/tree-walker/TreeWalker.d.ts.map +1 -1
- package/cjs/utilities/ClassMethodBinder.cjs.map +1 -0
- package/cjs/utilities/ClassMethodBinder.d.ts.map +1 -0
- package/cjs/utilities/StringUtility.cjs.map +1 -0
- package/cjs/utilities/StringUtility.d.ts.map +1 -0
- package/cjs/utilities/XMLEncodeUtility.cjs +119 -0
- package/cjs/utilities/XMLEncodeUtility.cjs.map +1 -0
- package/cjs/utilities/XMLEncodeUtility.d.ts +48 -0
- package/cjs/utilities/XMLEncodeUtility.d.ts.map +1 -0
- package/cjs/window/BrowserWindow.cjs +5 -3
- package/cjs/window/BrowserWindow.cjs.map +1 -1
- package/cjs/window/BrowserWindow.d.ts +2 -0
- package/cjs/window/BrowserWindow.d.ts.map +1 -1
- package/cjs/window/WindowErrorUtility.cjs +1 -1
- package/cjs/window/WindowErrorUtility.cjs.map +1 -1
- package/cjs/xml-http-request/XMLHttpRequest.cjs +2 -1
- package/cjs/xml-http-request/XMLHttpRequest.cjs.map +1 -1
- package/cjs/xml-http-request/XMLHttpRequest.d.ts.map +1 -1
- package/cjs/xml-http-request/XMLHttpRequestResponseDataParser.cjs +1 -1
- package/cjs/xml-http-request/XMLHttpRequestResponseDataParser.cjs.map +1 -1
- package/cjs/xml-parser/XMLParser.cjs +531 -242
- package/cjs/xml-parser/XMLParser.cjs.map +1 -1
- package/cjs/xml-parser/XMLParser.d.ts +89 -19
- package/cjs/xml-parser/XMLParser.d.ts.map +1 -1
- package/cjs/xml-serializer/XMLSerializer.cjs +136 -40
- package/cjs/xml-serializer/XMLSerializer.cjs.map +1 -1
- package/cjs/xml-serializer/XMLSerializer.d.ts +6 -17
- package/cjs/xml-serializer/XMLSerializer.d.ts.map +1 -1
- package/lib/PropertySymbol.d.ts +4 -1
- package/lib/PropertySymbol.d.ts.map +1 -1
- package/lib/PropertySymbol.js +4 -1
- package/lib/PropertySymbol.js.map +1 -1
- package/lib/config/HTMLElementConfig.d.ts +7 -0
- package/lib/config/HTMLElementConfig.d.ts.map +1 -1
- package/lib/config/HTMLElementConfig.js +42 -16
- package/lib/config/HTMLElementConfig.js.map +1 -1
- package/lib/config/HTMLElementConfigContentModelEnum.d.ts +3 -0
- package/lib/config/HTMLElementConfigContentModelEnum.d.ts.map +1 -1
- package/lib/config/HTMLElementConfigContentModelEnum.js +3 -0
- package/lib/config/HTMLElementConfigContentModelEnum.js.map +1 -1
- package/lib/config/NamespaceURI.d.ts +2 -0
- package/lib/config/NamespaceURI.d.ts.map +1 -1
- package/lib/config/NamespaceURI.js +2 -0
- package/lib/config/NamespaceURI.js.map +1 -1
- package/lib/css/declaration/CSSStyleDeclaration.d.ts.map +1 -1
- package/lib/css/declaration/CSSStyleDeclaration.js +1 -1
- package/lib/css/declaration/CSSStyleDeclaration.js.map +1 -1
- package/lib/css/declaration/computed-style/CSSStyleDeclarationComputedStyle.d.ts.map +1 -1
- package/lib/css/declaration/computed-style/CSSStyleDeclarationComputedStyle.js +2 -2
- package/lib/css/declaration/computed-style/CSSStyleDeclarationComputedStyle.js.map +1 -1
- package/lib/css/rules/CSSStyleRule.d.ts +1 -1
- package/lib/css/rules/CSSStyleRule.d.ts.map +1 -1
- package/lib/css/rules/CSSStyleRule.js +1 -1
- package/lib/css/rules/CSSStyleRule.js.map +1 -1
- package/lib/custom-element/CustomElementReactionStack.d.ts +27 -0
- package/lib/custom-element/CustomElementReactionStack.d.ts.map +1 -0
- package/lib/custom-element/CustomElementReactionStack.js +75 -0
- package/lib/custom-element/CustomElementReactionStack.js.map +1 -0
- package/lib/custom-element/CustomElementRegistry.d.ts +2 -6
- package/lib/custom-element/CustomElementRegistry.d.ts.map +1 -1
- package/lib/custom-element/CustomElementRegistry.js +32 -45
- package/lib/custom-element/CustomElementRegistry.js.map +1 -1
- package/lib/custom-element/CustomElementUtility.d.ts +14 -0
- package/lib/custom-element/CustomElementUtility.d.ts.map +1 -0
- package/lib/custom-element/CustomElementUtility.js +32 -0
- package/lib/custom-element/CustomElementUtility.js.map +1 -0
- package/lib/custom-element/ICustomElementDefinition.d.ts +12 -0
- package/lib/custom-element/ICustomElementDefinition.d.ts.map +1 -0
- package/lib/custom-element/ICustomElementDefinition.js +2 -0
- package/lib/custom-element/ICustomElementDefinition.js.map +1 -0
- package/lib/dom/DOMStringMap.d.ts.map +1 -1
- package/lib/dom/DOMStringMap.js +8 -8
- package/lib/dom/DOMStringMap.js.map +1 -1
- package/lib/dom/DOMTokenList.js +1 -1
- package/lib/dom/DOMTokenList.js.map +1 -1
- package/lib/dom-parser/DOMParser.d.ts +0 -1
- package/lib/dom-parser/DOMParser.d.ts.map +1 -1
- package/lib/dom-parser/DOMParser.js +5 -67
- package/lib/dom-parser/DOMParser.js.map +1 -1
- package/lib/exception/DOMExceptionNameEnum.d.ts +2 -1
- package/lib/exception/DOMExceptionNameEnum.d.ts.map +1 -1
- package/lib/exception/DOMExceptionNameEnum.js +1 -0
- package/lib/exception/DOMExceptionNameEnum.js.map +1 -1
- package/lib/history/History.js +6 -6
- package/lib/history/History.js.map +1 -1
- package/lib/html-parser/HTMLParser.d.ts +91 -0
- package/lib/html-parser/HTMLParser.d.ts.map +1 -0
- package/lib/html-parser/HTMLParser.js +697 -0
- package/lib/html-parser/HTMLParser.js.map +1 -0
- package/lib/html-serializer/HTMLSerializer.d.ts +36 -0
- package/lib/html-serializer/HTMLSerializer.d.ts.map +1 -0
- package/lib/html-serializer/HTMLSerializer.js +123 -0
- package/lib/html-serializer/HTMLSerializer.js.map +1 -0
- package/lib/nodes/document/Document.d.ts +8 -0
- package/lib/nodes/document/Document.d.ts.map +1 -1
- package/lib/nodes/document/Document.js +105 -121
- package/lib/nodes/document/Document.js.map +1 -1
- package/lib/nodes/element/Element.d.ts +2 -12
- package/lib/nodes/element/Element.d.ts.map +1 -1
- package/lib/nodes/element/Element.js +35 -53
- package/lib/nodes/element/Element.js.map +1 -1
- package/lib/nodes/element/HTMLCollection.d.ts.map +1 -1
- package/lib/nodes/element/HTMLCollection.js +5 -9
- package/lib/nodes/element/HTMLCollection.js.map +1 -1
- package/lib/nodes/element/NamedNodeMap.d.ts +1 -16
- package/lib/nodes/element/NamedNodeMap.d.ts.map +1 -1
- package/lib/nodes/element/NamedNodeMap.js +39 -52
- package/lib/nodes/element/NamedNodeMap.js.map +1 -1
- package/lib/nodes/element/NamedNodeMapProxyFactory.d.ts.map +1 -1
- package/lib/nodes/element/NamedNodeMapProxyFactory.js +12 -14
- package/lib/nodes/element/NamedNodeMapProxyFactory.js.map +1 -1
- package/lib/nodes/html-button-element/HTMLButtonElement.d.ts.map +1 -1
- package/lib/nodes/html-button-element/HTMLButtonElement.js +1 -1
- package/lib/nodes/html-button-element/HTMLButtonElement.js.map +1 -1
- package/lib/nodes/html-document/HTMLDocument.d.ts +10 -0
- package/lib/nodes/html-document/HTMLDocument.d.ts.map +1 -1
- package/lib/nodes/html-document/HTMLDocument.js +33 -2
- package/lib/nodes/html-document/HTMLDocument.js.map +1 -1
- package/lib/nodes/html-element/HTMLElement.d.ts +34 -0
- package/lib/nodes/html-element/HTMLElement.d.ts.map +1 -1
- package/lib/nodes/html-element/HTMLElement.js +58 -22
- package/lib/nodes/html-element/HTMLElement.js.map +1 -1
- package/lib/nodes/html-field-set-element/HTMLFieldSetElement.d.ts.map +1 -1
- package/lib/nodes/html-field-set-element/HTMLFieldSetElement.js +1 -1
- package/lib/nodes/html-field-set-element/HTMLFieldSetElement.js.map +1 -1
- package/lib/nodes/html-form-element/HTMLFormElement.d.ts.map +1 -1
- package/lib/nodes/html-form-element/HTMLFormElement.js +5 -8
- package/lib/nodes/html-form-element/HTMLFormElement.js.map +1 -1
- package/lib/nodes/html-iframe-element/HTMLIFrameElement.js +1 -1
- package/lib/nodes/html-iframe-element/HTMLIFrameElement.js.map +1 -1
- package/lib/nodes/html-input-element/HTMLInputElement.d.ts.map +1 -1
- package/lib/nodes/html-input-element/HTMLInputElement.js +1 -1
- package/lib/nodes/html-input-element/HTMLInputElement.js.map +1 -1
- package/lib/nodes/html-media-element/TextTrackList.js +1 -1
- package/lib/nodes/html-media-element/TextTrackList.js.map +1 -1
- package/lib/nodes/html-object-element/HTMLObjectElement.d.ts.map +1 -1
- package/lib/nodes/html-object-element/HTMLObjectElement.js +1 -1
- package/lib/nodes/html-object-element/HTMLObjectElement.js.map +1 -1
- package/lib/nodes/html-output-element/HTMLOutputElement.d.ts.map +1 -1
- package/lib/nodes/html-output-element/HTMLOutputElement.js +1 -1
- package/lib/nodes/html-output-element/HTMLOutputElement.js.map +1 -1
- package/lib/nodes/html-script-element/HTMLScriptElement.d.ts.map +1 -1
- package/lib/nodes/html-script-element/HTMLScriptElement.js +3 -1
- package/lib/nodes/html-script-element/HTMLScriptElement.js.map +1 -1
- package/lib/nodes/html-select-element/HTMLSelectElement.d.ts.map +1 -1
- package/lib/nodes/html-select-element/HTMLSelectElement.js +2 -2
- package/lib/nodes/html-select-element/HTMLSelectElement.js.map +1 -1
- package/lib/nodes/html-table-element/HTMLTableElement.d.ts.map +1 -1
- package/lib/nodes/html-table-element/HTMLTableElement.js +9 -1
- package/lib/nodes/html-table-element/HTMLTableElement.js.map +1 -1
- package/lib/nodes/html-table-row-element/HTMLTableRowElement.js +1 -1
- package/lib/nodes/html-template-element/HTMLTemplateElement.d.ts +2 -2
- package/lib/nodes/html-template-element/HTMLTemplateElement.d.ts.map +1 -1
- package/lib/nodes/html-template-element/HTMLTemplateElement.js +15 -17
- package/lib/nodes/html-template-element/HTMLTemplateElement.js.map +1 -1
- package/lib/nodes/html-text-area-element/HTMLTextAreaElement.d.ts.map +1 -1
- package/lib/nodes/html-text-area-element/HTMLTextAreaElement.js +1 -1
- package/lib/nodes/html-text-area-element/HTMLTextAreaElement.js.map +1 -1
- package/lib/nodes/node/Node.d.ts +2 -10
- package/lib/nodes/node/Node.d.ts.map +1 -1
- package/lib/nodes/node/Node.js +44 -48
- package/lib/nodes/node/Node.js.map +1 -1
- package/lib/nodes/node/NodeList.js +1 -1
- package/lib/nodes/node/NodeList.js.map +1 -1
- package/lib/nodes/node/NodeUtility.d.ts.map +1 -1
- package/lib/nodes/node/NodeUtility.js +4 -3
- package/lib/nodes/node/NodeUtility.js.map +1 -1
- package/lib/nodes/parent-node/ParentNodeUtility.d.ts.map +1 -1
- package/lib/nodes/parent-node/ParentNodeUtility.js +5 -2
- package/lib/nodes/parent-node/ParentNodeUtility.js.map +1 -1
- package/lib/nodes/shadow-root/ShadowRoot.d.ts.map +1 -1
- package/lib/nodes/shadow-root/ShadowRoot.js +8 -8
- package/lib/nodes/shadow-root/ShadowRoot.js.map +1 -1
- package/lib/nodes/xml-document/XMLDocument.d.ts +2 -0
- package/lib/nodes/xml-document/XMLDocument.d.ts.map +1 -1
- package/lib/nodes/xml-document/XMLDocument.js +3 -0
- package/lib/nodes/xml-document/XMLDocument.js.map +1 -1
- package/lib/query-selector/SelectorItem.d.ts.map +1 -1
- package/lib/query-selector/SelectorItem.js +1 -2
- package/lib/query-selector/SelectorItem.js.map +1 -1
- package/lib/range/Range.d.ts.map +1 -1
- package/lib/range/Range.js +3 -3
- package/lib/range/Range.js.map +1 -1
- package/lib/storage/Storage.js +1 -1
- package/lib/storage/Storage.js.map +1 -1
- package/lib/svg/SVGLengthList.js +1 -1
- package/lib/svg/SVGLengthList.js.map +1 -1
- package/lib/svg/SVGNumberList.js +1 -1
- package/lib/svg/SVGNumberList.js.map +1 -1
- package/lib/svg/SVGPointList.js +1 -1
- package/lib/svg/SVGPointList.js.map +1 -1
- package/lib/svg/SVGStringList.js +1 -1
- package/lib/svg/SVGStringList.js.map +1 -1
- package/lib/svg/SVGTransformList.js +1 -1
- package/lib/svg/SVGTransformList.js.map +1 -1
- package/lib/tree-walker/NodeIterator.d.ts +18 -3
- package/lib/tree-walker/NodeIterator.d.ts.map +1 -1
- package/lib/tree-walker/NodeIterator.js +40 -6
- package/lib/tree-walker/NodeIterator.js.map +1 -1
- package/lib/tree-walker/TreeWalker.d.ts +2 -1
- package/lib/tree-walker/TreeWalker.d.ts.map +1 -1
- package/lib/tree-walker/TreeWalker.js +6 -6
- package/lib/tree-walker/TreeWalker.js.map +1 -1
- package/lib/utilities/ClassMethodBinder.d.ts.map +1 -0
- package/lib/utilities/ClassMethodBinder.js.map +1 -0
- package/lib/utilities/StringUtility.d.ts.map +1 -0
- package/lib/utilities/StringUtility.js.map +1 -0
- package/lib/utilities/XMLEncodeUtility.d.ts +48 -0
- package/lib/utilities/XMLEncodeUtility.d.ts.map +1 -0
- package/lib/utilities/XMLEncodeUtility.js +116 -0
- package/lib/utilities/XMLEncodeUtility.js.map +1 -0
- package/lib/window/BrowserWindow.d.ts +2 -0
- package/lib/window/BrowserWindow.d.ts.map +1 -1
- package/lib/window/BrowserWindow.js +5 -3
- package/lib/window/BrowserWindow.js.map +1 -1
- package/lib/window/WindowErrorUtility.js +1 -1
- package/lib/window/WindowErrorUtility.js.map +1 -1
- package/lib/xml-http-request/XMLHttpRequest.d.ts.map +1 -1
- package/lib/xml-http-request/XMLHttpRequest.js +2 -1
- package/lib/xml-http-request/XMLHttpRequest.js.map +1 -1
- package/lib/xml-http-request/XMLHttpRequestResponseDataParser.js +1 -1
- package/lib/xml-http-request/XMLHttpRequestResponseDataParser.js.map +1 -1
- package/lib/xml-parser/XMLParser.d.ts +89 -19
- package/lib/xml-parser/XMLParser.d.ts.map +1 -1
- package/lib/xml-parser/XMLParser.js +531 -242
- package/lib/xml-parser/XMLParser.js.map +1 -1
- package/lib/xml-serializer/XMLSerializer.d.ts +6 -17
- package/lib/xml-serializer/XMLSerializer.d.ts.map +1 -1
- package/lib/xml-serializer/XMLSerializer.js +136 -40
- package/lib/xml-serializer/XMLSerializer.js.map +1 -1
- package/package.json +1 -2
- package/src/PropertySymbol.ts +4 -1
- package/src/config/HTMLElementConfig.ts +53 -17
- package/src/config/HTMLElementConfigContentModelEnum.ts +3 -0
- package/src/config/NamespaceURI.ts +2 -0
- package/src/css/declaration/CSSStyleDeclaration.ts +1 -4
- package/src/css/declaration/computed-style/CSSStyleDeclarationComputedStyle.ts +2 -4
- package/src/css/rules/CSSStyleRule.ts +1 -1
- package/src/custom-element/CustomElementReactionStack.ts +86 -0
- package/src/custom-element/CustomElementRegistry.ts +35 -54
- package/src/custom-element/CustomElementUtility.ts +34 -0
- package/src/custom-element/ICustomElementDefinition.ts +16 -0
- package/src/dom/DOMStringMap.ts +12 -10
- package/src/dom/DOMTokenList.ts +1 -1
- package/src/dom-parser/DOMParser.ts +5 -75
- package/src/exception/DOMExceptionNameEnum.ts +2 -1
- package/src/history/History.ts +6 -6
- package/src/html-parser/HTMLParser.ts +864 -0
- package/src/html-serializer/HTMLSerializer.ts +162 -0
- package/src/nodes/document/Document.ts +117 -136
- package/src/nodes/element/Element.ts +48 -95
- package/src/nodes/element/HTMLCollection.ts +5 -30
- package/src/nodes/element/NamedNodeMap.ts +58 -72
- package/src/nodes/element/NamedNodeMapProxyFactory.ts +12 -15
- package/src/nodes/html-button-element/HTMLButtonElement.ts +1 -4
- package/src/nodes/html-document/HTMLDocument.ts +58 -2
- package/src/nodes/html-element/HTMLElement.ts +117 -25
- package/src/nodes/html-field-set-element/HTMLFieldSetElement.ts +1 -4
- package/src/nodes/html-form-element/HTMLFormElement.ts +5 -27
- package/src/nodes/html-iframe-element/HTMLIFrameElement.ts +1 -1
- package/src/nodes/html-input-element/HTMLInputElement.ts +1 -4
- package/src/nodes/html-media-element/TextTrackList.ts +1 -1
- package/src/nodes/html-object-element/HTMLObjectElement.ts +1 -4
- package/src/nodes/html-output-element/HTMLOutputElement.ts +1 -4
- package/src/nodes/html-script-element/HTMLScriptElement.ts +4 -1
- package/src/nodes/html-select-element/HTMLSelectElement.ts +2 -5
- package/src/nodes/html-table-element/HTMLTableElement.ts +8 -1
- package/src/nodes/html-table-row-element/HTMLTableRowElement.ts +1 -1
- package/src/nodes/html-template-element/HTMLTemplateElement.ts +23 -17
- package/src/nodes/html-text-area-element/HTMLTextAreaElement.ts +1 -4
- package/src/nodes/node/Node.ts +57 -70
- package/src/nodes/node/NodeList.ts +1 -1
- package/src/nodes/node/NodeUtility.ts +4 -3
- package/src/nodes/parent-node/ParentNodeUtility.ts +6 -6
- package/src/nodes/shadow-root/ShadowRoot.ts +8 -8
- package/src/nodes/xml-document/XMLDocument.ts +5 -1
- package/src/query-selector/SelectorItem.ts +1 -2
- package/src/range/Range.ts +3 -3
- package/src/storage/Storage.ts +1 -1
- package/src/svg/SVGLengthList.ts +1 -1
- package/src/svg/SVGNumberList.ts +1 -1
- package/src/svg/SVGPointList.ts +1 -1
- package/src/svg/SVGStringList.ts +1 -1
- package/src/svg/SVGTransformList.ts +1 -1
- package/src/tree-walker/NodeIterator.ts +44 -8
- package/src/tree-walker/TreeWalker.ts +6 -6
- package/src/utilities/XMLEncodeUtility.ts +127 -0
- package/src/window/BrowserWindow.ts +7 -5
- package/src/window/WindowErrorUtility.ts +1 -1
- package/src/xml-http-request/XMLHttpRequest.ts +3 -1
- package/src/xml-http-request/XMLHttpRequestResponseDataParser.ts +1 -1
- package/src/xml-parser/XMLParser.ts +627 -313
- package/src/xml-serializer/XMLSerializer.ts +204 -58
- package/cjs/ClassMethodBinder.cjs.map +0 -1
- package/cjs/ClassMethodBinder.d.ts.map +0 -1
- package/cjs/StringUtility.cjs.map +0 -1
- package/cjs/StringUtility.d.ts.map +0 -1
- package/lib/ClassMethodBinder.d.ts.map +0 -1
- package/lib/ClassMethodBinder.js.map +0 -1
- package/lib/StringUtility.d.ts.map +0 -1
- package/lib/StringUtility.js.map +0 -1
- /package/cjs/{ClassMethodBinder.cjs → utilities/ClassMethodBinder.cjs} +0 -0
- /package/cjs/{ClassMethodBinder.d.ts → utilities/ClassMethodBinder.d.ts} +0 -0
- /package/cjs/{StringUtility.cjs → utilities/StringUtility.cjs} +0 -0
- /package/cjs/{StringUtility.d.ts → utilities/StringUtility.d.ts} +0 -0
- /package/lib/{ClassMethodBinder.d.ts → utilities/ClassMethodBinder.d.ts} +0 -0
- /package/lib/{ClassMethodBinder.js → utilities/ClassMethodBinder.js} +0 -0
- /package/lib/{StringUtility.d.ts → utilities/StringUtility.d.ts} +0 -0
- /package/lib/{StringUtility.js → utilities/StringUtility.js} +0 -0
- /package/src/{ClassMethodBinder.ts → utilities/ClassMethodBinder.ts} +0 -0
- /package/src/{StringUtility.ts → utilities/StringUtility.ts} +0 -0
@@ -0,0 +1,697 @@
|
|
1
|
+
import Document from '../nodes/document/Document.js';
|
2
|
+
import * as PropertySymbol from '../PropertySymbol.js';
|
3
|
+
import NamespaceURI from '../config/NamespaceURI.js';
|
4
|
+
import HTMLElementConfig from '../config/HTMLElementConfig.js';
|
5
|
+
import HTMLElementConfigContentModelEnum from '../config/HTMLElementConfigContentModelEnum.js';
|
6
|
+
import SVGElementConfig from '../config/SVGElementConfig.js';
|
7
|
+
import StringUtility from '../utilities/StringUtility.js';
|
8
|
+
import XMLEncodeUtility from '../utilities/XMLEncodeUtility.js';
|
9
|
+
import NodeTypeEnum from '../nodes/node/NodeTypeEnum.js';
|
10
|
+
/**
|
11
|
+
* Markup RegExp.
|
12
|
+
*
|
13
|
+
* Group 1: Beginning of start tag (e.g. "div" in "<div").
|
14
|
+
* Group 2: End tag (e.g. "div" in "</div>").
|
15
|
+
* Group 3: Comment start tag "<!--"
|
16
|
+
* Group 4: Comment end tag "-->"
|
17
|
+
* Group 5: Document type start tag "<!"
|
18
|
+
* Group 6: Processing instruction start tag "<?"
|
19
|
+
* Group 7: End of self closing start tag (e.g. "/>" in "<img/>").
|
20
|
+
* Group 8: End of start tag or comment tag (e.g. ">" in "<div>").
|
21
|
+
*/
|
22
|
+
const MARKUP_REGEXP = /<([^\s/!>?]+)|<\/([^\s/!>?]+)\s*>|(<!--)|(-->|--!>)|(<!)|(<\?)|(\/>)|(>)/gm;
|
23
|
+
/**
|
24
|
+
* Attribute RegExp.
|
25
|
+
*
|
26
|
+
* Group 1: Attribute name when the attribute has a value with no apostrophes (e.g. "name" in "<div name=value>").
|
27
|
+
* Group 2: Attribute value when the attribute has a value with no apostrophes (e.g. "value" in "<div name="value">").
|
28
|
+
* Group 3: Attribute name when the attribute has a value using double apostrophe (e.g. "name" in "<div name="value">").
|
29
|
+
* Group 4: Attribute value when the attribute has a value using double apostrophe (e.g. "value" in "<div name="value">").
|
30
|
+
* Group 5: Attribute end apostrophe when the attribute has a value using double apostrophe (e.g. '"' in "<div name="value">").
|
31
|
+
* Group 6: Attribute name when the attribute has a value using single apostrophe (e.g. "name" in "<div name='value'>").
|
32
|
+
* Group 7: Attribute value when the attribute has a value using single apostrophe (e.g. "value" in "<div name='value'>").
|
33
|
+
* Group 8: Attribute end apostrophe when the attribute has a value using single apostrophe (e.g. "'" in "<div name='value'>").
|
34
|
+
* Group 9: Attribute name when the attribute has no value (e.g. "disabled" in "<div disabled>").
|
35
|
+
*/
|
36
|
+
const ATTRIBUTE_REGEXP = /\s*([a-zA-Z0-9-_:.$@?\\<\[\]]+)\s*=\s*([a-zA-Z0-9-_:.$@?{}/<]+)|\s*([a-zA-Z0-9-_:.$@?\\<\[\]]+)\s*=\s*"([^"]*)("{0,1})|\s*([a-zA-Z0-9-_:.$@?\\<\[\]]+)\s*=\s*'([^']*)('{0,1})|\s*([a-zA-Z0-9-_:.$@?\\<\[\]]+)/gm;
|
37
|
+
/**
|
38
|
+
* Document type attribute RegExp.
|
39
|
+
*
|
40
|
+
* Group 1: Attribute value.
|
41
|
+
*/
|
42
|
+
const DOCUMENT_TYPE_ATTRIBUTE_REGEXP = /"([^"]+)"/gm;
|
43
|
+
/**
|
44
|
+
* Space RegExp.
|
45
|
+
*/
|
46
|
+
const SPACE_REGEXP = /\s+/;
|
47
|
+
/**
|
48
|
+
* Space in the beginning of string RegExp.
|
49
|
+
*/
|
50
|
+
const SPACE_IN_BEGINNING_REGEXP = /^\s+/;
|
51
|
+
/**
|
52
|
+
* Markup read state (which state the parser is in).
|
53
|
+
*/
|
54
|
+
var MarkupReadStateEnum;
|
55
|
+
(function (MarkupReadStateEnum) {
|
56
|
+
MarkupReadStateEnum["any"] = "any";
|
57
|
+
MarkupReadStateEnum["startTag"] = "startTag";
|
58
|
+
MarkupReadStateEnum["comment"] = "comment";
|
59
|
+
MarkupReadStateEnum["documentType"] = "documentType";
|
60
|
+
MarkupReadStateEnum["processingInstruction"] = "processingInstruction";
|
61
|
+
MarkupReadStateEnum["rawTextElement"] = "rawTextElement";
|
62
|
+
})(MarkupReadStateEnum || (MarkupReadStateEnum = {}));
|
63
|
+
/**
|
64
|
+
* How much of the HTML document that has been parsed (where the parser level is).
|
65
|
+
*/
|
66
|
+
var HTMLDocumentStructureLevelEnum;
|
67
|
+
(function (HTMLDocumentStructureLevelEnum) {
|
68
|
+
HTMLDocumentStructureLevelEnum[HTMLDocumentStructureLevelEnum["root"] = 0] = "root";
|
69
|
+
HTMLDocumentStructureLevelEnum[HTMLDocumentStructureLevelEnum["doctype"] = 1] = "doctype";
|
70
|
+
HTMLDocumentStructureLevelEnum[HTMLDocumentStructureLevelEnum["documentElement"] = 2] = "documentElement";
|
71
|
+
HTMLDocumentStructureLevelEnum[HTMLDocumentStructureLevelEnum["head"] = 3] = "head";
|
72
|
+
HTMLDocumentStructureLevelEnum[HTMLDocumentStructureLevelEnum["additionalHeadWithoutBody"] = 4] = "additionalHeadWithoutBody";
|
73
|
+
HTMLDocumentStructureLevelEnum[HTMLDocumentStructureLevelEnum["body"] = 5] = "body";
|
74
|
+
HTMLDocumentStructureLevelEnum[HTMLDocumentStructureLevelEnum["afterBody"] = 6] = "afterBody";
|
75
|
+
})(HTMLDocumentStructureLevelEnum || (HTMLDocumentStructureLevelEnum = {}));
|
76
|
+
/**
|
77
|
+
* HTML parser.
|
78
|
+
*/
|
79
|
+
export default class HTMLParser {
|
80
|
+
window;
|
81
|
+
evaluateScripts = false;
|
82
|
+
rootNode = null;
|
83
|
+
rootDocument = null;
|
84
|
+
nodeStack = [];
|
85
|
+
tagNameStack = [];
|
86
|
+
documentStructure = null;
|
87
|
+
startTagIndex = 0;
|
88
|
+
markupRegExp = null;
|
89
|
+
nextElement = null;
|
90
|
+
currentNode = null;
|
91
|
+
readState = MarkupReadStateEnum.any;
|
92
|
+
/**
|
93
|
+
* Constructor.
|
94
|
+
*
|
95
|
+
* @param window Window.
|
96
|
+
* @param [options] Options.
|
97
|
+
* @param [options.evaluateScripts] Set to "true" to enable script execution
|
98
|
+
*/
|
99
|
+
constructor(window, options) {
|
100
|
+
this.window = window;
|
101
|
+
if (options?.evaluateScripts) {
|
102
|
+
this.evaluateScripts = true;
|
103
|
+
}
|
104
|
+
}
|
105
|
+
/**
|
106
|
+
* Parses HTML a root element containing nodes found.
|
107
|
+
*
|
108
|
+
* @param html HTML string.
|
109
|
+
* @param [rootNode] Root node.
|
110
|
+
* @returns Root node.
|
111
|
+
*/
|
112
|
+
parse(html, rootNode) {
|
113
|
+
this.rootNode = rootNode || this.window.document.createDocumentFragment();
|
114
|
+
this.rootDocument = this.rootNode instanceof Document ? this.rootNode : this.window.document;
|
115
|
+
this.nodeStack = [this.rootNode];
|
116
|
+
this.tagNameStack = [null];
|
117
|
+
this.currentNode = this.rootNode;
|
118
|
+
this.readState = MarkupReadStateEnum.any;
|
119
|
+
this.documentStructure = null;
|
120
|
+
this.startTagIndex = 0;
|
121
|
+
this.markupRegExp = new RegExp(MARKUP_REGEXP, 'gm');
|
122
|
+
if (this.rootNode instanceof Document) {
|
123
|
+
const { doctype, documentElement, head, body } = this.rootNode;
|
124
|
+
if (!documentElement || !head || !body) {
|
125
|
+
throw new Error('Failed to parse HTML: The root node must have "documentElement", "head" and "body".\n\nWe should not end up here and it is therefore a bug in Happy DOM. Please report this issue.');
|
126
|
+
}
|
127
|
+
this.documentStructure = {
|
128
|
+
nodes: {
|
129
|
+
doctype: doctype || null,
|
130
|
+
documentElement,
|
131
|
+
head,
|
132
|
+
body
|
133
|
+
},
|
134
|
+
level: HTMLDocumentStructureLevelEnum.root
|
135
|
+
};
|
136
|
+
}
|
137
|
+
let match;
|
138
|
+
let lastIndex = 0;
|
139
|
+
html = String(html);
|
140
|
+
while ((match = this.markupRegExp.exec(html))) {
|
141
|
+
switch (this.readState) {
|
142
|
+
case MarkupReadStateEnum.any:
|
143
|
+
// Plain text between tags.
|
144
|
+
if (match.index !== lastIndex &&
|
145
|
+
(match[1] || match[2] || match[3] || match[4] || match[5] !== undefined || match[6])) {
|
146
|
+
this.parsePlainText(html.substring(lastIndex, match.index));
|
147
|
+
}
|
148
|
+
if (match[1]) {
|
149
|
+
// Start tag.
|
150
|
+
this.nextElement = this.getStartTagElement(match[1]);
|
151
|
+
this.startTagIndex = this.markupRegExp.lastIndex;
|
152
|
+
this.readState = MarkupReadStateEnum.startTag;
|
153
|
+
}
|
154
|
+
else if (match[2]) {
|
155
|
+
// End tag.
|
156
|
+
this.parseEndTag(match[2]);
|
157
|
+
}
|
158
|
+
else if (match[3]) {
|
159
|
+
// Comment.
|
160
|
+
this.startTagIndex = this.markupRegExp.lastIndex;
|
161
|
+
this.readState = MarkupReadStateEnum.comment;
|
162
|
+
}
|
163
|
+
else if (match[5] !== undefined) {
|
164
|
+
// Document type.
|
165
|
+
this.startTagIndex = this.markupRegExp.lastIndex;
|
166
|
+
this.readState = MarkupReadStateEnum.documentType;
|
167
|
+
}
|
168
|
+
else if (match[6]) {
|
169
|
+
// Processing instruction.
|
170
|
+
this.startTagIndex = this.markupRegExp.lastIndex;
|
171
|
+
this.readState = MarkupReadStateEnum.processingInstruction;
|
172
|
+
}
|
173
|
+
else {
|
174
|
+
// Plain text between tags, including the matched tag as it is not a valid start or end tag.
|
175
|
+
this.parsePlainText(html.substring(lastIndex, this.markupRegExp.lastIndex));
|
176
|
+
}
|
177
|
+
break;
|
178
|
+
case MarkupReadStateEnum.startTag:
|
179
|
+
// End of start tag
|
180
|
+
// match[2] is matching an end tag in case the start tag wasn't closed (e.g. "<div\n</ul>" instead of "<div>\n</ul>").
|
181
|
+
// match[7] is matching "/>" (e.g. "<img/>").
|
182
|
+
// match[8] is matching ">" (e.g. "<div>").
|
183
|
+
if (match[7] || match[8] || match[2]) {
|
184
|
+
if (this.nextElement) {
|
185
|
+
const attributeString = html.substring(this.startTagIndex, match[2] ? this.markupRegExp.lastIndex - 1 : match.index);
|
186
|
+
const isSelfClosed = !!match[7];
|
187
|
+
this.parseEndOfStartTag(attributeString, isSelfClosed);
|
188
|
+
}
|
189
|
+
else {
|
190
|
+
// If "nextElement" is set to null, the tag is not allowed (<html>, <head> and <body> are not allowed in an HTML fragment or to be nested).
|
191
|
+
this.readState = MarkupReadStateEnum.any;
|
192
|
+
}
|
193
|
+
}
|
194
|
+
break;
|
195
|
+
case MarkupReadStateEnum.comment:
|
196
|
+
// Comment end tag.
|
197
|
+
if (match[4]) {
|
198
|
+
this.parseComment(html.substring(this.startTagIndex, match.index));
|
199
|
+
}
|
200
|
+
break;
|
201
|
+
case MarkupReadStateEnum.documentType:
|
202
|
+
// Document type end tag.
|
203
|
+
if (match[7] || match[8]) {
|
204
|
+
this.parseDocumentType(html.substring(this.startTagIndex, match.index));
|
205
|
+
}
|
206
|
+
break;
|
207
|
+
case MarkupReadStateEnum.processingInstruction:
|
208
|
+
// Processing instruction end tag.
|
209
|
+
if (match[7] || match[8]) {
|
210
|
+
// Processing instructions are not supported in HTML and are rendered as comments.
|
211
|
+
this.parseComment('?' + html.substring(this.startTagIndex, match.index));
|
212
|
+
}
|
213
|
+
break;
|
214
|
+
case MarkupReadStateEnum.rawTextElement:
|
215
|
+
// End tag of raw text content.
|
216
|
+
// <script> and <style> elements are raw text elements.
|
217
|
+
if (match[2]) {
|
218
|
+
this.parseRawTextElementContent(match[2], html.substring(this.startTagIndex, match.index));
|
219
|
+
}
|
220
|
+
break;
|
221
|
+
}
|
222
|
+
lastIndex = this.markupRegExp.lastIndex;
|
223
|
+
}
|
224
|
+
// Plain text after tags.
|
225
|
+
if (lastIndex !== html.length && this.currentNode) {
|
226
|
+
this.parsePlainText(html.substring(lastIndex));
|
227
|
+
}
|
228
|
+
return this.rootNode;
|
229
|
+
}
|
230
|
+
/**
|
231
|
+
* Parses plain text.
|
232
|
+
*
|
233
|
+
* @param text Text.
|
234
|
+
*/
|
235
|
+
parsePlainText(text) {
|
236
|
+
if (this.documentStructure) {
|
237
|
+
const level = this.documentStructure.level;
|
238
|
+
const { documentElement, head, body } = this.documentStructure.nodes;
|
239
|
+
// We should remove space in beginning inside the document and the <html> tag.
|
240
|
+
const htmlText = (this.currentNode === this.rootNode || this.currentNode === documentElement) &&
|
241
|
+
level < HTMLDocumentStructureLevelEnum.head &&
|
242
|
+
body[PropertySymbol.elementArray].length === 0
|
243
|
+
? text.replace(SPACE_IN_BEGINNING_REGEXP, '')
|
244
|
+
: text;
|
245
|
+
if (htmlText) {
|
246
|
+
const textNode = this.rootDocument.createTextNode(XMLEncodeUtility.decodeHTMLEntities(htmlText));
|
247
|
+
if (this.currentNode === head &&
|
248
|
+
level === HTMLDocumentStructureLevelEnum.additionalHeadWithoutBody) {
|
249
|
+
documentElement[PropertySymbol.insertBefore](textNode, body, true);
|
250
|
+
}
|
251
|
+
else if (this.currentNode === this.rootNode ||
|
252
|
+
this.currentNode === documentElement ||
|
253
|
+
(this.currentNode === head && level >= HTMLDocumentStructureLevelEnum.body)) {
|
254
|
+
if (level === HTMLDocumentStructureLevelEnum.head) {
|
255
|
+
// Space between <head> and <body> is allowed
|
256
|
+
documentElement[PropertySymbol.insertBefore](textNode, body, true);
|
257
|
+
}
|
258
|
+
else if (body.lastChild?.[PropertySymbol.nodeType] === NodeTypeEnum.textNode) {
|
259
|
+
// If the last child of the body is a text node, we should append the text to it.
|
260
|
+
body.lastChild[PropertySymbol.data] += text;
|
261
|
+
}
|
262
|
+
else {
|
263
|
+
// Nodes outside <html>, <head> and <body> should be appended to the body
|
264
|
+
body[PropertySymbol.appendChild](textNode, true);
|
265
|
+
}
|
266
|
+
}
|
267
|
+
else {
|
268
|
+
this.currentNode[PropertySymbol.appendChild](textNode, true);
|
269
|
+
}
|
270
|
+
}
|
271
|
+
}
|
272
|
+
else {
|
273
|
+
const textNode = this.rootDocument.createTextNode(XMLEncodeUtility.decodeHTMLEntities(text));
|
274
|
+
this.currentNode[PropertySymbol.appendChild](textNode, true);
|
275
|
+
}
|
276
|
+
}
|
277
|
+
/**
|
278
|
+
* Parses end of start tag.
|
279
|
+
*
|
280
|
+
* @param attributeString Attribute string.
|
281
|
+
* @param isSelfClosed Is self closed.
|
282
|
+
*/
|
283
|
+
parseEndOfStartTag(attributeString, isSelfClosed) {
|
284
|
+
if (attributeString &&
|
285
|
+
(!this.documentStructure ||
|
286
|
+
this.nextElement !== this.documentStructure.nodes.head ||
|
287
|
+
this.documentStructure.level < HTMLDocumentStructureLevelEnum.body)) {
|
288
|
+
const attributeRegexp = new RegExp(ATTRIBUTE_REGEXP, 'gm');
|
289
|
+
let attributeMatch;
|
290
|
+
while ((attributeMatch = attributeRegexp.exec(attributeString))) {
|
291
|
+
if ((attributeMatch[1] && attributeMatch[2]) ||
|
292
|
+
(attributeMatch[3] && attributeMatch[5] === '"') ||
|
293
|
+
(attributeMatch[6] && attributeMatch[8] === "'") ||
|
294
|
+
attributeMatch[9]) {
|
295
|
+
// Valid attribute name and value.
|
296
|
+
const name = attributeMatch[1] || attributeMatch[3] || attributeMatch[6] || attributeMatch[9] || '';
|
297
|
+
const rawValue = attributeMatch[2] || attributeMatch[4] || attributeMatch[7] || '';
|
298
|
+
const value = rawValue ? XMLEncodeUtility.decodeAttributeValue(rawValue) : '';
|
299
|
+
const attributes = this.nextElement[PropertySymbol.attributes];
|
300
|
+
if (this.nextElement[PropertySymbol.namespaceURI] === NamespaceURI.svg) {
|
301
|
+
// In the SVG namespace, the attribute "xmlns" should be set to the "http://www.w3.org/2000/xmlns/" namespace.
|
302
|
+
const namespaceURI = name === 'xmlns' ? NamespaceURI.xmlns : null;
|
303
|
+
if (!attributes.getNamedItemNS(namespaceURI, name)) {
|
304
|
+
const attributeItem = this.rootDocument.createAttributeNS(namespaceURI, name);
|
305
|
+
attributeItem[PropertySymbol.value] = value;
|
306
|
+
attributes[PropertySymbol.setNamedItem](attributeItem);
|
307
|
+
}
|
308
|
+
}
|
309
|
+
else if (!attributes.getNamedItem(name)) {
|
310
|
+
const attributeItem = this.rootDocument.createAttribute(name);
|
311
|
+
attributeItem[PropertySymbol.value] = value;
|
312
|
+
attributes[PropertySymbol.setNamedItem](attributeItem);
|
313
|
+
}
|
314
|
+
this.startTagIndex += attributeMatch[0].length;
|
315
|
+
}
|
316
|
+
else if (!attributeMatch[1] &&
|
317
|
+
((attributeMatch[3] && !attributeMatch[5]) || (attributeMatch[6] && !attributeMatch[8]))) {
|
318
|
+
// End attribute apostrophe is missing (e.g. "attr='value" or 'attr="value').
|
319
|
+
// We should continue to the next end of start tag match.
|
320
|
+
return;
|
321
|
+
}
|
322
|
+
}
|
323
|
+
}
|
324
|
+
const tagName = this.nextElement[PropertySymbol.tagName];
|
325
|
+
const lowerTagName = tagName.toLowerCase();
|
326
|
+
const config = HTMLElementConfig[lowerTagName];
|
327
|
+
let previousCurrentNode = null;
|
328
|
+
while (previousCurrentNode !== this.rootNode) {
|
329
|
+
const parentLowerTagName = this.currentNode[PropertySymbol.tagName]?.toLowerCase();
|
330
|
+
const parentConfig = HTMLElementConfig[parentLowerTagName];
|
331
|
+
if (previousCurrentNode === this.currentNode) {
|
332
|
+
throw new Error('Failed to parse HTML: The parser is stuck in an infinite loop. Please report this issue.');
|
333
|
+
}
|
334
|
+
previousCurrentNode = this.currentNode;
|
335
|
+
// Some elements are not allowed to be nested (e.g. "<a><a></a></a>" is not allowed.).
|
336
|
+
// Therefore we need to auto-close tags with the same name matching the config, so that it become valid (e.g. "<a></a><a></a>").
|
337
|
+
if ((config?.contentModel === HTMLElementConfigContentModelEnum.noFirstLevelSelfDescendants &&
|
338
|
+
this.tagNameStack[this.tagNameStack.length - 1] === tagName) ||
|
339
|
+
parentConfig?.contentModel === HTMLElementConfigContentModelEnum.textOrComments ||
|
340
|
+
(parentConfig?.contentModel ===
|
341
|
+
HTMLElementConfigContentModelEnum.noForbiddenFirstLevelDescendants &&
|
342
|
+
parentConfig?.forbiddenDescendants?.includes(lowerTagName)) ||
|
343
|
+
(parentConfig?.contentModel === HTMLElementConfigContentModelEnum.permittedDescendants &&
|
344
|
+
!parentConfig?.permittedDescendants?.includes(lowerTagName) &&
|
345
|
+
(!config ||
|
346
|
+
!config.addPermittedParent ||
|
347
|
+
(HTMLElementConfig[config.addPermittedParent].permittedParents &&
|
348
|
+
!HTMLElementConfig[config.addPermittedParent].permittedParents.includes(parentLowerTagName)) ||
|
349
|
+
(HTMLElementConfig[config.addPermittedParent].permittedDescendants &&
|
350
|
+
!HTMLElementConfig[config.addPermittedParent].permittedDescendants.includes(lowerTagName))))) {
|
351
|
+
// We need to move forbidden elements inside <table> outside of the table if possible.
|
352
|
+
// E.g. "<table><div><tr><td></td></tr></div></table>"" should become "<div></div><table><tbody><tr><td></td></tr></tbody></table>" (<tbody> is added as <tr> has addPermittedParent as config).
|
353
|
+
if (parentConfig?.contentModel === HTMLElementConfigContentModelEnum.permittedDescendants &&
|
354
|
+
parentConfig.moveForbiddenDescendant &&
|
355
|
+
!parentConfig.moveForbiddenDescendant.exclude.includes(lowerTagName)) {
|
356
|
+
// We add the element before the first element that is not forbidden.
|
357
|
+
let before = this.currentNode;
|
358
|
+
while (before) {
|
359
|
+
if (!before.parentNode ||
|
360
|
+
!HTMLElementConfig[before.parentNode[PropertySymbol.localName]]
|
361
|
+
?.permittedDescendants ||
|
362
|
+
HTMLElementConfig[before.parentNode[PropertySymbol.localName]]?.permittedDescendants?.includes(lowerTagName)) {
|
363
|
+
break;
|
364
|
+
}
|
365
|
+
else {
|
366
|
+
before = before.parentNode;
|
367
|
+
}
|
368
|
+
}
|
369
|
+
if (before && before.parentNode) {
|
370
|
+
before.parentNode.insertBefore(this.nextElement, before);
|
371
|
+
}
|
372
|
+
else {
|
373
|
+
// If there is no element that is not forbidden, we append the element
|
374
|
+
before.appendChild(this.nextElement);
|
375
|
+
}
|
376
|
+
this.startTagIndex = this.markupRegExp.lastIndex;
|
377
|
+
this.readState = MarkupReadStateEnum.any;
|
378
|
+
return;
|
379
|
+
}
|
380
|
+
// This will close the current node
|
381
|
+
// E.g. "<a><a></a></a>" will become "<a></a><a></a>"
|
382
|
+
this.nodeStack.pop();
|
383
|
+
this.tagNameStack.pop();
|
384
|
+
this.currentNode = this.nodeStack[this.nodeStack.length - 1] || this.rootNode;
|
385
|
+
}
|
386
|
+
else if (config?.contentModel === HTMLElementConfigContentModelEnum.noSelfDescendants &&
|
387
|
+
this.tagNameStack.includes(tagName)) {
|
388
|
+
while (this.currentNode !== this.rootNode) {
|
389
|
+
if (this.currentNode[PropertySymbol.tagName] === tagName) {
|
390
|
+
this.nodeStack.pop();
|
391
|
+
this.tagNameStack.pop();
|
392
|
+
this.currentNode = this.nodeStack[this.nodeStack.length - 1] || this.rootNode;
|
393
|
+
break;
|
394
|
+
}
|
395
|
+
this.nodeStack.pop();
|
396
|
+
this.tagNameStack.pop();
|
397
|
+
this.currentNode = this.nodeStack[this.nodeStack.length - 1] || this.rootNode;
|
398
|
+
}
|
399
|
+
}
|
400
|
+
else if (config?.permittedParents &&
|
401
|
+
!config.permittedParents.includes(parentLowerTagName)) {
|
402
|
+
// <thead>, <tbody> and <tfoot> are only allowed as children of <table>.
|
403
|
+
// <tr> is only allowed as a child of <table>, <thead>, <tbody> and <tfoot>.
|
404
|
+
// <tbody> should be added automatically when <tr> is added directly to the table.
|
405
|
+
if (!config.addPermittedParent ||
|
406
|
+
(HTMLElementConfig[config.addPermittedParent].permittedParents &&
|
407
|
+
!HTMLElementConfig[config.addPermittedParent].permittedParents.includes(parentLowerTagName)) ||
|
408
|
+
(HTMLElementConfig[config.addPermittedParent].permittedDescendants &&
|
409
|
+
!HTMLElementConfig[config.addPermittedParent].permittedDescendants.includes(lowerTagName))) {
|
410
|
+
this.readState = MarkupReadStateEnum.any;
|
411
|
+
this.startTagIndex = this.markupRegExp.lastIndex;
|
412
|
+
return;
|
413
|
+
}
|
414
|
+
const permittedParent = this.rootDocument.createElement(config.addPermittedParent);
|
415
|
+
this.currentNode[PropertySymbol.appendChild](permittedParent, true);
|
416
|
+
this.nodeStack.push(permittedParent);
|
417
|
+
this.tagNameStack.push(permittedParent[PropertySymbol.tagName]);
|
418
|
+
this.currentNode = permittedParent;
|
419
|
+
}
|
420
|
+
else {
|
421
|
+
break;
|
422
|
+
}
|
423
|
+
}
|
424
|
+
// Appends the new element to its parent
|
425
|
+
if (this.documentStructure) {
|
426
|
+
const { documentElement, head, body } = this.documentStructure.nodes;
|
427
|
+
const level = this.documentStructure.level;
|
428
|
+
// Appends the new node to its parent and sets is as current node.
|
429
|
+
// Raw text elements (e.g. <script>) should be appended after the raw text has been added as content to the element.
|
430
|
+
// <html>, <head> and <body> are special elements with context constraints. They are already available in the document.
|
431
|
+
if ((!config || config.contentModel !== HTMLElementConfigContentModelEnum.rawText) &&
|
432
|
+
this.nextElement !== documentElement &&
|
433
|
+
this.nextElement !== head &&
|
434
|
+
this.nextElement !== body) {
|
435
|
+
// When parser mode is "htmlDocument", any element added directly to the document or document element should be added to the body.
|
436
|
+
if (documentElement &&
|
437
|
+
(this.currentNode === this.rootNode ||
|
438
|
+
this.currentNode === documentElement ||
|
439
|
+
(this.currentNode === head && level >= HTMLDocumentStructureLevelEnum.body))) {
|
440
|
+
if (level < HTMLDocumentStructureLevelEnum.body) {
|
441
|
+
this.documentStructure.level = HTMLDocumentStructureLevelEnum.afterBody;
|
442
|
+
}
|
443
|
+
body[PropertySymbol.appendChild](this.nextElement, true);
|
444
|
+
}
|
445
|
+
else {
|
446
|
+
this.currentNode[PropertySymbol.appendChild](this.nextElement, true);
|
447
|
+
}
|
448
|
+
}
|
449
|
+
}
|
450
|
+
else {
|
451
|
+
this.currentNode[PropertySymbol.appendChild](this.nextElement, true);
|
452
|
+
}
|
453
|
+
// Sets the new element as the current node.
|
454
|
+
if (!this.documentStructure ||
|
455
|
+
this.nextElement !== this.documentStructure.nodes.body ||
|
456
|
+
this.documentStructure.level <= HTMLDocumentStructureLevelEnum.body) {
|
457
|
+
this.currentNode = this.nextElement;
|
458
|
+
this.nodeStack.push(this.currentNode);
|
459
|
+
this.tagNameStack.push(tagName);
|
460
|
+
if (this.documentStructure && this.nextElement === this.documentStructure.nodes.body) {
|
461
|
+
this.documentStructure.level = HTMLDocumentStructureLevelEnum.afterBody;
|
462
|
+
}
|
463
|
+
// Check if the tag is a void element and should be closed immediately.
|
464
|
+
// Elements in the SVG namespace can be self-closed (e.g. "/>").
|
465
|
+
// "/>" will be ignored in the HTML namespace.
|
466
|
+
if (config?.contentModel === HTMLElementConfigContentModelEnum.noDescendants ||
|
467
|
+
(isSelfClosed &&
|
468
|
+
this.currentNode[PropertySymbol.namespaceURI] === NamespaceURI.svg)) {
|
469
|
+
this.nodeStack.pop();
|
470
|
+
this.tagNameStack.pop();
|
471
|
+
this.currentNode = this.nodeStack[this.nodeStack.length - 1] || this.rootNode;
|
472
|
+
this.readState = MarkupReadStateEnum.any;
|
473
|
+
}
|
474
|
+
else {
|
475
|
+
// We will set the read state to "rawText" for raw text elements such as <script> and <style> elements.
|
476
|
+
this.readState =
|
477
|
+
config?.contentModel === HTMLElementConfigContentModelEnum.rawText
|
478
|
+
? MarkupReadStateEnum.rawTextElement
|
479
|
+
: MarkupReadStateEnum.any;
|
480
|
+
}
|
481
|
+
}
|
482
|
+
else {
|
483
|
+
this.readState = MarkupReadStateEnum.any;
|
484
|
+
}
|
485
|
+
this.startTagIndex = this.markupRegExp.lastIndex;
|
486
|
+
}
|
487
|
+
/**
|
488
|
+
* Parses end tag.
|
489
|
+
*
|
490
|
+
* @param tagName Tag name.
|
491
|
+
*/
|
492
|
+
parseEndTag(tagName) {
|
493
|
+
// SVG elements are case-sensitive.
|
494
|
+
const name = this.currentNode[PropertySymbol.namespaceURI] === NamespaceURI.html
|
495
|
+
? StringUtility.asciiUpperCase(tagName)
|
496
|
+
: SVGElementConfig[StringUtility.asciiLowerCase(tagName)]?.localName || tagName;
|
497
|
+
const index = this.tagNameStack.lastIndexOf(name);
|
498
|
+
// We close all tags up until the first tag that matches the end tag.
|
499
|
+
if (index !== -1) {
|
500
|
+
this.nodeStack.splice(index, this.nodeStack.length - index);
|
501
|
+
this.tagNameStack.splice(index, this.tagNameStack.length - index);
|
502
|
+
this.currentNode = this.nodeStack[this.nodeStack.length - 1] || this.rootNode;
|
503
|
+
}
|
504
|
+
}
|
505
|
+
/**
|
506
|
+
* Parses comment.
|
507
|
+
*
|
508
|
+
* @param comment Comment.
|
509
|
+
*/
|
510
|
+
parseComment(comment) {
|
511
|
+
const commentNode = this.rootDocument.createComment(XMLEncodeUtility.decodeHTMLEntities(comment));
|
512
|
+
if (this.documentStructure) {
|
513
|
+
const level = this.documentStructure.level;
|
514
|
+
const { documentElement, head, body } = this.documentStructure.nodes;
|
515
|
+
// We need to add the comment node to the correct position in the document.
|
516
|
+
let beforeNode = null;
|
517
|
+
if (this.currentNode === this.rootNode && level === HTMLDocumentStructureLevelEnum.root) {
|
518
|
+
beforeNode = documentElement;
|
519
|
+
}
|
520
|
+
else if (this.currentNode === documentElement &&
|
521
|
+
level === HTMLDocumentStructureLevelEnum.documentElement) {
|
522
|
+
beforeNode = head;
|
523
|
+
}
|
524
|
+
else if (this.currentNode === documentElement &&
|
525
|
+
level === HTMLDocumentStructureLevelEnum.head) {
|
526
|
+
beforeNode = body;
|
527
|
+
}
|
528
|
+
this.currentNode[PropertySymbol.insertBefore](commentNode, beforeNode, true);
|
529
|
+
}
|
530
|
+
else {
|
531
|
+
this.currentNode[PropertySymbol.appendChild](commentNode, true);
|
532
|
+
}
|
533
|
+
this.readState = MarkupReadStateEnum.any;
|
534
|
+
}
|
535
|
+
/**
|
536
|
+
* Parses document type.
|
537
|
+
*
|
538
|
+
* @param text Text.
|
539
|
+
*/
|
540
|
+
parseDocumentType(text) {
|
541
|
+
const decodedText = XMLEncodeUtility.decodeHTMLEntities(text);
|
542
|
+
if (this.documentStructure) {
|
543
|
+
let { doctype } = this.documentStructure.nodes;
|
544
|
+
const documentType = this.getDocumentType(decodedText);
|
545
|
+
// Document type nodes are only allowed at the beginning of the document.
|
546
|
+
if (documentType) {
|
547
|
+
if (this.currentNode === this.rootNode &&
|
548
|
+
this.documentStructure.level === HTMLDocumentStructureLevelEnum.root) {
|
549
|
+
if (doctype) {
|
550
|
+
doctype[PropertySymbol.name] = documentType.name;
|
551
|
+
doctype[PropertySymbol.publicId] = documentType.publicId;
|
552
|
+
doctype[PropertySymbol.systemId] = documentType.systemId;
|
553
|
+
}
|
554
|
+
else {
|
555
|
+
doctype = this.rootNode.implementation.createDocumentType(documentType.name, documentType.publicId, documentType.systemId);
|
556
|
+
this.rootNode.insertBefore(doctype, this.rootNode.documentElement);
|
557
|
+
}
|
558
|
+
this.documentStructure.level = HTMLDocumentStructureLevelEnum.doctype;
|
559
|
+
}
|
560
|
+
}
|
561
|
+
else {
|
562
|
+
this.parseComment(decodedText);
|
563
|
+
}
|
564
|
+
}
|
565
|
+
else {
|
566
|
+
// Document type nodes are only allowed at the beginning of the document.
|
567
|
+
if (!this.getDocumentType(decodedText)) {
|
568
|
+
this.parseComment(decodedText);
|
569
|
+
}
|
570
|
+
}
|
571
|
+
this.readState = MarkupReadStateEnum.any;
|
572
|
+
}
|
573
|
+
/**
|
574
|
+
* Parses raw text content for elements such as <script> and <style>.
|
575
|
+
*
|
576
|
+
* @param tagName End tag name.
|
577
|
+
* @param text Text.
|
578
|
+
*/
|
579
|
+
parseRawTextElementContent(tagName, text) {
|
580
|
+
const upperTagName = StringUtility.asciiUpperCase(tagName);
|
581
|
+
if (upperTagName !== this.currentNode[PropertySymbol.tagName]) {
|
582
|
+
return;
|
583
|
+
}
|
584
|
+
// Scripts are not allowed to be executed when they are parsed using innerHTML, outerHTML, replaceWith() etc.
|
585
|
+
// However, they are allowed to be executed when document.write() is used.
|
586
|
+
// See: https://developer.mozilla.org/en-US/docs/Web/API/HTMLScriptElement
|
587
|
+
if (upperTagName === 'SCRIPT') {
|
588
|
+
this.currentNode[PropertySymbol.evaluateScript] = this.evaluateScripts;
|
589
|
+
}
|
590
|
+
else if (upperTagName === 'LINK') {
|
591
|
+
// An assumption that the same rule should be applied for the HTMLLinkElement is made here.
|
592
|
+
this.currentNode[PropertySymbol.evaluateCSS] = this.evaluateScripts;
|
593
|
+
}
|
594
|
+
// Plain text elements such as <script> and <style> should only contain text.
|
595
|
+
this.currentNode[PropertySymbol.appendChild](this.rootDocument.createTextNode(XMLEncodeUtility.decodeHTMLEntities(text)), true);
|
596
|
+
const rawTextElement = this.currentNode;
|
597
|
+
this.nodeStack.pop();
|
598
|
+
this.tagNameStack.pop();
|
599
|
+
this.currentNode = this.nodeStack[this.nodeStack.length - 1] || this.rootNode;
|
600
|
+
this.readState = MarkupReadStateEnum.any;
|
601
|
+
// Appends the raw text element to its parent.
|
602
|
+
if (this.documentStructure) {
|
603
|
+
const { documentElement, body } = this.documentStructure.nodes;
|
604
|
+
// When parser mode is "htmlDocument", any element added directly to the document or document element should be added to the body.
|
605
|
+
if (documentElement &&
|
606
|
+
(this.currentNode === this.rootNode || this.currentNode === documentElement)) {
|
607
|
+
body[PropertySymbol.appendChild](rawTextElement, true);
|
608
|
+
}
|
609
|
+
else {
|
610
|
+
this.currentNode[PropertySymbol.appendChild](rawTextElement, true);
|
611
|
+
}
|
612
|
+
}
|
613
|
+
else {
|
614
|
+
this.currentNode[PropertySymbol.appendChild](rawTextElement, true);
|
615
|
+
}
|
616
|
+
}
|
617
|
+
/**
|
618
|
+
* Creates an element or returns a reference to it.
|
619
|
+
*
|
620
|
+
* @param tagName Tag name.
|
621
|
+
*/
|
622
|
+
getStartTagElement(tagName) {
|
623
|
+
const lowerTagName = StringUtility.asciiLowerCase(tagName);
|
624
|
+
// NamespaceURI is inherited from the parent element.
|
625
|
+
const namespaceURI = this.currentNode[PropertySymbol.namespaceURI];
|
626
|
+
// NamespaceURI should be SVG when the tag name is "svg" (even in XML mode).
|
627
|
+
if (lowerTagName === 'svg') {
|
628
|
+
return this.rootDocument.createElementNS(NamespaceURI.svg, 'svg');
|
629
|
+
}
|
630
|
+
if (namespaceURI === NamespaceURI.svg) {
|
631
|
+
return this.rootDocument.createElementNS(NamespaceURI.svg, SVGElementConfig[lowerTagName]?.localName || tagName);
|
632
|
+
}
|
633
|
+
// New element.
|
634
|
+
switch (lowerTagName) {
|
635
|
+
case 'html':
|
636
|
+
if (!this.documentStructure) {
|
637
|
+
return null;
|
638
|
+
}
|
639
|
+
if (this.documentStructure.level < HTMLDocumentStructureLevelEnum.documentElement) {
|
640
|
+
this.documentStructure.level = HTMLDocumentStructureLevelEnum.documentElement;
|
641
|
+
}
|
642
|
+
return this.documentStructure.nodes.documentElement ?? null;
|
643
|
+
case 'head':
|
644
|
+
if (!this.documentStructure) {
|
645
|
+
return null;
|
646
|
+
}
|
647
|
+
if (this.documentStructure.level < HTMLDocumentStructureLevelEnum.head) {
|
648
|
+
this.documentStructure.level = HTMLDocumentStructureLevelEnum.head;
|
649
|
+
}
|
650
|
+
else if (this.documentStructure.level === HTMLDocumentStructureLevelEnum.head) {
|
651
|
+
this.documentStructure.level = HTMLDocumentStructureLevelEnum.additionalHeadWithoutBody;
|
652
|
+
}
|
653
|
+
return this.documentStructure.nodes.head ?? null;
|
654
|
+
case 'body':
|
655
|
+
if (!this.documentStructure) {
|
656
|
+
return null;
|
657
|
+
}
|
658
|
+
if (this.documentStructure.level < HTMLDocumentStructureLevelEnum.body) {
|
659
|
+
this.documentStructure.level = HTMLDocumentStructureLevelEnum.body;
|
660
|
+
}
|
661
|
+
return this.documentStructure.nodes.body ?? null;
|
662
|
+
default:
|
663
|
+
return this.rootDocument.createElementNS(NamespaceURI.html, lowerTagName);
|
664
|
+
}
|
665
|
+
}
|
666
|
+
/**
|
667
|
+
* Returns document type.
|
668
|
+
*
|
669
|
+
* @param value Value.
|
670
|
+
* @returns Document type.
|
671
|
+
*/
|
672
|
+
getDocumentType(value) {
|
673
|
+
if (!value.toUpperCase().startsWith('DOCTYPE')) {
|
674
|
+
return null;
|
675
|
+
}
|
676
|
+
const docTypeSplit = value.split(SPACE_REGEXP);
|
677
|
+
if (docTypeSplit.length <= 1) {
|
678
|
+
return null;
|
679
|
+
}
|
680
|
+
const docTypeString = docTypeSplit.slice(1).join(' ');
|
681
|
+
const attributes = [];
|
682
|
+
const attributeRegExp = new RegExp(DOCUMENT_TYPE_ATTRIBUTE_REGEXP, 'gm');
|
683
|
+
const isPublic = docTypeString.toUpperCase().includes('PUBLIC');
|
684
|
+
let attributeMatch;
|
685
|
+
while ((attributeMatch = attributeRegExp.exec(docTypeString))) {
|
686
|
+
attributes.push(attributeMatch[1]);
|
687
|
+
}
|
688
|
+
const publicId = isPublic ? attributes[0] || '' : '';
|
689
|
+
const systemId = isPublic ? attributes[1] || '' : attributes[0] || '';
|
690
|
+
return {
|
691
|
+
name: docTypeSplit[1].toLowerCase(),
|
692
|
+
publicId,
|
693
|
+
systemId
|
694
|
+
};
|
695
|
+
}
|
696
|
+
}
|
697
|
+
//# sourceMappingURL=HTMLParser.js.map
|