Refactor routing in App component to enhance navigation and improve error handling by integrating dynamic routes and updating the NotFound route.

This commit is contained in:
becarta
2025-05-23 12:43:00 +02:00
parent f40db0f5c9
commit a544759a3b
11127 changed files with 1647032 additions and 0 deletions

19
node_modules/hast-util-to-html/lib/handle/comment.d.ts generated vendored Normal file
View File

@@ -0,0 +1,19 @@
/**
* Serialize a comment.
*
* @param {Comment} node
* Node to handle.
* @param {number | undefined} _1
* Index of `node` in `parent.
* @param {Parents | undefined} _2
* Parent of `node`.
* @param {State} state
* Info passed around about the current state.
* @returns {string}
* Serialized node.
*/
export function comment(node: Comment, _1: number | undefined, _2: Parents | undefined, state: State): string;
import type { Comment } from 'hast';
import type { Parents } from 'hast';
import type { State } from '../index.js';
//# sourceMappingURL=comment.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"comment.d.ts","sourceRoot":"","sources":["comment.js"],"names":[],"mappings":"AAaA;;;;;;;;;;;;;GAaG;AACH,8BAXW,OAAO,MAEP,MAAM,GAAG,SAAS,MAElB,OAAO,GAAG,SAAS,SAEnB,KAAK,GAEH,MAAM,CA2BlB;6BAlDkC,MAAM;6BAAN,MAAM;2BACjB,aAAa"}

52
node_modules/hast-util-to-html/lib/handle/comment.js generated vendored Normal file
View File

@@ -0,0 +1,52 @@
/**
* @import {Comment, Parents} from 'hast'
* @import {State} from '../index.js'
*/
import {stringifyEntities} from 'stringify-entities'
const htmlCommentRegex = /^>|^->|<!--|-->|--!>|<!-$/g
// Declare arrays as variables so it can be cached by `stringifyEntities`
const bogusCommentEntitySubset = ['>']
const commentEntitySubset = ['<', '>']
/**
* Serialize a comment.
*
* @param {Comment} node
* Node to handle.
* @param {number | undefined} _1
* Index of `node` in `parent.
* @param {Parents | undefined} _2
* Parent of `node`.
* @param {State} state
* Info passed around about the current state.
* @returns {string}
* Serialized node.
*/
export function comment(node, _1, _2, state) {
// See: <https://html.spec.whatwg.org/multipage/syntax.html#comments>
return state.settings.bogusComments
? '<?' +
stringifyEntities(
node.value,
Object.assign({}, state.settings.characterReferences, {
subset: bogusCommentEntitySubset
})
) +
'>'
: '<!--' + node.value.replace(htmlCommentRegex, encode) + '-->'
/**
* @param {string} $0
*/
function encode($0) {
return stringifyEntities(
$0,
Object.assign({}, state.settings.characterReferences, {
subset: commentEntitySubset
})
)
}
}

23
node_modules/hast-util-to-html/lib/handle/doctype.d.ts generated vendored Normal file
View File

@@ -0,0 +1,23 @@
/**
* @import {Doctype, Parents} from 'hast'
* @import {State} from '../index.js'
*/
/**
* Serialize a doctype.
*
* @param {Doctype} _1
* Node to handle.
* @param {number | undefined} _2
* Index of `node` in `parent.
* @param {Parents | undefined} _3
* Parent of `node`.
* @param {State} state
* Info passed around about the current state.
* @returns {string}
* Serialized node.
*/
export function doctype(_1: Doctype, _2: number | undefined, _3: Parents | undefined, state: State): string;
import type { Doctype } from 'hast';
import type { Parents } from 'hast';
import type { State } from '../index.js';
//# sourceMappingURL=doctype.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"doctype.d.ts","sourceRoot":"","sources":["doctype.js"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;;;;;GAaG;AACH,4BAXW,OAAO,MAEP,MAAM,GAAG,SAAS,MAElB,OAAO,GAAG,SAAS,SAEnB,KAAK,GAEH,MAAM,CAUlB;6BAzBkC,MAAM;6BAAN,MAAM;2BACjB,aAAa"}

27
node_modules/hast-util-to-html/lib/handle/doctype.js generated vendored Normal file
View File

@@ -0,0 +1,27 @@
/**
* @import {Doctype, Parents} from 'hast'
* @import {State} from '../index.js'
*/
/**
* Serialize a doctype.
*
* @param {Doctype} _1
* Node to handle.
* @param {number | undefined} _2
* Index of `node` in `parent.
* @param {Parents | undefined} _3
* Parent of `node`.
* @param {State} state
* Info passed around about the current state.
* @returns {string}
* Serialized node.
*/
export function doctype(_1, _2, _3, state) {
return (
'<!' +
(state.settings.upperDoctype ? 'DOCTYPE' : 'doctype') +
(state.settings.tightDoctype ? '' : ' ') +
'html>'
)
}

19
node_modules/hast-util-to-html/lib/handle/element.d.ts generated vendored Normal file
View File

@@ -0,0 +1,19 @@
/**
* Serialize an element node.
*
* @param {Element} node
* Node to handle.
* @param {number | undefined} index
* Index of `node` in `parent.
* @param {Parents | undefined} parent
* Parent of `node`.
* @param {State} state
* Info passed around about the current state.
* @returns {string}
* Serialized node.
*/
export function element(node: Element, index: number | undefined, parent: Parents | undefined, state: State): string;
import type { Element } from 'hast';
import type { Parents } from 'hast';
import type { State } from '../index.js';
//# sourceMappingURL=element.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"element.d.ts","sourceRoot":"","sources":["element.js"],"names":[],"mappings":"AA6CA;;;;;;;;;;;;;GAaG;AACH,8BAXW,OAAO,SAEP,MAAM,GAAG,SAAS,UAElB,OAAO,GAAG,SAAS,SAEnB,KAAK,GAEH,MAAM,CAgElB;6BAvH8C,MAAM;6BAAN,MAAM;2BAC7B,aAAa"}

265
node_modules/hast-util-to-html/lib/handle/element.js generated vendored Normal file
View File

@@ -0,0 +1,265 @@
/**
* @import {Element, Parents, Properties} from 'hast'
* @import {State} from '../index.js'
*/
import {ccount} from 'ccount'
import {stringify as commas} from 'comma-separated-tokens'
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'
/**
* Maps of subsets.
*
* Each value is a matrix of tuples.
* The value at `0` causes parse errors, the value at `1` is valid.
* Of both, the value at `0` is unsafe, and the value at `1` is safe.
*
* @type {Record<'double' | 'name' | 'single' | 'unquoted', Array<[Array<string>, Array<string>]>>}
*/
const constants = {
// See: <https://html.spec.whatwg.org/#attribute-name-state>.
name: [
['\t\n\f\r &/=>'.split(''), '\t\n\f\r "&\'/=>`'.split('')],
['\0\t\n\f\r "&\'/<=>'.split(''), '\0\t\n\f\r "&\'/<=>`'.split('')]
],
// See: <https://html.spec.whatwg.org/#attribute-value-(unquoted)-state>.
unquoted: [
['\t\n\f\r &>'.split(''), '\0\t\n\f\r "&\'<=>`'.split('')],
['\0\t\n\f\r "&\'<=>`'.split(''), '\0\t\n\f\r "&\'<=>`'.split('')]
],
// See: <https://html.spec.whatwg.org/#attribute-value-(single-quoted)-state>.
single: [
["&'".split(''), '"&\'`'.split('')],
["\0&'".split(''), '\0"&\'`'.split('')]
],
// See: <https://html.spec.whatwg.org/#attribute-value-(double-quoted)-state>.
double: [
['"&'.split(''), '"&\'`'.split('')],
['\0"&'.split(''), '\0"&\'`'.split('')]
]
}
/**
* Serialize an element node.
*
* @param {Element} node
* Node to handle.
* @param {number | undefined} index
* Index of `node` in `parent.
* @param {Parents | undefined} parent
* Parent of `node`.
* @param {State} state
* Info passed around about the current state.
* @returns {string}
* Serialized node.
*/
export function element(node, index, parent, state) {
const schema = state.schema
const omit = schema.space === 'svg' ? false : state.settings.omitOptionalTags
let selfClosing =
schema.space === 'svg'
? state.settings.closeEmptyElements
: state.settings.voids.includes(node.tagName.toLowerCase())
/** @type {Array<string>} */
const parts = []
/** @type {string} */
let last
if (schema.space === 'html' && node.tagName === 'svg') {
state.schema = svg
}
const attributes = serializeAttributes(state, node.properties)
const content = state.all(
schema.space === 'html' && node.tagName === 'template' ? node.content : node
)
state.schema = schema
// If the node is categorised as void, but it has children, remove the
// categorisation.
// This enables for example `menuitem`s, which are void in W3C HTML but not
// 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
if (attributes || !omit || !opening(node, index, parent)) {
parts.push('<', node.tagName, attributes ? ' ' + attributes : '')
if (
selfClosing &&
(schema.space === 'svg' || state.settings.closeSelfClosing)
) {
last = attributes.charAt(attributes.length - 1)
if (
!state.settings.tightSelfClosing ||
last === '/' ||
(last && last !== '"' && last !== "'")
) {
parts.push(' ')
}
parts.push('/')
}
parts.push('>')
}
parts.push(content)
if (!selfClosing && (!omit || !closing(node, index, parent))) {
parts.push('</' + node.tagName + '>')
}
return parts.join('')
}
/**
* @param {State} state
* @param {Properties | null | undefined} properties
* @returns {string}
*/
function serializeAttributes(state, properties) {
/** @type {Array<string>} */
const values = []
let index = -1
/** @type {string} */
let key
if (properties) {
for (key in properties) {
if (properties[key] !== null && properties[key] !== undefined) {
const value = serializeAttribute(state, key, properties[key])
if (value) values.push(value)
}
}
}
while (++index < values.length) {
const last = state.settings.tightAttributes
? values[index].charAt(values[index].length - 1)
: undefined
// In tight mode, dont add a space after quoted attributes.
if (index !== values.length - 1 && last !== '"' && last !== "'") {
values[index] += ' '
}
}
return values.join('')
}
/**
* @param {State} state
* @param {string} key
* @param {Properties[keyof Properties]} value
* @returns {string}
*/
function serializeAttribute(state, key, value) {
const info = find(state.schema, key)
const x =
state.settings.allowParseErrors && state.schema.space === 'html' ? 0 : 1
const y = state.settings.allowDangerousCharacters ? 0 : 1
let quote = state.quote
/** @type {string | undefined} */
let result
if (info.overloadedBoolean && (value === info.attribute || value === '')) {
value = true
} else if (
(info.boolean || info.overloadedBoolean) &&
(typeof value !== 'string' || value === info.attribute || value === '')
) {
value = Boolean(value)
}
if (
value === null ||
value === undefined ||
value === false ||
(typeof value === 'number' && Number.isNaN(value))
) {
return ''
}
const name = stringifyEntities(
info.attribute,
Object.assign({}, state.settings.characterReferences, {
// Always encode without parse errors in non-HTML.
subset: constants.name[x][y]
})
)
// No value.
// There is currently only one boolean property in SVG: `[download]` on
// `<a>`.
// This property does not seem to work in browsers (Firefox, Safari, Chrome),
// so I cant test if dropping the value works.
// But I assume that it should:
//
// ```html
// <!doctype html>
// <svg viewBox="0 0 100 100">
// <a href=https://example.com download>
// <circle cx=50 cy=40 r=35 />
// </a>
// </svg>
// ```
//
// See: <https://github.com/wooorm/property-information/blob/main/lib/svg.js>
if (value === true) return name
// `spaces` doesnt accept a second argument, but its given here just to
// keep the code cleaner.
value = Array.isArray(value)
? (info.commaSeparated ? commas : spaces)(value, {
padLeft: !state.settings.tightCommaSeparatedLists
})
: String(value)
if (state.settings.collapseEmptyAttributes && !value) return name
// Check unquoted value.
if (state.settings.preferUnquoted) {
result = stringifyEntities(
value,
Object.assign({}, state.settings.characterReferences, {
attribute: true,
subset: constants.unquoted[x][y]
})
)
}
// If we dont want unquoted, or if `value` contains character references when
// unquoted…
if (result !== value) {
// If the alternative is less common than `quote`, switch.
if (
state.settings.quoteSmart &&
ccount(value, quote) > ccount(value, state.alternative)
) {
quote = state.alternative
}
result =
quote +
stringifyEntities(
value,
Object.assign({}, state.settings.characterReferences, {
// Always encode without parse errors in non-HTML.
subset: (quote === "'" ? constants.single : constants.double)[x][y],
attribute: true
})
) +
quote
}
// Dont add a `=` for unquoted empties.
return name + (result ? '=' + result : result)
}

8
node_modules/hast-util-to-html/lib/handle/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,8 @@
/**
* @type {(node: Nodes, index: number | undefined, parent: Parents | undefined, state: State) => string}
*/
export const handle: (node: Nodes, index: number | undefined, parent: Parents | undefined, state: State) => string;
import type { Nodes } from 'hast';
import type { Parents } from 'hast';
import type { State } from '../index.js';
//# sourceMappingURL=index.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.js"],"names":[],"mappings":"AAaA;;GAEG;AACH,qBAFU,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,EAAE,OAAO,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,KAAK,MAAM,CAMrG;2BAnB+B,MAAM;6BAAN,MAAM;2BACf,aAAa"}

47
node_modules/hast-util-to-html/lib/handle/index.js generated vendored Normal file
View File

@@ -0,0 +1,47 @@
/**
* @import {Nodes, Parents} from 'hast'
* @import {State} from '../index.js'
*/
import {zwitch} from 'zwitch'
import {comment} from './comment.js'
import {doctype} from './doctype.js'
import {element} from './element.js'
import {raw} from './raw.js'
import {root} from './root.js'
import {text} from './text.js'
/**
* @type {(node: Nodes, index: number | undefined, parent: Parents | undefined, state: State) => string}
*/
export const handle = zwitch('type', {
invalid,
unknown,
handlers: {comment, doctype, element, raw, root, text}
})
/**
* Fail when a non-node is found in the tree.
*
* @param {unknown} node
* Unknown value.
* @returns {never}
* Never.
*/
function invalid(node) {
throw new Error('Expected node, not `' + node + '`')
}
/**
* Fail when a node with an unknown type is found in the tree.
*
* @param {unknown} node_
* Unknown node.
* @returns {never}
* Never.
*/
function unknown(node_) {
// `type` is guaranteed by runtime JS.
const node = /** @type {Nodes} */ (node_)
throw new Error('Cannot compile unknown node `' + node.type + '`')
}

19
node_modules/hast-util-to-html/lib/handle/raw.d.ts generated vendored Normal file
View File

@@ -0,0 +1,19 @@
/**
* Serialize a raw node.
*
* @param {Raw} node
* Node to handle.
* @param {number | undefined} index
* Index of `node` in `parent.
* @param {Parents | undefined} parent
* Parent of `node`.
* @param {State} state
* Info passed around about the current state.
* @returns {string}
* Serialized node.
*/
export function raw(node: Raw, index: number | undefined, parent: Parents | undefined, state: State): string;
import type { Raw } from 'mdast-util-to-hast';
import type { Parents } from 'hast';
import type { State } from '../index.js';
//# sourceMappingURL=raw.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"raw.d.ts","sourceRoot":"","sources":["raw.js"],"names":[],"mappings":"AAQA;;;;;;;;;;;;;GAaG;AACH,0BAXW,GAAG,SAEH,MAAM,GAAG,SAAS,UAElB,OAAO,GAAG,SAAS,SAEnB,KAAK,GAEH,MAAM,CAOlB;yBAxBqB,oBAAoB;6BADhB,MAAM;2BAER,aAAa"}

27
node_modules/hast-util-to-html/lib/handle/raw.js generated vendored Normal file
View File

@@ -0,0 +1,27 @@
/**
* @import {Parents} from 'hast'
* @import {Raw} from 'mdast-util-to-hast'
* @import {State} from '../index.js'
*/
import {text} from './text.js'
/**
* Serialize a raw node.
*
* @param {Raw} node
* Node to handle.
* @param {number | undefined} index
* Index of `node` in `parent.
* @param {Parents | undefined} parent
* Parent of `node`.
* @param {State} state
* Info passed around about the current state.
* @returns {string}
* Serialized node.
*/
export function raw(node, index, parent, state) {
return state.settings.allowDangerousHtml
? node.value
: text(node, index, parent, state)
}

23
node_modules/hast-util-to-html/lib/handle/root.d.ts generated vendored Normal file
View File

@@ -0,0 +1,23 @@
/**
* @import {Parents, Root} from 'hast'
* @import {State} from '../index.js'
*/
/**
* Serialize a root.
*
* @param {Root} node
* Node to handle.
* @param {number | undefined} _1
* Index of `node` in `parent.
* @param {Parents | undefined} _2
* Parent of `node`.
* @param {State} state
* Info passed around about the current state.
* @returns {string}
* Serialized node.
*/
export function root(node: Root, _1: number | undefined, _2: Parents | undefined, state: State): string;
import type { Root } from 'hast';
import type { Parents } from 'hast';
import type { State } from '../index.js';
//# sourceMappingURL=root.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"root.d.ts","sourceRoot":"","sources":["root.js"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;;;;;GAaG;AACH,2BAXW,IAAI,MAEJ,MAAM,GAAG,SAAS,MAElB,OAAO,GAAG,SAAS,SAEnB,KAAK,GAEH,MAAM,CAKlB;0BApB+B,MAAM;6BAAN,MAAM;2BACd,aAAa"}

22
node_modules/hast-util-to-html/lib/handle/root.js generated vendored Normal file
View File

@@ -0,0 +1,22 @@
/**
* @import {Parents, Root} from 'hast'
* @import {State} from '../index.js'
*/
/**
* Serialize a root.
*
* @param {Root} node
* Node to handle.
* @param {number | undefined} _1
* Index of `node` in `parent.
* @param {Parents | undefined} _2
* Parent of `node`.
* @param {State} state
* Info passed around about the current state.
* @returns {string}
* Serialized node.
*/
export function root(node, _1, _2, state) {
return state.all(node)
}

20
node_modules/hast-util-to-html/lib/handle/text.d.ts generated vendored Normal file
View File

@@ -0,0 +1,20 @@
/**
* Serialize a text node.
*
* @param {Raw | Text} node
* Node to handle.
* @param {number | undefined} _
* Index of `node` in `parent.
* @param {Parents | undefined} parent
* Parent of `node`.
* @param {State} state
* Info passed around about the current state.
* @returns {string}
* Serialized node.
*/
export function text(node: Raw | Text, _: number | undefined, parent: Parents | undefined, state: State): string;
import type { Raw } from 'mdast-util-to-hast';
import type { Text } from 'hast';
import type { Parents } from 'hast';
import type { State } from '../index.js';
//# sourceMappingURL=text.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"text.d.ts","sourceRoot":"","sources":["text.js"],"names":[],"mappings":"AAWA;;;;;;;;;;;;;GAaG;AACH,2BAXW,GAAG,GAAG,IAAI,KAEV,MAAM,GAAG,SAAS,UAElB,OAAO,GAAG,SAAS,SAEnB,KAAK,GAEH,MAAM,CAelB;yBAnCqB,oBAAoB;0BADV,MAAM;6BAAN,MAAM;2BAEd,aAAa"}

38
node_modules/hast-util-to-html/lib/handle/text.js generated vendored Normal file
View File

@@ -0,0 +1,38 @@
/**
* @import {Parents, Text} from 'hast'
* @import {Raw} from 'mdast-util-to-hast'
* @import {State} from '../index.js'
*/
import {stringifyEntities} from 'stringify-entities'
// Declare array as variable so it can be cached by `stringifyEntities`
const textEntitySubset = ['<', '&']
/**
* Serialize a text node.
*
* @param {Raw | Text} node
* Node to handle.
* @param {number | undefined} _
* Index of `node` in `parent.
* @param {Parents | undefined} parent
* Parent of `node`.
* @param {State} state
* Info passed around about the current state.
* @returns {string}
* Serialized node.
*/
export function text(node, _, parent, state) {
// Check if content of `node` should be escaped.
return parent &&
parent.type === 'element' &&
(parent.tagName === 'script' || parent.tagName === 'style')
? node.value
: stringifyEntities(
node.value,
Object.assign({}, state.settings.characterReferences, {
subset: textEntitySubset
})
)
}

223
node_modules/hast-util-to-html/lib/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,223 @@
/**
* Serialize hast as HTML.
*
* @param {Array<RootContent> | Nodes} tree
* Tree to serialize.
* @param {Options | null | undefined} [options]
* Configuration (optional).
* @returns {string}
* Serialized HTML.
*/
export function toHtml(tree: Array<RootContent> | Nodes, options?: Options | null | undefined): string;
/**
* Serialize all children of `parent`.
*
* @this {State}
* Info passed around about the current state.
* @param {Parents | undefined} parent
* Parent whose children to serialize.
* @returns {string}
*/
export function all(this: State, parent: Parents | undefined): string;
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 isnt 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 isnt 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 its followed by another `li`, the last because its
* 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;
/**
* Use the other quote if that results in less bytes (default: `false`).
*/
quoteSmart?: boolean | null | undefined;
/**
* Preferred quote to use (default: `'"'`).
*/
quote?: Quote | 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 isnt 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 isnt 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**: Its 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 = Omit<Required<{ [key in keyof Options]: Exclude<Options[key], null | undefined>; }>, "space" | "quote">;
/**
* Namespace.
*/
export type Space = "html" | "svg";
/**
* Info passed around about the current state.
*/
export type State = {
/**
* Serialize the children of a parent node.
*/
all: (node: Parents | undefined) => string;
/**
* Alternative quote.
*/
alternative: Quote;
/**
* Serialize one node.
*/
one: (node: Nodes, index: number | undefined, parent: Parents | undefined) => string;
/**
* Preferred quote.
*/
quote: Quote;
/**
* Current schema.
*/
schema: Schema;
/**
* User configuration.
*/
settings: Settings;
};
import type { RootContent } from 'hast';
import type { Nodes } from 'hast';
import type { Parents } from 'hast';
import type { Options as StringifyEntitiesOptions } from 'stringify-entities';
import type { Schema } from 'property-information';
//# sourceMappingURL=index.d.ts.map

1
node_modules/hast-util-to-html/lib/index.d.ts.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.js"],"names":[],"mappings":"AAmKA;;;;;;;;;GASG;AACH,6BAPW,KAAK,CAAC,WAAW,CAAC,GAAG,KAAK,YAE1B,OAAO,GAAG,IAAI,GAAG,SAAS,GAExB,MAAM,CA8ClB;AAoBD;;;;;;;;GAQG;AACH,yCAJW,OAAO,GAAG,SAAS,GAEjB,MAAM,CAalB;kCAzPY,IAAI,CAAC,wBAAwB,EAAE,WAAW,GAAG,YAAY,GAAG,QAAQ,CAAC;;;;;;;;;;;+BAIpE,OAAO,GAAG,IAAI,GAAG,SAAS;;;;;;;;yBAK1B,OAAO,GAAG,IAAI,GAAG,SAAS;;;;;;;;;;uBAM1B,OAAO,GAAG,IAAI,GAAG,SAAS;;;;;;;;oBAQ1B,OAAO,GAAG,IAAI,GAAG,SAAS;;;;0BAM1B,mBAAmB,GAAG,IAAI,GAAG,SAAS;;;;;;;;;;;yBAEtC,OAAO,GAAG,IAAI,GAAG,SAAS;;;;;;;;;;uBAS1B,OAAO,GAAG,IAAI,GAAG,SAAS;;;;;;;;;8BAQ1B,OAAO,GAAG,IAAI,GAAG,SAAS;;;;;;;;;;;uBAO1B,OAAO,GAAG,IAAI,GAAG,SAAS;;;;;;qBAS1B,OAAO,GAAG,IAAI,GAAG,SAAS;;;;iBAI1B,OAAO,GAAG,IAAI,GAAG,SAAS;;;;YAE1B,KAAK,GAAG,IAAI,GAAG,SAAS;;;;;;;;;;;;YAExB,KAAK,GAAG,IAAI,GAAG,SAAS;;;;;;;;;;;sBAUxB,OAAO,GAAG,IAAI,GAAG,SAAS;;;;;;+BAS1B,OAAO,GAAG,IAAI,GAAG,SAAS;;;;;;;;mBAI1B,OAAO,GAAG,IAAI,GAAG,SAAS;;;;;;;;uBAM1B,OAAO,GAAG,IAAI,GAAG,SAAS;;;;;;mBAM1B,OAAO,GAAG,IAAI,GAAG,SAAS;;;;;;;;;YAI1B,aAAa,CAAC,MAAM,CAAC,GAAG,IAAI,GAAG,SAAS;;;;;oBAQzC,IAAG,GAAG,GAAG;uBAGT,IAAI,CAAC,QAAQ,CAAC,GAAE,GAAG,IAAI,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,IAAI,GAAG,SAAS,CAAC,GAAC,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;;;;oBAEpG,MAAM,GAAG,KAAK;;;;;;;;SAKb,CAAC,IAAI,EAAE,OAAO,GAAG,SAAS,KAAK,MAAM;;;;iBAErC,KAAK;;;;SAEL,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,EAAE,OAAO,GAAG,SAAS,KAAK,MAAM;;;;WAE/E,KAAK;;;;YAEL,MAAM;;;;cAEN,QAAQ;;iCAjJwB,MAAM;2BAAN,MAAM;6BAAN,MAAM;yDAEE,oBAAoB;4BADjD,sBAAsB"}

257
node_modules/hast-util-to-html/lib/index.js generated vendored Normal file
View File

@@ -0,0 +1,257 @@
/**
* @import {Nodes, Parents, RootContent} from 'hast'
* @import {Schema} from 'property-information'
* @import {Options as StringifyEntitiesOptions} from 'stringify-entities'
*/
/**
* @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 isnt 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 isnt 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 its followed by another `li`, the last because its
* 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 {boolean | null | undefined} [quoteSmart=false]
* Use the other quote if that results in less bytes (default: `false`).
* @property {Quote | null | undefined} [quote='"']
* Preferred quote to use (default: `'"'`).
* @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 isnt 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 isnt 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**: Its 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: Parents | undefined) => string} all
* Serialize the children of a parent node.
* @property {Quote} alternative
* Alternative quote.
* @property {(node: Nodes, index: number | undefined, parent: Parents | undefined) => string} one
* Serialize one node.
* @property {Quote} quote
* Preferred quote.
* @property {Schema} schema
* Current schema.
* @property {Settings} settings
* User configuration.
*/
import {htmlVoidElements} from 'html-void-elements'
import {html, svg} from 'property-information'
import {handle} from './handle/index.js'
/** @type {Options} */
const emptyOptions = {}
/** @type {CharacterReferences} */
const emptyCharacterReferences = {}
/** @type {Array<never>} */
const emptyChildren = []
/**
* Serialize hast as HTML.
*
* @param {Array<RootContent> | Nodes} tree
* Tree to serialize.
* @param {Options | null | undefined} [options]
* Configuration (optional).
* @returns {string}
* Serialized HTML.
*/
export function toHtml(tree, options) {
const options_ = options || emptyOptions
const quote = options_.quote || '"'
const alternative = quote === '"' ? "'" : '"'
if (quote !== '"' && quote !== "'") {
throw new Error('Invalid quote `' + quote + '`, expected `\'` or `"`')
}
/** @type {State} */
const state = {
one,
all,
settings: {
omitOptionalTags: options_.omitOptionalTags || false,
allowParseErrors: options_.allowParseErrors || false,
allowDangerousCharacters: options_.allowDangerousCharacters || false,
quoteSmart: options_.quoteSmart || false,
preferUnquoted: options_.preferUnquoted || false,
tightAttributes: options_.tightAttributes || false,
upperDoctype: options_.upperDoctype || false,
tightDoctype: options_.tightDoctype || false,
bogusComments: options_.bogusComments || false,
tightCommaSeparatedLists: options_.tightCommaSeparatedLists || false,
tightSelfClosing: options_.tightSelfClosing || false,
collapseEmptyAttributes: options_.collapseEmptyAttributes || false,
allowDangerousHtml: options_.allowDangerousHtml || false,
voids: options_.voids || htmlVoidElements,
characterReferences:
options_.characterReferences || emptyCharacterReferences,
closeSelfClosing: options_.closeSelfClosing || false,
closeEmptyElements: options_.closeEmptyElements || false
},
schema: options_.space === 'svg' ? svg : html,
quote,
alternative
}
return state.one(
Array.isArray(tree) ? {type: 'root', children: tree} : tree,
undefined,
undefined
)
}
/**
* Serialize a node.
*
* @this {State}
* Info passed around about the current state.
* @param {Nodes} node
* Node to handle.
* @param {number | undefined} index
* Index of `node` in `parent.
* @param {Parents | undefined} parent
* Parent of `node`.
* @returns {string}
* Serialized node.
*/
function one(node, index, parent) {
return handle(node, index, parent, this)
}
/**
* Serialize all children of `parent`.
*
* @this {State}
* Info passed around about the current state.
* @param {Parents | undefined} parent
* Parent whose children to serialize.
* @returns {string}
*/
export function all(parent) {
/** @type {Array<string>} */
const results = []
const children = (parent && parent.children) || emptyChildren
let index = -1
while (++index < children.length) {
results[index] = this.one(children[index], index, parent)
}
return results.join('')
}

View File

@@ -0,0 +1,2 @@
export const closing: import("./omission.js").OmitHandle;
//# sourceMappingURL=closing.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"closing.d.ts","sourceRoot":"","sources":["closing.js"],"names":[],"mappings":"AAQA,yDAoBE"}

358
node_modules/hast-util-to-html/lib/omission/closing.js generated vendored Normal file
View File

@@ -0,0 +1,358 @@
/**
* @import {Element, Parents} from 'hast'
*/
import {whitespace} from 'hast-util-whitespace'
import {siblingAfter} from './util/siblings.js'
import {omission} from './omission.js'
export const closing = omission({
body,
caption: headOrColgroupOrCaption,
colgroup: headOrColgroupOrCaption,
dd,
dt,
head: headOrColgroupOrCaption,
html,
li,
optgroup,
option,
p,
rp: rubyElement,
rt: rubyElement,
tbody,
td: cells,
tfoot,
th: cells,
thead,
tr
})
/**
* Macro for `</head>`, `</colgroup>`, and `</caption>`.
*
* @param {Element} _
* Element.
* @param {number | undefined} index
* Index of element in parent.
* @param {Parents | undefined} parent
* Parent of element.
* @returns {boolean}
* Whether the closing tag can be omitted.
*/
function headOrColgroupOrCaption(_, index, parent) {
const next = siblingAfter(parent, index, true)
return (
!next ||
(next.type !== 'comment' &&
!(next.type === 'text' && whitespace(next.value.charAt(0))))
)
}
/**
* Whether to omit `</html>`.
*
* @param {Element} _
* Element.
* @param {number | undefined} index
* Index of element in parent.
* @param {Parents | undefined} parent
* Parent of element.
* @returns {boolean}
* Whether the closing tag can be omitted.
*/
function html(_, index, parent) {
const next = siblingAfter(parent, index)
return !next || next.type !== 'comment'
}
/**
* Whether to omit `</body>`.
*
* @param {Element} _
* Element.
* @param {number | undefined} index
* Index of element in parent.
* @param {Parents | undefined} parent
* Parent of element.
* @returns {boolean}
* Whether the closing tag can be omitted.
*/
function body(_, index, parent) {
const next = siblingAfter(parent, index)
return !next || next.type !== 'comment'
}
/**
* Whether to omit `</p>`.
*
* @param {Element} _
* Element.
* @param {number | undefined} index
* Index of element in parent.
* @param {Parents | undefined} parent
* Parent of element.
* @returns {boolean}
* Whether the closing tag can be omitted.
*/
function p(_, index, parent) {
const next = siblingAfter(parent, index)
return next
? next.type === 'element' &&
(next.tagName === 'address' ||
next.tagName === 'article' ||
next.tagName === 'aside' ||
next.tagName === 'blockquote' ||
next.tagName === 'details' ||
next.tagName === 'div' ||
next.tagName === 'dl' ||
next.tagName === 'fieldset' ||
next.tagName === 'figcaption' ||
next.tagName === 'figure' ||
next.tagName === 'footer' ||
next.tagName === 'form' ||
next.tagName === 'h1' ||
next.tagName === 'h2' ||
next.tagName === 'h3' ||
next.tagName === 'h4' ||
next.tagName === 'h5' ||
next.tagName === 'h6' ||
next.tagName === 'header' ||
next.tagName === 'hgroup' ||
next.tagName === 'hr' ||
next.tagName === 'main' ||
next.tagName === 'menu' ||
next.tagName === 'nav' ||
next.tagName === 'ol' ||
next.tagName === 'p' ||
next.tagName === 'pre' ||
next.tagName === 'section' ||
next.tagName === 'table' ||
next.tagName === 'ul')
: !parent ||
// Confusing parent.
!(
parent.type === 'element' &&
(parent.tagName === 'a' ||
parent.tagName === 'audio' ||
parent.tagName === 'del' ||
parent.tagName === 'ins' ||
parent.tagName === 'map' ||
parent.tagName === 'noscript' ||
parent.tagName === 'video')
)
}
/**
* Whether to omit `</li>`.
*
* @param {Element} _
* Element.
* @param {number | undefined} index
* Index of element in parent.
* @param {Parents | undefined} parent
* Parent of element.
* @returns {boolean}
* Whether the closing tag can be omitted.
*/
function li(_, index, parent) {
const next = siblingAfter(parent, index)
return !next || (next.type === 'element' && next.tagName === 'li')
}
/**
* Whether to omit `</dt>`.
*
* @param {Element} _
* Element.
* @param {number | undefined} index
* Index of element in parent.
* @param {Parents | undefined} parent
* Parent of element.
* @returns {boolean}
* Whether the closing tag can be omitted.
*/
function dt(_, index, parent) {
const next = siblingAfter(parent, index)
return Boolean(
next &&
next.type === 'element' &&
(next.tagName === 'dt' || next.tagName === 'dd')
)
}
/**
* Whether to omit `</dd>`.
*
* @param {Element} _
* Element.
* @param {number | undefined} index
* Index of element in parent.
* @param {Parents | undefined} parent
* Parent of element.
* @returns {boolean}
* Whether the closing tag can be omitted.
*/
function dd(_, index, parent) {
const next = siblingAfter(parent, index)
return (
!next ||
(next.type === 'element' &&
(next.tagName === 'dt' || next.tagName === 'dd'))
)
}
/**
* Whether to omit `</rt>` or `</rp>`.
*
* @param {Element} _
* Element.
* @param {number | undefined} index
* Index of element in parent.
* @param {Parents | undefined} parent
* Parent of element.
* @returns {boolean}
* Whether the closing tag can be omitted.
*/
function rubyElement(_, index, parent) {
const next = siblingAfter(parent, index)
return (
!next ||
(next.type === 'element' &&
(next.tagName === 'rp' || next.tagName === 'rt'))
)
}
/**
* Whether to omit `</optgroup>`.
*
* @param {Element} _
* Element.
* @param {number | undefined} index
* Index of element in parent.
* @param {Parents | undefined} parent
* Parent of element.
* @returns {boolean}
* Whether the closing tag can be omitted.
*/
function optgroup(_, index, parent) {
const next = siblingAfter(parent, index)
return !next || (next.type === 'element' && next.tagName === 'optgroup')
}
/**
* Whether to omit `</option>`.
*
* @param {Element} _
* Element.
* @param {number | undefined} index
* Index of element in parent.
* @param {Parents | undefined} parent
* Parent of element.
* @returns {boolean}
* Whether the closing tag can be omitted.
*/
function option(_, index, parent) {
const next = siblingAfter(parent, index)
return (
!next ||
(next.type === 'element' &&
(next.tagName === 'option' || next.tagName === 'optgroup'))
)
}
/**
* Whether to omit `</thead>`.
*
* @param {Element} _
* Element.
* @param {number | undefined} index
* Index of element in parent.
* @param {Parents | undefined} parent
* Parent of element.
* @returns {boolean}
* Whether the closing tag can be omitted.
*/
function thead(_, index, parent) {
const next = siblingAfter(parent, index)
return Boolean(
next &&
next.type === 'element' &&
(next.tagName === 'tbody' || next.tagName === 'tfoot')
)
}
/**
* Whether to omit `</tbody>`.
*
* @param {Element} _
* Element.
* @param {number | undefined} index
* Index of element in parent.
* @param {Parents | undefined} parent
* Parent of element.
* @returns {boolean}
* Whether the closing tag can be omitted.
*/
function tbody(_, index, parent) {
const next = siblingAfter(parent, index)
return (
!next ||
(next.type === 'element' &&
(next.tagName === 'tbody' || next.tagName === 'tfoot'))
)
}
/**
* Whether to omit `</tfoot>`.
*
* @param {Element} _
* Element.
* @param {number | undefined} index
* Index of element in parent.
* @param {Parents | undefined} parent
* Parent of element.
* @returns {boolean}
* Whether the closing tag can be omitted.
*/
function tfoot(_, index, parent) {
return !siblingAfter(parent, index)
}
/**
* Whether to omit `</tr>`.
*
* @param {Element} _
* Element.
* @param {number | undefined} index
* Index of element in parent.
* @param {Parents | undefined} parent
* Parent of element.
* @returns {boolean}
* Whether the closing tag can be omitted.
*/
function tr(_, index, parent) {
const next = siblingAfter(parent, index)
return !next || (next.type === 'element' && next.tagName === 'tr')
}
/**
* Whether to omit `</td>` or `</th>`.
*
* @param {Element} _
* Element.
* @param {number | undefined} index
* Index of element in parent.
* @param {Parents | undefined} parent
* Parent of element.
* @returns {boolean}
* Whether the closing tag can be omitted.
*/
function cells(_, index, parent) {
const next = siblingAfter(parent, index)
return (
!next ||
(next.type === 'element' &&
(next.tagName === 'td' || next.tagName === 'th'))
)
}

View File

@@ -0,0 +1,17 @@
/**
* Factory to check if a given node can have a tag omitted.
*
* @param {Record<string, OmitHandle>} handlers
* Omission handlers, where each key is a tag name, and each value is the
* corresponding handler.
* @returns {OmitHandle}
* Whether to omit a tag of an element.
*/
export function omission(handlers: Record<string, OmitHandle>): OmitHandle;
/**
* Check if a tag can be omitted.
*/
export type OmitHandle = (element: Element, index: number | undefined, parent: Parents | undefined) => boolean;
import type { Element } from 'hast';
import type { Parents } from 'hast';
//# sourceMappingURL=omission.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"omission.d.ts","sourceRoot":"","sources":["omission.js"],"names":[],"mappings":"AAoBA;;;;;;;;GAQG;AACH,mCANW,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,GAGxB,UAAU,CAiBtB;;;;mCApCU,OAAO,SAEP,MAAM,GAAG,SAAS,UAElB,OAAO,GAAG,SAAS,KAEjB,OAAO;6BAZe,MAAM;6BAAN,MAAM"}

View File

@@ -0,0 +1,44 @@
/**
* @import {Element, Parents} from 'hast'
*/
/**
* @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
/**
* Factory to check if a given node can have a tag omitted.
*
* @param {Record<string, OmitHandle>} handlers
* Omission handlers, where each key is a tag name, and each value is the
* corresponding handler.
* @returns {OmitHandle}
* Whether to omit a tag of an element.
*/
export function omission(handlers) {
return omit
/**
* Check if a given node can have a tag omitted.
*
* @type {OmitHandle}
*/
function omit(node, index, parent) {
return (
own.call(handlers, node.tagName) &&
handlers[node.tagName](node, index, parent)
)
}
}

View File

@@ -0,0 +1,2 @@
export const opening: import("./omission.js").OmitHandle;
//# sourceMappingURL=opening.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"opening.d.ts","sourceRoot":"","sources":["opening.js"],"names":[],"mappings":"AASA,yDAME"}

148
node_modules/hast-util-to-html/lib/omission/opening.js generated vendored Normal file
View File

@@ -0,0 +1,148 @@
/**
* @import {Element, Parents} from 'hast'
*/
import {whitespace} from 'hast-util-whitespace'
import {siblingAfter, siblingBefore} from './util/siblings.js'
import {closing} from './closing.js'
import {omission} from './omission.js'
export const opening = omission({
body,
colgroup,
head,
html,
tbody
})
/**
* Whether to omit `<html>`.
*
* @param {Element} node
* Element.
* @returns {boolean}
* Whether the opening tag can be omitted.
*/
function html(node) {
const head = siblingAfter(node, -1)
return !head || head.type !== 'comment'
}
/**
* Whether to omit `<head>`.
*
* @param {Element} node
* Element.
* @returns {boolean}
* Whether the opening tag can be omitted.
*/
function head(node) {
/** @type {Set<string>} */
const seen = new Set()
// Whether `srcdoc` or not,
// make sure the content model at least doesnt have too many `base`s/`title`s.
for (const child of node.children) {
if (
child.type === 'element' &&
(child.tagName === 'base' || child.tagName === 'title')
) {
if (seen.has(child.tagName)) return false
seen.add(child.tagName)
}
}
// “May be omitted if the element is empty,
// or if the first thing inside the head element is an element.”
const child = node.children[0]
return !child || child.type === 'element'
}
/**
* Whether to omit `<body>`.
*
* @param {Element} node
* Element.
* @returns {boolean}
* Whether the opening tag can be omitted.
*/
function body(node) {
const head = siblingAfter(node, -1, true)
return (
!head ||
(head.type !== 'comment' &&
!(head.type === 'text' && whitespace(head.value.charAt(0))) &&
!(
head.type === 'element' &&
(head.tagName === 'meta' ||
head.tagName === 'link' ||
head.tagName === 'script' ||
head.tagName === 'style' ||
head.tagName === 'template')
))
)
}
/**
* Whether to omit `<colgroup>`.
* The spec describes some logic for the opening tag, but its easier to
* implement in the closing tag, to the same effect, so we handle it there
* instead.
*
* @param {Element} node
* Element.
* @param {number | undefined} index
* Index of element in parent.
* @param {Parents | undefined} parent
* Parent of element.
* @returns {boolean}
* Whether the opening tag can be omitted.
*/
function colgroup(node, index, parent) {
const previous = siblingBefore(parent, index)
const head = siblingAfter(node, -1, true)
// Previous colgroup was already omitted.
if (
parent &&
previous &&
previous.type === 'element' &&
previous.tagName === 'colgroup' &&
closing(previous, parent.children.indexOf(previous), parent)
) {
return false
}
return Boolean(head && head.type === 'element' && head.tagName === 'col')
}
/**
* Whether to omit `<tbody>`.
*
* @param {Element} node
* Element.
* @param {number | undefined} index
* Index of element in parent.
* @param {Parents | undefined} parent
* Parent of element.
* @returns {boolean}
* Whether the opening tag can be omitted.
*/
function tbody(node, index, parent) {
const previous = siblingBefore(parent, index)
const head = siblingAfter(node, -1)
// Previous table section was already omitted.
if (
parent &&
previous &&
previous.type === 'element' &&
(previous.tagName === 'thead' || previous.tagName === 'tbody') &&
closing(previous, parent.children.indexOf(previous), parent)
) {
return false
}
return Boolean(head && head.type === 'element' && head.tagName === 'tr')
}

View File

@@ -0,0 +1,36 @@
/**
* Find applicable siblings in a direction.
*
* @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 extends Parents>(parent: Parent | undefined, index: number | undefined, includeWhitespace?: boolean | undefined): Parent extends {
children: Array<infer Child>;
} ? Child | undefined : never;
/**
* Find applicable siblings in a direction.
*
* @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 extends Parents>(parent: Parent | undefined, index: number | undefined, includeWhitespace?: boolean | undefined): Parent extends {
children: Array<infer Child>;
} ? Child | undefined : never;
import type { Parents } from 'hast';
//# sourceMappingURL=siblings.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"siblings.d.ts","sourceRoot":"","sources":["siblings.js"],"names":[],"mappings":"AAoBE;;;;;;;;;;;;;GAaG;AACH,6BAXuB,MAAM,SAAhB,OAAS,UAEX,MAAM,GAAG,SAAS,SAElB,MAAM,GAAG,SAAS,sBAElB,OAAO,GAAG,SAAS,GAEjB,MAAM,SAAS;IAAC,QAAQ,EAAE,KAAK,CAAC,MAAM,KAAK,CAAC,CAAA;CAAC,GAAG,KAAK,GAAG,SAAS,GAAG,KAAK,CAiBrF;AA5BD;;;;;;;;;;;;;GAaG;AACH,8BAXuB,MAAM,SAAhB,OAAS,UAEX,MAAM,GAAG,SAAS,SAElB,MAAM,GAAG,SAAS,sBAElB,OAAO,GAAG,SAAS,GAEjB,MAAM,SAAS;IAAC,QAAQ,EAAE,KAAK,CAAC,MAAM,KAAK,CAAC,CAAA;CAAC,GAAG,KAAK,GAAG,SAAS,GAAG,KAAK,CAiBrF;6BA/CoC,MAAM"}

View File

@@ -0,0 +1,50 @@
/**
* @import {Parents, RootContent} from 'hast'
*/
import {whitespace} from 'hast-util-whitespace'
export const siblingAfter = siblings(1)
export const siblingBefore = siblings(-1)
/** @type {Array<RootContent>} */
const emptyChildren = []
/**
* Factory to check siblings in a direction.
*
* @param {number} increment
*/
function siblings(increment) {
return sibling
/**
* Find applicable siblings in a direction.
*
* @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 : emptyChildren
let offset = (index || 0) + increment
let next = siblings[offset]
if (!includeWhitespace) {
while (next && whitespace(next)) {
offset += increment
next = siblings[offset]
}
}
// @ts-expect-error: its a correct child.
return next
}
}