hast-util-to-html
Advanced tools
Comparing version 8.0.4 to 9.0.0
@@ -1,5 +0,5 @@ | ||
export {toHtml} from './lib/index.js' | ||
export type CharacterReferences = import('./lib/types.js').CharacterReferences | ||
export type Options = import('./lib/types.js').Options | ||
export type Quote = import('./lib/types.js').Quote | ||
export type Space = import('./lib/types.js').Space | ||
export { toHtml } from "./lib/index.js"; | ||
export type CharacterReferences = import('./lib/index.js').CharacterReferences; | ||
export type Options = import('./lib/index.js').Options; | ||
export type Quote = import('./lib/index.js').Quote; | ||
export type Space = import('./lib/index.js').Space; |
/** | ||
* @typedef {import('./lib/types.js').CharacterReferences} CharacterReferences | ||
* @typedef {import('./lib/types.js').Options} Options | ||
* @typedef {import('./lib/types.js').Quote} Quote | ||
* @typedef {import('./lib/types.js').Space} Space | ||
* @typedef {import('./lib/index.js').CharacterReferences} CharacterReferences | ||
* @typedef {import('./lib/index.js').Options} Options | ||
* @typedef {import('./lib/index.js').Quote} Quote | ||
* @typedef {import('./lib/index.js').Space} Space | ||
*/ | ||
export {toHtml} from './lib/index.js' |
@@ -8,3 +8,3 @@ /** | ||
* Index of `node` in `parent. | ||
* @param {Parent | undefined} _2 | ||
* @param {Parents | undefined} _2 | ||
* Parent of `node`. | ||
@@ -16,10 +16,5 @@ * @param {State} state | ||
*/ | ||
export function comment( | ||
node: Comment, | ||
_1: number | undefined, | ||
_2: Parent | undefined, | ||
state: State | ||
): string | ||
export type Comment = import('../types.js').Comment | ||
export type Parent = import('../types.js').Parent | ||
export type State = import('../types.js').State | ||
export function comment(node: Comment, _1: number | undefined, _2: Parents | undefined, state: State): string; | ||
export type Comment = import('hast').Comment; | ||
export type Parents = import('hast').Parents; | ||
export type State = import('../index.js').State; |
/** | ||
* @typedef {import('../types.js').Comment} Comment | ||
* @typedef {import('../types.js').Parent} Parent | ||
* @typedef {import('../types.js').State} State | ||
* @typedef {import('hast').Comment} Comment | ||
* @typedef {import('hast').Parents} Parents | ||
* | ||
* @typedef {import('../index.js').State} State | ||
*/ | ||
@@ -16,3 +17,3 @@ | ||
* Index of `node` in `parent. | ||
* @param {Parent | undefined} _2 | ||
* @param {Parents | undefined} _2 | ||
* Parent of `node`. | ||
@@ -19,0 +20,0 @@ * @param {State} state |
/** | ||
* @typedef {import('../types.js').DocType} DocType | ||
* @typedef {import('../types.js').Parent} Parent | ||
* @typedef {import('../types.js').State} State | ||
*/ | ||
/** | ||
* Serialize a doctype. | ||
* | ||
* @param {DocType} _1 | ||
* @param {Doctype} _1 | ||
* Node to handle. | ||
* @param {number | undefined} _2 | ||
* Index of `node` in `parent. | ||
* @param {Parent | undefined} _3 | ||
* @param {Parents | undefined} _3 | ||
* Parent of `node`. | ||
@@ -20,10 +15,5 @@ * @param {State} state | ||
*/ | ||
export function doctype( | ||
_1: DocType, | ||
_2: number | undefined, | ||
_3: Parent | undefined, | ||
state: State | ||
): string | ||
export type DocType = import('../types.js').DocType | ||
export type Parent = import('../types.js').Parent | ||
export type State = import('../types.js').State | ||
export function doctype(_1: Doctype, _2: number | undefined, _3: Parents | undefined, state: State): string; | ||
export type Doctype = import('hast').Doctype; | ||
export type Parents = import('hast').Parents; | ||
export type State = import('../index.js').State; |
/** | ||
* @typedef {import('../types.js').DocType} DocType | ||
* @typedef {import('../types.js').Parent} Parent | ||
* @typedef {import('../types.js').State} State | ||
* @typedef {import('hast').Doctype} Doctype | ||
* @typedef {import('hast').Parents} Parents | ||
* | ||
* @typedef {import('../index.js').State} State | ||
*/ | ||
// Make VS code see references to the above types. | ||
'' | ||
/** | ||
* Serialize a doctype. | ||
* | ||
* @param {DocType} _1 | ||
* @param {Doctype} _1 | ||
* Node to handle. | ||
* @param {number | undefined} _2 | ||
* Index of `node` in `parent. | ||
* @param {Parent | undefined} _3 | ||
* @param {Parents | undefined} _3 | ||
* Parent of `node`. | ||
@@ -16,0 +20,0 @@ * @param {State} state |
@@ -8,3 +8,3 @@ /** | ||
* Index of `node` in `parent. | ||
* @param {Parent | undefined} parent | ||
* @param {Parents | undefined} parent | ||
* Parent of `node`. | ||
@@ -16,12 +16,6 @@ * @param {State} state | ||
*/ | ||
export function element( | ||
node: Element, | ||
index: number | undefined, | ||
parent: Parent | undefined, | ||
state: State | ||
): string | ||
export type State = import('../types.js').State | ||
export type Parent = import('../types.js').Parent | ||
export type Element = import('../types.js').Element | ||
export type Properties = import('../types.js').Properties | ||
export type PropertyValue = import('../types.js').PropertyValue | ||
export function element(node: Element, index: number | undefined, parent: Parents | undefined, state: State): string; | ||
export type Element = import('hast').Element; | ||
export type Parents = import('hast').Parents; | ||
export type Properties = import('hast').Properties; | ||
export type State = import('../index.js').State; |
/** | ||
* @typedef {import('../types.js').State} State | ||
* @typedef {import('../types.js').Parent} Parent | ||
* @typedef {import('../types.js').Element} Element | ||
* @typedef {import('../types.js').Properties} Properties | ||
* @typedef {import('../types.js').PropertyValue} PropertyValue | ||
* @typedef {import('hast').Element} Element | ||
* @typedef {import('hast').Parents} Parents | ||
* @typedef {import('hast').Properties} Properties | ||
* | ||
* @typedef {import('../index.js').State} State | ||
*/ | ||
@@ -11,7 +11,7 @@ | ||
import {stringify as commas} from 'comma-separated-tokens' | ||
import {svg, find} from 'property-information' | ||
import {find, svg} from 'property-information' | ||
import {stringify as spaces} from 'space-separated-tokens' | ||
import {stringifyEntities} from 'stringify-entities' | ||
import {closing} from '../omission/closing.js' | ||
import {opening} from '../omission/opening.js' | ||
import {closing} from '../omission/closing.js' | ||
@@ -25,3 +25,3 @@ /** | ||
* | ||
* @type {Record<'name' | 'unquoted' | 'single' | 'double', Array<[Array<string>, Array<string>]>>} | ||
* @type {Record<'double' | 'name' | 'single' | 'unquoted', Array<[Array<string>, Array<string>]>>} | ||
*/ | ||
@@ -58,3 +58,3 @@ const constants = { | ||
* Index of `node` in `parent. | ||
* @param {Parent | undefined} parent | ||
* @param {Parents | undefined} parent | ||
* Parent of `node`. | ||
@@ -66,3 +66,2 @@ * @param {State} state | ||
*/ | ||
// eslint-disable-next-line complexity | ||
export function element(node, index, parent, state) { | ||
@@ -96,2 +95,4 @@ const schema = state.schema | ||
// void in WHATWG HTML, to be stringified properly. | ||
// Note: `menuitem` has since been removed from the HTML spec, and so is no | ||
// longer void. | ||
if (content) selfClosing = false | ||
@@ -144,3 +145,3 @@ | ||
for (key in props) { | ||
if (props[key] !== undefined && props[key] !== null) { | ||
if (props[key] !== null && props[key] !== undefined) { | ||
const value = serializeAttribute(state, key, props[key]) | ||
@@ -155,3 +156,3 @@ if (value) values.push(value) | ||
? values[index].charAt(values[index].length - 1) | ||
: null | ||
: undefined | ||
@@ -170,6 +171,5 @@ // In tight mode, don’t add a space after quoted attributes. | ||
* @param {string} key | ||
* @param {PropertyValue} value | ||
* @param {Properties[keyof Properties]} value | ||
* @returns {string} | ||
*/ | ||
// eslint-disable-next-line complexity | ||
function serializeAttribute(state, key, value) { | ||
@@ -194,4 +194,4 @@ const info = find(state.schema, key) | ||
if ( | ||
value === null || | ||
value === undefined || | ||
value === null || | ||
value === false || | ||
@@ -245,4 +245,4 @@ (typeof value === 'number' && Number.isNaN(value)) | ||
Object.assign({}, state.settings.characterReferences, { | ||
subset: constants.unquoted[x][y], | ||
attribute: true | ||
attribute: true, | ||
subset: constants.unquoted[x][y] | ||
}) | ||
@@ -249,0 +249,0 @@ ) |
/** | ||
* @type {(node: Node, index: number | undefined, parent: Parent | undefined, state: State) => string} | ||
* @type {(node: Nodes, index: number | undefined, parent: Parents | undefined, state: State) => string} | ||
*/ | ||
export const handle: ( | ||
node: Node, | ||
index: number | undefined, | ||
parent: Parent | undefined, | ||
state: State | ||
) => string | ||
export type State = import('../types.js').State | ||
export type Node = import('../types.js').Node | ||
export type Parent = import('../types.js').Parent | ||
export const handle: (node: Nodes, index: number | undefined, parent: Parents | undefined, state: State) => string; | ||
export type Nodes = import('hast').Nodes; | ||
export type Parents = import('hast').Parents; | ||
export type State = import('../index.js').State; |
/** | ||
* @typedef {import('../types.js').State} State | ||
* @typedef {import('../types.js').Node} Node | ||
* @typedef {import('../types.js').Parent} Parent | ||
* @typedef {import('hast').Nodes} Nodes | ||
* @typedef {import('hast').Parents} Parents | ||
* | ||
* @typedef {import('../index.js').State} State | ||
*/ | ||
@@ -16,3 +17,3 @@ | ||
/** | ||
* @type {(node: Node, index: number | undefined, parent: Parent | undefined, state: State) => string} | ||
* @type {(node: Nodes, index: number | undefined, parent: Parents | undefined, state: State) => string} | ||
*/ | ||
@@ -40,3 +41,3 @@ export const handle = zwitch('type', { | ||
* | ||
* @param {unknown} node | ||
* @param {unknown} node_ | ||
* Unknown node. | ||
@@ -46,5 +47,6 @@ * @returns {never} | ||
*/ | ||
function unknown(node) { | ||
// @ts-expect-error: `type` is defined. | ||
function unknown(node_) { | ||
// `type` is guaranteed by runtime JS. | ||
const node = /** @type {Nodes} */ (node_) | ||
throw new Error('Cannot compile unknown node `' + node.type + '`') | ||
} |
@@ -8,3 +8,3 @@ /** | ||
* Index of `node` in `parent. | ||
* @param {Parent | undefined} parent | ||
* @param {Parents | undefined} parent | ||
* Parent of `node`. | ||
@@ -16,10 +16,5 @@ * @param {State} state | ||
*/ | ||
export function raw( | ||
node: Raw, | ||
index: number | undefined, | ||
parent: Parent | undefined, | ||
state: State | ||
): string | ||
export type State = import('../types.js').State | ||
export type Parent = import('../types.js').Parent | ||
export type Raw = import('../types.js').Raw | ||
export function raw(node: Raw, index: number | undefined, parent: Parents | undefined, state: State): string; | ||
export type Parents = import('hast').Parents; | ||
export type Raw = import('mdast-util-to-hast').Raw; | ||
export type State = import('../index.js').State; |
/** | ||
* @typedef {import('../types.js').State} State | ||
* @typedef {import('../types.js').Parent} Parent | ||
* @typedef {import('../types.js').Raw} Raw | ||
* @typedef {import('hast').Parents} Parents | ||
* | ||
* @typedef {import('mdast-util-to-hast').Raw} Raw | ||
* | ||
* @typedef {import('../index.js').State} State | ||
*/ | ||
@@ -16,3 +18,3 @@ | ||
* Index of `node` in `parent. | ||
* @param {Parent | undefined} parent | ||
* @param {Parents | undefined} parent | ||
* Parent of `node`. | ||
@@ -19,0 +21,0 @@ * @param {State} state |
/** | ||
* @typedef {import('../types.js').Root} Root | ||
* @typedef {import('../types.js').Parent} Parent | ||
* @typedef {import('../types.js').State} State | ||
*/ | ||
/** | ||
* Serialize a root. | ||
@@ -13,3 +8,3 @@ * | ||
* Index of `node` in `parent. | ||
* @param {Parent | undefined} _2 | ||
* @param {Parents | undefined} _2 | ||
* Parent of `node`. | ||
@@ -21,10 +16,5 @@ * @param {State} state | ||
*/ | ||
export function root( | ||
node: Root, | ||
_1: number | undefined, | ||
_2: Parent | undefined, | ||
state: State | ||
): string | ||
export type Root = import('../types.js').Root | ||
export type Parent = import('../types.js').Parent | ||
export type State = import('../types.js').State | ||
export function root(node: Root, _1: number | undefined, _2: Parents | undefined, state: State): string; | ||
export type Parents = import('hast').Parents; | ||
export type Root = import('hast').Root; | ||
export type State = import('../index.js').State; |
/** | ||
* @typedef {import('../types.js').Root} Root | ||
* @typedef {import('../types.js').Parent} Parent | ||
* @typedef {import('../types.js').State} State | ||
* @typedef {import('hast').Parents} Parents | ||
* @typedef {import('hast').Root} Root | ||
* | ||
* @typedef {import('../index.js').State} State | ||
*/ | ||
// Make VS code see references to the above types. | ||
'' | ||
/** | ||
@@ -14,3 +18,3 @@ * Serialize a root. | ||
* Index of `node` in `parent. | ||
* @param {Parent | undefined} _2 | ||
* @param {Parents | undefined} _2 | ||
* Parent of `node`. | ||
@@ -17,0 +21,0 @@ * @param {State} state |
/** | ||
* Serialize a text node. | ||
* | ||
* @param {Text | Raw} node | ||
* @param {Raw | Text} node | ||
* Node to handle. | ||
* @param {number | undefined} _ | ||
* Index of `node` in `parent. | ||
* @param {Parent | undefined} parent | ||
* @param {Parents | undefined} parent | ||
* Parent of `node`. | ||
@@ -15,11 +15,6 @@ * @param {State} state | ||
*/ | ||
export function text( | ||
node: Text | Raw, | ||
_: number | undefined, | ||
parent: Parent | undefined, | ||
state: State | ||
): string | ||
export type State = import('../types.js').State | ||
export type Parent = import('../types.js').Parent | ||
export type Raw = import('../types.js').Raw | ||
export type Text = import('../types.js').Text | ||
export function text(node: Raw | Text, _: number | undefined, parent: Parents | undefined, state: State): string; | ||
export type Parents = import('hast').Parents; | ||
export type Text = import('hast').Text; | ||
export type Raw = import('mdast-util-to-hast').Raw; | ||
export type State = import('../index.js').State; |
/** | ||
* @typedef {import('../types.js').State} State | ||
* @typedef {import('../types.js').Parent} Parent | ||
* @typedef {import('../types.js').Raw} Raw | ||
* @typedef {import('../types.js').Text} Text | ||
* @typedef {import('hast').Parents} Parents | ||
* @typedef {import('hast').Text} Text | ||
* | ||
* @typedef {import('mdast-util-to-hast').Raw} Raw | ||
* | ||
* @typedef {import('../index.js').State} State | ||
*/ | ||
@@ -13,7 +15,7 @@ | ||
* | ||
* @param {Text | Raw} node | ||
* @param {Raw | Text} node | ||
* Node to handle. | ||
* @param {number | undefined} _ | ||
* Index of `node` in `parent. | ||
* @param {Parent | undefined} parent | ||
* @param {Parents | undefined} parent | ||
* Parent of `node`. | ||
@@ -20,0 +22,0 @@ * @param {State} state |
/** | ||
* Serialize hast as HTML. | ||
* | ||
* @param {Node | Array<Content>} tree | ||
* @param {Array<RootContent> | Nodes} tree | ||
* Tree to serialize. | ||
* @param {Options | null | undefined} [options] | ||
* Configuration. | ||
* Configuration (optional). | ||
* @returns {string} | ||
* Serialized HTML. | ||
*/ | ||
export function toHtml( | ||
tree: Node | Array<Content>, | ||
options?: Options | null | undefined | ||
): string | ||
export function toHtml(tree: Array<RootContent> | Nodes, options?: Options | null | undefined): string; | ||
/** | ||
@@ -20,14 +17,344 @@ * Serialize all children of `parent`. | ||
* Info passed around about the current state. | ||
* @param {Parent | undefined} parent | ||
* @param {Parents | undefined} parent | ||
* Parent whose children to serialize. | ||
* @returns {string} | ||
*/ | ||
export function all( | ||
this: import('./types.js').State, | ||
parent: Parent | undefined | ||
): string | ||
export type Node = import('./types.js').Node | ||
export type Parent = import('./types.js').Parent | ||
export type Content = import('./types.js').Content | ||
export type Options = import('./types.js').Options | ||
export type State = import('./types.js').State | ||
export function all(this: State, parent: Parents | undefined): string; | ||
export type Nodes = import('hast').Nodes; | ||
export type Parents = import('hast').Parents; | ||
export type RootContent = import('hast').RootContent; | ||
export type Schema = import('property-information').Schema; | ||
export type StringifyEntitiesOptions = import('stringify-entities').Options; | ||
export type CharacterReferences = Omit<StringifyEntitiesOptions, 'attribute' | 'escapeOnly' | 'subset'>; | ||
/** | ||
* Configuration. | ||
*/ | ||
export type Options = { | ||
/** | ||
* Do not encode some characters which cause XSS vulnerabilities in older | ||
* browsers (default: `false`). | ||
* | ||
* > ⚠️ **Danger**: only set this if you completely trust the content. | ||
*/ | ||
allowDangerousCharacters?: boolean | null | undefined; | ||
/** | ||
* Allow `raw` nodes and insert them as raw HTML (default: `false`). | ||
* | ||
* When `false`, `Raw` nodes are encoded. | ||
* | ||
* > ⚠️ **Danger**: only set this if you completely trust the content. | ||
*/ | ||
allowDangerousHtml?: boolean | null | undefined; | ||
/** | ||
* Do not encode characters which cause parse errors (even though they work), | ||
* to save bytes (default: `false`). | ||
* | ||
* Not used in the SVG space. | ||
* | ||
* > 👉 **Note**: intentionally creates parse errors in markup (how parse | ||
* > errors are handled is well defined, so this works but isn’t pretty). | ||
*/ | ||
allowParseErrors?: boolean | null | undefined; | ||
/** | ||
* Use “bogus comments” instead of comments to save byes: `<?charlie>` | ||
* instead of `<!--charlie-->` (default: `false`). | ||
* | ||
* > 👉 **Note**: intentionally creates parse errors in markup (how parse | ||
* > errors are handled is well defined, so this works but isn’t pretty). | ||
*/ | ||
bogusComments?: boolean | null | undefined; | ||
/** | ||
* Configure how to serialize character references (optional). | ||
*/ | ||
characterReferences?: CharacterReferences | null | undefined; | ||
/** | ||
* Close SVG elements without any content with slash (`/`) on the opening tag | ||
* instead of an end tag: `<circle />` instead of `<circle></circle>` | ||
* (default: `false`). | ||
* | ||
* See `tightSelfClosing` to control whether a space is used before the | ||
* slash. | ||
* | ||
* Not used in the HTML space. | ||
*/ | ||
closeEmptyElements?: boolean | null | undefined; | ||
/** | ||
* Close self-closing nodes with an extra slash (`/`): `<img />` instead of | ||
* `<img>` (default: `false`). | ||
* | ||
* See `tightSelfClosing` to control whether a space is used before the | ||
* slash. | ||
* | ||
* Not used in the SVG space. | ||
*/ | ||
closeSelfClosing?: boolean | null | undefined; | ||
/** | ||
* Collapse empty attributes: get `class` instead of `class=""` (default: | ||
* `false`). | ||
* | ||
* Not used in the SVG space. | ||
* | ||
* > 👉 **Note**: boolean attributes (such as `hidden`) are always collapsed. | ||
*/ | ||
collapseEmptyAttributes?: boolean | null | undefined; | ||
/** | ||
* Omit optional opening and closing tags (default: `false`). | ||
* | ||
* For example, in `<ol><li>one</li><li>two</li></ol>`, both `</li>` closing | ||
* tags can be omitted. | ||
* The first because it’s followed by another `li`, the last because it’s | ||
* followed by nothing. | ||
* | ||
* Not used in the SVG space. | ||
*/ | ||
omitOptionalTags?: boolean | null | undefined; | ||
/** | ||
* Leave attributes unquoted if that results in less bytes (default: `false`). | ||
* | ||
* Not used in the SVG space. | ||
*/ | ||
preferUnquoted?: boolean | null | undefined; | ||
/** | ||
* Preferred quote to use (default: `'"'`). | ||
*/ | ||
quote?: Quote | null | undefined; | ||
/** | ||
* Use the other quote if that results in less bytes (default: `false`). | ||
*/ | ||
quoteSmart?: boolean | null | undefined; | ||
/** | ||
* When an `<svg>` element is found in the HTML space, this package already | ||
* automatically switches to and from the SVG space when entering and exiting | ||
* it (default: `'html'`). | ||
* | ||
* > 👉 **Note**: hast is not XML. | ||
* > It supports SVG as embedded in HTML. | ||
* > It does not support the features available in XML. | ||
* > Passing SVG might break but fragments of modern SVG should be fine. | ||
* > Use [`xast`][xast] if you need to support SVG as XML. | ||
*/ | ||
space?: Space | null | undefined; | ||
/** | ||
* Join attributes together, without whitespace, if possible: get | ||
* `class="a b"title="c d"` instead of `class="a b" title="c d"` to save | ||
* bytes (default: `false`). | ||
* | ||
* Not used in the SVG space. | ||
* | ||
* > 👉 **Note**: intentionally creates parse errors in markup (how parse | ||
* > errors are handled is well defined, so this works but isn’t pretty). | ||
*/ | ||
tightAttributes?: boolean | null | undefined; | ||
/** | ||
* Join known comma-separated attribute values with just a comma (`,`), | ||
* instead of padding them on the right as well (`,␠`, where `␠` represents a | ||
* space) (default: `false`). | ||
*/ | ||
tightCommaSeparatedLists?: boolean | null | undefined; | ||
/** | ||
* Drop unneeded spaces in doctypes: `<!doctypehtml>` instead of | ||
* `<!doctype html>` to save bytes (default: `false`). | ||
* | ||
* > 👉 **Note**: intentionally creates parse errors in markup (how parse | ||
* > errors are handled is well defined, so this works but isn’t pretty). | ||
*/ | ||
tightDoctype?: boolean | null | undefined; | ||
/** | ||
* Do not use an extra space when closing self-closing elements: `<img/>` | ||
* instead of `<img />` (default: `false`). | ||
* | ||
* > 👉 **Note**: only used if `closeSelfClosing: true` or | ||
* > `closeEmptyElements: true`. | ||
*/ | ||
tightSelfClosing?: boolean | null | undefined; | ||
/** | ||
* Use a `<!DOCTYPE…` instead of `<!doctype…` (default: `false`). | ||
* | ||
* Useless except for XHTML. | ||
*/ | ||
upperDoctype?: boolean | null | undefined; | ||
/** | ||
* Tag names of elements to serialize without closing tag (default: `html-void-elements`). | ||
* | ||
* Not used in the SVG space. | ||
* | ||
* > 👉 **Note**: It’s highly unlikely that you want to pass this, because | ||
* > hast is not for XML, and HTML will not add more void elements. | ||
*/ | ||
voids?: ReadonlyArray<string> | null | undefined; | ||
}; | ||
/** | ||
* HTML quotes for attribute values. | ||
*/ | ||
export type Quote = '"' | "'"; | ||
export type Settings = { | ||
/** | ||
* Do not encode some characters which cause XSS vulnerabilities in older | ||
* browsers (default: `false`). | ||
* | ||
* > ⚠️ **Danger**: only set this if you completely trust the content. | ||
*/ | ||
allowDangerousCharacters: boolean; | ||
/** | ||
* Allow `raw` nodes and insert them as raw HTML (default: `false`). | ||
* | ||
* When `false`, `Raw` nodes are encoded. | ||
* | ||
* > ⚠️ **Danger**: only set this if you completely trust the content. | ||
*/ | ||
allowDangerousHtml: boolean; | ||
/** | ||
* Do not encode characters which cause parse errors (even though they work), | ||
* to save bytes (default: `false`). | ||
* | ||
* Not used in the SVG space. | ||
* | ||
* > 👉 **Note**: intentionally creates parse errors in markup (how parse | ||
* > errors are handled is well defined, so this works but isn’t pretty). | ||
*/ | ||
allowParseErrors: boolean; | ||
/** | ||
* Use “bogus comments” instead of comments to save byes: `<?charlie>` | ||
* instead of `<!--charlie-->` (default: `false`). | ||
* | ||
* > 👉 **Note**: intentionally creates parse errors in markup (how parse | ||
* > errors are handled is well defined, so this works but isn’t pretty). | ||
*/ | ||
bogusComments: boolean; | ||
/** | ||
* Configure how to serialize character references (optional). | ||
*/ | ||
characterReferences: CharacterReferences; | ||
/** | ||
* Close SVG elements without any content with slash (`/`) on the opening tag | ||
* instead of an end tag: `<circle />` instead of `<circle></circle>` | ||
* (default: `false`). | ||
* | ||
* See `tightSelfClosing` to control whether a space is used before the | ||
* slash. | ||
* | ||
* Not used in the HTML space. | ||
*/ | ||
closeEmptyElements: boolean; | ||
/** | ||
* Close self-closing nodes with an extra slash (`/`): `<img />` instead of | ||
* `<img>` (default: `false`). | ||
* | ||
* See `tightSelfClosing` to control whether a space is used before the | ||
* slash. | ||
* | ||
* Not used in the SVG space. | ||
*/ | ||
closeSelfClosing: boolean; | ||
/** | ||
* Collapse empty attributes: get `class` instead of `class=""` (default: | ||
* `false`). | ||
* | ||
* Not used in the SVG space. | ||
* | ||
* > 👉 **Note**: boolean attributes (such as `hidden`) are always collapsed. | ||
*/ | ||
collapseEmptyAttributes: boolean; | ||
/** | ||
* Omit optional opening and closing tags (default: `false`). | ||
* | ||
* For example, in `<ol><li>one</li><li>two</li></ol>`, both `</li>` closing | ||
* tags can be omitted. | ||
* The first because it’s followed by another `li`, the last because it’s | ||
* followed by nothing. | ||
* | ||
* Not used in the SVG space. | ||
*/ | ||
omitOptionalTags: boolean; | ||
/** | ||
* Leave attributes unquoted if that results in less bytes (default: `false`). | ||
* | ||
* Not used in the SVG space. | ||
*/ | ||
preferUnquoted: boolean; | ||
/** | ||
* Use the other quote if that results in less bytes (default: `false`). | ||
*/ | ||
quoteSmart: boolean; | ||
/** | ||
* Join attributes together, without whitespace, if possible: get | ||
* `class="a b"title="c d"` instead of `class="a b" title="c d"` to save | ||
* bytes (default: `false`). | ||
* | ||
* Not used in the SVG space. | ||
* | ||
* > 👉 **Note**: intentionally creates parse errors in markup (how parse | ||
* > errors are handled is well defined, so this works but isn’t pretty). | ||
*/ | ||
tightAttributes: boolean; | ||
/** | ||
* Join known comma-separated attribute values with just a comma (`,`), | ||
* instead of padding them on the right as well (`,␠`, where `␠` represents a | ||
* space) (default: `false`). | ||
*/ | ||
tightCommaSeparatedLists: boolean; | ||
/** | ||
* Drop unneeded spaces in doctypes: `<!doctypehtml>` instead of | ||
* `<!doctype html>` to save bytes (default: `false`). | ||
* | ||
* > 👉 **Note**: intentionally creates parse errors in markup (how parse | ||
* > errors are handled is well defined, so this works but isn’t pretty). | ||
*/ | ||
tightDoctype: boolean; | ||
/** | ||
* Do not use an extra space when closing self-closing elements: `<img/>` | ||
* instead of `<img />` (default: `false`). | ||
* | ||
* > 👉 **Note**: only used if `closeSelfClosing: true` or | ||
* > `closeEmptyElements: true`. | ||
*/ | ||
tightSelfClosing: boolean; | ||
/** | ||
* Use a `<!DOCTYPE…` instead of `<!doctype…` (default: `false`). | ||
* | ||
* Useless except for XHTML. | ||
*/ | ||
upperDoctype: boolean; | ||
/** | ||
* Tag names of elements to serialize without closing tag (default: `html-void-elements`). | ||
* | ||
* Not used in the SVG space. | ||
* | ||
* > 👉 **Note**: It’s highly unlikely that you want to pass this, because | ||
* > hast is not for XML, and HTML will not add more void elements. | ||
*/ | ||
voids: readonly string[]; | ||
}; | ||
/** | ||
* Namespace. | ||
*/ | ||
export type Space = 'html' | 'svg'; | ||
/** | ||
* Info passed around about the current state. | ||
*/ | ||
export type State = { | ||
/** | ||
* Serialize one node. | ||
*/ | ||
one: (node: Nodes, index: number | undefined, parent: Parents | undefined) => string; | ||
/** | ||
* Serialize the children of a parent node. | ||
*/ | ||
all: (node: Parents | undefined) => string; | ||
/** | ||
* User configuration. | ||
*/ | ||
settings: Settings; | ||
/** | ||
* Current schema. | ||
*/ | ||
schema: Schema; | ||
/** | ||
* Preferred quote. | ||
*/ | ||
quote: Quote; | ||
/** | ||
* Alternative quote. | ||
*/ | ||
alternative: Quote; | ||
}; |
184
lib/index.js
/** | ||
* @typedef {import('./types.js').Node} Node | ||
* @typedef {import('./types.js').Parent} Parent | ||
* @typedef {import('./types.js').Content} Content | ||
* @typedef {import('./types.js').Options} Options | ||
* @typedef {import('./types.js').State} State | ||
* @typedef {import('hast').Nodes} Nodes | ||
* @typedef {import('hast').Parents} Parents | ||
* @typedef {import('hast').RootContent} RootContent | ||
* | ||
* @typedef {import('property-information').Schema} Schema | ||
* | ||
* @typedef {import('stringify-entities').Options} StringifyEntitiesOptions | ||
*/ | ||
/** | ||
* @typedef {Omit<StringifyEntitiesOptions, 'attribute' | 'escapeOnly' | 'subset'>} CharacterReferences | ||
* | ||
* @typedef Options | ||
* Configuration. | ||
* @property {boolean | null | undefined} [allowDangerousCharacters=false] | ||
* Do not encode some characters which cause XSS vulnerabilities in older | ||
* browsers (default: `false`). | ||
* | ||
* > ⚠️ **Danger**: only set this if you completely trust the content. | ||
* @property {boolean | null | undefined} [allowDangerousHtml=false] | ||
* Allow `raw` nodes and insert them as raw HTML (default: `false`). | ||
* | ||
* When `false`, `Raw` nodes are encoded. | ||
* | ||
* > ⚠️ **Danger**: only set this if you completely trust the content. | ||
* @property {boolean | null | undefined} [allowParseErrors=false] | ||
* Do not encode characters which cause parse errors (even though they work), | ||
* to save bytes (default: `false`). | ||
* | ||
* Not used in the SVG space. | ||
* | ||
* > 👉 **Note**: intentionally creates parse errors in markup (how parse | ||
* > errors are handled is well defined, so this works but isn’t pretty). | ||
* @property {boolean | null | undefined} [bogusComments=false] | ||
* Use “bogus comments” instead of comments to save byes: `<?charlie>` | ||
* instead of `<!--charlie-->` (default: `false`). | ||
* | ||
* > 👉 **Note**: intentionally creates parse errors in markup (how parse | ||
* > errors are handled is well defined, so this works but isn’t pretty). | ||
* @property {CharacterReferences | null | undefined} [characterReferences] | ||
* Configure how to serialize character references (optional). | ||
* @property {boolean | null | undefined} [closeEmptyElements=false] | ||
* Close SVG elements without any content with slash (`/`) on the opening tag | ||
* instead of an end tag: `<circle />` instead of `<circle></circle>` | ||
* (default: `false`). | ||
* | ||
* See `tightSelfClosing` to control whether a space is used before the | ||
* slash. | ||
* | ||
* Not used in the HTML space. | ||
* @property {boolean | null | undefined} [closeSelfClosing=false] | ||
* Close self-closing nodes with an extra slash (`/`): `<img />` instead of | ||
* `<img>` (default: `false`). | ||
* | ||
* See `tightSelfClosing` to control whether a space is used before the | ||
* slash. | ||
* | ||
* Not used in the SVG space. | ||
* @property {boolean | null | undefined} [collapseEmptyAttributes=false] | ||
* Collapse empty attributes: get `class` instead of `class=""` (default: | ||
* `false`). | ||
* | ||
* Not used in the SVG space. | ||
* | ||
* > 👉 **Note**: boolean attributes (such as `hidden`) are always collapsed. | ||
* @property {boolean | null | undefined} [omitOptionalTags=false] | ||
* Omit optional opening and closing tags (default: `false`). | ||
* | ||
* For example, in `<ol><li>one</li><li>two</li></ol>`, both `</li>` closing | ||
* tags can be omitted. | ||
* The first because it’s followed by another `li`, the last because it’s | ||
* followed by nothing. | ||
* | ||
* Not used in the SVG space. | ||
* @property {boolean | null | undefined} [preferUnquoted=false] | ||
* Leave attributes unquoted if that results in less bytes (default: `false`). | ||
* | ||
* Not used in the SVG space. | ||
* @property {Quote | null | undefined} [quote='"'] | ||
* Preferred quote to use (default: `'"'`). | ||
* @property {boolean | null | undefined} [quoteSmart=false] | ||
* Use the other quote if that results in less bytes (default: `false`). | ||
* @property {Space | null | undefined} [space='html'] | ||
* When an `<svg>` element is found in the HTML space, this package already | ||
* automatically switches to and from the SVG space when entering and exiting | ||
* it (default: `'html'`). | ||
* | ||
* > 👉 **Note**: hast is not XML. | ||
* > It supports SVG as embedded in HTML. | ||
* > It does not support the features available in XML. | ||
* > Passing SVG might break but fragments of modern SVG should be fine. | ||
* > Use [`xast`][xast] if you need to support SVG as XML. | ||
* @property {boolean | null | undefined} [tightAttributes=false] | ||
* Join attributes together, without whitespace, if possible: get | ||
* `class="a b"title="c d"` instead of `class="a b" title="c d"` to save | ||
* bytes (default: `false`). | ||
* | ||
* Not used in the SVG space. | ||
* | ||
* > 👉 **Note**: intentionally creates parse errors in markup (how parse | ||
* > errors are handled is well defined, so this works but isn’t pretty). | ||
* @property {boolean | null | undefined} [tightCommaSeparatedLists=false] | ||
* Join known comma-separated attribute values with just a comma (`,`), | ||
* instead of padding them on the right as well (`,␠`, where `␠` represents a | ||
* space) (default: `false`). | ||
* @property {boolean | null | undefined} [tightDoctype=false] | ||
* Drop unneeded spaces in doctypes: `<!doctypehtml>` instead of | ||
* `<!doctype html>` to save bytes (default: `false`). | ||
* | ||
* > 👉 **Note**: intentionally creates parse errors in markup (how parse | ||
* > errors are handled is well defined, so this works but isn’t pretty). | ||
* @property {boolean | null | undefined} [tightSelfClosing=false] | ||
* Do not use an extra space when closing self-closing elements: `<img/>` | ||
* instead of `<img />` (default: `false`). | ||
* | ||
* > 👉 **Note**: only used if `closeSelfClosing: true` or | ||
* > `closeEmptyElements: true`. | ||
* @property {boolean | null | undefined} [upperDoctype=false] | ||
* Use a `<!DOCTYPE…` instead of `<!doctype…` (default: `false`). | ||
* | ||
* Useless except for XHTML. | ||
* @property {ReadonlyArray<string> | null | undefined} [voids] | ||
* Tag names of elements to serialize without closing tag (default: `html-void-elements`). | ||
* | ||
* Not used in the SVG space. | ||
* | ||
* > 👉 **Note**: It’s highly unlikely that you want to pass this, because | ||
* > hast is not for XML, and HTML will not add more void elements. | ||
* | ||
* @typedef {'"' | "'"} Quote | ||
* HTML quotes for attribute values. | ||
* | ||
* @typedef {Omit<Required<{[key in keyof Options]: Exclude<Options[key], null | undefined>}>, 'space' | 'quote'>} Settings | ||
* | ||
* @typedef {'html' | 'svg'} Space | ||
* Namespace. | ||
* | ||
* @typedef State | ||
* Info passed around about the current state. | ||
* @property {(node: Nodes, index: number | undefined, parent: Parents | undefined) => string} one | ||
* Serialize one node. | ||
* @property {(node: Parents | undefined) => string} all | ||
* Serialize the children of a parent node. | ||
* @property {Settings} settings | ||
* User configuration. | ||
* @property {Schema} schema | ||
* Current schema. | ||
* @property {Quote} quote | ||
* Preferred quote. | ||
* @property {Quote} alternative | ||
* Alternative quote. | ||
*/ | ||
import {htmlVoidElements} from 'html-void-elements' | ||
import {html, svg} from 'property-information' | ||
import {htmlVoidElements} from 'html-void-elements' | ||
import {handle} from './handle/index.js' | ||
/** @type {Options} */ | ||
const emptyOptions = {} | ||
/** @type {CharacterReferences} */ | ||
const emptyCharacterReferences = {} | ||
/** @type {Array<never>} */ | ||
const emptyChildren = [] | ||
/** | ||
* Serialize hast as HTML. | ||
* | ||
* @param {Node | Array<Content>} tree | ||
* @param {Array<RootContent> | Nodes} tree | ||
* Tree to serialize. | ||
* @param {Options | null | undefined} [options] | ||
* Configuration. | ||
* Configuration (optional). | ||
* @returns {string} | ||
* Serialized HTML. | ||
*/ | ||
// eslint-disable-next-line complexity | ||
export function toHtml(tree, options) { | ||
const options_ = options || {} | ||
const options_ = options || emptyOptions | ||
const quote = options_.quote || '"' | ||
@@ -53,3 +207,3 @@ const alternative = quote === '"' ? "'" : '"' | ||
characterReferences: | ||
options_.characterReferences || options_.entities || {}, | ||
options_.characterReferences || emptyCharacterReferences, | ||
closeSelfClosing: options_.closeSelfClosing || false, | ||
@@ -75,7 +229,7 @@ closeEmptyElements: options_.closeEmptyElements || false | ||
* Info passed around about the current state. | ||
* @param {Node} node | ||
* @param {Nodes} node | ||
* Node to handle. | ||
* @param {number | undefined} index | ||
* Index of `node` in `parent. | ||
* @param {Parent | undefined} parent | ||
* @param {Parents | undefined} parent | ||
* Parent of `node`. | ||
@@ -94,3 +248,3 @@ * @returns {string} | ||
* Info passed around about the current state. | ||
* @param {Parent | undefined} parent | ||
* @param {Parents | undefined} parent | ||
* Parent whose children to serialize. | ||
@@ -102,3 +256,3 @@ * @returns {string} | ||
const results = [] | ||
const children = (parent && parent.children) || [] | ||
const children = (parent && parent.children) || emptyChildren | ||
let index = -1 | ||
@@ -105,0 +259,0 @@ |
@@ -1,3 +0,3 @@ | ||
export const closing: import('../types.js').OmitHandle | ||
export type Element = import('../types.js').Element | ||
export type Parent = import('../types.js').Parent | ||
export const closing: import("./omission.js").OmitHandle; | ||
export type Element = import('hast').Element; | ||
export type Parents = import('hast').Parents; |
/** | ||
* @typedef {import('../types.js').Element} Element | ||
* @typedef {import('../types.js').Parent} Parent | ||
* @typedef {import('hast').Element} Element | ||
* @typedef {import('hast').Parents} Parents | ||
*/ | ||
@@ -11,22 +11,21 @@ | ||
export const closing = omission({ | ||
body, | ||
caption: headOrColgroupOrCaption, | ||
colgroup: headOrColgroupOrCaption, | ||
dd, | ||
dt, | ||
head: headOrColgroupOrCaption, | ||
html, | ||
head: headOrColgroupOrCaption, | ||
body, | ||
p, | ||
li, | ||
dt, | ||
dd, | ||
rt: rubyElement, | ||
rp: rubyElement, | ||
optgroup, | ||
option, | ||
menuitem, | ||
colgroup: headOrColgroupOrCaption, | ||
caption: headOrColgroupOrCaption, | ||
thead, | ||
p, | ||
rp: rubyElement, | ||
rt: rubyElement, | ||
tbody, | ||
td: cells, | ||
tfoot, | ||
tr, | ||
td: cells, | ||
th: cells | ||
th: cells, | ||
thead, | ||
tr | ||
}) | ||
@@ -41,3 +40,3 @@ | ||
* Index of element in parent. | ||
* @param {Parent | undefined} parent | ||
* @param {Parents | undefined} parent | ||
* Parent of element. | ||
@@ -63,3 +62,3 @@ * @returns {boolean} | ||
* Index of element in parent. | ||
* @param {Parent | undefined} parent | ||
* @param {Parents | undefined} parent | ||
* Parent of element. | ||
@@ -81,3 +80,3 @@ * @returns {boolean} | ||
* Index of element in parent. | ||
* @param {Parent | undefined} parent | ||
* @param {Parents | undefined} parent | ||
* Parent of element. | ||
@@ -99,3 +98,3 @@ * @returns {boolean} | ||
* Index of element in parent. | ||
* @param {Parent | undefined} parent | ||
* @param {Parents | undefined} parent | ||
* Parent of element. | ||
@@ -105,3 +104,2 @@ * @returns {boolean} | ||
*/ | ||
// eslint-disable-next-line complexity | ||
function p(_, index, parent) { | ||
@@ -162,3 +160,3 @@ const next = siblingAfter(parent, index) | ||
* Index of element in parent. | ||
* @param {Parent | undefined} parent | ||
* @param {Parents | undefined} parent | ||
* Parent of element. | ||
@@ -180,3 +178,3 @@ * @returns {boolean} | ||
* Index of element in parent. | ||
* @param {Parent | undefined} parent | ||
* @param {Parents | undefined} parent | ||
* Parent of element. | ||
@@ -188,6 +186,6 @@ * @returns {boolean} | ||
const next = siblingAfter(parent, index) | ||
return ( | ||
return Boolean( | ||
next && | ||
next.type === 'element' && | ||
(next.tagName === 'dt' || next.tagName === 'dd') | ||
next.type === 'element' && | ||
(next.tagName === 'dt' || next.tagName === 'dd') | ||
) | ||
@@ -203,3 +201,3 @@ } | ||
* Index of element in parent. | ||
* @param {Parent | undefined} parent | ||
* @param {Parents | undefined} parent | ||
* Parent of element. | ||
@@ -225,3 +223,3 @@ * @returns {boolean} | ||
* Index of element in parent. | ||
* @param {Parent | undefined} parent | ||
* @param {Parents | undefined} parent | ||
* Parent of element. | ||
@@ -247,3 +245,3 @@ * @returns {boolean} | ||
* Index of element in parent. | ||
* @param {Parent | undefined} parent | ||
* @param {Parents | undefined} parent | ||
* Parent of element. | ||
@@ -265,3 +263,3 @@ * @returns {boolean} | ||
* Index of element in parent. | ||
* @param {Parent | undefined} parent | ||
* @param {Parents | undefined} parent | ||
* Parent of element. | ||
@@ -281,25 +279,2 @@ * @returns {boolean} | ||
/** | ||
* Whether to omit `</menuitem>`. | ||
* | ||
* @param {Element} _ | ||
* Element. | ||
* @param {number | undefined} index | ||
* Index of element in parent. | ||
* @param {Parent | undefined} parent | ||
* Parent of element. | ||
* @returns {boolean} | ||
* Whether the closing tag can be omitted. | ||
*/ | ||
function menuitem(_, index, parent) { | ||
const next = siblingAfter(parent, index) | ||
return ( | ||
!next || | ||
(next.type === 'element' && | ||
(next.tagName === 'menuitem' || | ||
next.tagName === 'hr' || | ||
next.tagName === 'menu')) | ||
) | ||
} | ||
/** | ||
* Whether to omit `</thead>`. | ||
@@ -311,3 +286,3 @@ * | ||
* Index of element in parent. | ||
* @param {Parent | undefined} parent | ||
* @param {Parents | undefined} parent | ||
* Parent of element. | ||
@@ -319,6 +294,6 @@ * @returns {boolean} | ||
const next = siblingAfter(parent, index) | ||
return ( | ||
return Boolean( | ||
next && | ||
next.type === 'element' && | ||
(next.tagName === 'tbody' || next.tagName === 'tfoot') | ||
next.type === 'element' && | ||
(next.tagName === 'tbody' || next.tagName === 'tfoot') | ||
) | ||
@@ -334,3 +309,3 @@ } | ||
* Index of element in parent. | ||
* @param {Parent | undefined} parent | ||
* @param {Parents | undefined} parent | ||
* Parent of element. | ||
@@ -356,3 +331,3 @@ * @returns {boolean} | ||
* Index of element in parent. | ||
* @param {Parent | undefined} parent | ||
* @param {Parents | undefined} parent | ||
* Parent of element. | ||
@@ -373,3 +348,3 @@ * @returns {boolean} | ||
* Index of element in parent. | ||
* @param {Parent | undefined} parent | ||
* @param {Parents | undefined} parent | ||
* Parent of element. | ||
@@ -391,3 +366,3 @@ * @returns {boolean} | ||
* Index of element in parent. | ||
* @param {Parent | undefined} parent | ||
* @param {Parents | undefined} parent | ||
* Parent of element. | ||
@@ -394,0 +369,0 @@ * @returns {boolean} |
@@ -10,3 +10,8 @@ /** | ||
*/ | ||
export function omission(handlers: Record<string, OmitHandle>): OmitHandle | ||
export type OmitHandle = import('../types.js').OmitHandle | ||
export function omission(handlers: Record<string, OmitHandle>): OmitHandle; | ||
export type Element = import('hast').Element; | ||
export type Parents = import('hast').Parents; | ||
/** | ||
* Check if a tag can be omitted. | ||
*/ | ||
export type OmitHandle = (element: Element, index: number | undefined, parent: Parents | undefined) => boolean; |
/** | ||
* @typedef {import('../types.js').OmitHandle} OmitHandle | ||
* @typedef {import('hast').Element} Element | ||
* @typedef {import('hast').Parents} Parents | ||
*/ | ||
/** | ||
* @callback OmitHandle | ||
* Check if a tag can be omitted. | ||
* @param {Element} element | ||
* Element to check. | ||
* @param {number | undefined} index | ||
* Index of element in parent. | ||
* @param {Parents | undefined} parent | ||
* Parent of element. | ||
* @returns {boolean} | ||
* Whether to omit a tag. | ||
* | ||
*/ | ||
const own = {}.hasOwnProperty | ||
@@ -6,0 +21,0 @@ |
@@ -1,4 +0,3 @@ | ||
export const opening: import('../types.js').OmitHandle | ||
export type Element = import('../types.js').Element | ||
export type Parent = import('../types.js').Parent | ||
export type Content = import('../types.js').Content | ||
export const opening: import("./omission.js").OmitHandle; | ||
export type Element = import('hast').Element; | ||
export type Parents = import('hast').Parents; |
/** | ||
* @typedef {import('../types.js').Element} Element | ||
* @typedef {import('../types.js').Parent} Parent | ||
* @typedef {import('../types.js').Content} Content | ||
* @typedef {import('hast').Element} Element | ||
* @typedef {import('hast').Parents} Parents | ||
*/ | ||
import {whitespace} from 'hast-util-whitespace' | ||
import {siblingBefore, siblingAfter} from './util/siblings.js' | ||
import {siblingAfter, siblingBefore} from './util/siblings.js' | ||
import {closing} from './closing.js' | ||
@@ -13,6 +12,6 @@ import {omission} from './omission.js' | ||
export const opening = omission({ | ||
html, | ||
head, | ||
body, | ||
colgroup, | ||
head, | ||
html, | ||
tbody | ||
@@ -98,3 +97,3 @@ }) | ||
* Index of element in parent. | ||
* @param {Parent | undefined} parent | ||
* @param {Parents | undefined} parent | ||
* Parent of element. | ||
@@ -119,3 +118,3 @@ * @returns {boolean} | ||
return head && head.type === 'element' && head.tagName === 'col' | ||
return Boolean(head && head.type === 'element' && head.tagName === 'col') | ||
} | ||
@@ -130,3 +129,3 @@ | ||
* Index of element in parent. | ||
* @param {Parent | undefined} parent | ||
* @param {Parents | undefined} parent | ||
* Parent of element. | ||
@@ -151,3 +150,3 @@ * @returns {boolean} | ||
return head && head.type === 'element' && head.tagName === 'tr' | ||
return Boolean(head && head.type === 'element' && head.tagName === 'tr') | ||
} |
/** | ||
* Find applicable siblings in a direction. | ||
* | ||
* @param {Parent | null | undefined} parent | ||
* @param {number | null | undefined} index | ||
* @param {boolean | null | undefined} [includeWhitespace=false] | ||
* @returns {Content} | ||
* @template {Parents} Parent | ||
* Parent type. | ||
* @param {Parent | undefined} parent | ||
* Parent. | ||
* @param {number | undefined} index | ||
* Index of child in `parent`. | ||
* @param {boolean | undefined} [includeWhitespace=false] | ||
* Whether to include whitespace (default: `false`). | ||
* @returns {Parent extends {children: Array<infer Child>} ? Child | undefined : never} | ||
* Child of parent. | ||
*/ | ||
export function siblingAfter( | ||
parent: Parent | null | undefined, | ||
index: number | null | undefined, | ||
includeWhitespace?: boolean | null | undefined | ||
): Content | ||
export function siblingAfter<Parent extends import("hast").Parents>(parent: Parent | undefined, index: number | undefined, includeWhitespace?: boolean | undefined): Parent extends { | ||
children: (infer Child)[]; | ||
} ? Child | undefined : never; | ||
/** | ||
* Find applicable siblings in a direction. | ||
* | ||
* @param {Parent | null | undefined} parent | ||
* @param {number | null | undefined} index | ||
* @param {boolean | null | undefined} [includeWhitespace=false] | ||
* @returns {Content} | ||
* @template {Parents} Parent | ||
* Parent type. | ||
* @param {Parent | undefined} parent | ||
* Parent. | ||
* @param {number | undefined} index | ||
* Index of child in `parent`. | ||
* @param {boolean | undefined} [includeWhitespace=false] | ||
* Whether to include whitespace (default: `false`). | ||
* @returns {Parent extends {children: Array<infer Child>} ? Child | undefined : never} | ||
* Child of parent. | ||
*/ | ||
export function siblingBefore( | ||
parent: Parent | null | undefined, | ||
index: number | null | undefined, | ||
includeWhitespace?: boolean | null | undefined | ||
): Content | ||
export type Parent = import('../../types.js').Parent | ||
export type Content = import('../../types.js').Content | ||
export function siblingBefore<Parent extends import("hast").Parents>(parent: Parent | undefined, index: number | undefined, includeWhitespace?: boolean | undefined): Parent extends { | ||
children: (infer Child)[]; | ||
} ? Child | undefined : never; | ||
export type Parents = import('hast').Parents; | ||
export type RootContent = import('hast').RootContent; |
/** | ||
* @typedef {import('../../types.js').Parent} Parent | ||
* @typedef {import('../../types.js').Content} Content | ||
* @typedef {import('hast').Parents} Parents | ||
* @typedef {import('hast').RootContent} RootContent | ||
*/ | ||
@@ -11,2 +11,5 @@ | ||
/** @type {Array<RootContent>} */ | ||
const emptyChildren = [] | ||
/** | ||
@@ -23,11 +26,17 @@ * Factory to check siblings in a direction. | ||
* | ||
* @param {Parent | null | undefined} parent | ||
* @param {number | null | undefined} index | ||
* @param {boolean | null | undefined} [includeWhitespace=false] | ||
* @returns {Content} | ||
* @template {Parents} Parent | ||
* Parent type. | ||
* @param {Parent | undefined} parent | ||
* Parent. | ||
* @param {number | undefined} index | ||
* Index of child in `parent`. | ||
* @param {boolean | undefined} [includeWhitespace=false] | ||
* Whether to include whitespace (default: `false`). | ||
* @returns {Parent extends {children: Array<infer Child>} ? Child | undefined : never} | ||
* Child of parent. | ||
*/ | ||
function sibling(parent, index, includeWhitespace) { | ||
const siblings = parent ? parent.children : [] | ||
const siblings = parent ? parent.children : emptyChildren | ||
let offset = (index || 0) + increment | ||
let next = siblings && siblings[offset] | ||
let next = siblings[offset] | ||
@@ -41,4 +50,5 @@ if (!includeWhitespace) { | ||
// @ts-expect-error: it’s a correct child. | ||
return next | ||
} | ||
} |
{ | ||
"name": "hast-util-to-html", | ||
"version": "8.0.4", | ||
"version": "9.0.0", | ||
"description": "hast utility to serialize to HTML", | ||
@@ -29,4 +29,3 @@ "license": "MIT", | ||
"type": "module", | ||
"main": "index.js", | ||
"types": "index.d.ts", | ||
"exports": "./index.js", | ||
"files": [ | ||
@@ -38,9 +37,10 @@ "lib/", | ||
"dependencies": { | ||
"@types/hast": "^2.0.0", | ||
"@types/unist": "^2.0.0", | ||
"@types/hast": "^3.0.0", | ||
"@types/unist": "^3.0.0", | ||
"ccount": "^2.0.0", | ||
"comma-separated-tokens": "^2.0.0", | ||
"hast-util-raw": "^7.0.0", | ||
"hast-util-whitespace": "^2.0.0", | ||
"html-void-elements": "^2.0.0", | ||
"hast-util-raw": "^9.0.0", | ||
"hast-util-whitespace": "^3.0.0", | ||
"html-void-elements": "^3.0.0", | ||
"mdast-util-to-hast": "^13.0.0", | ||
"property-information": "^6.0.0", | ||
@@ -52,12 +52,12 @@ "space-separated-tokens": "^2.0.0", | ||
"devDependencies": { | ||
"@types/node": "^18.0.0", | ||
"c8": "^7.0.0", | ||
"hastscript": "^7.0.0", | ||
"prettier": "^2.0.0", | ||
"@types/node": "^20.0.0", | ||
"c8": "^8.0.0", | ||
"hastscript": "^8.0.0", | ||
"prettier": "^3.0.0", | ||
"remark-cli": "^11.0.0", | ||
"remark-preset-wooorm": "^9.0.0", | ||
"type-coverage": "^2.0.0", | ||
"typescript": "^4.0.0", | ||
"unist-builder": "^3.0.0", | ||
"xo": "^0.53.0" | ||
"typescript": "^5.0.0", | ||
"unist-builder": "^4.0.0", | ||
"xo": "^0.55.0" | ||
}, | ||
@@ -67,21 +67,18 @@ "scripts": { | ||
"build": "tsc --build --clean && tsc --build && type-coverage", | ||
"format": "remark . -qfo && prettier . -w --loglevel warn && xo --fix", | ||
"format": "remark . -qfo && prettier . -w --log-level warn && xo --fix", | ||
"test-api": "node --conditions development test/index.js", | ||
"test-coverage": "c8 --check-coverage --100 --reporter lcov npm run test-api", | ||
"test-coverage": "c8 --100 --reporter lcov npm run test-api", | ||
"test": "npm run build && npm run format && npm run test-coverage" | ||
}, | ||
"prettier": { | ||
"tabWidth": 2, | ||
"useTabs": false, | ||
"singleQuote": true, | ||
"bracketSpacing": false, | ||
"semi": false, | ||
"trailingComma": "none" | ||
"singleQuote": true, | ||
"tabWidth": 2, | ||
"trailingComma": "none", | ||
"useTabs": false | ||
}, | ||
"xo": { | ||
"prettier": true | ||
}, | ||
"remarkConfig": { | ||
"plugins": [ | ||
"preset-wooorm", | ||
"remark-preset-wooorm", | ||
[ | ||
@@ -96,4 +93,23 @@ "remark-lint-no-html", | ||
"detail": true, | ||
"ignoreCatch": true, | ||
"strict": true | ||
}, | ||
"xo": { | ||
"overrides": [ | ||
{ | ||
"files": [ | ||
"test/**/*.js" | ||
], | ||
"rules": { | ||
"no-await-in-loop": "off" | ||
} | ||
} | ||
], | ||
"prettier": true, | ||
"rules": { | ||
"complexity": "off", | ||
"unicorn/prefer-at": "off", | ||
"unicorn/prefer-string-replace-all": "off" | ||
} | ||
} | ||
} |
@@ -58,3 +58,3 @@ # hast-util-to-html | ||
This package is [ESM only][esm]. | ||
In Node.js (version 14.14+ and 16.0+), install with [npm][]: | ||
In Node.js (version 16+), install with [npm][]: | ||
@@ -68,3 +68,3 @@ ```sh | ||
```js | ||
import {toHtml} from "https://esm.sh/hast-util-to-html@8" | ||
import {toHtml} from "https://esm.sh/hast-util-to-html@9" | ||
``` | ||
@@ -76,3 +76,3 @@ | ||
<script type="module"> | ||
import {toHtml} from "https://esm.sh/hast-util-to-html@8?bundle" | ||
import {toHtml} from "https://esm.sh/hast-util-to-html@9?bundle" | ||
</script> | ||
@@ -113,3 +113,3 @@ ``` | ||
This package exports the identifier [`toHtml`][tohtml]. | ||
This package exports the identifier [`toHtml`][api-to-html]. | ||
There is no default export. | ||
@@ -125,3 +125,3 @@ | ||
— tree to serialize | ||
* `options` ([`Options`][options], optional) | ||
* `options` ([`Options`][api-options], optional) | ||
— configuration | ||
@@ -144,10 +144,2 @@ | ||
###### `useShortestReferences` | ||
Prefer the shortest possible reference, if that results in less bytes | ||
(`boolean`, default: `false`). | ||
> ⚠️ **Note**: `useNamedReferences` can be omitted when using | ||
> `useShortestReferences`. | ||
###### `omitOptionalSemicolons` | ||
@@ -162,2 +154,10 @@ | ||
###### `useShortestReferences` | ||
Prefer the shortest possible reference, if that results in less bytes | ||
(`boolean`, default: `false`). | ||
> ⚠️ **Note**: `useNamedReferences` can be omitted when using | ||
> `useShortestReferences`. | ||
### `Options` | ||
@@ -205,3 +205,3 @@ | ||
Configure how to serialize character references | ||
([`CharacterReferences`][characterreferences], optional). | ||
([`CharacterReferences`][api-character-references], optional). | ||
@@ -256,3 +256,3 @@ ###### `closeEmptyElements` | ||
Preferred quote to use ([`Quote`][quote], default: `'"'`). | ||
Preferred quote to use ([`Quote`][api-quote], default: `'"'`). | ||
@@ -265,3 +265,3 @@ ###### `quoteSmart` | ||
Which space the document is in ([`Space`][space], default: `'html'`). | ||
Which space the document is in ([`Space`][api-space], default: `'html'`). | ||
@@ -354,12 +354,18 @@ When an `<svg>` element is found in the HTML space, this package already | ||
This package is fully typed with [TypeScript][]. | ||
It exports the additional types [`CharacterReferences`][characterreferences], | ||
[`Options`][options], [`Quote`][quote], and [`Space`][space]. | ||
It exports the additional types | ||
[`CharacterReferences`][api-character-references], | ||
[`Options`][api-options], | ||
[`Quote`][api-quote], and | ||
[`Space`][api-space]. | ||
## Compatibility | ||
Projects maintained by the unified collective are compatible with all maintained | ||
Projects maintained by the unified collective are compatible with maintained | ||
versions of Node.js. | ||
As of now, that is Node.js 14.14+ and 16.0+. | ||
Our projects sometimes work with older versions, but this is not guaranteed. | ||
When we cut a new major release, we drop support for unmaintained versions of | ||
Node. | ||
This means we try to keep the current release line, `hast-util-to-html@^9`, | ||
compatible with Node.js 16. | ||
## Security | ||
@@ -404,5 +410,5 @@ | ||
[size-badge]: https://img.shields.io/bundlephobia/minzip/hast-util-to-html.svg | ||
[size-badge]: https://img.shields.io/badge/dynamic/json?label=minzipped%20size&query=$.size.compressedSize&url=https://deno.bundlejs.com/?q=hast-util-to-html | ||
[size]: https://bundlephobia.com/result?p=hast-util-to-html | ||
[size]: https://bundlejs.com/?q=hast-util-to-html | ||
@@ -455,10 +461,10 @@ [sponsors-badge]: https://opencollective.com/unified/sponsors/badge.svg | ||
[tohtml]: #tohtmltree-options | ||
[api-to-html]: #tohtmltree-options | ||
[characterreferences]: #characterreferences | ||
[api-character-references]: #characterreferences | ||
[options]: #options | ||
[api-options]: #options | ||
[space]: #space | ||
[api-space]: #space-1 | ||
[quote]: #quote | ||
[api-quote]: #quote-1 |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
458
0
72467
12
29
1797
+ Addedmdast-util-to-hast@^13.0.0
+ Added@types/hast@3.0.4(transitive)
+ Added@types/mdast@4.0.4(transitive)
+ Added@types/unist@3.0.3(transitive)
+ Added@ungap/structured-clone@1.2.0(transitive)
+ Addeddequal@2.0.3(transitive)
+ Addeddevlop@1.1.0(transitive)
+ Addedentities@4.5.0(transitive)
+ Addedhast-util-from-parse5@8.0.1(transitive)
+ Addedhast-util-parse-selector@4.0.0(transitive)
+ Addedhast-util-raw@9.0.4(transitive)
+ Addedhast-util-to-parse5@8.0.0(transitive)
+ Addedhast-util-whitespace@3.0.0(transitive)
+ Addedhastscript@8.0.0(transitive)
+ Addedhtml-void-elements@3.0.0(transitive)
+ Addedmdast-util-to-hast@13.2.0(transitive)
+ Addedmicromark-util-character@2.1.0(transitive)
+ Addedmicromark-util-encode@2.0.0(transitive)
+ Addedmicromark-util-sanitize-uri@2.0.0(transitive)
+ Addedmicromark-util-symbol@2.0.0(transitive)
+ Addedmicromark-util-types@2.0.0(transitive)
+ Addedparse5@7.1.2(transitive)
+ Addedtrim-lines@3.0.1(transitive)
+ Addedunist-util-is@6.0.0(transitive)
+ Addedunist-util-position@5.0.0(transitive)
+ Addedunist-util-stringify-position@4.0.0(transitive)
+ Addedunist-util-visit@5.0.0(transitive)
+ Addedunist-util-visit-parents@6.0.1(transitive)
+ Addedvfile@6.0.3(transitive)
+ Addedvfile-location@5.0.3(transitive)
+ Addedvfile-message@4.0.2(transitive)
- Removed@types/hast@2.3.10(transitive)
- Removed@types/parse5@6.0.3(transitive)
- Removed@types/unist@2.0.11(transitive)
- Removedhast-util-from-parse5@7.1.2(transitive)
- Removedhast-util-parse-selector@3.1.1(transitive)
- Removedhast-util-raw@7.2.3(transitive)
- Removedhast-util-to-parse5@7.1.0(transitive)
- Removedhast-util-whitespace@2.0.1(transitive)
- Removedhastscript@7.2.0(transitive)
- Removedhtml-void-elements@2.0.1(transitive)
- Removedis-buffer@2.0.5(transitive)
- Removedparse5@6.0.1(transitive)
- Removedunist-util-is@5.2.1(transitive)
- Removedunist-util-position@4.0.4(transitive)
- Removedunist-util-stringify-position@3.0.3(transitive)
- Removedunist-util-visit@4.1.2(transitive)
- Removedunist-util-visit-parents@5.1.3(transitive)
- Removedvfile@5.3.7(transitive)
- Removedvfile-location@4.1.0(transitive)
- Removedvfile-message@3.1.4(transitive)
Updated@types/hast@^3.0.0
Updated@types/unist@^3.0.0
Updatedhast-util-raw@^9.0.0
Updatedhast-util-whitespace@^3.0.0
Updatedhtml-void-elements@^3.0.0