From fd5148c9dceaed02a5697d04929684e15b585b83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20B=C3=B6hm?= <188768+fb55@users.noreply.github.com> Date: Sat, 12 Feb 2022 18:23:56 +0000 Subject: [PATCH] feat(parser): Add hooks for stack events (#385) --- packages/parse5/lib/parser/index.test.ts | 31 +++++++++++++++++++ packages/parse5/lib/parser/index.ts | 3 ++ .../parse5/lib/tree-adapters/interface.ts | 14 +++++++++ 3 files changed, 48 insertions(+) diff --git a/packages/parse5/lib/parser/index.test.ts b/packages/parse5/lib/parser/index.test.ts index 82fc0c06f..53170bafb 100644 --- a/packages/parse5/lib/parser/index.test.ts +++ b/packages/parse5/lib/parser/index.test.ts @@ -1,10 +1,12 @@ import * as assert from 'node:assert'; import * as parse5 from 'parse5'; +import { jest } from '@jest/globals'; import { Parser, ParserOptions } from './index.js'; import type { TreeAdapterTypeMap } from './../tree-adapters/interface.js'; import { generateParsingTests } from 'parse5-test-utils/utils/generate-parsing-tests.js'; import { treeAdapters } from 'parse5-test-utils/utils/common.js'; import { NAMESPACES as NS } from '../common/html.js'; +import { isElementNode } from '../tree-adapters/default.js'; const origParseFragment = Parser.prototype.parseFragment; @@ -98,4 +100,33 @@ describe('parser', () => { expect(doctype).toHaveProperty('publicId', ''); expect(doctype).toHaveProperty('systemId', ''); }); + + describe('Tree adapters', () => { + it('should support onItemPush and onItemPop', () => { + const onItemPush = jest.fn(); + const onItemPop = jest.fn(); + const document = parse5.parse('
', {
+ treeAdapter: {
+ ...treeAdapters.default,
+ onItemPush,
+ onItemPop,
+ },
+ });
+
+ const htmlElement = document.childNodes[0];
+ assert.ok(isElementNode(htmlElement));
+ const bodyElement = htmlElement.childNodes[1];
+ assert.ok(isElementNode(bodyElement));
+ // Expect 5 opened elements; in order: html, head, body, and 2x p
+ expect(onItemPush).toHaveBeenCalledTimes(5);
+ expect(onItemPush).toHaveBeenNthCalledWith(1, htmlElement);
+ expect(onItemPush).toHaveBeenNthCalledWith(3, bodyElement);
+ // The last opened element is the second p
+ expect(onItemPush).toHaveBeenLastCalledWith(bodyElement.childNodes[1]);
+ // The second p isn't closed, plus we never pop body and html. Alas, only 2 pop events (head and p).
+ expect(onItemPop).toHaveBeenCalledTimes(2);
+ // The last pop event should be the first p.
+ expect(onItemPop).toHaveBeenLastCalledWith(bodyElement.childNodes[0], bodyElement);
+ });
+ });
});
diff --git a/packages/parse5/lib/parser/index.ts b/packages/parse5/lib/parser/index.ts
index 3ddb4905b..97b528237 100644
--- a/packages/parse5/lib/parser/index.ts
+++ b/packages/parse5/lib/parser/index.ts
@@ -317,6 +317,7 @@ export class Parser