🎉 initiate project *astro_rewrite*
This commit is contained in:
parent
ffd4d5e86c
commit
2ba37bfbe3
8658 changed files with 2268794 additions and 2538 deletions
24
node_modules/hast-util-to-estree/lib/handlers/comment.d.ts
generated
vendored
Normal file
24
node_modules/hast-util-to-estree/lib/handlers/comment.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
/**
|
||||
* @typedef {import('estree').Comment} Comment
|
||||
* @typedef {import('estree-jsx').JSXExpressionContainer} JsxExpressionContainer
|
||||
* @typedef {import('estree-jsx').JSXEmptyExpression} JsxEmptyExpression
|
||||
* @typedef {import('../state.js').State} State
|
||||
*/
|
||||
/**
|
||||
* Turn a hast comment into an estree node.
|
||||
*
|
||||
* @param {import('hast').Comment} node
|
||||
* hast node to transform.
|
||||
* @param {State} state
|
||||
* Info passed around about the current state.
|
||||
* @returns {JsxExpressionContainer}
|
||||
* estree expression.
|
||||
*/
|
||||
export function comment(
|
||||
node: import('hast').Comment,
|
||||
state: State
|
||||
): JsxExpressionContainer
|
||||
export type Comment = import('estree').Comment
|
||||
export type JsxExpressionContainer = import('estree-jsx').JSXExpressionContainer
|
||||
export type JsxEmptyExpression = import('estree-jsx').JSXEmptyExpression
|
||||
export type State = import('../state.js').State
|
||||
36
node_modules/hast-util-to-estree/lib/handlers/comment.js
generated
vendored
Normal file
36
node_modules/hast-util-to-estree/lib/handlers/comment.js
generated
vendored
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/**
|
||||
* @typedef {import('estree').Comment} Comment
|
||||
* @typedef {import('estree-jsx').JSXExpressionContainer} JsxExpressionContainer
|
||||
* @typedef {import('estree-jsx').JSXEmptyExpression} JsxEmptyExpression
|
||||
* @typedef {import('../state.js').State} State
|
||||
*/
|
||||
|
||||
/**
|
||||
* Turn a hast comment into an estree node.
|
||||
*
|
||||
* @param {import('hast').Comment} node
|
||||
* hast node to transform.
|
||||
* @param {State} state
|
||||
* Info passed around about the current state.
|
||||
* @returns {JsxExpressionContainer}
|
||||
* estree expression.
|
||||
*/
|
||||
export function comment(node, state) {
|
||||
/** @type {Comment} */
|
||||
const result = {type: 'Block', value: node.value}
|
||||
state.inherit(node, result)
|
||||
state.comments.push(result)
|
||||
|
||||
/** @type {JsxEmptyExpression} */
|
||||
const expression = {
|
||||
type: 'JSXEmptyExpression',
|
||||
// @ts-expect-error: `comments` is custom.
|
||||
comments: [Object.assign({}, result, {leading: false, trailing: true})]
|
||||
}
|
||||
state.patch(node, expression)
|
||||
|
||||
/** @type {JsxExpressionContainer} */
|
||||
const container = {type: 'JSXExpressionContainer', expression}
|
||||
state.patch(node, container)
|
||||
return container
|
||||
}
|
||||
18
node_modules/hast-util-to-estree/lib/handlers/element.d.ts
generated
vendored
Normal file
18
node_modules/hast-util-to-estree/lib/handlers/element.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/**
|
||||
* Turn a hast element into an estree node.
|
||||
*
|
||||
* @param {Element} node
|
||||
* hast node to transform.
|
||||
* @param {State} state
|
||||
* Info passed around about the current state.
|
||||
* @returns {JsxElement}
|
||||
* estree expression.
|
||||
*/
|
||||
export function element(node: Element, state: State): JsxElement
|
||||
export type Element = import('hast').Element
|
||||
export type Property = import('estree').Property
|
||||
export type JsxElement = import('estree-jsx').JSXElement
|
||||
export type JsxSpreadAttribute = import('estree-jsx').JSXSpreadAttribute
|
||||
export type JsxAttribute = import('estree-jsx').JSXAttribute
|
||||
export type State = import('../state.js').State
|
||||
export type Style = Record<string, string>
|
||||
308
node_modules/hast-util-to-estree/lib/handlers/element.js
generated
vendored
Normal file
308
node_modules/hast-util-to-estree/lib/handlers/element.js
generated
vendored
Normal file
|
|
@ -0,0 +1,308 @@
|
|||
/**
|
||||
* @typedef {import('hast').Element} Element
|
||||
* @typedef {import('estree').Property} Property
|
||||
* @typedef {import('estree-jsx').JSXElement} JsxElement
|
||||
* @typedef {import('estree-jsx').JSXSpreadAttribute} JsxSpreadAttribute
|
||||
* @typedef {import('estree-jsx').JSXAttribute} JsxAttribute
|
||||
* @typedef {import('../state.js').State} State
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Record<string, string>} Style
|
||||
*/
|
||||
|
||||
import {stringify as commas} from 'comma-separated-tokens'
|
||||
import {svg, find, hastToReact} from 'property-information'
|
||||
import {stringify as spaces} from 'space-separated-tokens'
|
||||
import {
|
||||
start as identifierStart,
|
||||
cont as identifierCont,
|
||||
name as identifierName
|
||||
} from 'estree-util-is-identifier-name'
|
||||
import styleToObject from 'style-to-object'
|
||||
|
||||
const own = {}.hasOwnProperty
|
||||
const cap = /[A-Z]/g
|
||||
const dashSomething = /-([a-z])/g
|
||||
|
||||
/**
|
||||
* Turn a hast element into an estree node.
|
||||
*
|
||||
* @param {Element} node
|
||||
* hast node to transform.
|
||||
* @param {State} state
|
||||
* Info passed around about the current state.
|
||||
* @returns {JsxElement}
|
||||
* estree expression.
|
||||
*/
|
||||
// eslint-disable-next-line complexity
|
||||
export function element(node, state) {
|
||||
const parentSchema = state.schema
|
||||
let schema = parentSchema
|
||||
const props = node.properties || {}
|
||||
|
||||
if (parentSchema.space === 'html' && node.tagName.toLowerCase() === 'svg') {
|
||||
schema = svg
|
||||
state.schema = schema
|
||||
}
|
||||
|
||||
const children = state.all(node)
|
||||
|
||||
/** @type {Array<JsxAttribute | JsxSpreadAttribute>} */
|
||||
const attributes = []
|
||||
/** @type {string} */
|
||||
let prop
|
||||
|
||||
for (prop in props) {
|
||||
if (own.call(props, prop)) {
|
||||
let value = props[prop]
|
||||
const info = find(schema, prop)
|
||||
/** @type {JsxAttribute['value']} */
|
||||
let attributeValue
|
||||
|
||||
// Ignore nullish and `NaN` values.
|
||||
// Ignore `false` and falsey known booleans.
|
||||
if (
|
||||
value === undefined ||
|
||||
value === null ||
|
||||
(typeof value === 'number' && Number.isNaN(value)) ||
|
||||
value === false ||
|
||||
(!value && info.boolean)
|
||||
) {
|
||||
continue
|
||||
}
|
||||
|
||||
prop =
|
||||
state.elementAttributeNameCase === 'react' && info.space
|
||||
? hastToReact[info.property] || info.property
|
||||
: info.attribute
|
||||
|
||||
if (Array.isArray(value)) {
|
||||
// Accept `array`.
|
||||
// Most props are space-separated.
|
||||
value = info.commaSeparated ? commas(value) : spaces(value)
|
||||
}
|
||||
|
||||
if (prop === 'style') {
|
||||
let styleObject =
|
||||
typeof value === 'object'
|
||||
? value
|
||||
: parseStyle(String(value), node.tagName)
|
||||
|
||||
if (state.stylePropertyNameCase === 'css') {
|
||||
styleObject = transformStyleToCssCasing(styleObject)
|
||||
}
|
||||
|
||||
/** @type {Array<Property>} */
|
||||
const cssProperties = []
|
||||
/** @type {string} */
|
||||
let cssProp
|
||||
|
||||
for (cssProp in styleObject) {
|
||||
// eslint-disable-next-line max-depth
|
||||
if (own.call(styleObject, cssProp)) {
|
||||
cssProperties.push({
|
||||
type: 'Property',
|
||||
method: false,
|
||||
shorthand: false,
|
||||
computed: false,
|
||||
key: identifierName(cssProp)
|
||||
? {type: 'Identifier', name: cssProp}
|
||||
: {type: 'Literal', value: cssProp},
|
||||
value: {type: 'Literal', value: String(styleObject[cssProp])},
|
||||
kind: 'init'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
attributeValue = {
|
||||
type: 'JSXExpressionContainer',
|
||||
expression: {type: 'ObjectExpression', properties: cssProperties}
|
||||
}
|
||||
} else if (value === true) {
|
||||
attributeValue = null
|
||||
} else {
|
||||
attributeValue = {type: 'Literal', value: String(value)}
|
||||
}
|
||||
|
||||
if (jsxIdentifierName(prop)) {
|
||||
attributes.push({
|
||||
type: 'JSXAttribute',
|
||||
name: {type: 'JSXIdentifier', name: prop},
|
||||
value: attributeValue
|
||||
})
|
||||
} else {
|
||||
attributes.push({
|
||||
type: 'JSXSpreadAttribute',
|
||||
argument: {
|
||||
type: 'ObjectExpression',
|
||||
properties: [
|
||||
{
|
||||
type: 'Property',
|
||||
method: false,
|
||||
shorthand: false,
|
||||
computed: false,
|
||||
key: {type: 'Literal', value: String(prop)},
|
||||
// @ts-expect-error No need to worry about `style` (which has a
|
||||
// `JSXExpressionContainer` value) because that’s a valid identifier.
|
||||
value: attributeValue || {type: 'Literal', value: true},
|
||||
kind: 'init'
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Restore parent schema.
|
||||
state.schema = parentSchema
|
||||
|
||||
/** @type {JsxElement} */
|
||||
const result = {
|
||||
type: 'JSXElement',
|
||||
openingElement: {
|
||||
type: 'JSXOpeningElement',
|
||||
attributes,
|
||||
name: state.createJsxElementName(node.tagName),
|
||||
selfClosing: children.length === 0
|
||||
},
|
||||
closingElement:
|
||||
children.length > 0
|
||||
? {
|
||||
type: 'JSXClosingElement',
|
||||
name: state.createJsxElementName(node.tagName)
|
||||
}
|
||||
: null,
|
||||
children
|
||||
}
|
||||
state.inherit(node, result)
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse CSS rules as a declaration.
|
||||
*
|
||||
* @param {string} value
|
||||
* CSS text.
|
||||
* @param {string} tagName
|
||||
* Element name.
|
||||
* @returns {Style}
|
||||
* Props.
|
||||
*/
|
||||
function parseStyle(value, tagName) {
|
||||
/** @type {Style} */
|
||||
const result = {}
|
||||
|
||||
try {
|
||||
styleToObject(value, iterator)
|
||||
} catch (error) {
|
||||
const exception = /** @type {Error} */ (error)
|
||||
exception.message =
|
||||
tagName + '[style]' + exception.message.slice('undefined'.length)
|
||||
throw error
|
||||
}
|
||||
|
||||
return result
|
||||
|
||||
/**
|
||||
* Add `name`, as a CSS prop, to `result`.
|
||||
*
|
||||
* @param {string} name
|
||||
* Key.
|
||||
* @param {string} value
|
||||
* Value.
|
||||
* @returns {void}
|
||||
* Nothing.
|
||||
*/
|
||||
function iterator(name, value) {
|
||||
let key = name
|
||||
|
||||
if (key.slice(0, 2) !== '--') {
|
||||
// See: <https://alanhogan.com/code/vendor-prefixed-css-property-names-in-javascript>
|
||||
if (key.slice(0, 4) === '-ms-') key = 'ms-' + key.slice(4)
|
||||
key = key.replace(dashSomething, toCamel)
|
||||
}
|
||||
|
||||
result[key] = value
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform a DOM casing style object to a CSS casing style object.
|
||||
*
|
||||
* @param {Style} domCasing
|
||||
* @returns {Style}
|
||||
*/
|
||||
function transformStyleToCssCasing(domCasing) {
|
||||
/** @type {Style} */
|
||||
const cssCasing = {}
|
||||
/** @type {string} */
|
||||
let from
|
||||
|
||||
for (from in domCasing) {
|
||||
if (own.call(domCasing, from)) {
|
||||
let to = from.replace(cap, toDash)
|
||||
// Handle `ms-xxx` -> `-ms-xxx`.
|
||||
if (to.slice(0, 3) === 'ms-') to = '-' + to
|
||||
cssCasing[to] = domCasing[from]
|
||||
}
|
||||
}
|
||||
|
||||
return cssCasing
|
||||
}
|
||||
|
||||
/**
|
||||
* Make `$1` capitalized.
|
||||
*
|
||||
* @param {string} _
|
||||
* Whatever.
|
||||
* @param {string} $1
|
||||
* Single ASCII alphabetical.
|
||||
* @returns {string}
|
||||
* Capitalized `$1`.
|
||||
*/
|
||||
function toCamel(_, $1) {
|
||||
return $1.toUpperCase()
|
||||
}
|
||||
|
||||
/**
|
||||
* Make `$0` dash cased.
|
||||
*
|
||||
* @param {string} $0
|
||||
* Capitalized ASCII leter.
|
||||
* @returns {string}
|
||||
* Dash and lower letter.
|
||||
*/
|
||||
function toDash($0) {
|
||||
return '-' + $0.toLowerCase()
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given string is a valid identifier name.
|
||||
*
|
||||
* Allows dashes, so it’s actually JSX identifier names.
|
||||
*
|
||||
* @param {string} name
|
||||
* Whatever.
|
||||
* @returns {boolean}
|
||||
* Whether `name` is a valid JSX identifier.
|
||||
*/
|
||||
function jsxIdentifierName(name) {
|
||||
let index = -1
|
||||
|
||||
while (++index < name.length) {
|
||||
if (!(index ? cont : identifierStart)(name.charCodeAt(index))) return false
|
||||
}
|
||||
|
||||
// `false` if `name` is empty.
|
||||
return index > 0
|
||||
|
||||
/**
|
||||
* @param {number} code
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function cont(code) {
|
||||
return identifierCont(code) || code === 45 /* `-` */
|
||||
}
|
||||
}
|
||||
27
node_modules/hast-util-to-estree/lib/handlers/index.d.ts
generated
vendored
Normal file
27
node_modules/hast-util-to-estree/lib/handlers/index.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
export namespace handlers {
|
||||
export {comment}
|
||||
export {ignore as doctype}
|
||||
export {element}
|
||||
export {mdxExpression as mdxFlowExpression}
|
||||
export {mdxExpression as mdxTextExpression}
|
||||
export {mdxJsxElement as mdxJsxFlowElement}
|
||||
export {mdxJsxElement as mdxJsxTextElement}
|
||||
export {mdxjsEsm}
|
||||
export {text}
|
||||
export {root}
|
||||
}
|
||||
import {comment} from './comment.js'
|
||||
/**
|
||||
* Handle a node that is ignored.
|
||||
*
|
||||
* @returns {void}
|
||||
* Nothing.
|
||||
*/
|
||||
declare function ignore(): void
|
||||
import {element} from './element.js'
|
||||
import {mdxExpression} from './mdx-expression.js'
|
||||
import {mdxJsxElement} from './mdx-jsx-element.js'
|
||||
import {mdxjsEsm} from './mdxjs-esm.js'
|
||||
import {text} from './text.js'
|
||||
import {root} from './root.js'
|
||||
export {}
|
||||
28
node_modules/hast-util-to-estree/lib/handlers/index.js
generated
vendored
Normal file
28
node_modules/hast-util-to-estree/lib/handlers/index.js
generated
vendored
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
import {comment} from './comment.js'
|
||||
import {element} from './element.js'
|
||||
import {mdxExpression} from './mdx-expression.js'
|
||||
import {mdxJsxElement} from './mdx-jsx-element.js'
|
||||
import {mdxjsEsm} from './mdxjs-esm.js'
|
||||
import {text} from './text.js'
|
||||
import {root} from './root.js'
|
||||
|
||||
export const handlers = {
|
||||
comment,
|
||||
doctype: ignore,
|
||||
element,
|
||||
mdxFlowExpression: mdxExpression,
|
||||
mdxTextExpression: mdxExpression,
|
||||
mdxJsxFlowElement: mdxJsxElement,
|
||||
mdxJsxTextElement: mdxJsxElement,
|
||||
mdxjsEsm,
|
||||
text,
|
||||
root
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a node that is ignored.
|
||||
*
|
||||
* @returns {void}
|
||||
* Nothing.
|
||||
*/
|
||||
function ignore() {}
|
||||
22
node_modules/hast-util-to-estree/lib/handlers/mdx-expression.d.ts
generated
vendored
Normal file
22
node_modules/hast-util-to-estree/lib/handlers/mdx-expression.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
/**
|
||||
* Turn an MDX expression node into an estree node.
|
||||
*
|
||||
* @param {MdxFlowExpression | MdxTextExpression} node
|
||||
* hast node to transform.
|
||||
* @param {State} state
|
||||
* Info passed around about the current state.
|
||||
* @returns {JsxExpressionContainer}
|
||||
* estree expression.
|
||||
*/
|
||||
export function mdxExpression(
|
||||
node: MdxFlowExpression | MdxTextExpression,
|
||||
state: State
|
||||
): JsxExpressionContainer
|
||||
export type MdxFlowExpression =
|
||||
import('mdast-util-mdx-expression').MdxFlowExpression
|
||||
export type MdxTextExpression =
|
||||
import('mdast-util-mdx-expression').MdxTextExpression
|
||||
export type Expression = import('estree').Expression
|
||||
export type JsxEmptyExpression = import('estree-jsx').JSXEmptyExpression
|
||||
export type JsxExpressionContainer = import('estree-jsx').JSXExpressionContainer
|
||||
export type State = import('../state.js').State
|
||||
47
node_modules/hast-util-to-estree/lib/handlers/mdx-expression.js
generated
vendored
Normal file
47
node_modules/hast-util-to-estree/lib/handlers/mdx-expression.js
generated
vendored
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/**
|
||||
* @typedef {import('mdast-util-mdx-expression').MdxFlowExpression} MdxFlowExpression
|
||||
* @typedef {import('mdast-util-mdx-expression').MdxTextExpression} MdxTextExpression
|
||||
* @typedef {import('estree').Expression} Expression
|
||||
* @typedef {import('estree-jsx').JSXEmptyExpression} JsxEmptyExpression
|
||||
* @typedef {import('estree-jsx').JSXExpressionContainer} JsxExpressionContainer
|
||||
* @typedef {import('../state.js').State} State
|
||||
*/
|
||||
|
||||
import {attachComments} from 'estree-util-attach-comments'
|
||||
|
||||
/**
|
||||
* Turn an MDX expression node into an estree node.
|
||||
*
|
||||
* @param {MdxFlowExpression | MdxTextExpression} node
|
||||
* hast node to transform.
|
||||
* @param {State} state
|
||||
* Info passed around about the current state.
|
||||
* @returns {JsxExpressionContainer}
|
||||
* estree expression.
|
||||
*/
|
||||
export function mdxExpression(node, state) {
|
||||
const estree = node.data && node.data.estree
|
||||
const comments = (estree && estree.comments) || []
|
||||
/** @type {Expression | JsxEmptyExpression | undefined} */
|
||||
let expression
|
||||
|
||||
if (estree) {
|
||||
state.comments.push(...comments)
|
||||
attachComments(estree, estree.comments)
|
||||
expression =
|
||||
(estree.body[0] &&
|
||||
estree.body[0].type === 'ExpressionStatement' &&
|
||||
estree.body[0].expression) ||
|
||||
undefined
|
||||
}
|
||||
|
||||
if (!expression) {
|
||||
expression = {type: 'JSXEmptyExpression'}
|
||||
state.patch(node, expression)
|
||||
}
|
||||
|
||||
/** @type {JsxExpressionContainer} */
|
||||
const result = {type: 'JSXExpressionContainer', expression}
|
||||
state.inherit(node, result)
|
||||
return result
|
||||
}
|
||||
22
node_modules/hast-util-to-estree/lib/handlers/mdx-jsx-element.d.ts
generated
vendored
Normal file
22
node_modules/hast-util-to-estree/lib/handlers/mdx-jsx-element.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
/**
|
||||
* Turn an MDX JSX element node into an estree node.
|
||||
*
|
||||
* @param {MdxJsxFlowElement | MdxJsxTextElement} node
|
||||
* hast node to transform.
|
||||
* @param {State} state
|
||||
* Info passed around about the current state.
|
||||
* @returns {JsxElement | JsxFragment}
|
||||
* JSX element or fragment.
|
||||
*/
|
||||
export function mdxJsxElement(
|
||||
node: MdxJsxFlowElement | MdxJsxTextElement,
|
||||
state: State
|
||||
): JsxElement | JsxFragment
|
||||
export type MdxJsxFlowElement = import('mdast-util-mdx-jsx').MdxJsxFlowElement
|
||||
export type MdxJsxTextElement = import('mdast-util-mdx-jsx').MdxJsxTextElement
|
||||
export type Expression = import('estree').Expression
|
||||
export type JsxElement = import('estree-jsx').JSXElement
|
||||
export type JsxFragment = import('estree-jsx').JSXFragment
|
||||
export type JsxAttribute = import('estree-jsx').JSXAttribute
|
||||
export type JsxSpreadAttribute = import('estree-jsx').JSXSpreadAttribute
|
||||
export type State = import('../state.js').State
|
||||
161
node_modules/hast-util-to-estree/lib/handlers/mdx-jsx-element.js
generated
vendored
Normal file
161
node_modules/hast-util-to-estree/lib/handlers/mdx-jsx-element.js
generated
vendored
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
/**
|
||||
* @typedef {import('mdast-util-mdx-jsx').MdxJsxFlowElement} MdxJsxFlowElement
|
||||
* @typedef {import('mdast-util-mdx-jsx').MdxJsxTextElement} MdxJsxTextElement
|
||||
* @typedef {import('estree').Expression} Expression
|
||||
* @typedef {import('estree-jsx').JSXElement} JsxElement
|
||||
* @typedef {import('estree-jsx').JSXFragment} JsxFragment
|
||||
* @typedef {import('estree-jsx').JSXAttribute} JsxAttribute
|
||||
* @typedef {import('estree-jsx').JSXSpreadAttribute} JsxSpreadAttribute
|
||||
* @typedef {import('../state.js').State} State
|
||||
*/
|
||||
|
||||
import {attachComments} from 'estree-util-attach-comments'
|
||||
import {svg} from 'property-information'
|
||||
|
||||
/**
|
||||
* Turn an MDX JSX element node into an estree node.
|
||||
*
|
||||
* @param {MdxJsxFlowElement | MdxJsxTextElement} node
|
||||
* hast node to transform.
|
||||
* @param {State} state
|
||||
* Info passed around about the current state.
|
||||
* @returns {JsxElement | JsxFragment}
|
||||
* JSX element or fragment.
|
||||
*/
|
||||
// eslint-disable-next-line complexity
|
||||
export function mdxJsxElement(node, state) {
|
||||
const parentSchema = state.schema
|
||||
let schema = parentSchema
|
||||
const attrs = node.attributes || []
|
||||
let index = -1
|
||||
|
||||
if (
|
||||
node.name &&
|
||||
parentSchema.space === 'html' &&
|
||||
node.name.toLowerCase() === 'svg'
|
||||
) {
|
||||
schema = svg
|
||||
state.schema = schema
|
||||
}
|
||||
|
||||
const children = state.all(node)
|
||||
/** @type {Array<JsxAttribute | JsxSpreadAttribute>} */
|
||||
const attributes = []
|
||||
|
||||
while (++index < attrs.length) {
|
||||
const attr = attrs[index]
|
||||
const value = attr.value
|
||||
/** @type {JsxAttribute['value']} */
|
||||
let attributeValue
|
||||
|
||||
if (attr.type === 'mdxJsxAttribute') {
|
||||
if (value === undefined || value === null) {
|
||||
attributeValue = null
|
||||
// Empty.
|
||||
}
|
||||
// `MdxJsxAttributeValueExpression`.
|
||||
else if (typeof value === 'object') {
|
||||
const estree = value.data && value.data.estree
|
||||
const comments = (estree && estree.comments) || []
|
||||
/** @type {Expression | undefined} */
|
||||
let expression
|
||||
|
||||
if (estree) {
|
||||
state.comments.push(...comments)
|
||||
attachComments(estree, estree.comments)
|
||||
// Should exist.
|
||||
/* c8 ignore next 5 */
|
||||
expression =
|
||||
(estree.body[0] &&
|
||||
estree.body[0].type === 'ExpressionStatement' &&
|
||||
estree.body[0].expression) ||
|
||||
undefined
|
||||
}
|
||||
|
||||
attributeValue = {
|
||||
type: 'JSXExpressionContainer',
|
||||
expression: expression || {type: 'JSXEmptyExpression'}
|
||||
}
|
||||
state.inherit(value, attributeValue)
|
||||
}
|
||||
// Anything else.
|
||||
else {
|
||||
attributeValue = {type: 'Literal', value: String(value)}
|
||||
}
|
||||
|
||||
/** @type {JsxAttribute} */
|
||||
const attribute = {
|
||||
type: 'JSXAttribute',
|
||||
name: state.createJsxAttributeName(attr.name),
|
||||
value: attributeValue
|
||||
}
|
||||
|
||||
state.inherit(attr, attribute)
|
||||
attributes.push(attribute)
|
||||
}
|
||||
// MdxJsxExpressionAttribute.
|
||||
else {
|
||||
const estree = attr.data && attr.data.estree
|
||||
const comments = (estree && estree.comments) || []
|
||||
/** @type {JsxSpreadAttribute['argument'] | undefined} */
|
||||
let argumentValue
|
||||
|
||||
if (estree) {
|
||||
state.comments.push(...comments)
|
||||
attachComments(estree, estree.comments)
|
||||
// Should exist.
|
||||
/* c8 ignore next 10 */
|
||||
argumentValue =
|
||||
(estree.body[0] &&
|
||||
estree.body[0].type === 'ExpressionStatement' &&
|
||||
estree.body[0].expression &&
|
||||
estree.body[0].expression.type === 'ObjectExpression' &&
|
||||
estree.body[0].expression.properties &&
|
||||
estree.body[0].expression.properties[0] &&
|
||||
estree.body[0].expression.properties[0].type === 'SpreadElement' &&
|
||||
estree.body[0].expression.properties[0].argument) ||
|
||||
undefined
|
||||
}
|
||||
|
||||
/** @type {JsxSpreadAttribute} */
|
||||
const attribute = {
|
||||
type: 'JSXSpreadAttribute',
|
||||
argument: argumentValue || {type: 'ObjectExpression', properties: []}
|
||||
}
|
||||
state.inherit(attr, attribute)
|
||||
attributes.push(attribute)
|
||||
}
|
||||
}
|
||||
|
||||
// Restore parent schema.
|
||||
state.schema = parentSchema
|
||||
|
||||
/** @type {JsxElement | JsxFragment} */
|
||||
const result = node.name
|
||||
? {
|
||||
type: 'JSXElement',
|
||||
openingElement: {
|
||||
type: 'JSXOpeningElement',
|
||||
attributes,
|
||||
name: state.createJsxElementName(node.name),
|
||||
selfClosing: children.length === 0
|
||||
},
|
||||
closingElement:
|
||||
children.length > 0
|
||||
? {
|
||||
type: 'JSXClosingElement',
|
||||
name: state.createJsxElementName(node.name)
|
||||
}
|
||||
: null,
|
||||
children
|
||||
}
|
||||
: {
|
||||
type: 'JSXFragment',
|
||||
openingFragment: {type: 'JSXOpeningFragment'},
|
||||
closingFragment: {type: 'JSXClosingFragment'},
|
||||
children
|
||||
}
|
||||
|
||||
state.inherit(node, result)
|
||||
return result
|
||||
}
|
||||
13
node_modules/hast-util-to-estree/lib/handlers/mdxjs-esm.d.ts
generated
vendored
Normal file
13
node_modules/hast-util-to-estree/lib/handlers/mdxjs-esm.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
/**
|
||||
* Handle an MDX ESM node.
|
||||
*
|
||||
* @param {MdxjsEsm} node
|
||||
* hast node to transform.
|
||||
* @param {State} state
|
||||
* Info passed around about the current state.
|
||||
* @returns {void}
|
||||
* Nothing.
|
||||
*/
|
||||
export function mdxjsEsm(node: MdxjsEsm, state: State): void
|
||||
export type MdxjsEsm = import('mdast-util-mdxjs-esm').MdxjsEsm
|
||||
export type State = import('../state.js').State
|
||||
27
node_modules/hast-util-to-estree/lib/handlers/mdxjs-esm.js
generated
vendored
Normal file
27
node_modules/hast-util-to-estree/lib/handlers/mdxjs-esm.js
generated
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
/**
|
||||
* @typedef {import('mdast-util-mdxjs-esm').MdxjsEsm} MdxjsEsm
|
||||
* @typedef {import('../state.js').State} State
|
||||
*/
|
||||
|
||||
import {attachComments} from 'estree-util-attach-comments'
|
||||
|
||||
/**
|
||||
* Handle an MDX ESM node.
|
||||
*
|
||||
* @param {MdxjsEsm} node
|
||||
* hast node to transform.
|
||||
* @param {State} state
|
||||
* Info passed around about the current state.
|
||||
* @returns {void}
|
||||
* Nothing.
|
||||
*/
|
||||
export function mdxjsEsm(node, state) {
|
||||
const estree = node.data && node.data.estree
|
||||
const comments = (estree && estree.comments) || []
|
||||
|
||||
if (estree) {
|
||||
state.comments.push(...comments)
|
||||
attachComments(estree, comments)
|
||||
state.esm.push(...estree.body)
|
||||
}
|
||||
}
|
||||
15
node_modules/hast-util-to-estree/lib/handlers/root.d.ts
generated
vendored
Normal file
15
node_modules/hast-util-to-estree/lib/handlers/root.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
/**
|
||||
* Turn a hast root node into an estree node.
|
||||
*
|
||||
* @param {Root} node
|
||||
* hast node to transform.
|
||||
* @param {State} state
|
||||
* Info passed around about the current state.
|
||||
* @returns {JsxFragment}
|
||||
* estree JSX fragment.
|
||||
*/
|
||||
export function root(node: Root, state: State): JsxFragment
|
||||
export type Root = import('hast').Root
|
||||
export type JsxFragment = import('estree-jsx').JSXFragment
|
||||
export type JsxChild = JsxFragment['children'][number]
|
||||
export type State = import('../state.js').State
|
||||
54
node_modules/hast-util-to-estree/lib/handlers/root.js
generated
vendored
Normal file
54
node_modules/hast-util-to-estree/lib/handlers/root.js
generated
vendored
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
/**
|
||||
* @typedef {import('hast').Root} Root
|
||||
* @typedef {import('estree-jsx').JSXFragment} JsxFragment
|
||||
* @typedef {JsxFragment['children'][number]} JsxChild
|
||||
* @typedef {import('../state.js').State} State
|
||||
*/
|
||||
|
||||
import {whitespace} from 'hast-util-whitespace'
|
||||
|
||||
/**
|
||||
* Turn a hast root node into an estree node.
|
||||
*
|
||||
* @param {Root} node
|
||||
* hast node to transform.
|
||||
* @param {State} state
|
||||
* Info passed around about the current state.
|
||||
* @returns {JsxFragment}
|
||||
* estree JSX fragment.
|
||||
*/
|
||||
export function root(node, state) {
|
||||
const children = state.all(node)
|
||||
/** @type {Array<JsxChild>} */
|
||||
const cleanChildren = []
|
||||
let index = -1
|
||||
/** @type {Array<JsxChild> | undefined} */
|
||||
let queue
|
||||
|
||||
// Remove surrounding whitespace nodes from the fragment.
|
||||
while (++index < children.length) {
|
||||
const child = children[index]
|
||||
|
||||
if (
|
||||
child.type === 'JSXExpressionContainer' &&
|
||||
child.expression.type === 'Literal' &&
|
||||
whitespace(child.expression.value)
|
||||
) {
|
||||
if (queue) queue.push(child)
|
||||
} else {
|
||||
if (queue) cleanChildren.push(...queue)
|
||||
cleanChildren.push(child)
|
||||
queue = []
|
||||
}
|
||||
}
|
||||
|
||||
/** @type {JsxFragment} */
|
||||
const result = {
|
||||
type: 'JSXFragment',
|
||||
openingFragment: {type: 'JSXOpeningFragment'},
|
||||
closingFragment: {type: 'JSXClosingFragment'},
|
||||
children: cleanChildren
|
||||
}
|
||||
state.inherit(node, result)
|
||||
return result
|
||||
}
|
||||
21
node_modules/hast-util-to-estree/lib/handlers/text.d.ts
generated
vendored
Normal file
21
node_modules/hast-util-to-estree/lib/handlers/text.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
/**
|
||||
* @typedef {import('hast').Text} Text
|
||||
* @typedef {import('estree').Literal} Literal
|
||||
* @typedef {import('estree-jsx').JSXExpressionContainer} JsxExpressionContainer
|
||||
* @typedef {import('../state.js').State} State
|
||||
*/
|
||||
/**
|
||||
* Turn a hast text node into an estree node.
|
||||
*
|
||||
* @param {Text} node
|
||||
* hast node to transform.
|
||||
* @param {State} state
|
||||
* Info passed around about the current state.
|
||||
* @returns {JsxExpressionContainer | void}
|
||||
* JSX expression.
|
||||
*/
|
||||
export function text(node: Text, state: State): JsxExpressionContainer | void
|
||||
export type Text = import('hast').Text
|
||||
export type Literal = import('estree').Literal
|
||||
export type JsxExpressionContainer = import('estree-jsx').JSXExpressionContainer
|
||||
export type State = import('../state.js').State
|
||||
30
node_modules/hast-util-to-estree/lib/handlers/text.js
generated
vendored
Normal file
30
node_modules/hast-util-to-estree/lib/handlers/text.js
generated
vendored
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
/**
|
||||
* @typedef {import('hast').Text} Text
|
||||
* @typedef {import('estree').Literal} Literal
|
||||
* @typedef {import('estree-jsx').JSXExpressionContainer} JsxExpressionContainer
|
||||
* @typedef {import('../state.js').State} State
|
||||
*/
|
||||
|
||||
/**
|
||||
* Turn a hast text node into an estree node.
|
||||
*
|
||||
* @param {Text} node
|
||||
* hast node to transform.
|
||||
* @param {State} state
|
||||
* Info passed around about the current state.
|
||||
* @returns {JsxExpressionContainer | void}
|
||||
* JSX expression.
|
||||
*/
|
||||
export function text(node, state) {
|
||||
const value = String(node.value || '')
|
||||
|
||||
if (value) {
|
||||
/** @type {Literal} */
|
||||
const result = {type: 'Literal', value}
|
||||
state.inherit(node, result)
|
||||
/** @type {JsxExpressionContainer} */
|
||||
const container = {type: 'JSXExpressionContainer', expression: result}
|
||||
state.patch(node, container)
|
||||
return container
|
||||
}
|
||||
}
|
||||
80
node_modules/hast-util-to-estree/lib/index.d.ts
generated
vendored
Normal file
80
node_modules/hast-util-to-estree/lib/index.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
/**
|
||||
* Transform a hast tree (with embedded MDX nodes) into an estree.
|
||||
*
|
||||
* ##### Notes
|
||||
*
|
||||
* ###### Comments
|
||||
*
|
||||
* Comments are attached to the tree in their neighbouring nodes (`recast`,
|
||||
* `babel` style) and also added as a `comments` array on the program node
|
||||
* (`espree` style).
|
||||
* You may have to do `program.comments = undefined` for certain compilers.
|
||||
*
|
||||
* ###### Frameworks
|
||||
*
|
||||
* There are differences between what JSX frameworks accept, such as whether they
|
||||
* accept `class` or `className`, or `background-color` or `backgroundColor`.
|
||||
*
|
||||
* For JSX components written in MDX, the author has to be aware of this
|
||||
* difference and write code accordingly.
|
||||
* For hast elements transformed by this project, this will be handled through
|
||||
* options.
|
||||
*
|
||||
* | Framework | `elementAttributeNameCase` | `stylePropertyNameCase` |
|
||||
* | --------- | -------------------------- | ----------------------- |
|
||||
* | Preact | `'html'` | `'dom'` |
|
||||
* | React | `'react'` | `'dom'` |
|
||||
* | Solid | `'html'` | `'css'` |
|
||||
* | Vue | `'html'` | `'dom'` |
|
||||
*
|
||||
* @param {Node} tree
|
||||
* hast tree.
|
||||
* @param {Options | null | undefined} [options]
|
||||
* Configuration.
|
||||
* @returns {Program}
|
||||
* estree program node.
|
||||
*
|
||||
* The program’s last child in `body` is most likely an `ExpressionStatement`,
|
||||
* whose expression is a `JSXFragment` or a `JSXElement`.
|
||||
*
|
||||
* Typically, there is only one node in `body`, however, this utility also
|
||||
* supports embedded MDX nodes in the HTML (when `mdast-util-mdx` is used
|
||||
* with mdast to parse markdown before passing its nodes through to hast).
|
||||
* When MDX ESM import/exports are used, those nodes are added before the
|
||||
* fragment or element in body.
|
||||
*
|
||||
* There aren’t many great estree serializers out there that support JSX.
|
||||
* To do that, you can use `estree-util-to-js`.
|
||||
* Or, use `estree-util-build-jsx` to turn JSX into function calls, and then
|
||||
* serialize with whatever (`astring`, `escodegen`).
|
||||
*/
|
||||
export function toEstree(
|
||||
tree: Node,
|
||||
options?: Options | null | undefined
|
||||
): Program
|
||||
export type Content = import('hast').Content
|
||||
export type Root = import('hast').Root
|
||||
export type ExpressionStatement = import('estree').ExpressionStatement
|
||||
export type Program = import('estree').Program
|
||||
export type MdxJsxAttribute = import('mdast-util-mdx-jsx').MdxJsxAttribute
|
||||
export type MdxJsxAttributeValueExpression =
|
||||
import('mdast-util-mdx-jsx').MdxJsxAttributeValueExpression
|
||||
export type MdxJsxExpressionAttribute =
|
||||
import('mdast-util-mdx-jsx').MdxJsxExpressionAttribute
|
||||
export type MdxJsxFlowElement = import('mdast-util-mdx-jsx').MdxJsxFlowElement
|
||||
export type MdxJsxTextElement = import('mdast-util-mdx-jsx').MdxJsxTextElement
|
||||
export type MdxFlowExpression =
|
||||
import('mdast-util-mdx-expression').MdxFlowExpression
|
||||
export type MdxTextExpression =
|
||||
import('mdast-util-mdx-expression').MdxTextExpression
|
||||
export type Options = import('./state.js').Options
|
||||
export type Node =
|
||||
| Root
|
||||
| Content
|
||||
| MdxJsxAttributeValueExpression
|
||||
| MdxJsxAttribute
|
||||
| MdxJsxExpressionAttribute
|
||||
| MdxJsxFlowElement
|
||||
| MdxJsxTextElement
|
||||
| MdxFlowExpression
|
||||
| MdxTextExpression
|
||||
108
node_modules/hast-util-to-estree/lib/index.js
generated
vendored
Normal file
108
node_modules/hast-util-to-estree/lib/index.js
generated
vendored
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
/**
|
||||
* @typedef {import('hast').Content} Content
|
||||
* @typedef {import('hast').Root} Root
|
||||
*
|
||||
* @typedef {import('estree').ExpressionStatement} ExpressionStatement
|
||||
* @typedef {import('estree').Program} Program
|
||||
*
|
||||
* @typedef {import('mdast-util-mdx-jsx').MdxJsxAttribute} MdxJsxAttribute
|
||||
* @typedef {import('mdast-util-mdx-jsx').MdxJsxAttributeValueExpression} MdxJsxAttributeValueExpression
|
||||
* @typedef {import('mdast-util-mdx-jsx').MdxJsxExpressionAttribute} MdxJsxExpressionAttribute
|
||||
* @typedef {import('mdast-util-mdx-jsx').MdxJsxFlowElement} MdxJsxFlowElement
|
||||
* @typedef {import('mdast-util-mdx-jsx').MdxJsxTextElement} MdxJsxTextElement
|
||||
*
|
||||
* @typedef {import('mdast-util-mdx-expression').MdxFlowExpression} MdxFlowExpression
|
||||
* @typedef {import('mdast-util-mdx-expression').MdxTextExpression} MdxTextExpression
|
||||
*
|
||||
* @typedef {import('./state.js').Options} Options
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Root | Content | MdxJsxAttributeValueExpression | MdxJsxAttribute | MdxJsxExpressionAttribute | MdxJsxFlowElement | MdxJsxTextElement | MdxFlowExpression | MdxTextExpression} Node
|
||||
*/
|
||||
|
||||
import {createState} from './state.js'
|
||||
|
||||
/**
|
||||
* Transform a hast tree (with embedded MDX nodes) into an estree.
|
||||
*
|
||||
* ##### Notes
|
||||
*
|
||||
* ###### Comments
|
||||
*
|
||||
* Comments are attached to the tree in their neighbouring nodes (`recast`,
|
||||
* `babel` style) and also added as a `comments` array on the program node
|
||||
* (`espree` style).
|
||||
* You may have to do `program.comments = undefined` for certain compilers.
|
||||
*
|
||||
* ###### Frameworks
|
||||
*
|
||||
* There are differences between what JSX frameworks accept, such as whether they
|
||||
* accept `class` or `className`, or `background-color` or `backgroundColor`.
|
||||
*
|
||||
* For JSX components written in MDX, the author has to be aware of this
|
||||
* difference and write code accordingly.
|
||||
* For hast elements transformed by this project, this will be handled through
|
||||
* options.
|
||||
*
|
||||
* | Framework | `elementAttributeNameCase` | `stylePropertyNameCase` |
|
||||
* | --------- | -------------------------- | ----------------------- |
|
||||
* | Preact | `'html'` | `'dom'` |
|
||||
* | React | `'react'` | `'dom'` |
|
||||
* | Solid | `'html'` | `'css'` |
|
||||
* | Vue | `'html'` | `'dom'` |
|
||||
*
|
||||
* @param {Node} tree
|
||||
* hast tree.
|
||||
* @param {Options | null | undefined} [options]
|
||||
* Configuration.
|
||||
* @returns {Program}
|
||||
* estree program node.
|
||||
*
|
||||
* The program’s last child in `body` is most likely an `ExpressionStatement`,
|
||||
* whose expression is a `JSXFragment` or a `JSXElement`.
|
||||
*
|
||||
* Typically, there is only one node in `body`, however, this utility also
|
||||
* supports embedded MDX nodes in the HTML (when `mdast-util-mdx` is used
|
||||
* with mdast to parse markdown before passing its nodes through to hast).
|
||||
* When MDX ESM import/exports are used, those nodes are added before the
|
||||
* fragment or element in body.
|
||||
*
|
||||
* There aren’t many great estree serializers out there that support JSX.
|
||||
* To do that, you can use `estree-util-to-js`.
|
||||
* Or, use `estree-util-build-jsx` to turn JSX into function calls, and then
|
||||
* serialize with whatever (`astring`, `escodegen`).
|
||||
*/
|
||||
export function toEstree(tree, options) {
|
||||
const state = createState(options || {})
|
||||
let result = state.handle(tree)
|
||||
const body = state.esm
|
||||
|
||||
if (result) {
|
||||
if (result.type !== 'JSXFragment' && result.type !== 'JSXElement') {
|
||||
result = {
|
||||
type: 'JSXFragment',
|
||||
openingFragment: {type: 'JSXOpeningFragment'},
|
||||
closingFragment: {type: 'JSXClosingFragment'},
|
||||
children: [result]
|
||||
}
|
||||
state.patch(tree, result)
|
||||
}
|
||||
|
||||
/** @type {ExpressionStatement} */
|
||||
// @ts-expect-error Types are wrong (`expression` *can* be JSX).
|
||||
const statement = {type: 'ExpressionStatement', expression: result}
|
||||
state.patch(tree, statement)
|
||||
body.push(statement)
|
||||
}
|
||||
|
||||
/** @type {Program} */
|
||||
const program = {
|
||||
type: 'Program',
|
||||
body,
|
||||
sourceType: 'module',
|
||||
comments: state.comments
|
||||
}
|
||||
state.patch(tree, program)
|
||||
return program
|
||||
}
|
||||
153
node_modules/hast-util-to-estree/lib/state.d.ts
generated
vendored
Normal file
153
node_modules/hast-util-to-estree/lib/state.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
/**
|
||||
* Create a state from options.
|
||||
*
|
||||
* @param {Options} options
|
||||
* Configuration.
|
||||
* @returns {State}
|
||||
* Info passed around about the current state.
|
||||
*/
|
||||
export function createState(options: Options): State
|
||||
export type Comment = import('estree').Comment
|
||||
export type Directive = import('estree').Directive
|
||||
export type ModuleDeclaration = import('estree').ModuleDeclaration
|
||||
export type EstreeNode = import('estree').Node
|
||||
export type Statement = import('estree').Statement
|
||||
export type JsxAttribute = import('estree-jsx').JSXAttribute
|
||||
export type JsxElement = import('estree-jsx').JSXElement
|
||||
export type JsxIdentifier = import('estree-jsx').JSXIdentifier
|
||||
export type JsxMemberExpression = import('estree-jsx').JSXMemberExpression
|
||||
export type JsxNamespacedName = import('estree-jsx').JSXNamespacedName
|
||||
export type Content = import('hast').Content
|
||||
export type Root = import('hast').Root
|
||||
export type MdxFlowExpression =
|
||||
import('mdast-util-mdx-expression').MdxFlowExpression
|
||||
export type MdxTextExpression =
|
||||
import('mdast-util-mdx-expression').MdxTextExpression
|
||||
export type MdxJsxAttribute = import('mdast-util-mdx-jsx').MdxJsxAttribute
|
||||
export type MdxJsxAttributeValueExpression =
|
||||
import('mdast-util-mdx-jsx').MdxJsxAttributeValueExpression
|
||||
export type MdxJsxExpressionAttribute =
|
||||
import('mdast-util-mdx-jsx').MdxJsxExpressionAttribute
|
||||
export type MdxJsxFlowElement = import('mdast-util-mdx-jsx').MdxJsxFlowElement
|
||||
export type MdxJsxTextElement = import('mdast-util-mdx-jsx').MdxJsxTextElement
|
||||
export type Schema = import('property-information').Schema
|
||||
export type UnistParent = import('unist').Parent
|
||||
export type Node =
|
||||
| Content
|
||||
| MdxJsxAttributeValueExpression
|
||||
| MdxJsxAttribute
|
||||
| MdxJsxExpressionAttribute
|
||||
| MdxJsxFlowElement
|
||||
| MdxJsxTextElement
|
||||
| MdxFlowExpression
|
||||
| MdxTextExpression
|
||||
| Root
|
||||
export type Parent = Extract<Node, UnistParent>
|
||||
export type JsxElementName = JsxElement['openingElement']['name']
|
||||
export type JsxAttributeName = JsxAttribute['name']
|
||||
export type JsxChild = JsxElement['children'][number]
|
||||
/**
|
||||
* Namespace.
|
||||
*/
|
||||
export type Space = 'html' | 'svg'
|
||||
/**
|
||||
* Turn a hast node into an estree node.
|
||||
*/
|
||||
export type Handle = (
|
||||
node: any,
|
||||
state: State
|
||||
) => JsxChild | null | undefined | void
|
||||
/**
|
||||
* Specify casing to use for attribute names.
|
||||
*
|
||||
* HTML casing is for example `class`, `stroke-linecap`, `xml:lang`.
|
||||
* React casing is for example `className`, `strokeLinecap`, `xmlLang`.
|
||||
*/
|
||||
export type ElementAttributeNameCase = 'html' | 'react'
|
||||
/**
|
||||
* Casing to use for property names in `style` objects.
|
||||
*
|
||||
* CSS casing is for example `background-color` and `-webkit-line-clamp`.
|
||||
* DOM casing is for example `backgroundColor` and `WebkitLineClamp`.
|
||||
*/
|
||||
export type StylePropertyNameCase = 'css' | 'dom'
|
||||
/**
|
||||
* Configuration.
|
||||
*/
|
||||
export type Options = {
|
||||
/**
|
||||
* Specify casing to use for attribute names.
|
||||
*
|
||||
* This casing is used for hast elements, not for embedded MDX JSX nodes
|
||||
* (components that someone authored manually).
|
||||
*/
|
||||
elementAttributeNameCase?: ElementAttributeNameCase | null | undefined
|
||||
/**
|
||||
* Custom handlers.
|
||||
*/
|
||||
handlers?: Record<string, Handle | null | undefined> | null | undefined
|
||||
/**
|
||||
* Which space the document is in.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
space?: Space | null | undefined
|
||||
/**
|
||||
* Specify casing to use for property names in `style` objects.
|
||||
*
|
||||
* This casing is used for hast elements, not for embedded MDX JSX nodes
|
||||
* (components that someone authored manually).
|
||||
*/
|
||||
stylePropertyNameCase?: StylePropertyNameCase | null | undefined
|
||||
}
|
||||
/**
|
||||
* Info passed around about the current state.
|
||||
*/
|
||||
export type State = {
|
||||
/**
|
||||
* Current schema.
|
||||
*/
|
||||
schema: Schema
|
||||
/**
|
||||
* Casing to use for attribute names.
|
||||
*/
|
||||
elementAttributeNameCase: ElementAttributeNameCase
|
||||
/**
|
||||
* Casing to use for property names in `style` objects.
|
||||
*/
|
||||
stylePropertyNameCase: StylePropertyNameCase
|
||||
/**
|
||||
* List of estree comments.
|
||||
*/
|
||||
comments: Array<Comment>
|
||||
/**
|
||||
* List of top-level estree nodes.
|
||||
*/
|
||||
esm: Array<Directive | Statement | ModuleDeclaration>
|
||||
/**
|
||||
* Transform a hast node to estree.
|
||||
*/
|
||||
handle: (node: any) => JsxChild | null | undefined | void
|
||||
/**
|
||||
* Transform children of a hast parent to estree.
|
||||
*/
|
||||
all: (parent: Parent) => Array<JsxChild>
|
||||
/**
|
||||
* Take positional info from `from` (use `inherit` if you also want data).
|
||||
*/
|
||||
patch: (from: Node, to: EstreeNode | Comment) => void
|
||||
/**
|
||||
* Take positional info and data from `from` (use `patch` if you don’t want data).
|
||||
*/
|
||||
inherit: (from: Node, to: EstreeNode | Comment) => void
|
||||
/**
|
||||
* Create a JSX attribute name.
|
||||
*/
|
||||
createJsxAttributeName: (name: string) => JsxAttributeName
|
||||
/**
|
||||
* Create a JSX element name.
|
||||
*/
|
||||
createJsxElementName: (name: string) => JsxElementName
|
||||
}
|
||||
370
node_modules/hast-util-to-estree/lib/state.js
generated
vendored
Normal file
370
node_modules/hast-util-to-estree/lib/state.js
generated
vendored
Normal file
|
|
@ -0,0 +1,370 @@
|
|||
/**
|
||||
* @typedef {import('estree').Comment} Comment
|
||||
* @typedef {import('estree').Directive} Directive
|
||||
* @typedef {import('estree').ModuleDeclaration} ModuleDeclaration
|
||||
* @typedef {import('estree').Node} EstreeNode
|
||||
* @typedef {import('estree').Statement} Statement
|
||||
*
|
||||
* @typedef {import('estree-jsx').JSXAttribute} JsxAttribute
|
||||
* @typedef {import('estree-jsx').JSXElement} JsxElement
|
||||
* @typedef {import('estree-jsx').JSXIdentifier} JsxIdentifier
|
||||
* @typedef {import('estree-jsx').JSXMemberExpression} JsxMemberExpression
|
||||
* @typedef {import('estree-jsx').JSXNamespacedName} JsxNamespacedName
|
||||
*
|
||||
* @typedef {import('hast').Content} Content
|
||||
* @typedef {import('hast').Root} Root
|
||||
*
|
||||
* @typedef {import('mdast-util-mdx-expression').MdxFlowExpression} MdxFlowExpression
|
||||
* @typedef {import('mdast-util-mdx-expression').MdxTextExpression} MdxTextExpression
|
||||
*
|
||||
* @typedef {import('mdast-util-mdx-jsx').MdxJsxAttribute} MdxJsxAttribute
|
||||
* @typedef {import('mdast-util-mdx-jsx').MdxJsxAttributeValueExpression} MdxJsxAttributeValueExpression
|
||||
* @typedef {import('mdast-util-mdx-jsx').MdxJsxExpressionAttribute} MdxJsxExpressionAttribute
|
||||
* @typedef {import('mdast-util-mdx-jsx').MdxJsxFlowElement} MdxJsxFlowElement
|
||||
* @typedef {import('mdast-util-mdx-jsx').MdxJsxTextElement} MdxJsxTextElement
|
||||
*
|
||||
* @typedef {import('property-information').Schema} Schema
|
||||
*
|
||||
* @typedef {import('unist').Parent} UnistParent
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Content | MdxJsxAttributeValueExpression | MdxJsxAttribute | MdxJsxExpressionAttribute | MdxJsxFlowElement | MdxJsxTextElement | MdxFlowExpression | MdxTextExpression | Root} Node
|
||||
* @typedef {Extract<Node, UnistParent>} Parent
|
||||
* @typedef {JsxElement['openingElement']['name']} JsxElementName
|
||||
* @typedef {JsxAttribute['name']} JsxAttributeName
|
||||
* @typedef {JsxElement['children'][number]} JsxChild
|
||||
*
|
||||
* @typedef {'html' | 'svg'} Space
|
||||
* Namespace.
|
||||
*
|
||||
* @callback Handle
|
||||
* Turn a hast node into an estree node.
|
||||
* @param {any} node
|
||||
* Expected hast node.
|
||||
* @param {State} state
|
||||
* Info passed around about the current state.
|
||||
* @returns {JsxChild | null | undefined | void}
|
||||
* estree node.
|
||||
*
|
||||
* @typedef {'html' | 'react'} ElementAttributeNameCase
|
||||
* Specify casing to use for attribute names.
|
||||
*
|
||||
* HTML casing is for example `class`, `stroke-linecap`, `xml:lang`.
|
||||
* React casing is for example `className`, `strokeLinecap`, `xmlLang`.
|
||||
*
|
||||
* @typedef {'css' | 'dom'} StylePropertyNameCase
|
||||
* Casing to use for property names in `style` objects.
|
||||
*
|
||||
* CSS casing is for example `background-color` and `-webkit-line-clamp`.
|
||||
* DOM casing is for example `backgroundColor` and `WebkitLineClamp`.
|
||||
*
|
||||
* @typedef Options
|
||||
* Configuration.
|
||||
* @property {ElementAttributeNameCase | null | undefined} [elementAttributeNameCase='react']
|
||||
* Specify casing to use for attribute names.
|
||||
*
|
||||
* This casing is used for hast elements, not for embedded MDX JSX nodes
|
||||
* (components that someone authored manually).
|
||||
* @property {Record<string, Handle | null | undefined> | null | undefined} [handlers={}]
|
||||
* Custom handlers.
|
||||
* @property {Space | null | undefined} [space='html']
|
||||
* Which space the document is in.
|
||||
*
|
||||
* 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.
|
||||
* @property {StylePropertyNameCase | null | undefined} [stylePropertyNameCase='dom']
|
||||
* Specify casing to use for property names in `style` objects.
|
||||
*
|
||||
* This casing is used for hast elements, not for embedded MDX JSX nodes
|
||||
* (components that someone authored manually).
|
||||
*
|
||||
* @typedef State
|
||||
* Info passed around about the current state.
|
||||
* @property {Schema} schema
|
||||
* Current schema.
|
||||
* @property {ElementAttributeNameCase} elementAttributeNameCase
|
||||
* Casing to use for attribute names.
|
||||
* @property {StylePropertyNameCase} stylePropertyNameCase
|
||||
* Casing to use for property names in `style` objects.
|
||||
* @property {Array<Comment>} comments
|
||||
* List of estree comments.
|
||||
* @property {Array<Directive | Statement | ModuleDeclaration>} esm
|
||||
* List of top-level estree nodes.
|
||||
* @property {(node: any) => JsxChild | null | undefined | void} handle
|
||||
* Transform a hast node to estree.
|
||||
* @property {(parent: Parent) => Array<JsxChild>} all
|
||||
* Transform children of a hast parent to estree.
|
||||
* @property {(from: Node, to: EstreeNode | Comment) => void} patch
|
||||
* Take positional info from `from` (use `inherit` if you also want data).
|
||||
* @property {(from: Node, to: EstreeNode | Comment) => void} inherit
|
||||
* Take positional info and data from `from` (use `patch` if you don’t want data).
|
||||
* @property {(name: string) => JsxAttributeName} createJsxAttributeName
|
||||
* Create a JSX attribute name.
|
||||
* @property {(name: string) => JsxElementName} createJsxElementName
|
||||
* Create a JSX element name.
|
||||
*/
|
||||
|
||||
import {html, svg} from 'property-information'
|
||||
import {position} from 'unist-util-position'
|
||||
import {zwitch} from 'zwitch'
|
||||
import {handlers} from './handlers/index.js'
|
||||
|
||||
const own = {}.hasOwnProperty
|
||||
|
||||
// `react-dom` triggers a warning for *any* white space in tables.
|
||||
// To follow GFM, `mdast-util-to-hast` injects line endings between elements.
|
||||
// Other tools might do so too, but they don’t do here, so we remove all of
|
||||
// that.
|
||||
//
|
||||
// See: <https://github.com/facebook/react/pull/7081>.
|
||||
// See: <https://github.com/facebook/react/pull/7515>.
|
||||
// See: <https://github.com/remarkjs/remark-react/issues/64>.
|
||||
// See: <https://github.com/rehypejs/rehype-react/pull/29>.
|
||||
// See: <https://github.com/rehypejs/rehype-react/pull/32>.
|
||||
// See: <https://github.com/rehypejs/rehype-react/pull/45>.
|
||||
// See: <https://github.com/mdx-js/mdx/issues/2000>
|
||||
const tableElements = new Set(['table', 'thead', 'tbody', 'tfoot', 'tr'])
|
||||
|
||||
/**
|
||||
* Create a state from options.
|
||||
*
|
||||
* @param {Options} options
|
||||
* Configuration.
|
||||
* @returns {State}
|
||||
* Info passed around about the current state.
|
||||
*/
|
||||
|
||||
export function createState(options) {
|
||||
/** @type {Handle} */
|
||||
const one = zwitch('type', {
|
||||
invalid,
|
||||
unknown,
|
||||
handlers: {...handlers, ...options.handlers}
|
||||
})
|
||||
|
||||
return {
|
||||
// Current space.
|
||||
schema: options.space === 'svg' ? svg : html,
|
||||
elementAttributeNameCase: options.elementAttributeNameCase || 'react',
|
||||
stylePropertyNameCase: options.stylePropertyNameCase || 'dom',
|
||||
// Results.
|
||||
comments: [],
|
||||
esm: [],
|
||||
// Useful functions.
|
||||
handle,
|
||||
all,
|
||||
patch,
|
||||
inherit,
|
||||
createJsxAttributeName,
|
||||
createJsxElementName
|
||||
}
|
||||
|
||||
/**
|
||||
* @this {State}
|
||||
* @param {any} node
|
||||
* @returns {JsxChild | null | undefined | void}
|
||||
*/
|
||||
function handle(node) {
|
||||
return one(node, this)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Crash on an invalid value.
|
||||
*
|
||||
* @param {unknown} value
|
||||
* Non-node.
|
||||
* @returns {never}
|
||||
* Nothing (crashes).
|
||||
*/
|
||||
function invalid(value) {
|
||||
throw new Error('Cannot handle value `' + value + '`, expected node')
|
||||
}
|
||||
|
||||
/**
|
||||
* Crash on an unknown node.
|
||||
*
|
||||
* @param {unknown} node
|
||||
* Unknown node.
|
||||
* @returns {never}
|
||||
* Nothing (crashes).
|
||||
*/
|
||||
function unknown(node) {
|
||||
// @ts-expect-error: JS guarantees there’s a `type`.
|
||||
throw new Error('Cannot handle unknown node `' + node.type + '`')
|
||||
}
|
||||
|
||||
/**
|
||||
* @this {State} state
|
||||
* Info passed around about the current state.
|
||||
* @param {Parent | MdxJsxFlowElement | MdxJsxTextElement} parent
|
||||
* hast node whose children to transform.
|
||||
* @returns {Array<JsxChild>}
|
||||
* estree nodes.
|
||||
*/
|
||||
function all(parent) {
|
||||
const children = parent.children || []
|
||||
let index = -1
|
||||
/** @type {Array<JsxChild>} */
|
||||
const results = []
|
||||
const ignoreLineBreak =
|
||||
this.schema.space === 'html' &&
|
||||
parent.type === 'element' &&
|
||||
tableElements.has(parent.tagName.toLowerCase())
|
||||
|
||||
while (++index < children.length) {
|
||||
const child = children[index]
|
||||
|
||||
if (ignoreLineBreak && child.type === 'text' && child.value === '\n') {
|
||||
continue
|
||||
}
|
||||
|
||||
const result = this.handle(child)
|
||||
|
||||
if (Array.isArray(result)) {
|
||||
results.push(...result)
|
||||
} else if (result) {
|
||||
results.push(result)
|
||||
}
|
||||
}
|
||||
|
||||
return results
|
||||
}
|
||||
|
||||
/**
|
||||
* Take positional info and data from `hast`.
|
||||
*
|
||||
* Use `patch` if you don’t want data.
|
||||
*
|
||||
* @param {Node | MdxJsxAttributeValueExpression | MdxJsxAttribute | MdxJsxExpressionAttribute | MdxJsxFlowElement | MdxJsxTextElement | MdxFlowExpression | MdxTextExpression} from
|
||||
* hast node to take positional info and data from.
|
||||
* @param {EstreeNode | Comment} to
|
||||
* estree node to add positional info and data to.
|
||||
* @returns {void}
|
||||
* Nothing.
|
||||
*/
|
||||
function inherit(from, to) {
|
||||
/** @type {Record<string, unknown> | undefined} */
|
||||
const left = from.data
|
||||
/** @type {Record<string, unknown> | undefined} */
|
||||
let right
|
||||
/** @type {string} */
|
||||
let key
|
||||
|
||||
patch(from, to)
|
||||
|
||||
if (left) {
|
||||
for (key in left) {
|
||||
if (own.call(left, key) && key !== 'estree') {
|
||||
if (!right) right = {}
|
||||
right[key] = left[key]
|
||||
}
|
||||
}
|
||||
|
||||
if (right) {
|
||||
// @ts-expect-error `esast` extension.
|
||||
to.data = right
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Take positional info from `from`.
|
||||
*
|
||||
* Use `inherit` if you also want data.
|
||||
*
|
||||
* @param {Node | MdxJsxAttributeValueExpression | MdxJsxAttribute | MdxJsxExpressionAttribute | MdxJsxFlowElement | MdxJsxTextElement | MdxFlowExpression | MdxTextExpression} from
|
||||
* hast node to take positional info from.
|
||||
* @param {EstreeNode | Comment} to
|
||||
* estree node to add positional info to.
|
||||
* @returns {void}
|
||||
* Nothing.
|
||||
*/
|
||||
function patch(from, to) {
|
||||
const p = position(from)
|
||||
|
||||
if (
|
||||
p.start.line &&
|
||||
p.start.offset !== undefined &&
|
||||
p.end.offset !== undefined
|
||||
) {
|
||||
// @ts-expect-error acorn-style.
|
||||
to.start = p.start.offset
|
||||
// @ts-expect-error acorn-style.
|
||||
to.end = p.end.offset
|
||||
to.loc = {
|
||||
start: {line: p.start.line, column: p.start.column - 1},
|
||||
end: {line: p.end.line, column: p.end.column - 1}
|
||||
}
|
||||
to.range = [p.start.offset, p.end.offset]
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a JSX attribute name.
|
||||
*
|
||||
* @param {string} name
|
||||
* @returns {JsxAttributeName}
|
||||
*/
|
||||
function createJsxAttributeName(name) {
|
||||
const node = createJsxNameFromString(name)
|
||||
|
||||
// MDX never generates this.
|
||||
/* c8 ignore next 3 */
|
||||
if (node.type === 'JSXMemberExpression') {
|
||||
throw new Error('Member expressions in attribute names are not supported')
|
||||
}
|
||||
|
||||
return node
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a JSX element name.
|
||||
*
|
||||
* @param {string} name
|
||||
* @returns {JsxElementName}
|
||||
*/
|
||||
function createJsxElementName(name) {
|
||||
return createJsxNameFromString(name)
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a JSX name from a string.
|
||||
*
|
||||
* @param {string} name
|
||||
* Name.
|
||||
* @returns {JsxMemberExpression | JsxNamespacedName | JsxIdentifier}
|
||||
* Node.
|
||||
*/
|
||||
function createJsxNameFromString(name) {
|
||||
if (name.includes('.')) {
|
||||
const names = name.split('.')
|
||||
let part = names.shift()
|
||||
/** @type {JsxMemberExpression} */
|
||||
// @ts-expect-error: hush, the first is always defined.
|
||||
let node = {type: 'JSXIdentifier', name: part}
|
||||
|
||||
while ((part = names.shift())) {
|
||||
node = {
|
||||
type: 'JSXMemberExpression',
|
||||
object: node,
|
||||
property: {type: 'JSXIdentifier', name: part}
|
||||
}
|
||||
}
|
||||
|
||||
return node
|
||||
}
|
||||
|
||||
if (name.includes(':')) {
|
||||
const parts = name.split(':')
|
||||
return {
|
||||
type: 'JSXNamespacedName',
|
||||
namespace: {type: 'JSXIdentifier', name: parts[0]},
|
||||
name: {type: 'JSXIdentifier', name: parts[1]}
|
||||
}
|
||||
}
|
||||
|
||||
return {type: 'JSXIdentifier', name}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue