summaryrefslogtreecommitdiff
path: root/includes/external/addressbook/node_modules/parse5/dist/parser
diff options
context:
space:
mode:
Diffstat (limited to 'includes/external/addressbook/node_modules/parse5/dist/parser')
-rw-r--r--includes/external/addressbook/node_modules/parse5/dist/parser/formatting-element-list.d.ts37
-rw-r--r--includes/external/addressbook/node_modules/parse5/dist/parser/formatting-element-list.js111
-rw-r--r--includes/external/addressbook/node_modules/parse5/dist/parser/index.d.ts157
-rw-r--r--includes/external/addressbook/node_modules/parse5/dist/parser/index.js3168
-rw-r--r--includes/external/addressbook/node_modules/parse5/dist/parser/open-element-stack.d.ts53
-rw-r--r--includes/external/addressbook/node_modules/parse5/dist/parser/open-element-stack.js312
6 files changed, 3838 insertions, 0 deletions
diff --git a/includes/external/addressbook/node_modules/parse5/dist/parser/formatting-element-list.d.ts b/includes/external/addressbook/node_modules/parse5/dist/parser/formatting-element-list.d.ts
new file mode 100644
index 0000000..d6c9dcd
--- /dev/null
+++ b/includes/external/addressbook/node_modules/parse5/dist/parser/formatting-element-list.d.ts
@@ -0,0 +1,37 @@
+import type { TagToken } from '../common/token.js';
+import type { TreeAdapter, TreeAdapterTypeMap } from '../tree-adapters/interface.js';
+export declare enum EntryType {
+ Marker = 0,
+ Element = 1
+}
+interface MarkerEntry {
+ type: EntryType.Marker;
+}
+export interface ElementEntry<T extends TreeAdapterTypeMap> {
+ type: EntryType.Element;
+ element: T['element'];
+ token: TagToken;
+}
+export type Entry<T extends TreeAdapterTypeMap> = MarkerEntry | ElementEntry<T>;
+export declare class FormattingElementList<T extends TreeAdapterTypeMap> {
+ private treeAdapter;
+ entries: Entry<T>[];
+ bookmark: Entry<T> | null;
+ constructor(treeAdapter: TreeAdapter<T>);
+ private _getNoahArkConditionCandidates;
+ private _ensureNoahArkCondition;
+ insertMarker(): void;
+ pushElement(element: T['element'], token: TagToken): void;
+ insertElementAfterBookmark(element: T['element'], token: TagToken): void;
+ removeEntry(entry: Entry<T>): void;
+ /**
+ * Clears the list of formatting elements up to the last marker.
+ *
+ * @see https://html.spec.whatwg.org/multipage/parsing.html#clear-the-list-of-active-formatting-elements-up-to-the-last-marker
+ */
+ clearToLastMarker(): void;
+ getElementEntryInScopeWithTagName(tagName: string): ElementEntry<T> | null;
+ getElementEntry(element: T['element']): ElementEntry<T> | undefined;
+}
+export {};
+//# sourceMappingURL=formatting-element-list.d.ts.map \ No newline at end of file
diff --git a/includes/external/addressbook/node_modules/parse5/dist/parser/formatting-element-list.js b/includes/external/addressbook/node_modules/parse5/dist/parser/formatting-element-list.js
new file mode 100644
index 0000000..32736bc
--- /dev/null
+++ b/includes/external/addressbook/node_modules/parse5/dist/parser/formatting-element-list.js
@@ -0,0 +1,111 @@
+//Const
+const NOAH_ARK_CAPACITY = 3;
+export var EntryType;
+(function (EntryType) {
+ EntryType[EntryType["Marker"] = 0] = "Marker";
+ EntryType[EntryType["Element"] = 1] = "Element";
+})(EntryType = EntryType || (EntryType = {}));
+const MARKER = { type: EntryType.Marker };
+//List of formatting elements
+export class FormattingElementList {
+ constructor(treeAdapter) {
+ this.treeAdapter = treeAdapter;
+ this.entries = [];
+ this.bookmark = null;
+ }
+ //Noah Ark's condition
+ //OPTIMIZATION: at first we try to find possible candidates for exclusion using
+ //lightweight heuristics without thorough attributes check.
+ _getNoahArkConditionCandidates(newElement, neAttrs) {
+ const candidates = [];
+ const neAttrsLength = neAttrs.length;
+ const neTagName = this.treeAdapter.getTagName(newElement);
+ const neNamespaceURI = this.treeAdapter.getNamespaceURI(newElement);
+ for (let i = 0; i < this.entries.length; i++) {
+ const entry = this.entries[i];
+ if (entry.type === EntryType.Marker) {
+ break;
+ }
+ const { element } = entry;
+ if (this.treeAdapter.getTagName(element) === neTagName &&
+ this.treeAdapter.getNamespaceURI(element) === neNamespaceURI) {
+ const elementAttrs = this.treeAdapter.getAttrList(element);
+ if (elementAttrs.length === neAttrsLength) {
+ candidates.push({ idx: i, attrs: elementAttrs });
+ }
+ }
+ }
+ return candidates;
+ }
+ _ensureNoahArkCondition(newElement) {
+ if (this.entries.length < NOAH_ARK_CAPACITY)
+ return;
+ const neAttrs = this.treeAdapter.getAttrList(newElement);
+ const candidates = this._getNoahArkConditionCandidates(newElement, neAttrs);
+ if (candidates.length < NOAH_ARK_CAPACITY)
+ return;
+ //NOTE: build attrs map for the new element, so we can perform fast lookups
+ const neAttrsMap = new Map(neAttrs.map((neAttr) => [neAttr.name, neAttr.value]));
+ let validCandidates = 0;
+ //NOTE: remove bottommost candidates, until Noah's Ark condition will not be met
+ for (let i = 0; i < candidates.length; i++) {
+ const candidate = candidates[i];
+ // We know that `candidate.attrs.length === neAttrs.length`
+ if (candidate.attrs.every((cAttr) => neAttrsMap.get(cAttr.name) === cAttr.value)) {
+ validCandidates += 1;
+ if (validCandidates >= NOAH_ARK_CAPACITY) {
+ this.entries.splice(candidate.idx, 1);
+ }
+ }
+ }
+ }
+ //Mutations
+ insertMarker() {
+ this.entries.unshift(MARKER);
+ }
+ pushElement(element, token) {
+ this._ensureNoahArkCondition(element);
+ this.entries.unshift({
+ type: EntryType.Element,
+ element,
+ token,
+ });
+ }
+ insertElementAfterBookmark(element, token) {
+ const bookmarkIdx = this.entries.indexOf(this.bookmark);
+ this.entries.splice(bookmarkIdx, 0, {
+ type: EntryType.Element,
+ element,
+ token,
+ });
+ }
+ removeEntry(entry) {
+ const entryIndex = this.entries.indexOf(entry);
+ if (entryIndex >= 0) {
+ this.entries.splice(entryIndex, 1);
+ }
+ }
+ /**
+ * Clears the list of formatting elements up to the last marker.
+ *
+ * @see https://html.spec.whatwg.org/multipage/parsing.html#clear-the-list-of-active-formatting-elements-up-to-the-last-marker
+ */
+ clearToLastMarker() {
+ const markerIdx = this.entries.indexOf(MARKER);
+ if (markerIdx >= 0) {
+ this.entries.splice(0, markerIdx + 1);
+ }
+ else {
+ this.entries.length = 0;
+ }
+ }
+ //Search
+ getElementEntryInScopeWithTagName(tagName) {
+ const entry = this.entries.find((entry) => entry.type === EntryType.Marker || this.treeAdapter.getTagName(entry.element) === tagName);
+ return entry && entry.type === EntryType.Element ? entry : null;
+ }
+ getElementEntry(element) {
+ return this.entries.find((entry) => entry.type === EntryType.Element && entry.element === element);
+ }
+}
+//# sourceMappingURL=formatting-element-list.js.map \ No newline at end of file
diff --git a/includes/external/addressbook/node_modules/parse5/dist/parser/index.d.ts b/includes/external/addressbook/node_modules/parse5/dist/parser/index.d.ts
new file mode 100644
index 0000000..50a9bd0
--- /dev/null
+++ b/includes/external/addressbook/node_modules/parse5/dist/parser/index.d.ts
@@ -0,0 +1,157 @@
+import { Tokenizer, TokenizerMode, type TokenHandler } from '../tokenizer/index.js';
+import { OpenElementStack, type StackHandler } from './open-element-stack.js';
+import { FormattingElementList } from './formatting-element-list.js';
+import { ERR, type ParserErrorHandler } from '../common/error-codes.js';
+import { TAG_ID as $, NS } from '../common/html.js';
+import type { TreeAdapter, TreeAdapterTypeMap } from '../tree-adapters/interface.js';
+import { type Token, type CommentToken, type CharacterToken, type TagToken, type DoctypeToken, type EOFToken, type LocationWithAttributes } from '../common/token.js';
+declare enum InsertionMode {
+ INITIAL = 0,
+ BEFORE_HTML = 1,
+ BEFORE_HEAD = 2,
+ IN_HEAD = 3,
+ IN_HEAD_NO_SCRIPT = 4,
+ AFTER_HEAD = 5,
+ IN_BODY = 6,
+ TEXT = 7,
+ IN_TABLE = 8,
+ IN_TABLE_TEXT = 9,
+ IN_CAPTION = 10,
+ IN_COLUMN_GROUP = 11,
+ IN_TABLE_BODY = 12,
+ IN_ROW = 13,
+ IN_CELL = 14,
+ IN_SELECT = 15,
+ IN_SELECT_IN_TABLE = 16,
+ IN_TEMPLATE = 17,
+ AFTER_BODY = 18,
+ IN_FRAMESET = 19,
+ AFTER_FRAMESET = 20,
+ AFTER_AFTER_BODY = 21,
+ AFTER_AFTER_FRAMESET = 22
+}
+export interface ParserOptions<T extends TreeAdapterTypeMap> {
+ /**
+ * The [scripting flag](https://html.spec.whatwg.org/multipage/parsing.html#scripting-flag). If set
+ * to `true`, `noscript` element content will be parsed as text.
+ *
+ * @default `true`
+ */
+ scriptingEnabled?: boolean;
+ /**
+ * Enables source code location information. When enabled, each node (except the root node)
+ * will have a `sourceCodeLocation` property. If the node is not an empty element, `sourceCodeLocation` will
+ * be a {@link ElementLocation} object, otherwise it will be {@link Location}.
+ * If the element was implicitly created by the parser (as part of
+ * [tree correction](https://html.spec.whatwg.org/multipage/syntax.html#an-introduction-to-error-handling-and-strange-cases-in-the-parser)),
+ * its `sourceCodeLocation` property will be `undefined`.
+ *
+ * @default `false`
+ */
+ sourceCodeLocationInfo?: boolean;
+ /**
+ * Specifies the resulting tree format.
+ *
+ * @default `treeAdapters.default`
+ */
+ treeAdapter?: TreeAdapter<T>;
+ /**
+ * Callback for parse errors.
+ *
+ * @default `null`
+ */
+ onParseError?: ParserErrorHandler | null;
+}
+export declare class Parser<T extends TreeAdapterTypeMap> implements TokenHandler, StackHandler<T> {
+ fragmentContext: T['element'] | null;
+ scriptHandler: null | ((pendingScript: T['element']) => void);
+ treeAdapter: TreeAdapter<T>;
+ onParseError: ParserErrorHandler | null;
+ private currentToken;
+ options: Required<ParserOptions<T>>;
+ document: T['document'];
+ constructor(options?: ParserOptions<T>, document?: T['document'], fragmentContext?: T['element'] | null, scriptHandler?: null | ((pendingScript: T['element']) => void));
+ static parse<T extends TreeAdapterTypeMap>(html: string, options?: ParserOptions<T>): T['document'];
+ static getFragmentParser<T extends TreeAdapterTypeMap>(fragmentContext?: T['parentNode'] | null, options?: ParserOptions<T>): Parser<T>;
+ getFragment(): T['documentFragment'];
+ tokenizer: Tokenizer;
+ stopped: boolean;
+ insertionMode: InsertionMode;
+ originalInsertionMode: InsertionMode;
+ fragmentContextID: $;
+ headElement: null | T['element'];
+ formElement: null | T['element'];
+ openElements: OpenElementStack<T>;
+ activeFormattingElements: FormattingElementList<T>;
+ /** Indicates that the current node is not an element in the HTML namespace */
+ private currentNotInHTML;
+ /**
+ * The template insertion mode stack is maintained from the left.
+ * Ie. the topmost element will always have index 0.
+ */
+ tmplInsertionModeStack: InsertionMode[];
+ pendingCharacterTokens: CharacterToken[];
+ hasNonWhitespacePendingCharacterToken: boolean;
+ framesetOk: boolean;
+ skipNextNewLine: boolean;
+ fosterParentingEnabled: boolean;
+ _err(token: Token, code: ERR, beforeToken?: boolean): void;
+ onItemPush(node: T['parentNode'], tid: number, isTop: boolean): void;
+ onItemPop(node: T['parentNode'], isTop: boolean): void;
+ private _setContextModes;
+ _switchToTextParsing(currentToken: TagToken, nextTokenizerState: typeof TokenizerMode[keyof typeof TokenizerMode]): void;
+ switchToPlaintextParsing(): void;
+ _getAdjustedCurrentElement(): T['element'];
+ _findFormInFragmentContext(): void;
+ private _initTokenizerForFragmentParsing;
+ _setDocumentType(token: DoctypeToken): void;
+ _attachElementToTree(element: T['element'], location: LocationWithAttributes | null): void;
+ _appendElement(token: TagToken, namespaceURI: NS): void;
+ _insertElement(token: TagToken, namespaceURI: NS): void;
+ _insertFakeElement(tagName: string, tagID: $): void;
+ _insertTemplate(token: TagToken): void;
+ _insertFakeRootElement(): void;
+ _appendCommentNode(token: CommentToken, parent: T['parentNode']): void;
+ _insertCharacters(token: CharacterToken): void;
+ _adoptNodes(donor: T['parentNode'], recipient: T['parentNode']): void;
+ _setEndLocation(element: T['element'], closingToken: Token): void;
+ private shouldProcessStartTagTokenInForeignContent;
+ _processToken(token: Token): void;
+ _isIntegrationPoint(tid: $, element: T['element'], foreignNS?: NS): boolean;
+ _reconstructActiveFormattingElements(): void;
+ _closeTableCell(): void;
+ _closePElement(): void;
+ _resetInsertionMode(): void;
+ _resetInsertionModeForSelect(selectIdx: number): void;
+ _isElementCausesFosterParenting(tn: $): boolean;
+ _shouldFosterParentOnInsertion(): boolean;
+ _findFosterParentingLocation(): {
+ parent: T['parentNode'];
+ beforeElement: T['element'] | null;
+ };
+ _fosterParentElement(element: T['element']): void;
+ _isSpecialElement(element: T['element'], id: $): boolean;
+ onCharacter(token: CharacterToken): void;
+ onNullCharacter(token: CharacterToken): void;
+ onComment(token: CommentToken): void;
+ onDoctype(token: DoctypeToken): void;
+ onStartTag(token: TagToken): void;
+ /**
+ * Processes a given start tag.
+ *
+ * `onStartTag` checks if a self-closing tag was recognized. When a token
+ * is moved inbetween multiple insertion modes, this check for self-closing
+ * could lead to false positives. To avoid this, `_processStartTag` is used
+ * for nested calls.
+ *
+ * @param token The token to process.
+ */
+ _processStartTag(token: TagToken): void;
+ _startTagOutsideForeignContent(token: TagToken): void;
+ onEndTag(token: TagToken): void;
+ _endTagOutsideForeignContent(token: TagToken): void;
+ onEof(token: EOFToken): void;
+ onWhitespaceCharacter(token: CharacterToken): void;
+}
+export {};
+//# sourceMappingURL=index.d.ts.map \ No newline at end of file
diff --git a/includes/external/addressbook/node_modules/parse5/dist/parser/index.js b/includes/external/addressbook/node_modules/parse5/dist/parser/index.js
new file mode 100644
index 0000000..4a3dc7a
--- /dev/null
+++ b/includes/external/addressbook/node_modules/parse5/dist/parser/index.js
@@ -0,0 +1,3168 @@
+import { Tokenizer, TokenizerMode } from '../tokenizer/index.js';
+import { OpenElementStack } from './open-element-stack.js';
+import { FormattingElementList, EntryType } from './formatting-element-list.js';
+import { defaultTreeAdapter } from '../tree-adapters/default.js';
+import * as doctype from '../common/doctype.js';
+import * as foreignContent from '../common/foreign-content.js';
+import { ERR } from '../common/error-codes.js';
+import * as unicode from '../common/unicode.js';
+import { TAG_ID as $, TAG_NAMES as TN, NS, ATTRS, SPECIAL_ELEMENTS, DOCUMENT_MODE, isNumberedHeader, getTagID, } from '../common/html.js';
+import { TokenType, getTokenAttr, } from '../common/token.js';
+//Misc constants
+const HIDDEN_INPUT_TYPE = 'hidden';
+//Adoption agency loops iteration count
+const AA_OUTER_LOOP_ITER = 8;
+const AA_INNER_LOOP_ITER = 3;
+//Insertion modes
+var InsertionMode;
+(function (InsertionMode) {
+ InsertionMode[InsertionMode["INITIAL"] = 0] = "INITIAL";
+ InsertionMode[InsertionMode["BEFORE_HTML"] = 1] = "BEFORE_HTML";
+ InsertionMode[InsertionMode["BEFORE_HEAD"] = 2] = "BEFORE_HEAD";
+ InsertionMode[InsertionMode["IN_HEAD"] = 3] = "IN_HEAD";
+ InsertionMode[InsertionMode["IN_HEAD_NO_SCRIPT"] = 4] = "IN_HEAD_NO_SCRIPT";
+ InsertionMode[InsertionMode["AFTER_HEAD"] = 5] = "AFTER_HEAD";
+ InsertionMode[InsertionMode["IN_BODY"] = 6] = "IN_BODY";
+ InsertionMode[InsertionMode["TEXT"] = 7] = "TEXT";
+ InsertionMode[InsertionMode["IN_TABLE"] = 8] = "IN_TABLE";
+ InsertionMode[InsertionMode["IN_TABLE_TEXT"] = 9] = "IN_TABLE_TEXT";
+ InsertionMode[InsertionMode["IN_CAPTION"] = 10] = "IN_CAPTION";
+ InsertionMode[InsertionMode["IN_COLUMN_GROUP"] = 11] = "IN_COLUMN_GROUP";
+ InsertionMode[InsertionMode["IN_TABLE_BODY"] = 12] = "IN_TABLE_BODY";
+ InsertionMode[InsertionMode["IN_ROW"] = 13] = "IN_ROW";
+ InsertionMode[InsertionMode["IN_CELL"] = 14] = "IN_CELL";
+ InsertionMode[InsertionMode["IN_SELECT"] = 15] = "IN_SELECT";
+ InsertionMode[InsertionMode["IN_SELECT_IN_TABLE"] = 16] = "IN_SELECT_IN_TABLE";
+ InsertionMode[InsertionMode["IN_TEMPLATE"] = 17] = "IN_TEMPLATE";
+ InsertionMode[InsertionMode["AFTER_BODY"] = 18] = "AFTER_BODY";
+ InsertionMode[InsertionMode["IN_FRAMESET"] = 19] = "IN_FRAMESET";
+ InsertionMode[InsertionMode["AFTER_FRAMESET"] = 20] = "AFTER_FRAMESET";
+ InsertionMode[InsertionMode["AFTER_AFTER_BODY"] = 21] = "AFTER_AFTER_BODY";
+ InsertionMode[InsertionMode["AFTER_AFTER_FRAMESET"] = 22] = "AFTER_AFTER_FRAMESET";
+})(InsertionMode || (InsertionMode = {}));
+const BASE_LOC = {
+ startLine: -1,
+ startCol: -1,
+ startOffset: -1,
+ endLine: -1,
+ endCol: -1,
+ endOffset: -1,
+};
+const TABLE_STRUCTURE_TAGS = new Set([$.TABLE, $.TBODY, $.TFOOT, $.THEAD, $.TR]);
+const defaultParserOptions = {
+ scriptingEnabled: true,
+ sourceCodeLocationInfo: false,
+ treeAdapter: defaultTreeAdapter,
+ onParseError: null,
+};
+//Parser
+export class Parser {
+ constructor(options, document, fragmentContext = null, scriptHandler = null) {
+ this.fragmentContext = fragmentContext;
+ this.scriptHandler = scriptHandler;
+ this.currentToken = null;
+ this.stopped = false;
+ this.insertionMode = InsertionMode.INITIAL;
+ this.originalInsertionMode = InsertionMode.INITIAL;
+ this.headElement = null;
+ this.formElement = null;
+ /** Indicates that the current node is not an element in the HTML namespace */
+ this.currentNotInHTML = false;
+ /**
+ * The template insertion mode stack is maintained from the left.
+ * Ie. the topmost element will always have index 0.
+ */
+ this.tmplInsertionModeStack = [];
+ this.pendingCharacterTokens = [];
+ this.hasNonWhitespacePendingCharacterToken = false;
+ this.framesetOk = true;
+ this.skipNextNewLine = false;
+ this.fosterParentingEnabled = false;
+ this.options = {
+ ...defaultParserOptions,
+ ...options,
+ };
+ this.treeAdapter = this.options.treeAdapter;
+ this.onParseError = this.options.onParseError;
+ // Always enable location info if we report parse errors.
+ if (this.onParseError) {
+ this.options.sourceCodeLocationInfo = true;
+ }
+ this.document = document !== null && document !== void 0 ? document : this.treeAdapter.createDocument();
+ this.tokenizer = new Tokenizer(this.options, this);
+ this.activeFormattingElements = new FormattingElementList(this.treeAdapter);
+ this.fragmentContextID = fragmentContext ? getTagID(this.treeAdapter.getTagName(fragmentContext)) : $.UNKNOWN;
+ this._setContextModes(fragmentContext !== null && fragmentContext !== void 0 ? fragmentContext : this.document, this.fragmentContextID);
+ this.openElements = new OpenElementStack(this.document, this.treeAdapter, this);
+ }
+ // API
+ static parse(html, options) {
+ const parser = new this(options);
+ parser.tokenizer.write(html, true);
+ return parser.document;
+ }
+ static getFragmentParser(fragmentContext, options) {
+ const opts = {
+ ...defaultParserOptions,
+ ...options,
+ };
+ //NOTE: use a <template> element as the fragment context if no context element was provided,
+ //so we will parse in a "forgiving" manner
+ fragmentContext !== null && fragmentContext !== void 0 ? fragmentContext : (fragmentContext = opts.treeAdapter.createElement(TN.TEMPLATE, NS.HTML, []));
+ //NOTE: create a fake element which will be used as the `document` for fragment parsing.
+ //This is important for jsdom, where a new `document` cannot be created. This led to
+ //fragment parsing messing with the main `document`.
+ const documentMock = opts.treeAdapter.createElement('documentmock', NS.HTML, []);
+ const parser = new this(opts, documentMock, fragmentContext);
+ if (parser.fragmentContextID === $.TEMPLATE) {
+ parser.tmplInsertionModeStack.unshift(InsertionMode.IN_TEMPLATE);
+ }
+ parser._initTokenizerForFragmentParsing();
+ parser._insertFakeRootElement();
+ parser._resetInsertionMode();
+ parser._findFormInFragmentContext();
+ return parser;
+ }
+ getFragment() {
+ const rootElement = this.treeAdapter.getFirstChild(this.document);
+ const fragment = this.treeAdapter.createDocumentFragment();
+ this._adoptNodes(rootElement, fragment);
+ return fragment;
+ }
+ //Errors
+ _err(token, code, beforeToken) {
+ var _a;
+ if (!this.onParseError)
+ return;
+ const loc = (_a = token.location) !== null && _a !== void 0 ? _a : BASE_LOC;
+ const err = {
+ code,
+ startLine: loc.startLine,
+ startCol: loc.startCol,
+ startOffset: loc.startOffset,
+ endLine: beforeToken ? loc.startLine : loc.endLine,
+ endCol: beforeToken ? loc.startCol : loc.endCol,
+ endOffset: beforeToken ? loc.startOffset : loc.endOffset,
+ };
+ this.onParseError(err);
+ }
+ //Stack events
+ onItemPush(node, tid, isTop) {
+ var _a, _b;
+ (_b = (_a = this.treeAdapter).onItemPush) === null || _b === void 0 ? void 0 : _b.call(_a, node);
+ if (isTop && this.openElements.stackTop > 0)
+ this._setContextModes(node, tid);
+ }
+ onItemPop(node, isTop) {
+ var _a, _b;
+ if (this.options.sourceCodeLocationInfo) {
+ this._setEndLocation(node, this.currentToken);
+ }
+ (_b = (_a = this.treeAdapter).onItemPop) === null || _b === void 0 ? void 0 : _b.call(_a, node, this.openElements.current);
+ if (isTop) {
+ let current;
+ let currentTagId;
+ if (this.openElements.stackTop === 0 && this.fragmentContext) {
+ current = this.fragmentContext;
+ currentTagId = this.fragmentContextID;
+ }
+ else {
+ ({ current, currentTagId } = this.openElements);
+ }
+ this._setContextModes(current, currentTagId);
+ }
+ }
+ _setContextModes(current, tid) {
+ const isHTML = current === this.document || this.treeAdapter.getNamespaceURI(current) === NS.HTML;
+ this.currentNotInHTML = !isHTML;
+ this.tokenizer.inForeignNode = !isHTML && !this._isIntegrationPoint(tid, current);
+ }
+ _switchToTextParsing(currentToken, nextTokenizerState) {
+ this._insertElement(currentToken, NS.HTML);
+ this.tokenizer.state = nextTokenizerState;
+ this.originalInsertionMode = this.insertionMode;
+ this.insertionMode = InsertionMode.TEXT;
+ }
+ switchToPlaintextParsing() {
+ this.insertionMode = InsertionMode.TEXT;
+ this.originalInsertionMode = InsertionMode.IN_BODY;
+ this.tokenizer.state = TokenizerMode.PLAINTEXT;
+ }
+ //Fragment parsing
+ _getAdjustedCurrentElement() {
+ return this.openElements.stackTop === 0 && this.fragmentContext
+ ? this.fragmentContext
+ : this.openElements.current;
+ }
+ _findFormInFragmentContext() {
+ let node = this.fragmentContext;
+ while (node) {
+ if (this.treeAdapter.getTagName(node) === TN.FORM) {
+ this.formElement = node;
+ break;
+ }
+ node = this.treeAdapter.getParentNode(node);
+ }
+ }
+ _initTokenizerForFragmentParsing() {
+ if (!this.fragmentContext || this.treeAdapter.getNamespaceURI(this.fragmentContext) !== NS.HTML) {
+ return;
+ }
+ switch (this.fragmentContextID) {
+ case $.TITLE:
+ case $.TEXTAREA: {
+ this.tokenizer.state = TokenizerMode.RCDATA;
+ break;
+ }
+ case $.STYLE:
+ case $.XMP:
+ case $.IFRAME:
+ case $.NOEMBED:
+ case $.NOFRAMES:
+ case $.NOSCRIPT: {
+ this.tokenizer.state = TokenizerMode.RAWTEXT;
+ break;
+ }
+ case $.SCRIPT: {
+ this.tokenizer.state = TokenizerMode.SCRIPT_DATA;
+ break;
+ }
+ case $.PLAINTEXT: {
+ this.tokenizer.state = TokenizerMode.PLAINTEXT;
+ break;
+ }
+ default:
+ // Do nothing
+ }
+ }
+ //Tree mutation
+ _setDocumentType(token) {
+ const name = token.name || '';
+ const publicId = token.publicId || '';
+ const systemId = token.systemId || '';
+ this.treeAdapter.setDocumentType(this.document, name, publicId, systemId);
+ if (token.location) {
+ const documentChildren = this.treeAdapter.getChildNodes(this.document);
+ const docTypeNode = documentChildren.find((node) => this.treeAdapter.isDocumentTypeNode(node));
+ if (docTypeNode) {
+ this.treeAdapter.setNodeSourceCodeLocation(docTypeNode, token.location);
+ }
+ }
+ }
+ _attachElementToTree(element, location) {
+ if (this.options.sourceCodeLocationInfo) {
+ const loc = location && {
+ ...location,
+ startTag: location,
+ };
+ this.treeAdapter.setNodeSourceCodeLocation(element, loc);
+ }
+ if (this._shouldFosterParentOnInsertion()) {
+ this._fosterParentElement(element);
+ }
+ else {
+ const parent = this.openElements.currentTmplContentOrNode;
+ this.treeAdapter.appendChild(parent, element);
+ }
+ }
+ _appendElement(token, namespaceURI) {
+ const element = this.treeAdapter.createElement(token.tagName, namespaceURI, token.attrs);
+ this._attachElementToTree(element, token.location);
+ }
+ _insertElement(token, namespaceURI) {
+ const element = this.treeAdapter.createElement(token.tagName, namespaceURI, token.attrs);
+ this._attachElementToTree(element, token.location);
+ this.openElements.push(element, token.tagID);
+ }
+ _insertFakeElement(tagName, tagID) {
+ const element = this.treeAdapter.createElement(tagName, NS.HTML, []);
+ this._attachElementToTree(element, null);
+ this.openElements.push(element, tagID);
+ }
+ _insertTemplate(token) {
+ const tmpl = this.treeAdapter.createElement(token.tagName, NS.HTML, token.attrs);
+ const content = this.treeAdapter.createDocumentFragment();
+ this.treeAdapter.setTemplateContent(tmpl, content);
+ this._attachElementToTree(tmpl, token.location);
+ this.openElements.push(tmpl, token.tagID);
+ if (this.options.sourceCodeLocationInfo)
+ this.treeAdapter.setNodeSourceCodeLocation(content, null);
+ }
+ _insertFakeRootElement() {
+ const element = this.treeAdapter.createElement(TN.HTML, NS.HTML, []);
+ if (this.options.sourceCodeLocationInfo)
+ this.treeAdapter.setNodeSourceCodeLocation(element, null);
+ this.treeAdapter.appendChild(this.openElements.current, element);
+ this.openElements.push(element, $.HTML);
+ }
+ _appendCommentNode(token, parent) {
+ const commentNode = this.treeAdapter.createCommentNode(token.data);
+ this.treeAdapter.appendChild(parent, commentNode);
+ if (this.options.sourceCodeLocationInfo) {
+ this.treeAdapter.setNodeSourceCodeLocation(commentNode, token.location);
+ }
+ }
+ _insertCharacters(token) {
+ let parent;
+ let beforeElement;
+ if (this._shouldFosterParentOnInsertion()) {
+ ({ parent, beforeElement } = this._findFosterParentingLocation());
+ if (beforeElement) {
+ this.treeAdapter.insertTextBefore(parent, token.chars, beforeElement);
+ }
+ else {
+ this.treeAdapter.insertText(parent, token.chars);
+ }
+ }
+ else {
+ parent = this.openElements.currentTmplContentOrNode;
+ this.treeAdapter.insertText(parent, token.chars);
+ }
+ if (!token.location)
+ return;
+ const siblings = this.treeAdapter.getChildNodes(parent);
+ const textNodeIdx = beforeElement ? siblings.lastIndexOf(beforeElement) : siblings.length;
+ const textNode = siblings[textNodeIdx - 1];
+ //NOTE: if we have a location assigned by another token, then just update the end position
+ const tnLoc = this.treeAdapter.getNodeSourceCodeLocation(textNode);
+ if (tnLoc) {
+ const { endLine, endCol, endOffset } = token.location;
+ this.treeAdapter.updateNodeSourceCodeLocation(textNode, { endLine, endCol, endOffset });
+ }
+ else if (this.options.sourceCodeLocationInfo) {
+ this.treeAdapter.setNodeSourceCodeLocation(textNode, token.location);
+ }
+ }
+ _adoptNodes(donor, recipient) {
+ for (let child = this.treeAdapter.getFirstChild(donor); child; child = this.treeAdapter.getFirstChild(donor)) {
+ this.treeAdapter.detachNode(child);
+ this.treeAdapter.appendChild(recipient, child);
+ }
+ }
+ _setEndLocation(element, closingToken) {
+ if (this.treeAdapter.getNodeSourceCodeLocation(element) && closingToken.location) {
+ const ctLoc = closingToken.location;
+ const tn = this.treeAdapter.getTagName(element);
+ const endLoc =
+ // NOTE: For cases like <p> <p> </p> - First 'p' closes without a closing
+ // tag and for cases like <td> <p> </td> - 'p' closes without a closing tag.
+ closingToken.type === TokenType.END_TAG && tn === closingToken.tagName
+ ? {
+ endTag: { ...ctLoc },
+ endLine: ctLoc.endLine,
+ endCol: ctLoc.endCol,
+ endOffset: ctLoc.endOffset,
+ }
+ : {
+ endLine: ctLoc.startLine,
+ endCol: ctLoc.startCol,
+ endOffset: ctLoc.startOffset,
+ };
+ this.treeAdapter.updateNodeSourceCodeLocation(element, endLoc);
+ }
+ }
+ //Token processing
+ shouldProcessStartTagTokenInForeignContent(token) {
+ // Check that neither current === document, or ns === NS.HTML
+ if (!this.currentNotInHTML)
+ return false;
+ let current;
+ let currentTagId;
+ if (this.openElements.stackTop === 0 && this.fragmentContext) {
+ current = this.fragmentContext;
+ currentTagId = this.fragmentContextID;
+ }
+ else {
+ ({ current, currentTagId } = this.openElements);
+ }
+ if (token.tagID === $.SVG &&
+ this.treeAdapter.getTagName(current) === TN.ANNOTATION_XML &&
+ this.treeAdapter.getNamespaceURI(current) === NS.MATHML) {
+ return false;
+ }
+ return (
+ // Check that `current` is not an integration point for HTML or MathML elements.
+ this.tokenizer.inForeignNode ||
+ // If it _is_ an integration point, then we might have to check that it is not an HTML
+ // integration point.
+ ((token.tagID === $.MGLYPH || token.tagID === $.MALIGNMARK) &&
+ !this._isIntegrationPoint(currentTagId, current, NS.HTML)));
+ }
+ _processToken(token) {
+ switch (token.type) {
+ case TokenType.CHARACTER: {
+ this.onCharacter(token);
+ break;
+ }
+ case TokenType.NULL_CHARACTER: {
+ this.onNullCharacter(token);
+ break;
+ }
+ case TokenType.COMMENT: {
+ this.onComment(token);
+ break;
+ }
+ case TokenType.DOCTYPE: {
+ this.onDoctype(token);
+ break;
+ }
+ case TokenType.START_TAG: {
+ this._processStartTag(token);
+ break;
+ }
+ case TokenType.END_TAG: {
+ this.onEndTag(token);
+ break;
+ }
+ case TokenType.EOF: {
+ this.onEof(token);
+ break;
+ }
+ case TokenType.WHITESPACE_CHARACTER: {
+ this.onWhitespaceCharacter(token);
+ break;
+ }
+ }
+ }
+ //Integration points
+ _isIntegrationPoint(tid, element, foreignNS) {
+ const ns = this.treeAdapter.getNamespaceURI(element);
+ const attrs = this.treeAdapter.getAttrList(element);
+ return foreignContent.isIntegrationPoint(tid, ns, attrs, foreignNS);
+ }
+ //Active formatting elements reconstruction
+ _reconstructActiveFormattingElements() {
+ const listLength = this.activeFormattingElements.entries.length;
+ if (listLength) {
+ const endIndex = this.activeFormattingElements.entries.findIndex((entry) => entry.type === EntryType.Marker || this.openElements.contains(entry.element));
+ const unopenIdx = endIndex < 0 ? listLength - 1 : endIndex - 1;
+ for (let i = unopenIdx; i >= 0; i--) {
+ const entry = this.activeFormattingElements.entries[i];
+ this._insertElement(entry.token, this.treeAdapter.getNamespaceURI(entry.element));
+ entry.element = this.openElements.current;
+ }
+ }
+ }
+ //Close elements
+ _closeTableCell() {
+ this.openElements.generateImpliedEndTags();
+ this.openElements.popUntilTableCellPopped();
+ this.activeFormattingElements.clearToLastMarker();
+ this.insertionMode = InsertionMode.IN_ROW;
+ }
+ _closePElement() {
+ this.openElements.generateImpliedEndTagsWithExclusion($.P);
+ this.openElements.popUntilTagNamePopped($.P);
+ }
+ //Insertion modes
+ _resetInsertionMode() {
+ for (let i = this.openElements.stackTop; i >= 0; i--) {
+ //Insertion mode reset map
+ switch (i === 0 && this.fragmentContext ? this.fragmentContextID : this.openElements.tagIDs[i]) {
+ case $.TR: {
+ this.insertionMode = InsertionMode.IN_ROW;
+ return;
+ }
+ case $.TBODY:
+ case $.THEAD:
+ case $.TFOOT: {
+ this.insertionMode = InsertionMode.IN_TABLE_BODY;
+ return;
+ }
+ case $.CAPTION: {
+ this.insertionMode = InsertionMode.IN_CAPTION;
+ return;
+ }
+ case $.COLGROUP: {
+ this.insertionMode = InsertionMode.IN_COLUMN_GROUP;
+ return;
+ }
+ case $.TABLE: {
+ this.insertionMode = InsertionMode.IN_TABLE;
+ return;
+ }
+ case $.BODY: {
+ this.insertionMode = InsertionMode.IN_BODY;
+ return;
+ }
+ case $.FRAMESET: {
+ this.insertionMode = InsertionMode.IN_FRAMESET;
+ return;
+ }
+ case $.SELECT: {
+ this._resetInsertionModeForSelect(i);
+ return;
+ }
+ case $.TEMPLATE: {
+ this.insertionMode = this.tmplInsertionModeStack[0];
+ return;
+ }
+ case $.HTML: {
+ this.insertionMode = this.headElement ? InsertionMode.AFTER_HEAD : InsertionMode.BEFORE_HEAD;
+ return;
+ }
+ case $.TD:
+ case $.TH: {
+ if (i > 0) {
+ this.insertionMode = InsertionMode.IN_CELL;
+ return;
+ }
+ break;
+ }
+ case $.HEAD: {
+ if (i > 0) {
+ this.insertionMode = InsertionMode.IN_HEAD;
+ return;
+ }
+ break;
+ }
+ }
+ }
+ this.insertionMode = InsertionMode.IN_BODY;
+ }
+ _resetInsertionModeForSelect(selectIdx) {
+ if (selectIdx > 0) {
+ for (let i = selectIdx - 1; i > 0; i--) {
+ const tn = this.openElements.tagIDs[i];
+ if (tn === $.TEMPLATE) {
+ break;
+ }
+ else if (tn === $.TABLE) {
+ this.insertionMode = InsertionMode.IN_SELECT_IN_TABLE;
+ return;
+ }
+ }
+ }
+ this.insertionMode = InsertionMode.IN_SELECT;
+ }
+ //Foster parenting
+ _isElementCausesFosterParenting(tn) {
+ return TABLE_STRUCTURE_TAGS.has(tn);
+ }
+ _shouldFosterParentOnInsertion() {
+ return this.fosterParentingEnabled && this._isElementCausesFosterParenting(this.openElements.currentTagId);
+ }
+ _findFosterParentingLocation() {
+ for (let i = this.openElements.stackTop; i >= 0; i--) {
+ const openElement = this.openElements.items[i];
+ switch (this.openElements.tagIDs[i]) {
+ case $.TEMPLATE: {
+ if (this.treeAdapter.getNamespaceURI(openElement) === NS.HTML) {
+ return { parent: this.treeAdapter.getTemplateContent(openElement), beforeElement: null };
+ }
+ break;
+ }
+ case $.TABLE: {
+ const parent = this.treeAdapter.getParentNode(openElement);
+ if (parent) {
+ return { parent, beforeElement: openElement };
+ }
+ return { parent: this.openElements.items[i - 1], beforeElement: null };
+ }
+ default:
+ // Do nothing
+ }
+ }
+ return { parent: this.openElements.items[0], beforeElement: null };
+ }
+ _fosterParentElement(element) {
+ const location = this._findFosterParentingLocation();
+ if (location.beforeElement) {
+ this.treeAdapter.insertBefore(location.parent, element, location.beforeElement);
+ }
+ else {
+ this.treeAdapter.appendChild(location.parent, element);
+ }
+ }
+ //Special elements
+ _isSpecialElement(element, id) {
+ const ns = this.treeAdapter.getNamespaceURI(element);
+ return SPECIAL_ELEMENTS[ns].has(id);
+ }
+ onCharacter(token) {
+ this.skipNextNewLine = false;
+ if (this.tokenizer.inForeignNode) {
+ characterInForeignContent(this, token);
+ return;
+ }
+ switch (this.insertionMode) {
+ case InsertionMode.INITIAL: {
+ tokenInInitialMode(this, token);
+ break;
+ }
+ case InsertionMode.BEFORE_HTML: {
+ tokenBeforeHtml(this, token);
+ break;
+ }
+ case InsertionMode.BEFORE_HEAD: {
+ tokenBeforeHead(this, token);
+ break;
+ }
+ case InsertionMode.IN_HEAD: {
+ tokenInHead(this, token);
+ break;
+ }
+ case InsertionMode.IN_HEAD_NO_SCRIPT: {
+ tokenInHeadNoScript(this, token);
+ break;
+ }
+ case InsertionMode.AFTER_HEAD: {
+ tokenAfterHead(this, token);
+ break;
+ }
+ case InsertionMode.IN_BODY:
+ case InsertionMode.IN_CAPTION:
+ case InsertionMode.IN_CELL:
+ case InsertionMode.IN_TEMPLATE: {
+ characterInBody(this, token);
+ break;
+ }
+ case InsertionMode.TEXT:
+ case InsertionMode.IN_SELECT:
+ case InsertionMode.IN_SELECT_IN_TABLE: {
+ this._insertCharacters(token);
+ break;
+ }
+ case InsertionMode.IN_TABLE:
+ case InsertionMode.IN_TABLE_BODY:
+ case InsertionMode.IN_ROW: {
+ characterInTable(this, token);
+ break;
+ }
+ case InsertionMode.IN_TABLE_TEXT: {
+ characterInTableText(this, token);
+ break;
+ }
+ case InsertionMode.IN_COLUMN_GROUP: {
+ tokenInColumnGroup(this, token);
+ break;
+ }
+ case InsertionMode.AFTER_BODY: {
+ tokenAfterBody(this, token);
+ break;
+ }
+ case InsertionMode.AFTER_AFTER_BODY: {
+ tokenAfterAfterBody(this, token);
+ break;
+ }
+ default:
+ // Do nothing
+ }
+ }
+ onNullCharacter(token) {
+ this.skipNextNewLine = false;
+ if (this.tokenizer.inForeignNode) {
+ nullCharacterInForeignContent(this, token);
+ return;
+ }
+ switch (this.insertionMode) {
+ case InsertionMode.INITIAL: {
+ tokenInInitialMode(this, token);
+ break;
+ }
+ case InsertionMode.BEFORE_HTML: {
+ tokenBeforeHtml(this, token);
+ break;
+ }
+ case InsertionMode.BEFORE_HEAD: {
+ tokenBeforeHead(this, token);
+ break;
+ }
+ case InsertionMode.IN_HEAD: {
+ tokenInHead(this, token);
+ break;
+ }
+ case InsertionMode.IN_HEAD_NO_SCRIPT: {
+ tokenInHeadNoScript(this, token);
+ break;
+ }
+ case InsertionMode.AFTER_HEAD: {
+ tokenAfterHead(this, token);
+ break;
+ }
+ case InsertionMode.TEXT: {
+ this._insertCharacters(token);
+ break;
+ }
+ case InsertionMode.IN_TABLE:
+ case InsertionMode.IN_TABLE_BODY:
+ case InsertionMode.IN_ROW: {
+ characterInTable(this, token);
+ break;
+ }
+ case InsertionMode.IN_COLUMN_GROUP: {
+ tokenInColumnGroup(this, token);
+ break;
+ }
+ case InsertionMode.AFTER_BODY: {
+ tokenAfterBody(this, token);
+ break;
+ }
+ case InsertionMode.AFTER_AFTER_BODY: {
+ tokenAfterAfterBody(this, token);
+ break;
+ }
+ default:
+ // Do nothing
+ }
+ }
+ onComment(token) {
+ this.skipNextNewLine = false;
+ if (this.currentNotInHTML) {
+ appendComment(this, token);
+ return;
+ }
+ switch (this.insertionMode) {
+ case InsertionMode.INITIAL:
+ case InsertionMode.BEFORE_HTML:
+ case InsertionMode.BEFORE_HEAD:
+ case InsertionMode.IN_HEAD:
+ case InsertionMode.IN_HEAD_NO_SCRIPT:
+ case InsertionMode.AFTER_HEAD:
+ case InsertionMode.IN_BODY:
+ case InsertionMode.IN_TABLE:
+ case InsertionMode.IN_CAPTION:
+ case InsertionMode.IN_COLUMN_GROUP:
+ case InsertionMode.IN_TABLE_BODY:
+ case InsertionMode.IN_ROW:
+ case InsertionMode.IN_CELL:
+ case InsertionMode.IN_SELECT:
+ case InsertionMode.IN_SELECT_IN_TABLE:
+ case InsertionMode.IN_TEMPLATE:
+ case InsertionMode.IN_FRAMESET:
+ case InsertionMode.AFTER_FRAMESET: {
+ appendComment(this, token);
+ break;
+ }
+ case InsertionMode.IN_TABLE_TEXT: {
+ tokenInTableText(this, token);
+ break;
+ }
+ case InsertionMode.AFTER_BODY: {
+ appendCommentToRootHtmlElement(this, token);
+ break;
+ }
+ case InsertionMode.AFTER_AFTER_BODY:
+ case InsertionMode.AFTER_AFTER_FRAMESET: {
+ appendCommentToDocument(this, token);
+ break;
+ }
+ default:
+ // Do nothing
+ }
+ }
+ onDoctype(token) {
+ this.skipNextNewLine = false;
+ switch (this.insertionMode) {
+ case InsertionMode.INITIAL: {
+ doctypeInInitialMode(this, token);
+ break;
+ }
+ case InsertionMode.BEFORE_HEAD:
+ case InsertionMode.IN_HEAD:
+ case InsertionMode.IN_HEAD_NO_SCRIPT:
+ case InsertionMode.AFTER_HEAD: {
+ this._err(token, ERR.misplacedDoctype);
+ break;
+ }
+ case InsertionMode.IN_TABLE_TEXT: {
+ tokenInTableText(this, token);
+ break;
+ }
+ default:
+ // Do nothing
+ }
+ }
+ onStartTag(token) {
+ this.skipNextNewLine = false;
+ this.currentToken = token;
+ this._processStartTag(token);
+ if (token.selfClosing && !token.ackSelfClosing) {
+ this._err(token, ERR.nonVoidHtmlElementStartTagWithTrailingSolidus);
+ }
+ }
+ /**
+ * Processes a given start tag.
+ *
+ * `onStartTag` checks if a self-closing tag was recognized. When a token
+ * is moved inbetween multiple insertion modes, this check for self-closing
+ * could lead to false positives. To avoid this, `_processStartTag` is used
+ * for nested calls.
+ *
+ * @param token The token to process.
+ */
+ _processStartTag(token) {
+ if (this.shouldProcessStartTagTokenInForeignContent(token)) {
+ startTagInForeignContent(this, token);
+ }
+ else {
+ this._startTagOutsideForeignContent(token);
+ }
+ }
+ _startTagOutsideForeignContent(token) {
+ switch (this.insertionMode) {
+ case InsertionMode.INITIAL: {
+ tokenInInitialMode(this, token);
+ break;
+ }
+ case InsertionMode.BEFORE_HTML: {
+ startTagBeforeHtml(this, token);
+ break;
+ }
+ case InsertionMode.BEFORE_HEAD: {
+ startTagBeforeHead(this, token);
+ break;
+ }
+ case InsertionMode.IN_HEAD: {
+ startTagInHead(this, token);
+ break;
+ }
+ case InsertionMode.IN_HEAD_NO_SCRIPT: {
+ startTagInHeadNoScript(this, token);
+ break;
+ }
+ case InsertionMode.AFTER_HEAD: {
+ startTagAfterHead(this, token);
+ break;
+ }
+ case InsertionMode.IN_BODY: {
+ startTagInBody(this, token);
+ break;
+ }
+ case InsertionMode.IN_TABLE: {
+ startTagInTable(this, token);
+ break;
+ }
+ case InsertionMode.IN_TABLE_TEXT: {
+ tokenInTableText(this, token);
+ break;
+ }
+ case InsertionMode.IN_CAPTION: {
+ startTagInCaption(this, token);
+ break;
+ }
+ case InsertionMode.IN_COLUMN_GROUP: {
+ startTagInColumnGroup(this, token);
+ break;
+ }
+ case InsertionMode.IN_TABLE_BODY: {
+ startTagInTableBody(this, token);
+ break;
+ }
+ case InsertionMode.IN_ROW: {
+ startTagInRow(this, token);
+ break;
+ }
+ case InsertionMode.IN_CELL: {
+ startTagInCell(this, token);
+ break;
+ }
+ case InsertionMode.IN_SELECT: {
+ startTagInSelect(this, token);
+ break;
+ }
+ case InsertionMode.IN_SELECT_IN_TABLE: {
+ startTagInSelectInTable(this, token);
+ break;
+ }
+ case InsertionMode.IN_TEMPLATE: {
+ startTagInTemplate(this, token);
+ break;
+ }
+ case InsertionMode.AFTER_BODY: {
+ startTagAfterBody(this, token);
+ break;
+ }
+ case InsertionMode.IN_FRAMESET: {
+ startTagInFrameset(this, token);
+ break;
+ }
+ case InsertionMode.AFTER_FRAMESET: {
+ startTagAfterFrameset(this, token);
+ break;
+ }
+ case InsertionMode.AFTER_AFTER_BODY: {
+ startTagAfterAfterBody(this, token);
+ break;
+ }
+ case InsertionMode.AFTER_AFTER_FRAMESET: {
+ startTagAfterAfterFrameset(this, token);
+ break;
+ }
+ default:
+ // Do nothing
+ }
+ }
+ onEndTag(token) {
+ this.skipNextNewLine = false;
+ this.currentToken = token;
+ if (this.currentNotInHTML) {
+ endTagInForeignContent(this, token);
+ }
+ else {
+ this._endTagOutsideForeignContent(token);
+ }
+ }
+ _endTagOutsideForeignContent(token) {
+ switch (this.insertionMode) {
+ case InsertionMode.INITIAL: {
+ tokenInInitialMode(this, token);
+ break;
+ }
+ case InsertionMode.BEFORE_HTML: {
+ endTagBeforeHtml(this, token);
+ break;
+ }
+ case InsertionMode.BEFORE_HEAD: {
+ endTagBeforeHead(this, token);
+ break;
+ }
+ case InsertionMode.IN_HEAD: {
+ endTagInHead(this, token);
+ break;
+ }
+ case InsertionMode.IN_HEAD_NO_SCRIPT: {
+ endTagInHeadNoScript(this, token);
+ break;
+ }
+ case InsertionMode.AFTER_HEAD: {
+ endTagAfterHead(this, token);
+ break;
+ }
+ case InsertionMode.IN_BODY: {
+ endTagInBody(this, token);
+ break;
+ }
+ case InsertionMode.TEXT: {
+ endTagInText(this, token);
+ break;
+ }
+ case InsertionMode.IN_TABLE: {
+ endTagInTable(this, token);
+ break;
+ }
+ case InsertionMode.IN_TABLE_TEXT: {
+ tokenInTableText(this, token);
+ break;
+ }
+ case InsertionMode.IN_CAPTION: {
+ endTagInCaption(this, token);
+ break;
+ }
+ case InsertionMode.IN_COLUMN_GROUP: {
+ endTagInColumnGroup(this, token);
+ break;
+ }
+ case InsertionMode.IN_TABLE_BODY: {
+ endTagInTableBody(this, token);
+ break;
+ }
+ case InsertionMode.IN_ROW: {
+ endTagInRow(this, token);
+ break;
+ }
+ case InsertionMode.IN_CELL: {
+ endTagInCell(this, token);
+ break;
+ }
+ case InsertionMode.IN_SELECT: {
+ endTagInSelect(this, token);
+ break;
+ }
+ case InsertionMode.IN_SELECT_IN_TABLE: {
+ endTagInSelectInTable(this, token);
+ break;
+ }
+ case InsertionMode.IN_TEMPLATE: {
+ endTagInTemplate(this, token);
+ break;
+ }
+ case InsertionMode.AFTER_BODY: {
+ endTagAfterBody(this, token);
+ break;
+ }
+ case InsertionMode.IN_FRAMESET: {
+ endTagInFrameset(this, token);
+ break;
+ }
+ case InsertionMode.AFTER_FRAMESET: {
+ endTagAfterFrameset(this, token);
+ break;
+ }
+ case InsertionMode.AFTER_AFTER_BODY: {
+ tokenAfterAfterBody(this, token);
+ break;
+ }
+ default:
+ // Do nothing
+ }
+ }
+ onEof(token) {
+ switch (this.insertionMode) {
+ case InsertionMode.INITIAL: {
+ tokenInInitialMode(this, token);
+ break;
+ }
+ case InsertionMode.BEFORE_HTML: {
+ tokenBeforeHtml(this, token);
+ break;
+ }
+ case InsertionMode.BEFORE_HEAD: {
+ tokenBeforeHead(this, token);
+ break;
+ }
+ case InsertionMode.IN_HEAD: {
+ tokenInHead(this, token);
+ break;
+ }
+ case InsertionMode.IN_HEAD_NO_SCRIPT: {
+ tokenInHeadNoScript(this, token);
+ break;
+ }
+ case InsertionMode.AFTER_HEAD: {
+ tokenAfterHead(this, token);
+ break;
+ }
+ case InsertionMode.IN_BODY:
+ case InsertionMode.IN_TABLE:
+ case InsertionMode.IN_CAPTION:
+ case InsertionMode.IN_COLUMN_GROUP:
+ case InsertionMode.IN_TABLE_BODY:
+ case InsertionMode.IN_ROW:
+ case InsertionMode.IN_CELL:
+ case InsertionMode.IN_SELECT:
+ case InsertionMode.IN_SELECT_IN_TABLE: {
+ eofInBody(this, token);
+ break;
+ }
+ case InsertionMode.TEXT: {
+ eofInText(this, token);
+ break;
+ }
+ case InsertionMode.IN_TABLE_TEXT: {
+ tokenInTableText(this, token);
+ break;
+ }
+ case InsertionMode.IN_TEMPLATE: {
+ eofInTemplate(this, token);
+ break;
+ }
+ case InsertionMode.AFTER_BODY:
+ case InsertionMode.IN_FRAMESET:
+ case InsertionMode.AFTER_FRAMESET:
+ case InsertionMode.AFTER_AFTER_BODY:
+ case InsertionMode.AFTER_AFTER_FRAMESET: {
+ stopParsing(this, token);
+ break;
+ }
+ default:
+ // Do nothing
+ }
+ }
+ onWhitespaceCharacter(token) {
+ if (this.skipNextNewLine) {
+ this.skipNextNewLine = false;
+ if (token.chars.charCodeAt(0) === unicode.CODE_POINTS.LINE_FEED) {
+ if (token.chars.length === 1) {
+ return;
+ }
+ token.chars = token.chars.substr(1);
+ }
+ }
+ if (this.tokenizer.inForeignNode) {
+ this._insertCharacters(token);
+ return;
+ }
+ switch (this.insertionMode) {
+ case InsertionMode.IN_HEAD:
+ case InsertionMode.IN_HEAD_NO_SCRIPT:
+ case InsertionMode.AFTER_HEAD:
+ case InsertionMode.TEXT:
+ case InsertionMode.IN_COLUMN_GROUP:
+ case InsertionMode.IN_SELECT:
+ case InsertionMode.IN_SELECT_IN_TABLE:
+ case InsertionMode.IN_FRAMESET:
+ case InsertionMode.AFTER_FRAMESET: {
+ this._insertCharacters(token);
+ break;
+ }
+ case InsertionMode.IN_BODY:
+ case InsertionMode.IN_CAPTION:
+ case InsertionMode.IN_CELL:
+ case InsertionMode.IN_TEMPLATE:
+ case InsertionMode.AFTER_BODY:
+ case InsertionMode.AFTER_AFTER_BODY:
+ case InsertionMode.AFTER_AFTER_FRAMESET: {
+ whitespaceCharacterInBody(this, token);
+ break;
+ }
+ case InsertionMode.IN_TABLE:
+ case InsertionMode.IN_TABLE_BODY:
+ case InsertionMode.IN_ROW: {
+ characterInTable(this, token);
+ break;
+ }
+ case InsertionMode.IN_TABLE_TEXT: {
+ whitespaceCharacterInTableText(this, token);
+ break;
+ }
+ default:
+ // Do nothing
+ }
+ }
+}
+//Adoption agency algorithm
+//(see: http://www.whatwg.org/specs/web-apps/current-work/multipage/tree-construction.html#adoptionAgency)
+//------------------------------------------------------------------
+//Steps 5-8 of the algorithm
+function aaObtainFormattingElementEntry(p, token) {
+ let formattingElementEntry = p.activeFormattingElements.getElementEntryInScopeWithTagName(token.tagName);
+ if (formattingElementEntry) {
+ if (!p.openElements.contains(formattingElementEntry.element)) {
+ p.activeFormattingElements.removeEntry(formattingElementEntry);
+ formattingElementEntry = null;
+ }
+ else if (!p.openElements.hasInScope(token.tagID)) {
+ formattingElementEntry = null;
+ }
+ }
+ else {
+ genericEndTagInBody(p, token);
+ }
+ return formattingElementEntry;
+}
+//Steps 9 and 10 of the algorithm
+function aaObtainFurthestBlock(p, formattingElementEntry) {
+ let furthestBlock = null;
+ let idx = p.openElements.stackTop;
+ for (; idx >= 0; idx--) {
+ const element = p.openElements.items[idx];
+ if (element === formattingElementEntry.element) {
+ break;
+ }
+ if (p._isSpecialElement(element, p.openElements.tagIDs[idx])) {
+ furthestBlock = element;
+ }
+ }
+ if (!furthestBlock) {
+ p.openElements.shortenToLength(idx < 0 ? 0 : idx);
+ p.activeFormattingElements.removeEntry(formattingElementEntry);
+ }
+ return furthestBlock;
+}
+//Step 13 of the algorithm
+function aaInnerLoop(p, furthestBlock, formattingElement) {
+ let lastElement = furthestBlock;
+ let nextElement = p.openElements.getCommonAncestor(furthestBlock);
+ for (let i = 0, element = nextElement; element !== formattingElement; i++, element = nextElement) {
+ //NOTE: store the next element for the next loop iteration (it may be deleted from the stack by step 9.5)
+ nextElement = p.openElements.getCommonAncestor(element);
+ const elementEntry = p.activeFormattingElements.getElementEntry(element);
+ const counterOverflow = elementEntry && i >= AA_INNER_LOOP_ITER;
+ const shouldRemoveFromOpenElements = !elementEntry || counterOverflow;
+ if (shouldRemoveFromOpenElements) {
+ if (counterOverflow) {
+ p.activeFormattingElements.removeEntry(elementEntry);
+ }
+ p.openElements.remove(element);
+ }
+ else {
+ element = aaRecreateElementFromEntry(p, elementEntry);
+ if (lastElement === furthestBlock) {
+ p.activeFormattingElements.bookmark = elementEntry;
+ }
+ p.treeAdapter.detachNode(lastElement);
+ p.treeAdapter.appendChild(element, lastElement);
+ lastElement = element;
+ }
+ }
+ return lastElement;
+}
+//Step 13.7 of the algorithm
+function aaRecreateElementFromEntry(p, elementEntry) {
+ const ns = p.treeAdapter.getNamespaceURI(elementEntry.element);
+ const newElement = p.treeAdapter.createElement(elementEntry.token.tagName, ns, elementEntry.token.attrs);
+ p.openElements.replace(elementEntry.element, newElement);
+ elementEntry.element = newElement;
+ return newElement;
+}
+//Step 14 of the algorithm
+function aaInsertLastNodeInCommonAncestor(p, commonAncestor, lastElement) {
+ const tn = p.treeAdapter.getTagName(commonAncestor);
+ const tid = getTagID(tn);
+ if (p._isElementCausesFosterParenting(tid)) {
+ p._fosterParentElement(lastElement);
+ }
+ else {
+ const ns = p.treeAdapter.getNamespaceURI(commonAncestor);
+ if (tid === $.TEMPLATE && ns === NS.HTML) {
+ commonAncestor = p.treeAdapter.getTemplateContent(commonAncestor);
+ }
+ p.treeAdapter.appendChild(commonAncestor, lastElement);
+ }
+}
+//Steps 15-19 of the algorithm
+function aaReplaceFormattingElement(p, furthestBlock, formattingElementEntry) {
+ const ns = p.treeAdapter.getNamespaceURI(formattingElementEntry.element);
+ const { token } = formattingElementEntry;
+ const newElement = p.treeAdapter.createElement(token.tagName, ns, token.attrs);
+ p._adoptNodes(furthestBlock, newElement);
+ p.treeAdapter.appendChild(furthestBlock, newElement);
+ p.activeFormattingElements.insertElementAfterBookmark(newElement, token);
+ p.activeFormattingElements.removeEntry(formattingElementEntry);
+ p.openElements.remove(formattingElementEntry.element);
+ p.openElements.insertAfter(furthestBlock, newElement, token.tagID);
+}
+//Algorithm entry point
+function callAdoptionAgency(p, token) {
+ for (let i = 0; i < AA_OUTER_LOOP_ITER; i++) {
+ const formattingElementEntry = aaObtainFormattingElementEntry(p, token);
+ if (!formattingElementEntry) {
+ break;
+ }
+ const furthestBlock = aaObtainFurthestBlock(p, formattingElementEntry);
+ if (!furthestBlock) {
+ break;
+ }
+ p.activeFormattingElements.bookmark = formattingElementEntry;
+ const lastElement = aaInnerLoop(p, furthestBlock, formattingElementEntry.element);
+ const commonAncestor = p.openElements.getCommonAncestor(formattingElementEntry.element);
+ p.treeAdapter.detachNode(lastElement);
+ if (commonAncestor)
+ aaInsertLastNodeInCommonAncestor(p, commonAncestor, lastElement);
+ aaReplaceFormattingElement(p, furthestBlock, formattingElementEntry);
+ }
+}
+//Generic token handlers
+//------------------------------------------------------------------
+function appendComment(p, token) {
+ p._appendCommentNode(token, p.openElements.currentTmplContentOrNode);
+}
+function appendCommentToRootHtmlElement(p, token) {
+ p._appendCommentNode(token, p.openElements.items[0]);
+}
+function appendCommentToDocument(p, token) {
+ p._appendCommentNode(token, p.document);
+}
+function stopParsing(p, token) {
+ p.stopped = true;
+ // NOTE: Set end locations for elements that remain on the open element stack.
+ if (token.location) {
+ // NOTE: If we are not in a fragment, `html` and `body` will stay on the stack.
+ // This is a problem, as we might overwrite their end position here.
+ const target = p.fragmentContext ? 0 : 2;
+ for (let i = p.openElements.stackTop; i >= target; i--) {
+ p._setEndLocation(p.openElements.items[i], token);
+ }
+ // Handle `html` and `body`
+ if (!p.fragmentContext && p.openElements.stackTop >= 0) {
+ const htmlElement = p.openElements.items[0];
+ const htmlLocation = p.treeAdapter.getNodeSourceCodeLocation(htmlElement);
+ if (htmlLocation && !htmlLocation.endTag) {
+ p._setEndLocation(htmlElement, token);
+ if (p.openElements.stackTop >= 1) {
+ const bodyElement = p.openElements.items[1];
+ const bodyLocation = p.treeAdapter.getNodeSourceCodeLocation(bodyElement);
+ if (bodyLocation && !bodyLocation.endTag) {
+ p._setEndLocation(bodyElement, token);
+ }
+ }
+ }
+ }
+ }
+}
+// The "initial" insertion mode
+//------------------------------------------------------------------
+function doctypeInInitialMode(p, token) {
+ p._setDocumentType(token);
+ const mode = token.forceQuirks ? DOCUMENT_MODE.QUIRKS : doctype.getDocumentMode(token);
+ if (!doctype.isConforming(token)) {
+ p._err(token, ERR.nonConformingDoctype);
+ }
+ p.treeAdapter.setDocumentMode(p.document, mode);
+ p.insertionMode = InsertionMode.BEFORE_HTML;
+}
+function tokenInInitialMode(p, token) {
+ p._err(token, ERR.missingDoctype, true);
+ p.treeAdapter.setDocumentMode(p.document, DOCUMENT_MODE.QUIRKS);
+ p.insertionMode = InsertionMode.BEFORE_HTML;
+ p._processToken(token);
+}
+// The "before html" insertion mode
+//------------------------------------------------------------------
+function startTagBeforeHtml(p, token) {
+ if (token.tagID === $.HTML) {
+ p._insertElement(token, NS.HTML);
+ p.insertionMode = InsertionMode.BEFORE_HEAD;
+ }
+ else {
+ tokenBeforeHtml(p, token);
+ }
+}
+function endTagBeforeHtml(p, token) {
+ const tn = token.tagID;
+ if (tn === $.HTML || tn === $.HEAD || tn === $.BODY || tn === $.BR) {
+ tokenBeforeHtml(p, token);
+ }
+}
+function tokenBeforeHtml(p, token) {
+ p._insertFakeRootElement();
+ p.insertionMode = InsertionMode.BEFORE_HEAD;
+ p._processToken(token);
+}
+// The "before head" insertion mode
+//------------------------------------------------------------------
+function startTagBeforeHead(p, token) {
+ switch (token.tagID) {
+ case $.HTML: {
+ startTagInBody(p, token);
+ break;
+ }
+ case $.HEAD: {
+ p._insertElement(token, NS.HTML);
+ p.headElement = p.openElements.current;
+ p.insertionMode = InsertionMode.IN_HEAD;
+ break;
+ }
+ default: {
+ tokenBeforeHead(p, token);
+ }
+ }
+}
+function endTagBeforeHead(p, token) {
+ const tn = token.tagID;
+ if (tn === $.HEAD || tn === $.BODY || tn === $.HTML || tn === $.BR) {
+ tokenBeforeHead(p, token);
+ }
+ else {
+ p._err(token, ERR.endTagWithoutMatchingOpenElement);
+ }
+}
+function tokenBeforeHead(p, token) {
+ p._insertFakeElement(TN.HEAD, $.HEAD);
+ p.headElement = p.openElements.current;
+ p.insertionMode = InsertionMode.IN_HEAD;
+ p._processToken(token);
+}
+// The "in head" insertion mode
+//------------------------------------------------------------------
+function startTagInHead(p, token) {
+ switch (token.tagID) {
+ case $.HTML: {
+ startTagInBody(p, token);
+ break;
+ }
+ case $.BASE:
+ case $.BASEFONT:
+ case $.BGSOUND:
+ case $.LINK:
+ case $.META: {
+ p._appendElement(token, NS.HTML);
+ token.ackSelfClosing = true;
+ break;
+ }
+ case $.TITLE: {
+ p._switchToTextParsing(token, TokenizerMode.RCDATA);
+ break;
+ }
+ case $.NOSCRIPT: {
+ if (p.options.scriptingEnabled) {
+ p._switchToTextParsing(token, TokenizerMode.RAWTEXT);
+ }
+ else {
+ p._insertElement(token, NS.HTML);
+ p.insertionMode = InsertionMode.IN_HEAD_NO_SCRIPT;
+ }
+ break;
+ }
+ case $.NOFRAMES:
+ case $.STYLE: {
+ p._switchToTextParsing(token, TokenizerMode.RAWTEXT);
+ break;
+ }
+ case $.SCRIPT: {
+ p._switchToTextParsing(token, TokenizerMode.SCRIPT_DATA);
+ break;
+ }
+ case $.TEMPLATE: {
+ p._insertTemplate(token);
+ p.activeFormattingElements.insertMarker();
+ p.framesetOk = false;
+ p.insertionMode = InsertionMode.IN_TEMPLATE;
+ p.tmplInsertionModeStack.unshift(InsertionMode.IN_TEMPLATE);
+ break;
+ }
+ case $.HEAD: {
+ p._err(token, ERR.misplacedStartTagForHeadElement);
+ break;
+ }
+ default: {
+ tokenInHead(p, token);
+ }
+ }
+}
+function endTagInHead(p, token) {
+ switch (token.tagID) {
+ case $.HEAD: {
+ p.openElements.pop();
+ p.insertionMode = InsertionMode.AFTER_HEAD;
+ break;
+ }
+ case $.BODY:
+ case $.BR:
+ case $.HTML: {
+ tokenInHead(p, token);
+ break;
+ }
+ case $.TEMPLATE: {
+ templateEndTagInHead(p, token);
+ break;
+ }
+ default: {
+ p._err(token, ERR.endTagWithoutMatchingOpenElement);
+ }
+ }
+}
+function templateEndTagInHead(p, token) {
+ if (p.openElements.tmplCount > 0) {
+ p.openElements.generateImpliedEndTagsThoroughly();
+ if (p.openElements.currentTagId !== $.TEMPLATE) {
+ p._err(token, ERR.closingOfElementWithOpenChildElements);
+ }
+ p.openElements.popUntilTagNamePopped($.TEMPLATE);
+ p.activeFormattingElements.clearToLastMarker();
+ p.tmplInsertionModeStack.shift();
+ p._resetInsertionMode();
+ }
+ else {
+ p._err(token, ERR.endTagWithoutMatchingOpenElement);
+ }
+}
+function tokenInHead(p, token) {
+ p.openElements.pop();
+ p.insertionMode = InsertionMode.AFTER_HEAD;
+ p._processToken(token);
+}
+// The "in head no script" insertion mode
+//------------------------------------------------------------------
+function startTagInHeadNoScript(p, token) {
+ switch (token.tagID) {
+ case $.HTML: {
+ startTagInBody(p, token);
+ break;
+ }
+ case $.BASEFONT:
+ case $.BGSOUND:
+ case $.HEAD:
+ case $.LINK:
+ case $.META:
+ case $.NOFRAMES:
+ case $.STYLE: {
+ startTagInHead(p, token);
+ break;
+ }
+ case $.NOSCRIPT: {
+ p._err(token, ERR.nestedNoscriptInHead);
+ break;
+ }
+ default: {
+ tokenInHeadNoScript(p, token);
+ }
+ }
+}
+function endTagInHeadNoScript(p, token) {
+ switch (token.tagID) {
+ case $.NOSCRIPT: {
+ p.openElements.pop();
+ p.insertionMode = InsertionMode.IN_HEAD;
+ break;
+ }
+ case $.BR: {
+ tokenInHeadNoScript(p, token);
+ break;
+ }
+ default: {
+ p._err(token, ERR.endTagWithoutMatchingOpenElement);
+ }
+ }
+}
+function tokenInHeadNoScript(p, token) {
+ const errCode = token.type === TokenType.EOF ? ERR.openElementsLeftAfterEof : ERR.disallowedContentInNoscriptInHead;
+ p._err(token, errCode);
+ p.openElements.pop();
+ p.insertionMode = InsertionMode.IN_HEAD;
+ p._processToken(token);
+}
+// The "after head" insertion mode
+//------------------------------------------------------------------
+function startTagAfterHead(p, token) {
+ switch (token.tagID) {
+ case $.HTML: {
+ startTagInBody(p, token);
+ break;
+ }
+ case $.BODY: {
+ p._insertElement(token, NS.HTML);
+ p.framesetOk = false;
+ p.insertionMode = InsertionMode.IN_BODY;
+ break;
+ }
+ case $.FRAMESET: {
+ p._insertElement(token, NS.HTML);
+ p.insertionMode = InsertionMode.IN_FRAMESET;
+ break;
+ }
+ case $.BASE:
+ case $.BASEFONT:
+ case $.BGSOUND:
+ case $.LINK:
+ case $.META:
+ case $.NOFRAMES:
+ case $.SCRIPT:
+ case $.STYLE:
+ case $.TEMPLATE:
+ case $.TITLE: {
+ p._err(token, ERR.abandonedHeadElementChild);
+ p.openElements.push(p.headElement, $.HEAD);
+ startTagInHead(p, token);
+ p.openElements.remove(p.headElement);
+ break;
+ }
+ case $.HEAD: {
+ p._err(token, ERR.misplacedStartTagForHeadElement);
+ break;
+ }
+ default: {
+ tokenAfterHead(p, token);
+ }
+ }
+}
+function endTagAfterHead(p, token) {
+ switch (token.tagID) {
+ case $.BODY:
+ case $.HTML:
+ case $.BR: {
+ tokenAfterHead(p, token);
+ break;
+ }
+ case $.TEMPLATE: {
+ templateEndTagInHead(p, token);
+ break;
+ }
+ default: {
+ p._err(token, ERR.endTagWithoutMatchingOpenElement);
+ }
+ }
+}
+function tokenAfterHead(p, token) {
+ p._insertFakeElement(TN.BODY, $.BODY);
+ p.insertionMode = InsertionMode.IN_BODY;
+ modeInBody(p, token);
+}
+// The "in body" insertion mode
+//------------------------------------------------------------------
+function modeInBody(p, token) {
+ switch (token.type) {
+ case TokenType.CHARACTER: {
+ characterInBody(p, token);
+ break;
+ }
+ case TokenType.WHITESPACE_CHARACTER: {
+ whitespaceCharacterInBody(p, token);
+ break;
+ }
+ case TokenType.COMMENT: {
+ appendComment(p, token);
+ break;
+ }
+ case TokenType.START_TAG: {
+ startTagInBody(p, token);
+ break;
+ }
+ case TokenType.END_TAG: {
+ endTagInBody(p, token);
+ break;
+ }
+ case TokenType.EOF: {
+ eofInBody(p, token);
+ break;
+ }
+ default:
+ // Do nothing
+ }
+}
+function whitespaceCharacterInBody(p, token) {
+ p._reconstructActiveFormattingElements();
+ p._insertCharacters(token);
+}
+function characterInBody(p, token) {
+ p._reconstructActiveFormattingElements();
+ p._insertCharacters(token);
+ p.framesetOk = false;
+}
+function htmlStartTagInBody(p, token) {
+ if (p.openElements.tmplCount === 0) {
+ p.treeAdapter.adoptAttributes(p.openElements.items[0], token.attrs);
+ }
+}
+function bodyStartTagInBody(p, token) {
+ const bodyElement = p.openElements.tryPeekProperlyNestedBodyElement();
+ if (bodyElement && p.openElements.tmplCount === 0) {
+ p.framesetOk = false;
+ p.treeAdapter.adoptAttributes(bodyElement, token.attrs);
+ }
+}
+function framesetStartTagInBody(p, token) {
+ const bodyElement = p.openElements.tryPeekProperlyNestedBodyElement();
+ if (p.framesetOk && bodyElement) {
+ p.treeAdapter.detachNode(bodyElement);
+ p.openElements.popAllUpToHtmlElement();
+ p._insertElement(token, NS.HTML);
+ p.insertionMode = InsertionMode.IN_FRAMESET;
+ }
+}
+function addressStartTagInBody(p, token) {
+ if (p.openElements.hasInButtonScope($.P)) {
+ p._closePElement();
+ }
+ p._insertElement(token, NS.HTML);
+}
+function numberedHeaderStartTagInBody(p, token) {
+ if (p.openElements.hasInButtonScope($.P)) {
+ p._closePElement();
+ }
+ if (isNumberedHeader(p.openElements.currentTagId)) {
+ p.openElements.pop();
+ }
+ p._insertElement(token, NS.HTML);
+}
+function preStartTagInBody(p, token) {
+ if (p.openElements.hasInButtonScope($.P)) {
+ p._closePElement();
+ }
+ p._insertElement(token, NS.HTML);
+ //NOTE: If the next token is a U+000A LINE FEED (LF) character token, then ignore that token and move
+ //on to the next one. (Newlines at the start of pre blocks are ignored as an authoring convenience.)
+ p.skipNextNewLine = true;
+ p.framesetOk = false;
+}
+function formStartTagInBody(p, token) {
+ const inTemplate = p.openElements.tmplCount > 0;
+ if (!p.formElement || inTemplate) {
+ if (p.openElements.hasInButtonScope($.P)) {
+ p._closePElement();
+ }
+ p._insertElement(token, NS.HTML);
+ if (!inTemplate) {
+ p.formElement = p.openElements.current;
+ }
+ }
+}
+function listItemStartTagInBody(p, token) {
+ p.framesetOk = false;
+ const tn = token.tagID;
+ for (let i = p.openElements.stackTop; i >= 0; i--) {
+ const elementId = p.openElements.tagIDs[i];
+ if ((tn === $.LI && elementId === $.LI) ||
+ ((tn === $.DD || tn === $.DT) && (elementId === $.DD || elementId === $.DT))) {
+ p.openElements.generateImpliedEndTagsWithExclusion(elementId);
+ p.openElements.popUntilTagNamePopped(elementId);
+ break;
+ }
+ if (elementId !== $.ADDRESS &&
+ elementId !== $.DIV &&
+ elementId !== $.P &&
+ p._isSpecialElement(p.openElements.items[i], elementId)) {
+ break;
+ }
+ }
+ if (p.openElements.hasInButtonScope($.P)) {
+ p._closePElement();
+ }
+ p._insertElement(token, NS.HTML);
+}
+function plaintextStartTagInBody(p, token) {
+ if (p.openElements.hasInButtonScope($.P)) {
+ p._closePElement();
+ }
+ p._insertElement(token, NS.HTML);
+ p.tokenizer.state = TokenizerMode.PLAINTEXT;
+}
+function buttonStartTagInBody(p, token) {
+ if (p.openElements.hasInScope($.BUTTON)) {
+ p.openElements.generateImpliedEndTags();
+ p.openElements.popUntilTagNamePopped($.BUTTON);
+ }
+ p._reconstructActiveFormattingElements();
+ p._insertElement(token, NS.HTML);
+ p.framesetOk = false;
+}
+function aStartTagInBody(p, token) {
+ const activeElementEntry = p.activeFormattingElements.getElementEntryInScopeWithTagName(TN.A);
+ if (activeElementEntry) {
+ callAdoptionAgency(p, token);
+ p.openElements.remove(activeElementEntry.element);
+ p.activeFormattingElements.removeEntry(activeElementEntry);
+ }
+ p._reconstructActiveFormattingElements();
+ p._insertElement(token, NS.HTML);
+ p.activeFormattingElements.pushElement(p.openElements.current, token);
+}
+function bStartTagInBody(p, token) {
+ p._reconstructActiveFormattingElements();
+ p._insertElement(token, NS.HTML);
+ p.activeFormattingElements.pushElement(p.openElements.current, token);
+}
+function nobrStartTagInBody(p, token) {
+ p._reconstructActiveFormattingElements();
+ if (p.openElements.hasInScope($.NOBR)) {
+ callAdoptionAgency(p, token);
+ p._reconstructActiveFormattingElements();
+ }
+ p._insertElement(token, NS.HTML);
+ p.activeFormattingElements.pushElement(p.openElements.current, token);
+}
+function appletStartTagInBody(p, token) {
+ p._reconstructActiveFormattingElements();
+ p._insertElement(token, NS.HTML);
+ p.activeFormattingElements.insertMarker();
+ p.framesetOk = false;
+}
+function tableStartTagInBody(p, token) {
+ if (p.treeAdapter.getDocumentMode(p.document) !== DOCUMENT_MODE.QUIRKS && p.openElements.hasInButtonScope($.P)) {
+ p._closePElement();
+ }
+ p._insertElement(token, NS.HTML);
+ p.framesetOk = false;
+ p.insertionMode = InsertionMode.IN_TABLE;
+}
+function areaStartTagInBody(p, token) {
+ p._reconstructActiveFormattingElements();
+ p._appendElement(token, NS.HTML);
+ p.framesetOk = false;
+ token.ackSelfClosing = true;
+}
+function isHiddenInput(token) {
+ const inputType = getTokenAttr(token, ATTRS.TYPE);
+ return inputType != null && inputType.toLowerCase() === HIDDEN_INPUT_TYPE;
+}
+function inputStartTagInBody(p, token) {
+ p._reconstructActiveFormattingElements();
+ p._appendElement(token, NS.HTML);
+ if (!isHiddenInput(token)) {
+ p.framesetOk = false;
+ }
+ token.ackSelfClosing = true;
+}
+function paramStartTagInBody(p, token) {
+ p._appendElement(token, NS.HTML);
+ token.ackSelfClosing = true;
+}
+function hrStartTagInBody(p, token) {
+ if (p.openElements.hasInButtonScope($.P)) {
+ p._closePElement();
+ }
+ p._appendElement(token, NS.HTML);
+ p.framesetOk = false;
+ token.ackSelfClosing = true;
+}
+function imageStartTagInBody(p, token) {
+ token.tagName = TN.IMG;
+ token.tagID = $.IMG;
+ areaStartTagInBody(p, token);
+}
+function textareaStartTagInBody(p, token) {
+ p._insertElement(token, NS.HTML);
+ //NOTE: If the next token is a U+000A LINE FEED (LF) character token, then ignore that token and move
+ //on to the next one. (Newlines at the start of textarea elements are ignored as an authoring convenience.)
+ p.skipNextNewLine = true;
+ p.tokenizer.state = TokenizerMode.RCDATA;
+ p.originalInsertionMode = p.insertionMode;
+ p.framesetOk = false;
+ p.insertionMode = InsertionMode.TEXT;
+}
+function xmpStartTagInBody(p, token) {
+ if (p.openElements.hasInButtonScope($.P)) {
+ p._closePElement();
+ }
+ p._reconstructActiveFormattingElements();
+ p.framesetOk = false;
+ p._switchToTextParsing(token, TokenizerMode.RAWTEXT);
+}
+function iframeStartTagInBody(p, token) {
+ p.framesetOk = false;
+ p._switchToTextParsing(token, TokenizerMode.RAWTEXT);
+}
+//NOTE: here we assume that we always act as an user agent with enabled plugins, so we parse
+//<noembed> as rawtext.
+function noembedStartTagInBody(p, token) {
+ p._switchToTextParsing(token, TokenizerMode.RAWTEXT);
+}
+function selectStartTagInBody(p, token) {
+ p._reconstructActiveFormattingElements();
+ p._insertElement(token, NS.HTML);
+ p.framesetOk = false;
+ p.insertionMode =
+ p.insertionMode === InsertionMode.IN_TABLE ||
+ p.insertionMode === InsertionMode.IN_CAPTION ||
+ p.insertionMode === InsertionMode.IN_TABLE_BODY ||
+ p.insertionMode === InsertionMode.IN_ROW ||
+ p.insertionMode === InsertionMode.IN_CELL
+ ? InsertionMode.IN_SELECT_IN_TABLE
+ : InsertionMode.IN_SELECT;
+}
+function optgroupStartTagInBody(p, token) {
+ if (p.openElements.currentTagId === $.OPTION) {
+ p.openElements.pop();
+ }
+ p._reconstructActiveFormattingElements();
+ p._insertElement(token, NS.HTML);
+}
+function rbStartTagInBody(p, token) {
+ if (p.openElements.hasInScope($.RUBY)) {
+ p.openElements.generateImpliedEndTags();
+ }
+ p._insertElement(token, NS.HTML);
+}
+function rtStartTagInBody(p, token) {
+ if (p.openElements.hasInScope($.RUBY)) {
+ p.openElements.generateImpliedEndTagsWithExclusion($.RTC);
+ }
+ p._insertElement(token, NS.HTML);
+}
+function mathStartTagInBody(p, token) {
+ p._reconstructActiveFormattingElements();
+ foreignContent.adjustTokenMathMLAttrs(token);
+ foreignContent.adjustTokenXMLAttrs(token);
+ if (token.selfClosing) {
+ p._appendElement(token, NS.MATHML);
+ }
+ else {
+ p._insertElement(token, NS.MATHML);
+ }
+ token.ackSelfClosing = true;
+}
+function svgStartTagInBody(p, token) {
+ p._reconstructActiveFormattingElements();
+ foreignContent.adjustTokenSVGAttrs(token);
+ foreignContent.adjustTokenXMLAttrs(token);
+ if (token.selfClosing) {
+ p._appendElement(token, NS.SVG);
+ }
+ else {
+ p._insertElement(token, NS.SVG);
+ }
+ token.ackSelfClosing = true;
+}
+function genericStartTagInBody(p, token) {
+ p._reconstructActiveFormattingElements();
+ p._insertElement(token, NS.HTML);
+}
+function startTagInBody(p, token) {
+ switch (token.tagID) {
+ case $.I:
+ case $.S:
+ case $.B:
+ case $.U:
+ case $.EM:
+ case $.TT:
+ case $.BIG:
+ case $.CODE:
+ case $.FONT:
+ case $.SMALL:
+ case $.STRIKE:
+ case $.STRONG: {
+ bStartTagInBody(p, token);
+ break;
+ }
+ case $.A: {
+ aStartTagInBody(p, token);
+ break;
+ }
+ case $.H1:
+ case $.H2:
+ case $.H3:
+ case $.H4:
+ case $.H5:
+ case $.H6: {
+ numberedHeaderStartTagInBody(p, token);
+ break;
+ }
+ case $.P:
+ case $.DL:
+ case $.OL:
+ case $.UL:
+ case $.DIV:
+ case $.DIR:
+ case $.NAV:
+ case $.MAIN:
+ case $.MENU:
+ case $.ASIDE:
+ case $.CENTER:
+ case $.FIGURE:
+ case $.FOOTER:
+ case $.HEADER:
+ case $.HGROUP:
+ case $.DIALOG:
+ case $.DETAILS:
+ case $.ADDRESS:
+ case $.ARTICLE:
+ case $.SECTION:
+ case $.SUMMARY:
+ case $.FIELDSET:
+ case $.BLOCKQUOTE:
+ case $.FIGCAPTION: {
+ addressStartTagInBody(p, token);
+ break;
+ }
+ case $.LI:
+ case $.DD:
+ case $.DT: {
+ listItemStartTagInBody(p, token);
+ break;
+ }
+ case $.BR:
+ case $.IMG:
+ case $.WBR:
+ case $.AREA:
+ case $.EMBED:
+ case $.KEYGEN: {
+ areaStartTagInBody(p, token);
+ break;
+ }
+ case $.HR: {
+ hrStartTagInBody(p, token);
+ break;
+ }
+ case $.RB:
+ case $.RTC: {
+ rbStartTagInBody(p, token);
+ break;
+ }
+ case $.RT:
+ case $.RP: {
+ rtStartTagInBody(p, token);
+ break;
+ }
+ case $.PRE:
+ case $.LISTING: {
+ preStartTagInBody(p, token);
+ break;
+ }
+ case $.XMP: {
+ xmpStartTagInBody(p, token);
+ break;
+ }
+ case $.SVG: {
+ svgStartTagInBody(p, token);
+ break;
+ }
+ case $.HTML: {
+ htmlStartTagInBody(p, token);
+ break;
+ }
+ case $.BASE:
+ case $.LINK:
+ case $.META:
+ case $.STYLE:
+ case $.TITLE:
+ case $.SCRIPT:
+ case $.BGSOUND:
+ case $.BASEFONT:
+ case $.TEMPLATE: {
+ startTagInHead(p, token);
+ break;
+ }
+ case $.BODY: {
+ bodyStartTagInBody(p, token);
+ break;
+ }
+ case $.FORM: {
+ formStartTagInBody(p, token);
+ break;
+ }
+ case $.NOBR: {
+ nobrStartTagInBody(p, token);
+ break;
+ }
+ case $.MATH: {
+ mathStartTagInBody(p, token);
+ break;
+ }
+ case $.TABLE: {
+ tableStartTagInBody(p, token);
+ break;
+ }
+ case $.INPUT: {
+ inputStartTagInBody(p, token);
+ break;
+ }
+ case $.PARAM:
+ case $.TRACK:
+ case $.SOURCE: {
+ paramStartTagInBody(p, token);
+ break;
+ }
+ case $.IMAGE: {
+ imageStartTagInBody(p, token);
+ break;
+ }
+ case $.BUTTON: {
+ buttonStartTagInBody(p, token);
+ break;
+ }
+ case $.APPLET:
+ case $.OBJECT:
+ case $.MARQUEE: {
+ appletStartTagInBody(p, token);
+ break;
+ }
+ case $.IFRAME: {
+ iframeStartTagInBody(p, token);
+ break;
+ }
+ case $.SELECT: {
+ selectStartTagInBody(p, token);
+ break;
+ }
+ case $.OPTION:
+ case $.OPTGROUP: {
+ optgroupStartTagInBody(p, token);
+ break;
+ }
+ case $.NOEMBED: {
+ noembedStartTagInBody(p, token);
+ break;
+ }
+ case $.FRAMESET: {
+ framesetStartTagInBody(p, token);
+ break;
+ }
+ case $.TEXTAREA: {
+ textareaStartTagInBody(p, token);
+ break;
+ }
+ case $.NOSCRIPT: {
+ if (p.options.scriptingEnabled) {
+ noembedStartTagInBody(p, token);
+ }
+ else {
+ genericStartTagInBody(p, token);
+ }
+ break;
+ }
+ case $.PLAINTEXT: {
+ plaintextStartTagInBody(p, token);
+ break;
+ }
+ case $.COL:
+ case $.TH:
+ case $.TD:
+ case $.TR:
+ case $.HEAD:
+ case $.FRAME:
+ case $.TBODY:
+ case $.TFOOT:
+ case $.THEAD:
+ case $.CAPTION:
+ case $.COLGROUP: {
+ // Ignore token
+ break;
+ }
+ default: {
+ genericStartTagInBody(p, token);
+ }
+ }
+}
+function bodyEndTagInBody(p, token) {
+ if (p.openElements.hasInScope($.BODY)) {
+ p.insertionMode = InsertionMode.AFTER_BODY;
+ //NOTE: <body> is never popped from the stack, so we need to updated
+ //the end location explicitly.
+ if (p.options.sourceCodeLocationInfo) {
+ const bodyElement = p.openElements.tryPeekProperlyNestedBodyElement();
+ if (bodyElement) {
+ p._setEndLocation(bodyElement, token);
+ }
+ }
+ }
+}
+function htmlEndTagInBody(p, token) {
+ if (p.openElements.hasInScope($.BODY)) {
+ p.insertionMode = InsertionMode.AFTER_BODY;
+ endTagAfterBody(p, token);
+ }
+}
+function addressEndTagInBody(p, token) {
+ const tn = token.tagID;
+ if (p.openElements.hasInScope(tn)) {
+ p.openElements.generateImpliedEndTags();
+ p.openElements.popUntilTagNamePopped(tn);
+ }
+}
+function formEndTagInBody(p) {
+ const inTemplate = p.openElements.tmplCount > 0;
+ const { formElement } = p;
+ if (!inTemplate) {
+ p.formElement = null;
+ }
+ if ((formElement || inTemplate) && p.openElements.hasInScope($.FORM)) {
+ p.openElements.generateImpliedEndTags();
+ if (inTemplate) {
+ p.openElements.popUntilTagNamePopped($.FORM);
+ }
+ else if (formElement) {
+ p.openElements.remove(formElement);
+ }
+ }
+}
+function pEndTagInBody(p) {
+ if (!p.openElements.hasInButtonScope($.P)) {
+ p._insertFakeElement(TN.P, $.P);
+ }
+ p._closePElement();
+}
+function liEndTagInBody(p) {
+ if (p.openElements.hasInListItemScope($.LI)) {
+ p.openElements.generateImpliedEndTagsWithExclusion($.LI);
+ p.openElements.popUntilTagNamePopped($.LI);
+ }
+}
+function ddEndTagInBody(p, token) {
+ const tn = token.tagID;
+ if (p.openElements.hasInScope(tn)) {
+ p.openElements.generateImpliedEndTagsWithExclusion(tn);
+ p.openElements.popUntilTagNamePopped(tn);
+ }
+}
+function numberedHeaderEndTagInBody(p) {
+ if (p.openElements.hasNumberedHeaderInScope()) {
+ p.openElements.generateImpliedEndTags();
+ p.openElements.popUntilNumberedHeaderPopped();
+ }
+}
+function appletEndTagInBody(p, token) {
+ const tn = token.tagID;
+ if (p.openElements.hasInScope(tn)) {
+ p.openElements.generateImpliedEndTags();
+ p.openElements.popUntilTagNamePopped(tn);
+ p.activeFormattingElements.clearToLastMarker();
+ }
+}
+function brEndTagInBody(p) {
+ p._reconstructActiveFormattingElements();
+ p._insertFakeElement(TN.BR, $.BR);
+ p.openElements.pop();
+ p.framesetOk = false;
+}
+function genericEndTagInBody(p, token) {
+ const tn = token.tagName;
+ const tid = token.tagID;
+ for (let i = p.openElements.stackTop; i > 0; i--) {
+ const element = p.openElements.items[i];
+ const elementId = p.openElements.tagIDs[i];
+ // Compare the tag name here, as the tag might not be a known tag with an ID.
+ if (tid === elementId && (tid !== $.UNKNOWN || p.treeAdapter.getTagName(element) === tn)) {
+ p.openElements.generateImpliedEndTagsWithExclusion(tid);
+ if (p.openElements.stackTop >= i)
+ p.openElements.shortenToLength(i);
+ break;
+ }
+ if (p._isSpecialElement(element, elementId)) {
+ break;
+ }
+ }
+}
+function endTagInBody(p, token) {
+ switch (token.tagID) {
+ case $.A:
+ case $.B:
+ case $.I:
+ case $.S:
+ case $.U:
+ case $.EM:
+ case $.TT:
+ case $.BIG:
+ case $.CODE:
+ case $.FONT:
+ case $.NOBR:
+ case $.SMALL:
+ case $.STRIKE:
+ case $.STRONG: {
+ callAdoptionAgency(p, token);
+ break;
+ }
+ case $.P: {
+ pEndTagInBody(p);
+ break;
+ }
+ case $.DL:
+ case $.UL:
+ case $.OL:
+ case $.DIR:
+ case $.DIV:
+ case $.NAV:
+ case $.PRE:
+ case $.MAIN:
+ case $.MENU:
+ case $.ASIDE:
+ case $.BUTTON:
+ case $.CENTER:
+ case $.FIGURE:
+ case $.FOOTER:
+ case $.HEADER:
+ case $.HGROUP:
+ case $.DIALOG:
+ case $.ADDRESS:
+ case $.ARTICLE:
+ case $.DETAILS:
+ case $.SECTION:
+ case $.SUMMARY:
+ case $.LISTING:
+ case $.FIELDSET:
+ case $.BLOCKQUOTE:
+ case $.FIGCAPTION: {
+ addressEndTagInBody(p, token);
+ break;
+ }
+ case $.LI: {
+ liEndTagInBody(p);
+ break;
+ }
+ case $.DD:
+ case $.DT: {
+ ddEndTagInBody(p, token);
+ break;
+ }
+ case $.H1:
+ case $.H2:
+ case $.H3:
+ case $.H4:
+ case $.H5:
+ case $.H6: {
+ numberedHeaderEndTagInBody(p);
+ break;
+ }
+ case $.BR: {
+ brEndTagInBody(p);
+ break;
+ }
+ case $.BODY: {
+ bodyEndTagInBody(p, token);
+ break;
+ }
+ case $.HTML: {
+ htmlEndTagInBody(p, token);
+ break;
+ }
+ case $.FORM: {
+ formEndTagInBody(p);
+ break;
+ }
+ case $.APPLET:
+ case $.OBJECT:
+ case $.MARQUEE: {
+ appletEndTagInBody(p, token);
+ break;
+ }
+ case $.TEMPLATE: {
+ templateEndTagInHead(p, token);
+ break;
+ }
+ default: {
+ genericEndTagInBody(p, token);
+ }
+ }
+}
+function eofInBody(p, token) {
+ if (p.tmplInsertionModeStack.length > 0) {
+ eofInTemplate(p, token);
+ }
+ else {
+ stopParsing(p, token);
+ }
+}
+// The "text" insertion mode
+//------------------------------------------------------------------
+function endTagInText(p, token) {
+ var _a;
+ if (token.tagID === $.SCRIPT) {
+ (_a = p.scriptHandler) === null || _a === void 0 ? void 0 : _a.call(p, p.openElements.current);
+ }
+ p.openElements.pop();
+ p.insertionMode = p.originalInsertionMode;
+}
+function eofInText(p, token) {
+ p._err(token, ERR.eofInElementThatCanContainOnlyText);
+ p.openElements.pop();
+ p.insertionMode = p.originalInsertionMode;
+ p.onEof(token);
+}
+// The "in table" insertion mode
+//------------------------------------------------------------------
+function characterInTable(p, token) {
+ if (TABLE_STRUCTURE_TAGS.has(p.openElements.currentTagId)) {
+ p.pendingCharacterTokens.length = 0;
+ p.hasNonWhitespacePendingCharacterToken = false;
+ p.originalInsertionMode = p.insertionMode;
+ p.insertionMode = InsertionMode.IN_TABLE_TEXT;
+ switch (token.type) {
+ case TokenType.CHARACTER: {
+ characterInTableText(p, token);
+ break;
+ }
+ case TokenType.WHITESPACE_CHARACTER: {
+ whitespaceCharacterInTableText(p, token);
+ break;
+ }
+ // Ignore null
+ }
+ }
+ else {
+ tokenInTable(p, token);
+ }
+}
+function captionStartTagInTable(p, token) {
+ p.openElements.clearBackToTableContext();
+ p.activeFormattingElements.insertMarker();
+ p._insertElement(token, NS.HTML);
+ p.insertionMode = InsertionMode.IN_CAPTION;
+}
+function colgroupStartTagInTable(p, token) {
+ p.openElements.clearBackToTableContext();
+ p._insertElement(token, NS.HTML);
+ p.insertionMode = InsertionMode.IN_COLUMN_GROUP;
+}
+function colStartTagInTable(p, token) {
+ p.openElements.clearBackToTableContext();
+ p._insertFakeElement(TN.COLGROUP, $.COLGROUP);
+ p.insertionMode = InsertionMode.IN_COLUMN_GROUP;
+ startTagInColumnGroup(p, token);
+}
+function tbodyStartTagInTable(p, token) {
+ p.openElements.clearBackToTableContext();
+ p._insertElement(token, NS.HTML);
+ p.insertionMode = InsertionMode.IN_TABLE_BODY;
+}
+function tdStartTagInTable(p, token) {
+ p.openElements.clearBackToTableContext();
+ p._insertFakeElement(TN.TBODY, $.TBODY);
+ p.insertionMode = InsertionMode.IN_TABLE_BODY;
+ startTagInTableBody(p, token);
+}
+function tableStartTagInTable(p, token) {
+ if (p.openElements.hasInTableScope($.TABLE)) {
+ p.openElements.popUntilTagNamePopped($.TABLE);
+ p._resetInsertionMode();
+ p._processStartTag(token);
+ }
+}
+function inputStartTagInTable(p, token) {
+ if (isHiddenInput(token)) {
+ p._appendElement(token, NS.HTML);
+ }
+ else {
+ tokenInTable(p, token);
+ }
+ token.ackSelfClosing = true;
+}
+function formStartTagInTable(p, token) {
+ if (!p.formElement && p.openElements.tmplCount === 0) {
+ p._insertElement(token, NS.HTML);
+ p.formElement = p.openElements.current;
+ p.openElements.pop();
+ }
+}
+function startTagInTable(p, token) {
+ switch (token.tagID) {
+ case $.TD:
+ case $.TH:
+ case $.TR: {
+ tdStartTagInTable(p, token);
+ break;
+ }
+ case $.STYLE:
+ case $.SCRIPT:
+ case $.TEMPLATE: {
+ startTagInHead(p, token);
+ break;
+ }
+ case $.COL: {
+ colStartTagInTable(p, token);
+ break;
+ }
+ case $.FORM: {
+ formStartTagInTable(p, token);
+ break;
+ }
+ case $.TABLE: {
+ tableStartTagInTable(p, token);
+ break;
+ }
+ case $.TBODY:
+ case $.TFOOT:
+ case $.THEAD: {
+ tbodyStartTagInTable(p, token);
+ break;
+ }
+ case $.INPUT: {
+ inputStartTagInTable(p, token);
+ break;
+ }
+ case $.CAPTION: {
+ captionStartTagInTable(p, token);
+ break;
+ }
+ case $.COLGROUP: {
+ colgroupStartTagInTable(p, token);
+ break;
+ }
+ default: {
+ tokenInTable(p, token);
+ }
+ }
+}
+function endTagInTable(p, token) {
+ switch (token.tagID) {
+ case $.TABLE: {
+ if (p.openElements.hasInTableScope($.TABLE)) {
+ p.openElements.popUntilTagNamePopped($.TABLE);
+ p._resetInsertionMode();
+ }
+ break;
+ }
+ case $.TEMPLATE: {
+ templateEndTagInHead(p, token);
+ break;
+ }
+ case $.BODY:
+ case $.CAPTION:
+ case $.COL:
+ case $.COLGROUP:
+ case $.HTML:
+ case $.TBODY:
+ case $.TD:
+ case $.TFOOT:
+ case $.TH:
+ case $.THEAD:
+ case $.TR: {
+ // Ignore token
+ break;
+ }
+ default: {
+ tokenInTable(p, token);
+ }
+ }
+}
+function tokenInTable(p, token) {
+ const savedFosterParentingState = p.fosterParentingEnabled;
+ p.fosterParentingEnabled = true;
+ // Process token in `In Body` mode
+ modeInBody(p, token);
+ p.fosterParentingEnabled = savedFosterParentingState;
+}
+// The "in table text" insertion mode
+//------------------------------------------------------------------
+function whitespaceCharacterInTableText(p, token) {
+ p.pendingCharacterTokens.push(token);
+}
+function characterInTableText(p, token) {
+ p.pendingCharacterTokens.push(token);
+ p.hasNonWhitespacePendingCharacterToken = true;
+}
+function tokenInTableText(p, token) {
+ let i = 0;
+ if (p.hasNonWhitespacePendingCharacterToken) {
+ for (; i < p.pendingCharacterTokens.length; i++) {
+ tokenInTable(p, p.pendingCharacterTokens[i]);
+ }
+ }
+ else {
+ for (; i < p.pendingCharacterTokens.length; i++) {
+ p._insertCharacters(p.pendingCharacterTokens[i]);
+ }
+ }
+ p.insertionMode = p.originalInsertionMode;
+ p._processToken(token);
+}
+// The "in caption" insertion mode
+//------------------------------------------------------------------
+const TABLE_VOID_ELEMENTS = new Set([$.CAPTION, $.COL, $.COLGROUP, $.TBODY, $.TD, $.TFOOT, $.TH, $.THEAD, $.TR]);
+function startTagInCaption(p, token) {
+ const tn = token.tagID;
+ if (TABLE_VOID_ELEMENTS.has(tn)) {
+ if (p.openElements.hasInTableScope($.CAPTION)) {
+ p.openElements.generateImpliedEndTags();
+ p.openElements.popUntilTagNamePopped($.CAPTION);
+ p.activeFormattingElements.clearToLastMarker();
+ p.insertionMode = InsertionMode.IN_TABLE;
+ startTagInTable(p, token);
+ }
+ }
+ else {
+ startTagInBody(p, token);
+ }
+}
+function endTagInCaption(p, token) {
+ const tn = token.tagID;
+ switch (tn) {
+ case $.CAPTION:
+ case $.TABLE: {
+ if (p.openElements.hasInTableScope($.CAPTION)) {
+ p.openElements.generateImpliedEndTags();
+ p.openElements.popUntilTagNamePopped($.CAPTION);
+ p.activeFormattingElements.clearToLastMarker();
+ p.insertionMode = InsertionMode.IN_TABLE;
+ if (tn === $.TABLE) {
+ endTagInTable(p, token);
+ }
+ }
+ break;
+ }
+ case $.BODY:
+ case $.COL:
+ case $.COLGROUP:
+ case $.HTML:
+ case $.TBODY:
+ case $.TD:
+ case $.TFOOT:
+ case $.TH:
+ case $.THEAD:
+ case $.TR: {
+ // Ignore token
+ break;
+ }
+ default: {
+ endTagInBody(p, token);
+ }
+ }
+}
+// The "in column group" insertion mode
+//------------------------------------------------------------------
+function startTagInColumnGroup(p, token) {
+ switch (token.tagID) {
+ case $.HTML: {
+ startTagInBody(p, token);
+ break;
+ }
+ case $.COL: {
+ p._appendElement(token, NS.HTML);
+ token.ackSelfClosing = true;
+ break;
+ }
+ case $.TEMPLATE: {
+ startTagInHead(p, token);
+ break;
+ }
+ default: {
+ tokenInColumnGroup(p, token);
+ }
+ }
+}
+function endTagInColumnGroup(p, token) {
+ switch (token.tagID) {
+ case $.COLGROUP: {
+ if (p.openElements.currentTagId === $.COLGROUP) {
+ p.openElements.pop();
+ p.insertionMode = InsertionMode.IN_TABLE;
+ }
+ break;
+ }
+ case $.TEMPLATE: {
+ templateEndTagInHead(p, token);
+ break;
+ }
+ case $.COL: {
+ // Ignore token
+ break;
+ }
+ default: {
+ tokenInColumnGroup(p, token);
+ }
+ }
+}
+function tokenInColumnGroup(p, token) {
+ if (p.openElements.currentTagId === $.COLGROUP) {
+ p.openElements.pop();
+ p.insertionMode = InsertionMode.IN_TABLE;
+ p._processToken(token);
+ }
+}
+// The "in table body" insertion mode
+//------------------------------------------------------------------
+function startTagInTableBody(p, token) {
+ switch (token.tagID) {
+ case $.TR: {
+ p.openElements.clearBackToTableBodyContext();
+ p._insertElement(token, NS.HTML);
+ p.insertionMode = InsertionMode.IN_ROW;
+ break;
+ }
+ case $.TH:
+ case $.TD: {
+ p.openElements.clearBackToTableBodyContext();
+ p._insertFakeElement(TN.TR, $.TR);
+ p.insertionMode = InsertionMode.IN_ROW;
+ startTagInRow(p, token);
+ break;
+ }
+ case $.CAPTION:
+ case $.COL:
+ case $.COLGROUP:
+ case $.TBODY:
+ case $.TFOOT:
+ case $.THEAD: {
+ if (p.openElements.hasTableBodyContextInTableScope()) {
+ p.openElements.clearBackToTableBodyContext();
+ p.openElements.pop();
+ p.insertionMode = InsertionMode.IN_TABLE;
+ startTagInTable(p, token);
+ }
+ break;
+ }
+ default: {
+ startTagInTable(p, token);
+ }
+ }
+}
+function endTagInTableBody(p, token) {
+ const tn = token.tagID;
+ switch (token.tagID) {
+ case $.TBODY:
+ case $.TFOOT:
+ case $.THEAD: {
+ if (p.openElements.hasInTableScope(tn)) {
+ p.openElements.clearBackToTableBodyContext();
+ p.openElements.pop();
+ p.insertionMode = InsertionMode.IN_TABLE;
+ }
+ break;
+ }
+ case $.TABLE: {
+ if (p.openElements.hasTableBodyContextInTableScope()) {
+ p.openElements.clearBackToTableBodyContext();
+ p.openElements.pop();
+ p.insertionMode = InsertionMode.IN_TABLE;
+ endTagInTable(p, token);
+ }
+ break;
+ }
+ case $.BODY:
+ case $.CAPTION:
+ case $.COL:
+ case $.COLGROUP:
+ case $.HTML:
+ case $.TD:
+ case $.TH:
+ case $.TR: {
+ // Ignore token
+ break;
+ }
+ default: {
+ endTagInTable(p, token);
+ }
+ }
+}
+// The "in row" insertion mode
+//------------------------------------------------------------------
+function startTagInRow(p, token) {
+ switch (token.tagID) {
+ case $.TH:
+ case $.TD: {
+ p.openElements.clearBackToTableRowContext();
+ p._insertElement(token, NS.HTML);
+ p.insertionMode = InsertionMode.IN_CELL;
+ p.activeFormattingElements.insertMarker();
+ break;
+ }
+ case $.CAPTION:
+ case $.COL:
+ case $.COLGROUP:
+ case $.TBODY:
+ case $.TFOOT:
+ case $.THEAD:
+ case $.TR: {
+ if (p.openElements.hasInTableScope($.TR)) {
+ p.openElements.clearBackToTableRowContext();
+ p.openElements.pop();
+ p.insertionMode = InsertionMode.IN_TABLE_BODY;
+ startTagInTableBody(p, token);
+ }
+ break;
+ }
+ default: {
+ startTagInTable(p, token);
+ }
+ }
+}
+function endTagInRow(p, token) {
+ switch (token.tagID) {
+ case $.TR: {
+ if (p.openElements.hasInTableScope($.TR)) {
+ p.openElements.clearBackToTableRowContext();
+ p.openElements.pop();
+ p.insertionMode = InsertionMode.IN_TABLE_BODY;
+ }
+ break;
+ }
+ case $.TABLE: {
+ if (p.openElements.hasInTableScope($.TR)) {
+ p.openElements.clearBackToTableRowContext();
+ p.openElements.pop();
+ p.insertionMode = InsertionMode.IN_TABLE_BODY;
+ endTagInTableBody(p, token);
+ }
+ break;
+ }
+ case $.TBODY:
+ case $.TFOOT:
+ case $.THEAD: {
+ if (p.openElements.hasInTableScope(token.tagID) || p.openElements.hasInTableScope($.TR)) {
+ p.openElements.clearBackToTableRowContext();
+ p.openElements.pop();
+ p.insertionMode = InsertionMode.IN_TABLE_BODY;
+ endTagInTableBody(p, token);
+ }
+ break;
+ }
+ case $.BODY:
+ case $.CAPTION:
+ case $.COL:
+ case $.COLGROUP:
+ case $.HTML:
+ case $.TD:
+ case $.TH: {
+ // Ignore end tag
+ break;
+ }
+ default: {
+ endTagInTable(p, token);
+ }
+ }
+}
+// The "in cell" insertion mode
+//------------------------------------------------------------------
+function startTagInCell(p, token) {
+ const tn = token.tagID;
+ if (TABLE_VOID_ELEMENTS.has(tn)) {
+ if (p.openElements.hasInTableScope($.TD) || p.openElements.hasInTableScope($.TH)) {
+ p._closeTableCell();
+ startTagInRow(p, token);
+ }
+ }
+ else {
+ startTagInBody(p, token);
+ }
+}
+function endTagInCell(p, token) {
+ const tn = token.tagID;
+ switch (tn) {
+ case $.TD:
+ case $.TH: {
+ if (p.openElements.hasInTableScope(tn)) {
+ p.openElements.generateImpliedEndTags();
+ p.openElements.popUntilTagNamePopped(tn);
+ p.activeFormattingElements.clearToLastMarker();
+ p.insertionMode = InsertionMode.IN_ROW;
+ }
+ break;
+ }
+ case $.TABLE:
+ case $.TBODY:
+ case $.TFOOT:
+ case $.THEAD:
+ case $.TR: {
+ if (p.openElements.hasInTableScope(tn)) {
+ p._closeTableCell();
+ endTagInRow(p, token);
+ }
+ break;
+ }
+ case $.BODY:
+ case $.CAPTION:
+ case $.COL:
+ case $.COLGROUP:
+ case $.HTML: {
+ // Ignore token
+ break;
+ }
+ default: {
+ endTagInBody(p, token);
+ }
+ }
+}
+// The "in select" insertion mode
+//------------------------------------------------------------------
+function startTagInSelect(p, token) {
+ switch (token.tagID) {
+ case $.HTML: {
+ startTagInBody(p, token);
+ break;
+ }
+ case $.OPTION: {
+ if (p.openElements.currentTagId === $.OPTION) {
+ p.openElements.pop();
+ }
+ p._insertElement(token, NS.HTML);
+ break;
+ }
+ case $.OPTGROUP: {
+ if (p.openElements.currentTagId === $.OPTION) {
+ p.openElements.pop();
+ }
+ if (p.openElements.currentTagId === $.OPTGROUP) {
+ p.openElements.pop();
+ }
+ p._insertElement(token, NS.HTML);
+ break;
+ }
+ case $.INPUT:
+ case $.KEYGEN:
+ case $.TEXTAREA:
+ case $.SELECT: {
+ if (p.openElements.hasInSelectScope($.SELECT)) {
+ p.openElements.popUntilTagNamePopped($.SELECT);
+ p._resetInsertionMode();
+ if (token.tagID !== $.SELECT) {
+ p._processStartTag(token);
+ }
+ }
+ break;
+ }
+ case $.SCRIPT:
+ case $.TEMPLATE: {
+ startTagInHead(p, token);
+ break;
+ }
+ default:
+ // Do nothing
+ }
+}
+function endTagInSelect(p, token) {
+ switch (token.tagID) {
+ case $.OPTGROUP: {
+ if (p.openElements.stackTop > 0 &&
+ p.openElements.currentTagId === $.OPTION &&
+ p.openElements.tagIDs[p.openElements.stackTop - 1] === $.OPTGROUP) {
+ p.openElements.pop();
+ }
+ if (p.openElements.currentTagId === $.OPTGROUP) {
+ p.openElements.pop();
+ }
+ break;
+ }
+ case $.OPTION: {
+ if (p.openElements.currentTagId === $.OPTION) {
+ p.openElements.pop();
+ }
+ break;
+ }
+ case $.SELECT: {
+ if (p.openElements.hasInSelectScope($.SELECT)) {
+ p.openElements.popUntilTagNamePopped($.SELECT);
+ p._resetInsertionMode();
+ }
+ break;
+ }
+ case $.TEMPLATE: {
+ templateEndTagInHead(p, token);
+ break;
+ }
+ default:
+ // Do nothing
+ }
+}
+// The "in select in table" insertion mode
+//------------------------------------------------------------------
+function startTagInSelectInTable(p, token) {
+ const tn = token.tagID;
+ if (tn === $.CAPTION ||
+ tn === $.TABLE ||
+ tn === $.TBODY ||
+ tn === $.TFOOT ||
+ tn === $.THEAD ||
+ tn === $.TR ||
+ tn === $.TD ||
+ tn === $.TH) {
+ p.openElements.popUntilTagNamePopped($.SELECT);
+ p._resetInsertionMode();
+ p._processStartTag(token);
+ }
+ else {
+ startTagInSelect(p, token);
+ }
+}
+function endTagInSelectInTable(p, token) {
+ const tn = token.tagID;
+ if (tn === $.CAPTION ||
+ tn === $.TABLE ||
+ tn === $.TBODY ||
+ tn === $.TFOOT ||
+ tn === $.THEAD ||
+ tn === $.TR ||
+ tn === $.TD ||
+ tn === $.TH) {
+ if (p.openElements.hasInTableScope(tn)) {
+ p.openElements.popUntilTagNamePopped($.SELECT);
+ p._resetInsertionMode();
+ p.onEndTag(token);
+ }
+ }
+ else {
+ endTagInSelect(p, token);
+ }
+}
+// The "in template" insertion mode
+//------------------------------------------------------------------
+function startTagInTemplate(p, token) {
+ switch (token.tagID) {
+ // First, handle tags that can start without a mode change
+ case $.BASE:
+ case $.BASEFONT:
+ case $.BGSOUND:
+ case $.LINK:
+ case $.META:
+ case $.NOFRAMES:
+ case $.SCRIPT:
+ case $.STYLE:
+ case $.TEMPLATE:
+ case $.TITLE: {
+ startTagInHead(p, token);
+ break;
+ }
+ // Re-process the token in the appropriate mode
+ case $.CAPTION:
+ case $.COLGROUP:
+ case $.TBODY:
+ case $.TFOOT:
+ case $.THEAD: {
+ p.tmplInsertionModeStack[0] = InsertionMode.IN_TABLE;
+ p.insertionMode = InsertionMode.IN_TABLE;
+ startTagInTable(p, token);
+ break;
+ }
+ case $.COL: {
+ p.tmplInsertionModeStack[0] = InsertionMode.IN_COLUMN_GROUP;
+ p.insertionMode = InsertionMode.IN_COLUMN_GROUP;
+ startTagInColumnGroup(p, token);
+ break;
+ }
+ case $.TR: {
+ p.tmplInsertionModeStack[0] = InsertionMode.IN_TABLE_BODY;
+ p.insertionMode = InsertionMode.IN_TABLE_BODY;
+ startTagInTableBody(p, token);
+ break;
+ }
+ case $.TD:
+ case $.TH: {
+ p.tmplInsertionModeStack[0] = InsertionMode.IN_ROW;
+ p.insertionMode = InsertionMode.IN_ROW;
+ startTagInRow(p, token);
+ break;
+ }
+ default: {
+ p.tmplInsertionModeStack[0] = InsertionMode.IN_BODY;
+ p.insertionMode = InsertionMode.IN_BODY;
+ startTagInBody(p, token);
+ }
+ }
+}
+function endTagInTemplate(p, token) {
+ if (token.tagID === $.TEMPLATE) {
+ templateEndTagInHead(p, token);
+ }
+}
+function eofInTemplate(p, token) {
+ if (p.openElements.tmplCount > 0) {
+ p.openElements.popUntilTagNamePopped($.TEMPLATE);
+ p.activeFormattingElements.clearToLastMarker();
+ p.tmplInsertionModeStack.shift();
+ p._resetInsertionMode();
+ p.onEof(token);
+ }
+ else {
+ stopParsing(p, token);
+ }
+}
+// The "after body" insertion mode
+//------------------------------------------------------------------
+function startTagAfterBody(p, token) {
+ if (token.tagID === $.HTML) {
+ startTagInBody(p, token);
+ }
+ else {
+ tokenAfterBody(p, token);
+ }
+}
+function endTagAfterBody(p, token) {
+ var _a;
+ if (token.tagID === $.HTML) {
+ if (!p.fragmentContext) {
+ p.insertionMode = InsertionMode.AFTER_AFTER_BODY;
+ }
+ //NOTE: <html> is never popped from the stack, so we need to updated
+ //the end location explicitly.
+ if (p.options.sourceCodeLocationInfo && p.openElements.tagIDs[0] === $.HTML) {
+ p._setEndLocation(p.openElements.items[0], token);
+ // Update the body element, if it doesn't have an end tag
+ const bodyElement = p.openElements.items[1];
+ if (bodyElement && !((_a = p.treeAdapter.getNodeSourceCodeLocation(bodyElement)) === null || _a === void 0 ? void 0 : _a.endTag)) {
+ p._setEndLocation(bodyElement, token);
+ }
+ }
+ }
+ else {
+ tokenAfterBody(p, token);
+ }
+}
+function tokenAfterBody(p, token) {
+ p.insertionMode = InsertionMode.IN_BODY;
+ modeInBody(p, token);
+}
+// The "in frameset" insertion mode
+//------------------------------------------------------------------
+function startTagInFrameset(p, token) {
+ switch (token.tagID) {
+ case $.HTML: {
+ startTagInBody(p, token);
+ break;
+ }
+ case $.FRAMESET: {
+ p._insertElement(token, NS.HTML);
+ break;
+ }
+ case $.FRAME: {
+ p._appendElement(token, NS.HTML);
+ token.ackSelfClosing = true;
+ break;
+ }
+ case $.NOFRAMES: {
+ startTagInHead(p, token);
+ break;
+ }
+ default:
+ // Do nothing
+ }
+}
+function endTagInFrameset(p, token) {
+ if (token.tagID === $.FRAMESET && !p.openElements.isRootHtmlElementCurrent()) {
+ p.openElements.pop();
+ if (!p.fragmentContext && p.openElements.currentTagId !== $.FRAMESET) {
+ p.insertionMode = InsertionMode.AFTER_FRAMESET;
+ }
+ }
+}
+// The "after frameset" insertion mode
+//------------------------------------------------------------------
+function startTagAfterFrameset(p, token) {
+ switch (token.tagID) {
+ case $.HTML: {
+ startTagInBody(p, token);
+ break;
+ }
+ case $.NOFRAMES: {
+ startTagInHead(p, token);
+ break;
+ }
+ default:
+ // Do nothing
+ }
+}
+function endTagAfterFrameset(p, token) {
+ if (token.tagID === $.HTML) {
+ p.insertionMode = InsertionMode.AFTER_AFTER_FRAMESET;
+ }
+}
+// The "after after body" insertion mode
+//------------------------------------------------------------------
+function startTagAfterAfterBody(p, token) {
+ if (token.tagID === $.HTML) {
+ startTagInBody(p, token);
+ }
+ else {
+ tokenAfterAfterBody(p, token);
+ }
+}
+function tokenAfterAfterBody(p, token) {
+ p.insertionMode = InsertionMode.IN_BODY;
+ modeInBody(p, token);
+}
+// The "after after frameset" insertion mode
+//------------------------------------------------------------------
+function startTagAfterAfterFrameset(p, token) {
+ switch (token.tagID) {
+ case $.HTML: {
+ startTagInBody(p, token);
+ break;
+ }
+ case $.NOFRAMES: {
+ startTagInHead(p, token);
+ break;
+ }
+ default:
+ // Do nothing
+ }
+}
+// The rules for parsing tokens in foreign content
+//------------------------------------------------------------------
+function nullCharacterInForeignContent(p, token) {
+ token.chars = unicode.REPLACEMENT_CHARACTER;
+ p._insertCharacters(token);
+}
+function characterInForeignContent(p, token) {
+ p._insertCharacters(token);
+ p.framesetOk = false;
+}
+function popUntilHtmlOrIntegrationPoint(p) {
+ while (p.treeAdapter.getNamespaceURI(p.openElements.current) !== NS.HTML &&
+ !p._isIntegrationPoint(p.openElements.currentTagId, p.openElements.current)) {
+ p.openElements.pop();
+ }
+}
+function startTagInForeignContent(p, token) {
+ if (foreignContent.causesExit(token)) {
+ popUntilHtmlOrIntegrationPoint(p);
+ p._startTagOutsideForeignContent(token);
+ }
+ else {
+ const current = p._getAdjustedCurrentElement();
+ const currentNs = p.treeAdapter.getNamespaceURI(current);
+ if (currentNs === NS.MATHML) {
+ foreignContent.adjustTokenMathMLAttrs(token);
+ }
+ else if (currentNs === NS.SVG) {
+ foreignContent.adjustTokenSVGTagName(token);
+ foreignContent.adjustTokenSVGAttrs(token);
+ }
+ foreignContent.adjustTokenXMLAttrs(token);
+ if (token.selfClosing) {
+ p._appendElement(token, currentNs);
+ }
+ else {
+ p._insertElement(token, currentNs);
+ }
+ token.ackSelfClosing = true;
+ }
+}
+function endTagInForeignContent(p, token) {
+ if (token.tagID === $.P || token.tagID === $.BR) {
+ popUntilHtmlOrIntegrationPoint(p);
+ p._endTagOutsideForeignContent(token);
+ return;
+ }
+ for (let i = p.openElements.stackTop; i > 0; i--) {
+ const element = p.openElements.items[i];
+ if (p.treeAdapter.getNamespaceURI(element) === NS.HTML) {
+ p._endTagOutsideForeignContent(token);
+ break;
+ }
+ const tagName = p.treeAdapter.getTagName(element);
+ if (tagName.toLowerCase() === token.tagName) {
+ //NOTE: update the token tag name for `_setEndLocation`.
+ token.tagName = tagName;
+ p.openElements.shortenToLength(i);
+ break;
+ }
+ }
+}
+//# sourceMappingURL=index.js.map \ No newline at end of file
diff --git a/includes/external/addressbook/node_modules/parse5/dist/parser/open-element-stack.d.ts b/includes/external/addressbook/node_modules/parse5/dist/parser/open-element-stack.d.ts
new file mode 100644
index 0000000..77c1800
--- /dev/null
+++ b/includes/external/addressbook/node_modules/parse5/dist/parser/open-element-stack.d.ts
@@ -0,0 +1,53 @@
+import { TAG_ID as $ } from '../common/html.js';
+import type { TreeAdapter, TreeAdapterTypeMap } from '../tree-adapters/interface.js';
+export interface StackHandler<T extends TreeAdapterTypeMap> {
+ onItemPush: (node: T['parentNode'], tid: number, isTop: boolean) => void;
+ onItemPop: (node: T['parentNode'], isTop: boolean) => void;
+}
+export declare class OpenElementStack<T extends TreeAdapterTypeMap> {
+ private treeAdapter;
+ private handler;
+ items: T['parentNode'][];
+ tagIDs: $[];
+ current: T['parentNode'];
+ stackTop: number;
+ tmplCount: number;
+ currentTagId: $;
+ get currentTmplContentOrNode(): T['parentNode'];
+ constructor(document: T['document'], treeAdapter: TreeAdapter<T>, handler: StackHandler<T>);
+ private _indexOf;
+ private _isInTemplate;
+ private _updateCurrentElement;
+ push(element: T['element'], tagID: $): void;
+ pop(): void;
+ replace(oldElement: T['element'], newElement: T['element']): void;
+ insertAfter(referenceElement: T['element'], newElement: T['element'], newElementID: $): void;
+ popUntilTagNamePopped(tagName: $): void;
+ shortenToLength(idx: number): void;
+ popUntilElementPopped(element: T['element']): void;
+ private popUntilPopped;
+ popUntilNumberedHeaderPopped(): void;
+ popUntilTableCellPopped(): void;
+ popAllUpToHtmlElement(): void;
+ private _indexOfTagNames;
+ private clearBackTo;
+ clearBackToTableContext(): void;
+ clearBackToTableBodyContext(): void;
+ clearBackToTableRowContext(): void;
+ remove(element: T['element']): void;
+ tryPeekProperlyNestedBodyElement(): T['element'] | null;
+ contains(element: T['element']): boolean;
+ getCommonAncestor(element: T['element']): T['element'] | null;
+ isRootHtmlElementCurrent(): boolean;
+ hasInScope(tagName: $): boolean;
+ hasNumberedHeaderInScope(): boolean;
+ hasInListItemScope(tagName: $): boolean;
+ hasInButtonScope(tagName: $): boolean;
+ hasInTableScope(tagName: $): boolean;
+ hasTableBodyContextInTableScope(): boolean;
+ hasInSelectScope(tagName: $): boolean;
+ generateImpliedEndTags(): void;
+ generateImpliedEndTagsThoroughly(): void;
+ generateImpliedEndTagsWithExclusion(exclusionId: $): void;
+}
+//# sourceMappingURL=open-element-stack.d.ts.map \ No newline at end of file
diff --git a/includes/external/addressbook/node_modules/parse5/dist/parser/open-element-stack.js b/includes/external/addressbook/node_modules/parse5/dist/parser/open-element-stack.js
new file mode 100644
index 0000000..bd136ea
--- /dev/null
+++ b/includes/external/addressbook/node_modules/parse5/dist/parser/open-element-stack.js
@@ -0,0 +1,312 @@
+import { TAG_ID as $, NS, isNumberedHeader } from '../common/html.js';
+//Element utils
+const IMPLICIT_END_TAG_REQUIRED = new Set([$.DD, $.DT, $.LI, $.OPTGROUP, $.OPTION, $.P, $.RB, $.RP, $.RT, $.RTC]);
+const IMPLICIT_END_TAG_REQUIRED_THOROUGHLY = new Set([
+ ...IMPLICIT_END_TAG_REQUIRED,
+ $.CAPTION,
+ $.COLGROUP,
+ $.TBODY,
+ $.TD,
+ $.TFOOT,
+ $.TH,
+ $.THEAD,
+ $.TR,
+]);
+const SCOPING_ELEMENT_NS = new Map([
+ [$.APPLET, NS.HTML],
+ [$.CAPTION, NS.HTML],
+ [$.HTML, NS.HTML],
+ [$.MARQUEE, NS.HTML],
+ [$.OBJECT, NS.HTML],
+ [$.TABLE, NS.HTML],
+ [$.TD, NS.HTML],
+ [$.TEMPLATE, NS.HTML],
+ [$.TH, NS.HTML],
+ [$.ANNOTATION_XML, NS.MATHML],
+ [$.MI, NS.MATHML],
+ [$.MN, NS.MATHML],
+ [$.MO, NS.MATHML],
+ [$.MS, NS.MATHML],
+ [$.MTEXT, NS.MATHML],
+ [$.DESC, NS.SVG],
+ [$.FOREIGN_OBJECT, NS.SVG],
+ [$.TITLE, NS.SVG],
+]);
+const NAMED_HEADERS = [$.H1, $.H2, $.H3, $.H4, $.H5, $.H6];
+const TABLE_ROW_CONTEXT = [$.TR, $.TEMPLATE, $.HTML];
+const TABLE_BODY_CONTEXT = [$.TBODY, $.TFOOT, $.THEAD, $.TEMPLATE, $.HTML];
+const TABLE_CONTEXT = [$.TABLE, $.TEMPLATE, $.HTML];
+const TABLE_CELLS = [$.TD, $.TH];
+//Stack of open elements
+export class OpenElementStack {
+ get currentTmplContentOrNode() {
+ return this._isInTemplate() ? this.treeAdapter.getTemplateContent(this.current) : this.current;
+ }
+ constructor(document, treeAdapter, handler) {
+ this.treeAdapter = treeAdapter;
+ this.handler = handler;
+ this.items = [];
+ this.tagIDs = [];
+ this.stackTop = -1;
+ this.tmplCount = 0;
+ this.currentTagId = $.UNKNOWN;
+ this.current = document;
+ }
+ //Index of element
+ _indexOf(element) {
+ return this.items.lastIndexOf(element, this.stackTop);
+ }
+ //Update current element
+ _isInTemplate() {
+ return this.currentTagId === $.TEMPLATE && this.treeAdapter.getNamespaceURI(this.current) === NS.HTML;
+ }
+ _updateCurrentElement() {
+ this.current = this.items[this.stackTop];
+ this.currentTagId = this.tagIDs[this.stackTop];
+ }
+ //Mutations
+ push(element, tagID) {
+ this.stackTop++;
+ this.items[this.stackTop] = element;
+ this.current = element;
+ this.tagIDs[this.stackTop] = tagID;
+ this.currentTagId = tagID;
+ if (this._isInTemplate()) {
+ this.tmplCount++;
+ }
+ this.handler.onItemPush(element, tagID, true);
+ }
+ pop() {
+ const popped = this.current;
+ if (this.tmplCount > 0 && this._isInTemplate()) {
+ this.tmplCount--;
+ }
+ this.stackTop--;
+ this._updateCurrentElement();
+ this.handler.onItemPop(popped, true);
+ }
+ replace(oldElement, newElement) {
+ const idx = this._indexOf(oldElement);
+ this.items[idx] = newElement;
+ if (idx === this.stackTop) {
+ this.current = newElement;
+ }
+ }
+ insertAfter(referenceElement, newElement, newElementID) {
+ const insertionIdx = this._indexOf(referenceElement) + 1;
+ this.items.splice(insertionIdx, 0, newElement);
+ this.tagIDs.splice(insertionIdx, 0, newElementID);
+ this.stackTop++;
+ if (insertionIdx === this.stackTop) {
+ this._updateCurrentElement();
+ }
+ this.handler.onItemPush(this.current, this.currentTagId, insertionIdx === this.stackTop);
+ }
+ popUntilTagNamePopped(tagName) {
+ let targetIdx = this.stackTop + 1;
+ do {
+ targetIdx = this.tagIDs.lastIndexOf(tagName, targetIdx - 1);
+ } while (targetIdx > 0 && this.treeAdapter.getNamespaceURI(this.items[targetIdx]) !== NS.HTML);
+ this.shortenToLength(targetIdx < 0 ? 0 : targetIdx);
+ }
+ shortenToLength(idx) {
+ while (this.stackTop >= idx) {
+ const popped = this.current;
+ if (this.tmplCount > 0 && this._isInTemplate()) {
+ this.tmplCount -= 1;
+ }
+ this.stackTop--;
+ this._updateCurrentElement();
+ this.handler.onItemPop(popped, this.stackTop < idx);
+ }
+ }
+ popUntilElementPopped(element) {
+ const idx = this._indexOf(element);
+ this.shortenToLength(idx < 0 ? 0 : idx);
+ }
+ popUntilPopped(tagNames, targetNS) {
+ const idx = this._indexOfTagNames(tagNames, targetNS);
+ this.shortenToLength(idx < 0 ? 0 : idx);
+ }
+ popUntilNumberedHeaderPopped() {
+ this.popUntilPopped(NAMED_HEADERS, NS.HTML);
+ }
+ popUntilTableCellPopped() {
+ this.popUntilPopped(TABLE_CELLS, NS.HTML);
+ }
+ popAllUpToHtmlElement() {
+ //NOTE: here we assume that the root <html> element is always first in the open element stack, so
+ //we perform this fast stack clean up.
+ this.tmplCount = 0;
+ this.shortenToLength(1);
+ }
+ _indexOfTagNames(tagNames, namespace) {
+ for (let i = this.stackTop; i >= 0; i--) {
+ if (tagNames.includes(this.tagIDs[i]) && this.treeAdapter.getNamespaceURI(this.items[i]) === namespace) {
+ return i;
+ }
+ }
+ return -1;
+ }
+ clearBackTo(tagNames, targetNS) {
+ const idx = this._indexOfTagNames(tagNames, targetNS);
+ this.shortenToLength(idx + 1);
+ }
+ clearBackToTableContext() {
+ this.clearBackTo(TABLE_CONTEXT, NS.HTML);
+ }
+ clearBackToTableBodyContext() {
+ this.clearBackTo(TABLE_BODY_CONTEXT, NS.HTML);
+ }
+ clearBackToTableRowContext() {
+ this.clearBackTo(TABLE_ROW_CONTEXT, NS.HTML);
+ }
+ remove(element) {
+ const idx = this._indexOf(element);
+ if (idx >= 0) {
+ if (idx === this.stackTop) {
+ this.pop();
+ }
+ else {
+ this.items.splice(idx, 1);
+ this.tagIDs.splice(idx, 1);
+ this.stackTop--;
+ this._updateCurrentElement();
+ this.handler.onItemPop(element, false);
+ }
+ }
+ }
+ //Search
+ tryPeekProperlyNestedBodyElement() {
+ //Properly nested <body> element (should be second element in stack).
+ return this.stackTop >= 1 && this.tagIDs[1] === $.BODY ? this.items[1] : null;
+ }
+ contains(element) {
+ return this._indexOf(element) > -1;
+ }
+ getCommonAncestor(element) {
+ const elementIdx = this._indexOf(element) - 1;
+ return elementIdx >= 0 ? this.items[elementIdx] : null;
+ }
+ isRootHtmlElementCurrent() {
+ return this.stackTop === 0 && this.tagIDs[0] === $.HTML;
+ }
+ //Element in scope
+ hasInScope(tagName) {
+ for (let i = this.stackTop; i >= 0; i--) {
+ const tn = this.tagIDs[i];
+ const ns = this.treeAdapter.getNamespaceURI(this.items[i]);
+ if (tn === tagName && ns === NS.HTML) {
+ return true;
+ }
+ if (SCOPING_ELEMENT_NS.get(tn) === ns) {
+ return false;
+ }
+ }
+ return true;
+ }
+ hasNumberedHeaderInScope() {
+ for (let i = this.stackTop; i >= 0; i--) {
+ const tn = this.tagIDs[i];
+ const ns = this.treeAdapter.getNamespaceURI(this.items[i]);
+ if (isNumberedHeader(tn) && ns === NS.HTML) {
+ return true;
+ }
+ if (SCOPING_ELEMENT_NS.get(tn) === ns) {
+ return false;
+ }
+ }
+ return true;
+ }
+ hasInListItemScope(tagName) {
+ for (let i = this.stackTop; i >= 0; i--) {
+ const tn = this.tagIDs[i];
+ const ns = this.treeAdapter.getNamespaceURI(this.items[i]);
+ if (tn === tagName && ns === NS.HTML) {
+ return true;
+ }
+ if (((tn === $.UL || tn === $.OL) && ns === NS.HTML) || SCOPING_ELEMENT_NS.get(tn) === ns) {
+ return false;
+ }
+ }
+ return true;
+ }
+ hasInButtonScope(tagName) {
+ for (let i = this.stackTop; i >= 0; i--) {
+ const tn = this.tagIDs[i];
+ const ns = this.treeAdapter.getNamespaceURI(this.items[i]);
+ if (tn === tagName && ns === NS.HTML) {
+ return true;
+ }
+ if ((tn === $.BUTTON && ns === NS.HTML) || SCOPING_ELEMENT_NS.get(tn) === ns) {
+ return false;
+ }
+ }
+ return true;
+ }
+ hasInTableScope(tagName) {
+ for (let i = this.stackTop; i >= 0; i--) {
+ const tn = this.tagIDs[i];
+ const ns = this.treeAdapter.getNamespaceURI(this.items[i]);
+ if (ns !== NS.HTML) {
+ continue;
+ }
+ if (tn === tagName) {
+ return true;
+ }
+ if (tn === $.TABLE || tn === $.TEMPLATE || tn === $.HTML) {
+ return false;
+ }
+ }
+ return true;
+ }
+ hasTableBodyContextInTableScope() {
+ for (let i = this.stackTop; i >= 0; i--) {
+ const tn = this.tagIDs[i];
+ const ns = this.treeAdapter.getNamespaceURI(this.items[i]);
+ if (ns !== NS.HTML) {
+ continue;
+ }
+ if (tn === $.TBODY || tn === $.THEAD || tn === $.TFOOT) {
+ return true;
+ }
+ if (tn === $.TABLE || tn === $.HTML) {
+ return false;
+ }
+ }
+ return true;
+ }
+ hasInSelectScope(tagName) {
+ for (let i = this.stackTop; i >= 0; i--) {
+ const tn = this.tagIDs[i];
+ const ns = this.treeAdapter.getNamespaceURI(this.items[i]);
+ if (ns !== NS.HTML) {
+ continue;
+ }
+ if (tn === tagName) {
+ return true;
+ }
+ if (tn !== $.OPTION && tn !== $.OPTGROUP) {
+ return false;
+ }
+ }
+ return true;
+ }
+ //Implied end tags
+ generateImpliedEndTags() {
+ while (IMPLICIT_END_TAG_REQUIRED.has(this.currentTagId)) {
+ this.pop();
+ }
+ }
+ generateImpliedEndTagsThoroughly() {
+ while (IMPLICIT_END_TAG_REQUIRED_THOROUGHLY.has(this.currentTagId)) {
+ this.pop();
+ }
+ }
+ generateImpliedEndTagsWithExclusion(exclusionId) {
+ while (this.currentTagId !== exclusionId && IMPLICIT_END_TAG_REQUIRED_THOROUGHLY.has(this.currentTagId)) {
+ this.pop();
+ }
+ }
+}
+//# sourceMappingURL=open-element-stack.js.map \ No newline at end of file