From 8b96699ea19534ee4b206aa9908e772b62034e60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20B=C3=B6hm?= <188768+fb55@users.noreply.github.com> Date: Tue, 15 Feb 2022 13:01:20 +0000 Subject: [PATCH] Refactor & improve serializer (#383) Co-authored-by: Joel Denning <5524384+joeldenning@users.noreply.github.com> --- .../parse5-serializer-stream/lib/index.ts | 19 +- packages/parse5/lib/index.ts | 35 +-- packages/parse5/lib/serializer/index.test.ts | 22 +- packages/parse5/lib/serializer/index.ts | 260 +++++++++++------- test/data/serialization/tests.json | 11 + test/utils/generate-serializer-tests.ts | 3 +- 6 files changed, 196 insertions(+), 154 deletions(-) diff --git a/packages/parse5-serializer-stream/lib/index.ts b/packages/parse5-serializer-stream/lib/index.ts index c0d7863cb..2cbf9f550 100644 --- a/packages/parse5-serializer-stream/lib/index.ts +++ b/packages/parse5-serializer-stream/lib/index.ts @@ -1,5 +1,5 @@ import { Readable } from 'node:stream'; -import { Serializer, SerializerOptions } from 'parse5/dist/serializer/index.js'; +import { serialize, type SerializerOptions } from 'parse5/dist/serializer/index.js'; import type { TreeAdapterTypeMap } from 'parse5/dist/tree-adapters/interface.js'; /** @@ -22,32 +22,19 @@ import type { TreeAdapterTypeMap } from 'parse5/dist/tree-adapters/interface.js' * ``` */ export class SerializerStream extends Readable { - private serializer: Serializer; - /** * Streaming AST node to an HTML serializer. A readable stream. * * @param node Node to serialize. * @param options Serialization options. */ - constructor(node: T['parentNode'], options: SerializerOptions) { + constructor(private node: T['parentNode'], private options: SerializerOptions) { super({ encoding: 'utf8' }); - - this.serializer = new Serializer(node, options); - - Object.defineProperty(this.serializer, 'html', { - //NOTE: To make `+=` concat operator work properly we define - //getter which always returns empty string - get() { - return ''; - }, - set: (data: string) => this.push(data), - }); } //Readable stream implementation override _read(): void { - this.serializer.serialize(); + this.push(serialize(this.node, this.options)); this.push(null); } } diff --git a/packages/parse5/lib/index.ts b/packages/parse5/lib/index.ts index 1e770816e..dd3744b2c 100644 --- a/packages/parse5/lib/index.ts +++ b/packages/parse5/lib/index.ts @@ -1,10 +1,10 @@ import { Parser, ParserOptions } from './parser/index.js'; -import { Serializer, SerializerOptions } from './serializer/index.js'; + import type { DefaultTreeAdapterMap } from './tree-adapters/default.js'; import type { TreeAdapterTypeMap } from './tree-adapters/interface.js'; export { ParserOptions } from './parser/index.js'; -export { SerializerOptions } from './serializer/index.js'; +export { serialize, serializeOuter, SerializerOptions } from './serializer/index.js'; // Shorthands @@ -81,34 +81,3 @@ export function parseFragmentHi there!'); - * - * // Serializes a document. - * const html = parse5.serialize(document); - * - * // Serializes the element content. - * const str = parse5.serialize(document.childNodes[1]); - * - * console.log(str); //> 'Hi there!' - * ``` - * - * @param node Node to serialize. - * @param options Serialization options. - */ -export function serialize( - node: T['parentNode'], - options: SerializerOptions -): string { - const serializer = new Serializer(node, options); - - return serializer.serialize(); -} diff --git a/packages/parse5/lib/serializer/index.test.ts b/packages/parse5/lib/serializer/index.test.ts index 3fc221817..5d9dc5516 100644 --- a/packages/parse5/lib/serializer/index.test.ts +++ b/packages/parse5/lib/serializer/index.test.ts @@ -2,7 +2,7 @@ import * as assert from 'node:assert'; import * as parse5 from 'parse5'; import { generateSerializerTests } from 'parse5-test-utils/utils/generate-serializer-tests.js'; import { treeAdapters } from 'parse5-test-utils/utils/common.js'; -import type { Element } from 'parse5/dist/tree-adapters/default'; +import { type Element, isElementNode } from 'parse5/dist/tree-adapters/default'; generateSerializerTests('serializer', 'Serializer', parse5.serialize); @@ -22,4 +22,24 @@ describe('serializer', () => { parse5.serialize(document, { treeAdapter }); }); }); + + describe('serializeOuter', () => { + it('serializes outerHTML correctly', () => { + const document = parse5.parseFragment('
'); + const div = document.childNodes[0]; + assert.ok(isElementNode(div)); + const html = parse5.serializeOuter(div); + + assert.equal(html, '
'); + }); + }); + + it('serializes