🎉 initiate project *astro_rewrite*
This commit is contained in:
parent
ffd4d5e86c
commit
2ba37bfbe3
8658 changed files with 2268794 additions and 2538 deletions
19
node_modules/hast-util-raw/complex-types.d.ts
generated
vendored
Normal file
19
node_modules/hast-util-raw/complex-types.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import type {Literal} from 'hast'
|
||||
|
||||
/* eslint-disable @typescript-eslint/consistent-type-definitions */
|
||||
|
||||
export interface Raw extends Literal {
|
||||
type: 'raw'
|
||||
}
|
||||
|
||||
declare module 'hast' {
|
||||
interface RootContentMap {
|
||||
raw: Raw
|
||||
}
|
||||
|
||||
interface ElementContentMap {
|
||||
raw: Raw
|
||||
}
|
||||
}
|
||||
|
||||
/* eslint-enable @typescript-eslint/consistent-type-definitions */
|
||||
3
node_modules/hast-util-raw/index.d.ts
generated
vendored
Normal file
3
node_modules/hast-util-raw/index.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
export {raw} from './lib/index.js'
|
||||
export type Options = import('./lib/index.js').Options
|
||||
export type Raw = import('./complex-types').Raw
|
||||
6
node_modules/hast-util-raw/index.js
generated
vendored
Normal file
6
node_modules/hast-util-raw/index.js
generated
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
/**
|
||||
* @typedef {import('./lib/index.js').Options} Options
|
||||
* @typedef {import('./complex-types').Raw} Raw
|
||||
*/
|
||||
|
||||
export {raw} from './lib/index.js'
|
||||
100
node_modules/hast-util-raw/lib/index.d.ts
generated
vendored
Normal file
100
node_modules/hast-util-raw/lib/index.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
/**
|
||||
* Given a hast tree and an optional vfile (for positional info), return a new
|
||||
* parsed-again hast tree.
|
||||
*
|
||||
* @param tree
|
||||
* Original hast tree.
|
||||
* @param file
|
||||
* Virtual file for positional info, optional.
|
||||
* @param options
|
||||
* Configuration.
|
||||
*/
|
||||
export const raw: ((
|
||||
tree: Node,
|
||||
file: VFile | undefined,
|
||||
options?: Options
|
||||
) => Node) &
|
||||
((tree: Node, options?: Options) => Node)
|
||||
export type VFile = import('vfile').VFile
|
||||
export type P5Document = import('parse5').Document
|
||||
export type P5Fragment = import('parse5').DocumentFragment
|
||||
export type P5Element = Omit<import('parse5').Element, 'parentNode'>
|
||||
export type P5Attribute = import('parse5').Attribute
|
||||
export type P5Location = Omit<
|
||||
import('parse5').Location,
|
||||
'startOffset' | 'endOffset'
|
||||
> & {
|
||||
startOffset: number | undefined
|
||||
endOffset: number | undefined
|
||||
}
|
||||
export type P5ParserOptions = import('parse5').ParserOptions
|
||||
export type Root = import('hast').Root
|
||||
export type Doctype = import('hast').DocType
|
||||
export type Element = import('hast').Element
|
||||
export type Text = import('hast').Text
|
||||
export type Comment = import('hast').Comment
|
||||
export type Content = import('hast').Content
|
||||
export type Node = Root | Content
|
||||
export type Raw = import('../complex-types').Raw
|
||||
export type Stitch = Omit<Comment, 'value'> & {
|
||||
value: {
|
||||
stitch: Node
|
||||
}
|
||||
}
|
||||
export type Options = {
|
||||
/**
|
||||
* List of custom hast node types to pass through (keep) in hast.
|
||||
* If the passed through nodes have children, those children are expected to
|
||||
* be hast and will be handled.
|
||||
*/
|
||||
passThrough?: string[] | undefined
|
||||
}
|
||||
export type HiddenTokenizer = {
|
||||
/**
|
||||
* Way too simple, but works for us.
|
||||
*/
|
||||
__mixins: Array<HiddenLocationTracker>
|
||||
preprocessor: HiddenPreprocessor
|
||||
write: (value: string) => void
|
||||
_consume: () => number
|
||||
tokenQueue: Array<HiddenToken>
|
||||
state: string
|
||||
returnState: string
|
||||
charRefCode: number
|
||||
tempBuff: Array<number>
|
||||
_flushCodePointsConsumedAsCharacterReference: Function
|
||||
lastStartTagName: string
|
||||
consumedAfterSnapshot: number
|
||||
active: boolean
|
||||
currentCharacterToken: HiddenToken | undefined
|
||||
currentToken: HiddenToken | undefined
|
||||
currentAttr: unknown
|
||||
NAMED_CHARACTER_REFERENCE_STATE: Function
|
||||
NUMERIC_CHARACTER_REFERENCE_END_STATE: Function
|
||||
}
|
||||
export type HiddenToken = Record<string, unknown> & {
|
||||
location: P5Location
|
||||
}
|
||||
export type HiddenPreprocessor = {
|
||||
html: string | undefined
|
||||
pos: number
|
||||
lastGapPos: number
|
||||
lastCharPos: number
|
||||
gapStack: Array<number>
|
||||
skipNextNewLine: boolean
|
||||
lastChunkWritten: boolean
|
||||
endOfChunkHit: boolean
|
||||
}
|
||||
export type HiddenLocationTracker = {
|
||||
currentAttrLocation: P5Location | undefined
|
||||
ctLoc: P5Location
|
||||
posTracker: HiddenPosTracker
|
||||
}
|
||||
export type HiddenPosTracker = {
|
||||
isEol: boolean
|
||||
lineStartPos: number
|
||||
droppedBufferSize: number
|
||||
offset: number
|
||||
col: number
|
||||
line: number
|
||||
}
|
||||
551
node_modules/hast-util-raw/lib/index.js
generated
vendored
Normal file
551
node_modules/hast-util-raw/lib/index.js
generated
vendored
Normal file
|
|
@ -0,0 +1,551 @@
|
|||
/**
|
||||
* @typedef {import('vfile').VFile} VFile
|
||||
* @typedef {import('parse5').Document} P5Document
|
||||
* @typedef {import('parse5').DocumentFragment} P5Fragment
|
||||
* @typedef {Omit<import('parse5').Element, 'parentNode'>} P5Element
|
||||
* @typedef {import('parse5').Attribute} P5Attribute
|
||||
* @typedef {Omit<import('parse5').Location, 'startOffset' | 'endOffset'> & {startOffset: number|undefined, endOffset: number|undefined}} P5Location
|
||||
* @typedef {import('parse5').ParserOptions} P5ParserOptions
|
||||
* @typedef {import('hast').Root} Root
|
||||
* @typedef {import('hast').DocType} Doctype
|
||||
* @typedef {import('hast').Element} Element
|
||||
* @typedef {import('hast').Text} Text
|
||||
* @typedef {import('hast').Comment} Comment
|
||||
* @typedef {import('hast').Content} Content
|
||||
* @typedef {Root|Content} Node
|
||||
* @typedef {import('../complex-types').Raw} Raw
|
||||
*
|
||||
* @typedef {Omit<Comment, 'value'> & {value: {stitch: Node}}} Stitch
|
||||
*
|
||||
* @typedef Options
|
||||
* @property {Array<string>} [passThrough]
|
||||
* List of custom hast node types to pass through (keep) in hast.
|
||||
* If the passed through nodes have children, those children are expected to
|
||||
* be hast and will be handled.
|
||||
*
|
||||
* @typedef HiddenTokenizer
|
||||
* @property {Array<HiddenLocationTracker>} __mixins
|
||||
* Way too simple, but works for us.
|
||||
* @property {HiddenPreprocessor} preprocessor
|
||||
* @property {(value: string) => void} write
|
||||
* @property {() => number} _consume
|
||||
* @property {Array<HiddenToken>} tokenQueue
|
||||
* @property {string} state
|
||||
* @property {string} returnState
|
||||
* @property {number} charRefCode
|
||||
* @property {Array<number>} tempBuff
|
||||
* @property {Function} _flushCodePointsConsumedAsCharacterReference
|
||||
* @property {string} lastStartTagName
|
||||
* @property {number} consumedAfterSnapshot
|
||||
* @property {boolean} active
|
||||
* @property {HiddenToken|undefined} currentCharacterToken
|
||||
* @property {HiddenToken|undefined} currentToken
|
||||
* @property {unknown} currentAttr
|
||||
* @property {Function} NAMED_CHARACTER_REFERENCE_STATE
|
||||
* @property {Function} NUMERIC_CHARACTER_REFERENCE_END_STATE
|
||||
*
|
||||
* @typedef {Record<string, unknown> & {location: P5Location}} HiddenToken
|
||||
*
|
||||
* @typedef HiddenPreprocessor
|
||||
* @property {string|undefined} html
|
||||
* @property {number} pos
|
||||
* @property {number} lastGapPos
|
||||
* @property {number} lastCharPos
|
||||
* @property {Array<number>} gapStack
|
||||
* @property {boolean} skipNextNewLine
|
||||
* @property {boolean} lastChunkWritten
|
||||
* @property {boolean} endOfChunkHit
|
||||
*
|
||||
* @typedef HiddenLocationTracker
|
||||
* @property {P5Location|undefined} currentAttrLocation
|
||||
* @property {P5Location} ctLoc
|
||||
* @property {HiddenPosTracker} posTracker
|
||||
*
|
||||
* @typedef HiddenPosTracker
|
||||
* @property {boolean} isEol
|
||||
* @property {number} lineStartPos
|
||||
* @property {number} droppedBufferSize
|
||||
* @property {number} offset
|
||||
* @property {number} col
|
||||
* @property {number} line
|
||||
*/
|
||||
|
||||
// @ts-expect-error: untyped.
|
||||
import Parser from 'parse5/lib/parser/index.js'
|
||||
import {pointStart, pointEnd} from 'unist-util-position'
|
||||
import {visit} from 'unist-util-visit'
|
||||
import {fromParse5} from 'hast-util-from-parse5'
|
||||
import {toParse5} from 'hast-util-to-parse5'
|
||||
import {htmlVoidElements} from 'html-void-elements'
|
||||
import {webNamespaces} from 'web-namespaces'
|
||||
import {zwitch} from 'zwitch'
|
||||
|
||||
const inTemplateMode = 'IN_TEMPLATE_MODE'
|
||||
const dataState = 'DATA_STATE'
|
||||
const characterToken = 'CHARACTER_TOKEN'
|
||||
const startTagToken = 'START_TAG_TOKEN'
|
||||
const endTagToken = 'END_TAG_TOKEN'
|
||||
const commentToken = 'COMMENT_TOKEN'
|
||||
const doctypeToken = 'DOCTYPE_TOKEN'
|
||||
|
||||
/** @type {P5ParserOptions} */
|
||||
const parseOptions = {sourceCodeLocationInfo: true, scriptingEnabled: false}
|
||||
|
||||
/**
|
||||
* Given a hast tree and an optional vfile (for positional info), return a new
|
||||
* parsed-again hast tree.
|
||||
*
|
||||
* @param tree
|
||||
* Original hast tree.
|
||||
* @param file
|
||||
* Virtual file for positional info, optional.
|
||||
* @param options
|
||||
* Configuration.
|
||||
*/
|
||||
export const raw =
|
||||
/**
|
||||
* @type {(
|
||||
* ((tree: Node, file: VFile|undefined, options?: Options) => Node) &
|
||||
* ((tree: Node, options?: Options) => Node)
|
||||
* )}
|
||||
*/
|
||||
(
|
||||
/**
|
||||
* @param {Node} tree
|
||||
* @param {VFile} [file]
|
||||
* @param {Options} [options]
|
||||
*/
|
||||
function (tree, file, options) {
|
||||
let index = -1
|
||||
const parser = new Parser(parseOptions)
|
||||
const one = zwitch('type', {
|
||||
handlers: {root, element, text, comment, doctype, raw: handleRaw},
|
||||
// @ts-expect-error: hush.
|
||||
unknown
|
||||
})
|
||||
/** @type {boolean|undefined} */
|
||||
let stitches
|
||||
/** @type {HiddenTokenizer|undefined} */
|
||||
let tokenizer
|
||||
/** @type {HiddenPreprocessor|undefined} */
|
||||
let preprocessor
|
||||
/** @type {HiddenPosTracker|undefined} */
|
||||
let posTracker
|
||||
/** @type {HiddenLocationTracker|undefined} */
|
||||
let locationTracker
|
||||
|
||||
if (isOptions(file)) {
|
||||
options = file
|
||||
file = undefined
|
||||
}
|
||||
|
||||
if (options && options.passThrough) {
|
||||
while (++index < options.passThrough.length) {
|
||||
// @ts-expect-error: hush.
|
||||
one.handlers[options.passThrough[index]] = stitch
|
||||
}
|
||||
}
|
||||
|
||||
const result = fromParse5(
|
||||
documentMode(tree) ? document() : fragment(),
|
||||
file
|
||||
)
|
||||
|
||||
if (stitches) {
|
||||
visit(result, 'comment', (node, index, parent) => {
|
||||
const stitch = /** @type {Stitch} */ (/** @type {unknown} */ (node))
|
||||
if (stitch.value.stitch && parent !== null && index !== null) {
|
||||
// @ts-expect-error: assume the stitch is allowed.
|
||||
parent.children[index] = stitch.value.stitch
|
||||
return index
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Unpack if possible and when not given a `root`.
|
||||
if (
|
||||
tree.type !== 'root' &&
|
||||
result.type === 'root' &&
|
||||
result.children.length === 1
|
||||
) {
|
||||
return result.children[0]
|
||||
}
|
||||
|
||||
return result
|
||||
|
||||
/**
|
||||
* @returns {P5Fragment}
|
||||
*/
|
||||
function fragment() {
|
||||
/** @type {P5Element} */
|
||||
const context = {
|
||||
nodeName: 'template',
|
||||
tagName: 'template',
|
||||
attrs: [],
|
||||
namespaceURI: webNamespaces.html,
|
||||
childNodes: []
|
||||
}
|
||||
/** @type {P5Element} */
|
||||
const mock = {
|
||||
nodeName: 'documentmock',
|
||||
tagName: 'documentmock',
|
||||
attrs: [],
|
||||
namespaceURI: webNamespaces.html,
|
||||
childNodes: []
|
||||
}
|
||||
/** @type {P5Fragment} */
|
||||
const doc = {nodeName: '#document-fragment', childNodes: []}
|
||||
|
||||
parser._bootstrap(mock, context)
|
||||
parser._pushTmplInsertionMode(inTemplateMode)
|
||||
parser._initTokenizerForFragmentParsing()
|
||||
parser._insertFakeRootElement()
|
||||
parser._resetInsertionMode()
|
||||
parser._findFormInFragmentContext()
|
||||
|
||||
tokenizer = parser.tokenizer
|
||||
/* c8 ignore next */
|
||||
if (!tokenizer) throw new Error('Expected `tokenizer`')
|
||||
preprocessor = tokenizer.preprocessor
|
||||
locationTracker = tokenizer.__mixins[0]
|
||||
posTracker = locationTracker.posTracker
|
||||
|
||||
one(tree)
|
||||
|
||||
resetTokenizer()
|
||||
|
||||
parser._adoptNodes(mock.childNodes[0], doc)
|
||||
|
||||
return doc
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {P5Document}
|
||||
*/
|
||||
function document() {
|
||||
/** @type {P5Document} */
|
||||
const doc = parser.treeAdapter.createDocument()
|
||||
|
||||
parser._bootstrap(doc, undefined)
|
||||
tokenizer = parser.tokenizer
|
||||
/* c8 ignore next */
|
||||
if (!tokenizer) throw new Error('Expected `tokenizer`')
|
||||
preprocessor = tokenizer.preprocessor
|
||||
locationTracker = tokenizer.__mixins[0]
|
||||
posTracker = locationTracker.posTracker
|
||||
|
||||
one(tree)
|
||||
|
||||
resetTokenizer()
|
||||
|
||||
return doc
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Array<Content>} nodes
|
||||
* @returns {void}
|
||||
*/
|
||||
function all(nodes) {
|
||||
let index = -1
|
||||
|
||||
/* istanbul ignore else - invalid nodes, see rehypejs/rehype-raw#7. */
|
||||
if (nodes) {
|
||||
while (++index < nodes.length) {
|
||||
one(nodes[index])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Root} node
|
||||
* @returns {void}
|
||||
*/
|
||||
function root(node) {
|
||||
all(node.children)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Element} node
|
||||
* @returns {void}
|
||||
*/
|
||||
function element(node) {
|
||||
resetTokenizer()
|
||||
parser._processInputToken(startTag(node))
|
||||
|
||||
all(node.children)
|
||||
|
||||
if (!htmlVoidElements.includes(node.tagName)) {
|
||||
resetTokenizer()
|
||||
parser._processInputToken(endTag(node))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Text} node
|
||||
* @returns {void}
|
||||
*/
|
||||
function text(node) {
|
||||
resetTokenizer()
|
||||
parser._processInputToken({
|
||||
type: characterToken,
|
||||
chars: node.value,
|
||||
location: createParse5Location(node)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Doctype} node
|
||||
* @returns {void}
|
||||
*/
|
||||
function doctype(node) {
|
||||
resetTokenizer()
|
||||
parser._processInputToken({
|
||||
type: doctypeToken,
|
||||
name: 'html',
|
||||
forceQuirks: false,
|
||||
publicId: '',
|
||||
systemId: '',
|
||||
location: createParse5Location(node)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Comment|Stitch} node
|
||||
* @returns {void}
|
||||
*/
|
||||
function comment(node) {
|
||||
resetTokenizer()
|
||||
parser._processInputToken({
|
||||
type: commentToken,
|
||||
data: node.value,
|
||||
location: createParse5Location(node)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Raw} node
|
||||
* @returns {void}
|
||||
*/
|
||||
function handleRaw(node) {
|
||||
const start = pointStart(node)
|
||||
const line = start.line || 1
|
||||
const column = start.column || 1
|
||||
const offset = start.offset || 0
|
||||
|
||||
/* c8 ignore next 4 */
|
||||
if (!preprocessor) throw new Error('Expected `preprocessor`')
|
||||
if (!tokenizer) throw new Error('Expected `tokenizer`')
|
||||
if (!posTracker) throw new Error('Expected `posTracker`')
|
||||
if (!locationTracker) throw new Error('Expected `locationTracker`')
|
||||
|
||||
// Reset preprocessor:
|
||||
// See: <https://github.com/inikulin/parse5/blob/9c683e1/packages/parse5/lib/tokenizer/preprocessor.js#L17>.
|
||||
preprocessor.html = undefined
|
||||
preprocessor.pos = -1
|
||||
preprocessor.lastGapPos = -1
|
||||
preprocessor.lastCharPos = -1
|
||||
preprocessor.gapStack = []
|
||||
preprocessor.skipNextNewLine = false
|
||||
preprocessor.lastChunkWritten = false
|
||||
preprocessor.endOfChunkHit = false
|
||||
|
||||
// Reset preprocessor mixin:
|
||||
// See: <https://github.com/inikulin/parse5/blob/9c683e1/packages/parse5/lib/extensions/position-tracking/preprocessor-mixin.js>.
|
||||
posTracker.isEol = false
|
||||
posTracker.lineStartPos = -column + 1 // Looks weird, but ensures we get correct positional info.
|
||||
posTracker.droppedBufferSize = offset
|
||||
posTracker.offset = 0
|
||||
posTracker.col = 1
|
||||
posTracker.line = line
|
||||
|
||||
// Reset location tracker:
|
||||
// See: <https://github.com/inikulin/parse5/blob/9c683e1/packages/parse5/lib/extensions/location-info/tokenizer-mixin.js>.
|
||||
locationTracker.currentAttrLocation = undefined
|
||||
locationTracker.ctLoc = createParse5Location(node)
|
||||
|
||||
// See the code for `parse` and `parseFragment`:
|
||||
// See: <https://github.com/inikulin/parse5/blob/9c683e1/packages/parse5/lib/parser/index.js#L371>.
|
||||
tokenizer.write(node.value)
|
||||
parser._runParsingLoop(null)
|
||||
|
||||
// Character references hang, so if we ended there, we need to flush
|
||||
// those too.
|
||||
// We reset the preprocessor as if the document ends here.
|
||||
// Then one single call to the relevant state does the trick, parse5
|
||||
// consumes the whole token.
|
||||
if (
|
||||
tokenizer.state === 'NAMED_CHARACTER_REFERENCE_STATE' ||
|
||||
tokenizer.state === 'NUMERIC_CHARACTER_REFERENCE_END_STATE'
|
||||
) {
|
||||
preprocessor.lastChunkWritten = true
|
||||
tokenizer[tokenizer.state](tokenizer._consume())
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
*/
|
||||
function stitch(node) {
|
||||
stitches = true
|
||||
|
||||
/** @type {Node} */
|
||||
let clone
|
||||
|
||||
// Recurse, because to somewhat handle `[<x>]</x>` (where `[]` denotes the
|
||||
// passed through node).
|
||||
if ('children' in node) {
|
||||
clone = {
|
||||
...node,
|
||||
children: raw(
|
||||
{type: 'root', children: node.children},
|
||||
file,
|
||||
options
|
||||
// @ts-expect-error Assume a given parent yields a parent.
|
||||
).children
|
||||
}
|
||||
} else {
|
||||
clone = {...node}
|
||||
}
|
||||
|
||||
// Hack: `value` is supposed to be a string, but as none of the tools
|
||||
// (`parse5` or `hast-util-from-parse5`) looks at it, we can pass nodes
|
||||
// through.
|
||||
comment({type: 'comment', value: {stitch: clone}})
|
||||
}
|
||||
|
||||
function resetTokenizer() {
|
||||
/* c8 ignore next 2 */
|
||||
if (!tokenizer) throw new Error('Expected `tokenizer`')
|
||||
if (!posTracker) throw new Error('Expected `posTracker`')
|
||||
|
||||
// Process final characters if they’re still there after hibernating.
|
||||
// Similar to:
|
||||
// See: <https://github.com/inikulin/parse5/blob/9c683e1/packages/parse5/lib/extensions/location-info/tokenizer-mixin.js#L95>.
|
||||
const token = tokenizer.currentCharacterToken
|
||||
|
||||
if (token) {
|
||||
token.location.endLine = posTracker.line
|
||||
token.location.endCol = posTracker.col + 1
|
||||
token.location.endOffset = posTracker.offset + 1
|
||||
parser._processInputToken(token)
|
||||
}
|
||||
|
||||
// Reset tokenizer:
|
||||
// See: <https://github.com/inikulin/parse5/blob/9c683e1/packages/parse5/lib/tokenizer/index.js#L218-L234>.
|
||||
// Especially putting it back in the `data` state is useful: some elements,
|
||||
// like textareas and iframes, change the state.
|
||||
// See GH-7.
|
||||
// But also if broken HTML is in `raw`, and then a correct element is given.
|
||||
// See GH-11.
|
||||
tokenizer.tokenQueue = []
|
||||
tokenizer.state = dataState
|
||||
tokenizer.returnState = ''
|
||||
tokenizer.charRefCode = -1
|
||||
tokenizer.tempBuff = []
|
||||
tokenizer.lastStartTagName = ''
|
||||
tokenizer.consumedAfterSnapshot = -1
|
||||
tokenizer.active = false
|
||||
tokenizer.currentCharacterToken = undefined
|
||||
tokenizer.currentToken = undefined
|
||||
tokenizer.currentAttr = undefined
|
||||
}
|
||||
}
|
||||
)
|
||||
/**
|
||||
* @param {Element} node
|
||||
* @returns {HiddenToken}
|
||||
*/
|
||||
function startTag(node) {
|
||||
/** @type {P5Location} */
|
||||
const location = Object.assign(createParse5Location(node))
|
||||
// @ts-expect-error extra positional info.
|
||||
location.startTag = Object.assign({}, location)
|
||||
|
||||
// Untyped token.
|
||||
return {
|
||||
type: startTagToken,
|
||||
tagName: node.tagName,
|
||||
selfClosing: false,
|
||||
attrs: attributes(node),
|
||||
location
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Element} node
|
||||
* @returns {Array<P5Attribute>}
|
||||
*/
|
||||
function attributes(node) {
|
||||
return toParse5({
|
||||
tagName: node.tagName,
|
||||
type: 'element',
|
||||
properties: node.properties,
|
||||
children: []
|
||||
// @ts-expect-error Assume element.
|
||||
}).attrs
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Element} node
|
||||
* @returns {HiddenToken}
|
||||
*/
|
||||
function endTag(node) {
|
||||
/** @type {P5Location} */
|
||||
const location = Object.assign(createParse5Location(node))
|
||||
// @ts-expect-error extra positional info.
|
||||
location.startTag = Object.assign({}, location)
|
||||
|
||||
// Untyped token.
|
||||
return {
|
||||
type: endTagToken,
|
||||
tagName: node.tagName,
|
||||
attrs: [],
|
||||
location
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
*/
|
||||
function unknown(node) {
|
||||
throw new Error('Cannot compile `' + node.type + '` node')
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function documentMode(node) {
|
||||
const head = node.type === 'root' ? node.children[0] : node
|
||||
return Boolean(
|
||||
head &&
|
||||
(head.type === 'doctype' ||
|
||||
(head.type === 'element' && head.tagName === 'html'))
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node|Stitch} node
|
||||
* @returns {P5Location}
|
||||
*/
|
||||
function createParse5Location(node) {
|
||||
const start = pointStart(node)
|
||||
const end = pointEnd(node)
|
||||
|
||||
return {
|
||||
startLine: start.line,
|
||||
startCol: start.column,
|
||||
startOffset: start.offset,
|
||||
endLine: end.line,
|
||||
endCol: end.column,
|
||||
endOffset: end.offset
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {VFile|Options|undefined} value
|
||||
* @return {value is Options}
|
||||
*/
|
||||
function isOptions(value) {
|
||||
return Boolean(value && !('message' in value && 'messages' in value))
|
||||
}
|
||||
22
node_modules/hast-util-raw/license
generated
vendored
Normal file
22
node_modules/hast-util-raw/license
generated
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
(The MIT License)
|
||||
|
||||
Copyright (c) 2016 Titus Wormer <tituswormer@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
'Software'), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
97
node_modules/hast-util-raw/package.json
generated
vendored
Normal file
97
node_modules/hast-util-raw/package.json
generated
vendored
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
{
|
||||
"name": "hast-util-raw",
|
||||
"version": "7.2.3",
|
||||
"description": "hast utility to reparse a tree",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
"unist",
|
||||
"hast",
|
||||
"hast-util",
|
||||
"util",
|
||||
"utility",
|
||||
"parse",
|
||||
"raw",
|
||||
"html"
|
||||
],
|
||||
"repository": "syntax-tree/hast-util-raw",
|
||||
"bugs": "https://github.com/syntax-tree/hast-util-raw/issues",
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/unified"
|
||||
},
|
||||
"author": "Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)",
|
||||
"contributors": [
|
||||
"Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)",
|
||||
"Christian Murphy <christian.murphy.42@gmail.com>"
|
||||
],
|
||||
"sideEffects": false,
|
||||
"type": "module",
|
||||
"main": "index.js",
|
||||
"types": "index.d.ts",
|
||||
"files": [
|
||||
"lib/",
|
||||
"complex-types.d.ts",
|
||||
"index.d.ts",
|
||||
"index.js"
|
||||
],
|
||||
"dependencies": {
|
||||
"@types/hast": "^2.0.0",
|
||||
"@types/parse5": "^6.0.0",
|
||||
"hast-util-from-parse5": "^7.0.0",
|
||||
"hast-util-to-parse5": "^7.0.0",
|
||||
"html-void-elements": "^2.0.0",
|
||||
"parse5": "^6.0.0",
|
||||
"unist-util-position": "^4.0.0",
|
||||
"unist-util-visit": "^4.0.0",
|
||||
"vfile": "^5.0.0",
|
||||
"web-namespaces": "^2.0.0",
|
||||
"zwitch": "^2.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/tape": "^4.0.0",
|
||||
"c8": "^7.0.0",
|
||||
"hastscript": "^7.0.0",
|
||||
"prettier": "^2.0.0",
|
||||
"rehype-stringify": "^9.0.0",
|
||||
"remark-cli": "^11.0.0",
|
||||
"remark-parse": "^10.0.0",
|
||||
"remark-preset-wooorm": "^9.0.0",
|
||||
"remark-rehype": "^10.0.0",
|
||||
"rimraf": "^3.0.0",
|
||||
"tape": "^5.0.0",
|
||||
"type-coverage": "^2.0.0",
|
||||
"typescript": "^4.0.0",
|
||||
"unified": "^10.0.0",
|
||||
"unist-builder": "^3.0.0",
|
||||
"xo": "^0.52.0"
|
||||
},
|
||||
"scripts": {
|
||||
"prepack": "npm run build && npm run format",
|
||||
"build": "rimraf \"lib/**/*.d.ts\" \"{index,test}.d.ts\" && tsc && type-coverage",
|
||||
"format": "remark . -qfo && prettier . -w --loglevel warn && xo --fix",
|
||||
"test-api": "node test.js",
|
||||
"test-coverage": "c8 --check-coverage --branches 100 --functions 100 --lines 100 --statements 100 --reporter lcov node test.js",
|
||||
"test": "npm run build && npm run format && npm run test-coverage"
|
||||
},
|
||||
"prettier": {
|
||||
"tabWidth": 2,
|
||||
"useTabs": false,
|
||||
"singleQuote": true,
|
||||
"bracketSpacing": false,
|
||||
"semi": false,
|
||||
"trailingComma": "none"
|
||||
},
|
||||
"xo": {
|
||||
"prettier": true
|
||||
},
|
||||
"remarkConfig": {
|
||||
"plugins": [
|
||||
"preset-wooorm"
|
||||
]
|
||||
},
|
||||
"typeCoverage": {
|
||||
"atLeast": 100,
|
||||
"detail": true,
|
||||
"strict": true
|
||||
}
|
||||
}
|
||||
271
node_modules/hast-util-raw/readme.md
generated
vendored
Normal file
271
node_modules/hast-util-raw/readme.md
generated
vendored
Normal file
|
|
@ -0,0 +1,271 @@
|
|||
# hast-util-raw
|
||||
|
||||
[![Build][build-badge]][build]
|
||||
[![Coverage][coverage-badge]][coverage]
|
||||
[![Downloads][downloads-badge]][downloads]
|
||||
[![Size][size-badge]][size]
|
||||
[![Sponsors][sponsors-badge]][collective]
|
||||
[![Backers][backers-badge]][collective]
|
||||
[![Chat][chat-badge]][chat]
|
||||
|
||||
[hast][] utility to parse the tree and semistandard `raw` nodes (strings of
|
||||
HTML) again, keeping positional info okay.
|
||||
|
||||
## Contents
|
||||
|
||||
* [What is this?](#what-is-this)
|
||||
* [When should I use this?](#when-should-i-use-this)
|
||||
* [Install](#install)
|
||||
* [Use](#use)
|
||||
* [API](#api)
|
||||
* [`raw(tree[, file][, options])`](#rawtree-file-options)
|
||||
* [Types](#types)
|
||||
* [Compatibility](#compatibility)
|
||||
* [Security](#security)
|
||||
* [Related](#related)
|
||||
* [Contribute](#contribute)
|
||||
* [License](#license)
|
||||
|
||||
## What is this?
|
||||
|
||||
This package is a utility to parse a document again.
|
||||
It passes each node and embedded raw HTML through an HTML parser
|
||||
([`parse5`][parse5]), to recreate a tree exactly as how a browser would parse
|
||||
it, while keeping the original data and positional info intact.
|
||||
|
||||
## When should I use this?
|
||||
|
||||
This utility is particularly useful when coming from markdown and wanting to
|
||||
support HTML embedded inside that markdown (which requires passing
|
||||
`allowDangerousHtml: true` to `mdast-util-to-hast`).
|
||||
Markdown dictates how, say, a list item or emphasis can be parsed.
|
||||
We can use that to turn the markdown syntax tree into an HTML syntax tree.
|
||||
But markdown also dictates that things that look like HTML, are passed through
|
||||
untouched, even when it just looks like XML but doesn’t really make sense, so we
|
||||
can’t normally use these strings of “HTML” to create an HTML syntax tree.
|
||||
This utility can.
|
||||
It can be used to take those strings of HTML and include them into the syntax
|
||||
tree as actual nodes.
|
||||
|
||||
If your final result is HTML and you trust content, then “strings” are fine
|
||||
(you can pass `allowDangerousHtml: true` to `hast-util-to-html`, which passes
|
||||
HTML through untouched).
|
||||
But there are two main cases where a proper syntax tree is preferred:
|
||||
|
||||
* hast utilities need a proper syntax tree as they operate on actual nodes to
|
||||
inspect or transform things, they can’t operate on strings of HTML
|
||||
* other output formats (React, MDX, etc) need actual nodes and can’t handle
|
||||
strings of HTML
|
||||
|
||||
The plugin [`rehype-raw`][rehype-raw] wraps this utility at a higher-level
|
||||
(easier) abstraction.
|
||||
|
||||
## Install
|
||||
|
||||
This package is [ESM only][esm].
|
||||
In Node.js (version 12.20+, 14.14+, 16.0+, or 18.0+), install with [npm][]:
|
||||
|
||||
```sh
|
||||
npm install hast-util-raw
|
||||
```
|
||||
|
||||
In Deno with [`esm.sh`][esmsh]:
|
||||
|
||||
```js
|
||||
import {raw} from 'https://esm.sh/hast-util-raw@7'
|
||||
```
|
||||
|
||||
In browsers with [`esm.sh`][esmsh]:
|
||||
|
||||
```html
|
||||
<script type="module">
|
||||
import {raw} from 'https://esm.sh/hast-util-raw@7?bundle'
|
||||
</script>
|
||||
```
|
||||
|
||||
## Use
|
||||
|
||||
```js
|
||||
import {h} from 'hastscript'
|
||||
import {raw} from 'hast-util-raw'
|
||||
|
||||
const tree = h('div', [h('h1', ['Foo ', h('h2', 'Bar'), ' Baz'])])
|
||||
|
||||
const reformatted = raw(tree)
|
||||
|
||||
console.log(reformatted)
|
||||
```
|
||||
|
||||
Yields:
|
||||
|
||||
```js
|
||||
{ type: 'element',
|
||||
tagName: 'div',
|
||||
properties: {},
|
||||
children:
|
||||
[ { type: 'element',
|
||||
tagName: 'h1',
|
||||
properties: {},
|
||||
children: [Object] },
|
||||
{ type: 'element',
|
||||
tagName: 'h2',
|
||||
properties: {},
|
||||
children: [Object] },
|
||||
{ type: 'text', value: ' Baz' } ] }
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
This package exports the identifier `raw`.
|
||||
There is no default export.
|
||||
|
||||
### `raw(tree[, file][, options])`
|
||||
|
||||
Parse the tree and raw nodes (strings of HTML) again, keeping positional info
|
||||
okay.
|
||||
|
||||
> 👉 **Note**: `tree` should have positional info and `file`, when given, must
|
||||
> be a [vfile][] corresponding to `tree`.
|
||||
|
||||
##### `options`
|
||||
|
||||
Configuration (optional).
|
||||
|
||||
###### `options.passThrough`
|
||||
|
||||
List of custom hast node types to pass through (keep) in hast (`Array<string>`,
|
||||
default: `[]`).
|
||||
If the passed through nodes have children, those children are expected to be
|
||||
hast and will be handled by this utility.
|
||||
|
||||
## Types
|
||||
|
||||
This package is fully typed with [TypeScript][].
|
||||
It exports the additional type `Options`.
|
||||
|
||||
It also registers the `Raw` node type with `@types/hast`.
|
||||
If you’re working with the syntax tree, make sure to import this utility
|
||||
somewhere in your types, as that registers the new node types in the tree.
|
||||
|
||||
```js
|
||||
/**
|
||||
* @typedef {import('hast-util-raw')}
|
||||
*/
|
||||
|
||||
import {visit} from 'unist-util-visit'
|
||||
|
||||
/** @type {import('hast').Root} */
|
||||
const tree = getHastNodeSomeHow()
|
||||
|
||||
visit(tree, (node) => {
|
||||
// `node` can now be a `raw` node.
|
||||
})
|
||||
```
|
||||
|
||||
## Compatibility
|
||||
|
||||
Projects maintained by the unified collective are compatible with all maintained
|
||||
versions of Node.js.
|
||||
As of now, that is Node.js 12.20+, 14.14+, 16.0+, and 18.0+.
|
||||
Our projects sometimes work with older versions, but this is not guaranteed.
|
||||
|
||||
## Security
|
||||
|
||||
Use of `hast-util-raw` can open you up to a [cross-site scripting (XSS)][xss]
|
||||
attack as `raw` nodes are unsafe.
|
||||
The following example shows how a raw node is used to inject a script that runs
|
||||
when loaded in a browser.
|
||||
|
||||
```js
|
||||
raw(u('root', [u('raw', '<script>alert(1)</script>')]))
|
||||
```
|
||||
|
||||
Yields:
|
||||
|
||||
```html
|
||||
<script>alert(1)</script>
|
||||
```
|
||||
|
||||
Either do not use this utility in combination with user input, or use
|
||||
[`hast-util-santize`][hast-util-sanitize].
|
||||
|
||||
## Related
|
||||
|
||||
* [`mdast-util-to-hast`](https://github.com/syntax-tree/mdast-util-to-hast)
|
||||
— transform mdast to hast
|
||||
* [`rehype-raw`](https://github.com/rehypejs/rehype-raw)
|
||||
— rehype plugin
|
||||
|
||||
## Contribute
|
||||
|
||||
See [`contributing.md`][contributing] in [`syntax-tree/.github`][health] for
|
||||
ways to get started.
|
||||
See [`support.md`][support] for ways to get help.
|
||||
|
||||
This project has a [code of conduct][coc].
|
||||
By interacting with this repository, organization, or community you agree to
|
||||
abide by its terms.
|
||||
|
||||
## License
|
||||
|
||||
[MIT][license] © [Titus Wormer][author]
|
||||
|
||||
<!-- Definitions -->
|
||||
|
||||
[build-badge]: https://github.com/syntax-tree/hast-util-raw/workflows/main/badge.svg
|
||||
|
||||
[build]: https://github.com/syntax-tree/hast-util-raw/actions
|
||||
|
||||
[coverage-badge]: https://img.shields.io/codecov/c/github/syntax-tree/hast-util-raw.svg
|
||||
|
||||
[coverage]: https://codecov.io/github/syntax-tree/hast-util-raw
|
||||
|
||||
[downloads-badge]: https://img.shields.io/npm/dm/hast-util-raw.svg
|
||||
|
||||
[downloads]: https://www.npmjs.com/package/hast-util-raw
|
||||
|
||||
[size-badge]: https://img.shields.io/bundlephobia/minzip/hast-util-raw.svg
|
||||
|
||||
[size]: https://bundlephobia.com/result?p=hast-util-raw
|
||||
|
||||
[sponsors-badge]: https://opencollective.com/unified/sponsors/badge.svg
|
||||
|
||||
[backers-badge]: https://opencollective.com/unified/backers/badge.svg
|
||||
|
||||
[collective]: https://opencollective.com/unified
|
||||
|
||||
[chat-badge]: https://img.shields.io/badge/chat-discussions-success.svg
|
||||
|
||||
[chat]: https://github.com/syntax-tree/unist/discussions
|
||||
|
||||
[npm]: https://docs.npmjs.com/cli/install
|
||||
|
||||
[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c
|
||||
|
||||
[esmsh]: https://esm.sh
|
||||
|
||||
[typescript]: https://www.typescriptlang.org
|
||||
|
||||
[license]: license
|
||||
|
||||
[author]: https://wooorm.com
|
||||
|
||||
[health]: https://github.com/syntax-tree/.github
|
||||
|
||||
[contributing]: https://github.com/syntax-tree/.github/blob/main/contributing.md
|
||||
|
||||
[support]: https://github.com/syntax-tree/.github/blob/main/support.md
|
||||
|
||||
[coc]: https://github.com/syntax-tree/.github/blob/main/code-of-conduct.md
|
||||
|
||||
[xss]: https://en.wikipedia.org/wiki/Cross-site_scripting
|
||||
|
||||
[hast]: https://github.com/syntax-tree/hast
|
||||
|
||||
[hast-util-sanitize]: https://github.com/syntax-tree/hast-util-sanitize
|
||||
|
||||
[vfile]: https://github.com/vfile/vfile
|
||||
|
||||
[rehype-raw]: https://github.com/rehypejs/rehype-raw
|
||||
|
||||
[parse5]: https://github.com/inikulin/parse5
|
||||
Loading…
Add table
Add a link
Reference in a new issue