(source, fragmentContext)
| 4624 | * @returns {HtmlDocument} document AST |
| 4625 | */ |
| 4626 | const buildHtmlAst = (source, fragmentContext) => { |
| 4627 | /** @type {HtmlDocument} */ |
| 4628 | const doc = { type: NodeType.Document, children: [] }; |
| 4629 | let mode = MODE_INITIAL; |
| 4630 | class="cm">// Mode to return to after MODE_TEXT / MODE_IN_TABLE_TEXT (0 = unset). |
| 4631 | let originalMode = 0; |
| 4632 | /** @type {HtmlElement[]} stack of open elements (bottom .. top) */ |
| 4633 | const open = []; |
| 4634 | /** @type {{ element?: HtmlElement, marker?: boolean }[]} active formatting elements */ |
| 4635 | const afe = []; |
| 4636 | const afeEl = (/** @type {{ element?: HtmlElement }} */ e) => |
| 4637 | /** @type {HtmlElement} */ (e.element); |
| 4638 | /** @type {HtmlElement | null} */ |
| 4639 | let head = null; |
| 4640 | /** @type {HtmlElement | null} */ |
| 4641 | let form = null; |
| 4642 | let framesetOk = true; |
| 4643 | /** @type {HtmlAttribute[]} */ |
| 4644 | let pendingAttrs = []; |
| 4645 | let fosterParenting = false; |
| 4646 | /** @type {number[]} */ |
| 4647 | const templateModes = []; |
| 4648 | let quirks = false; |
| 4649 | /** @type {HtmlElement | null} */ |
| 4650 | let fragment = null; |
| 4651 | class="cm">// End offset of the token currently being processed (for element `.end`). |
| 4652 | let tokenEnd = 0; |
| 4653 | |
| 4654 | const cur = () => /** @type {HtmlElement} */ (open[open.length - 1]); |
| 4655 | const adjustedCurrent = () => { |
| 4656 | if (open.length === 1 && fragment) return fragment; |
| 4657 | return cur(); |
| 4658 | }; |
| 4659 | |
| 4660 | const mkEl = ( |
| 4661 | /** @type {string} */ tagName, |
| 4662 | /** @type {number} */ ns, |
| 4663 | /** @type {HtmlAttribute[] | undefined} */ attributes, |
| 4664 | /** @type {TagPos | null | undefined} */ pos |
| 4665 | ) => |
| 4666 | /** @type {HtmlElement} */ ({ |
| 4667 | type: NodeType.Element, |
| 4668 | tagName, |
| 4669 | namespace: ns, |
| 4670 | attributes: attributes || EMPTY_ATTRS, |
| 4671 | children: [], |
| 4672 | selfClosing: ns === NS_HTML && VOID.has(tagName), |
| 4673 | start: pos ? pos.start : 0, |
| 4674 | end: pos ? pos.end : 0, |
| 4675 | tagEnd: pos ? pos.tagEnd : 0, |
| 4676 | nameEnd: pos ? pos.nameEnd : 0, |
| 4677 | class="cm">// Present from creation (only `<template>` fills it) so every element |
| 4678 | class="cm">// keeps one monomorphic hidden class for the open-stack/scope loops. |
| 4679 | templateContent: undefined |
| 4680 | }); |
| 4681 | |
| 4682 | class="cm">// Clone of a formatting element's attributes: keep name/value (and the |
| 4683 | class="cm">// serializer name) but drop source offsets so the consumer doesn't emit a |
no test coverage detected