diff --git a/packages/parse5/lib/parser/index.ts b/packages/parse5/lib/parser/index.ts index ab989bfdd..f52b94486 100644 --- a/packages/parse5/lib/parser/index.ts +++ b/packages/parse5/lib/parser/index.ts @@ -1,5 +1,5 @@ import { TokenHandler, Tokenizer, TokenizerMode } from '../tokenizer/index.js'; -import { OpenElementStack } from './open-element-stack.js'; +import { OpenElementStack, StackHandler } from './open-element-stack.js'; import { FormattingElementList, ElementEntry, EntryType } from './formatting-element-list.js'; import * as defaultTreeAdapter from '../tree-adapters/default.js'; import * as doctype from '../common/doctype.js'; @@ -119,7 +119,7 @@ const defaultParserOptions = { }; //Parser -export class Parser implements TokenHandler { +export class Parser implements TokenHandler, StackHandler { treeAdapter: TreeAdapter; onParseError: ParserErrorHandler | null; private currentToken: Token | null = null; @@ -152,12 +152,7 @@ export class Parser implements TokenHandler { this.fragmentContextID = fragmentContext ? getTagID(this.treeAdapter.getTagName(fragmentContext)) : $.UNKNOWN; this._setContextModes(fragmentContext ?? this.document, this.fragmentContextID); - this.openElements = new OpenElementStack( - this.document, - this.treeAdapter, - this.onItemPush.bind(this), - this.onItemPop.bind(this) - ); + this.openElements = new OpenElementStack(this.document, this.treeAdapter, this); } // API @@ -289,12 +284,12 @@ export class Parser implements TokenHandler { } //Text parsing - private onItemPush(node: T['parentNode'], tid: number, isTop: boolean): void { + onItemPush(node: T['parentNode'], tid: number, isTop: boolean): void { this.treeAdapter.onItemPush?.(node); if (isTop && this.openElements.stackTop > 0) this._setContextModes(node, tid); } - private onItemPop(node: T['parentNode'], isTop: boolean): void { + onItemPop(node: T['parentNode'], isTop: boolean): void { if (this.options.sourceCodeLocationInfo) { this._setEndLocation(node, this.currentToken!); } diff --git a/packages/parse5/lib/parser/open-element-stack.ts b/packages/parse5/lib/parser/open-element-stack.ts index 02054eebd..ea75b2103 100644 --- a/packages/parse5/lib/parser/open-element-stack.ts +++ b/packages/parse5/lib/parser/open-element-stack.ts @@ -41,6 +41,11 @@ const TABLE_BODY_CONTEXT = [$.TBODY, $.TFOOT, $.THEAD, $.TEMPLATE, $.HTML]; const TABLE_CONTEXT = [$.TABLE, $.TEMPLATE, $.HTML]; const TABLE_CELLS = [$.TD, $.TH]; +export interface StackHandler { + onItemPush: (node: T['parentNode'], tid: number, isTop: boolean) => void; + onItemPop: (node: T['parentNode'], isTop: boolean) => void; +} + //Stack of open elements export class OpenElementStack { items: T['parentNode'][] = []; @@ -55,12 +60,7 @@ export class OpenElementStack { return this._isInTemplate() ? this.treeAdapter.getTemplateContent(this.current) : this.current; } - constructor( - document: T['document'], - private treeAdapter: TreeAdapter, - private onItemPush: (node: T['parentNode'], tid: number, isTop: boolean) => void, - private onItemPop: (node: T['parentNode'], isTop: boolean) => void - ) { + constructor(document: T['document'], private treeAdapter: TreeAdapter, private handler: StackHandler) { this.current = document; } @@ -92,7 +92,7 @@ export class OpenElementStack { this.tmplCount++; } - this.onItemPush(element, tagID, true); + this.handler.onItemPush(element, tagID, true); } pop(): void { @@ -104,7 +104,7 @@ export class OpenElementStack { this.stackTop--; this._updateCurrentElement(); - this.onItemPop(popped, true); + this.handler.onItemPop(popped, true); } replace(oldElement: T['element'], newElement: T['element']): void { @@ -128,7 +128,7 @@ export class OpenElementStack { this._updateCurrentElement(); } - this.onItemPush(this.current, this.currentTagId, insertionIdx === this.stackTop); + this.handler.onItemPush(this.current, this.currentTagId, insertionIdx === this.stackTop); } popUntilTagNamePopped(tagName: $): void { @@ -152,7 +152,7 @@ export class OpenElementStack { this.stackTop--; this._updateCurrentElement(); - this.onItemPop(popped, this.stackTop < idx); + this.handler.onItemPop(popped, this.stackTop < idx); } } @@ -218,7 +218,7 @@ export class OpenElementStack { this.tagIDs.splice(idx, 1); this.stackTop--; this._updateCurrentElement(); - this.onItemPop(element, false); + this.handler.onItemPop(element, false); } } }