Skip to content
This repository has been archived by the owner on Mar 24, 2022. It is now read-only.

Commit

Permalink
feat: Add serializeOuter method
Browse files Browse the repository at this point in the history
Fixes inikulin#230, inikulin#378

Uses the test case from inikulin#378, by @joeldenning

Co-Authored-By: Joel Denning <5524384+joeldenning@users.noreply.github.com>
  • Loading branch information
fb55 and joeldenning committed Feb 7, 2022
1 parent 67dbf72 commit 844f072
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 3 deletions.
2 changes: 1 addition & 1 deletion packages/parse5/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type { DefaultTreeAdapterMap } from './tree-adapters/default.js';
import type { TreeAdapterTypeMap } from './tree-adapters/interface.js';

export { ParserOptions } from './parser/index.js';
export { serialize, SerializerOptions } from './serializer/index.js';
export { serialize, serializeOuter, SerializerOptions } from './serializer/index.js';

// Shorthands

Expand Down
13 changes: 12 additions & 1 deletion packages/parse5/lib/serializer/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import * as parse5 from 'parse5';
import outdent from 'outdent';
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);

Expand Down Expand Up @@ -49,4 +49,15 @@ describe('serializer', () => {
expect(parse5.serialize(document)).toContain(input);
});
});

describe('serializeOuter', () => {
it('serializes outerHTML correctly', () => {
const document = parse5.parseFragment('<div><button>Hello</button></div>');
const div = document.childNodes[0];
assert.ok(isElementNode(div));
const html = parse5.serializeOuter(div);

assert.equal(html, '<div><button>Hello</button></div>');
});
});
});
31 changes: 30 additions & 1 deletion packages/parse5/lib/serializer/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ export interface SerializerOptions<T extends TreeAdapterTypeMap> {

type InternalOptions<T extends TreeAdapterTypeMap> = Required<SerializerOptions<T>>;

const defaultOpts = { treeAdapter: DefaultTreeAdapter, scriptingEnabled: true };

/**
* Serializes an AST node to an HTML string.
*
Expand All @@ -76,10 +78,37 @@ export function serialize<T extends TreeAdapterTypeMap = DefaultTreeAdapter.Defa
node: T['parentNode'],
options?: SerializerOptions<T>
): string {
const opts = { treeAdapter: DefaultTreeAdapter, scriptingEnabled: true, ...options };
const opts = { ...defaultOpts, ...options };
return serializeChildNodes(node, opts);
}

/**
* Serializes an AST element node to an HTML string, including the element node.
*
* @example
*
* ```js
* const parse5 = require('parse5');
*
* const document = parse5.parseFragment('<div>Hello, <b>world</b>!</div>');
*
* // Serializes the <div> element.
* const html = parse5.serializeOuter(document.childNodes[0]);
*
* console.log(str); //> '<div>Hello, <b>world</b>!</div>'
* ```
*
* @param node Node to serialize.
* @param options Serialization options.
*/
export function serializeOuter<T extends TreeAdapterTypeMap = DefaultTreeAdapter.DefaultTreeAdapterMap>(
node: T['element'],
options?: SerializerOptions<T>
): string {
const opts = { ...defaultOpts, ...options };
return serializeElement(node, opts);
}

function serializeChildNodes<T extends TreeAdapterTypeMap>(
parentNode: T['parentNode'],
options: InternalOptions<T>
Expand Down

0 comments on commit 844f072

Please sign in to comment.