Initial commit
This commit is contained in:
commit
78f8d225ee
21173 changed files with 2907774 additions and 0 deletions
166
node_modules/react-markdown/lib/index.d.ts
generated
vendored
Normal file
166
node_modules/react-markdown/lib/index.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,166 @@
|
|||
/**
|
||||
* Component to render markdown.
|
||||
*
|
||||
* This is a synchronous component.
|
||||
* When using async plugins,
|
||||
* see {@linkcode MarkdownAsync} or {@linkcode MarkdownHooks}.
|
||||
*
|
||||
* @param {Readonly<Options>} options
|
||||
* Props.
|
||||
* @returns {ReactElement}
|
||||
* React element.
|
||||
*/
|
||||
export function Markdown(options: Readonly<Options>): ReactElement;
|
||||
/**
|
||||
* Component to render markdown with support for async plugins
|
||||
* through async/await.
|
||||
*
|
||||
* Components returning promises are supported on the server.
|
||||
* For async support on the client,
|
||||
* see {@linkcode MarkdownHooks}.
|
||||
*
|
||||
* @param {Readonly<Options>} options
|
||||
* Props.
|
||||
* @returns {Promise<ReactElement>}
|
||||
* Promise to a React element.
|
||||
*/
|
||||
export function MarkdownAsync(options: Readonly<Options>): Promise<ReactElement>;
|
||||
/**
|
||||
* Component to render markdown with support for async plugins through hooks.
|
||||
*
|
||||
* This uses `useEffect` and `useState` hooks.
|
||||
* Hooks run on the client and do not immediately render something.
|
||||
* For async support on the server,
|
||||
* see {@linkcode MarkdownAsync}.
|
||||
*
|
||||
* @param {Readonly<HooksOptions>} options
|
||||
* Props.
|
||||
* @returns {ReactNode}
|
||||
* React node.
|
||||
*/
|
||||
export function MarkdownHooks(options: Readonly<HooksOptions>): ReactNode;
|
||||
/**
|
||||
* Make a URL safe.
|
||||
*
|
||||
* @satisfies {UrlTransform}
|
||||
* @param {string} value
|
||||
* URL.
|
||||
* @returns {string}
|
||||
* Safe URL.
|
||||
*/
|
||||
export function defaultUrlTransform(value: string): string;
|
||||
/**
|
||||
* Filter elements.
|
||||
*/
|
||||
export type AllowElement = (element: Readonly<Element>, index: number, parent: Readonly<Parents> | undefined) => boolean | null | undefined;
|
||||
/**
|
||||
* Extra fields we pass.
|
||||
*/
|
||||
export type ExtraProps = {
|
||||
/**
|
||||
* passed when `passNode` is on.
|
||||
*/
|
||||
node?: Element | undefined;
|
||||
};
|
||||
/**
|
||||
* Map tag names to components.
|
||||
*/
|
||||
export type Components = { [Key in keyof JSX.IntrinsicElements]?: ComponentType<JSX.IntrinsicElements[Key] & ExtraProps> | keyof JSX.IntrinsicElements; };
|
||||
/**
|
||||
* Deprecation.
|
||||
*/
|
||||
export type Deprecation = {
|
||||
/**
|
||||
* Old field.
|
||||
*/
|
||||
from: string;
|
||||
/**
|
||||
* ID in readme.
|
||||
*/
|
||||
id: string;
|
||||
/**
|
||||
* New field.
|
||||
*/
|
||||
to?: keyof Options;
|
||||
};
|
||||
/**
|
||||
* Configuration.
|
||||
*/
|
||||
export type Options = {
|
||||
/**
|
||||
* Filter elements (optional);
|
||||
* `allowedElements` / `disallowedElements` is used first.
|
||||
*/
|
||||
allowElement?: AllowElement | null | undefined;
|
||||
/**
|
||||
* Tag names to allow (default: all tag names);
|
||||
* cannot combine w/ `disallowedElements`.
|
||||
*/
|
||||
allowedElements?: ReadonlyArray<string> | null | undefined;
|
||||
/**
|
||||
* Markdown.
|
||||
*/
|
||||
children?: string | null | undefined;
|
||||
/**
|
||||
* Map tag names to components.
|
||||
*/
|
||||
components?: Components | null | undefined;
|
||||
/**
|
||||
* Tag names to disallow (default: `[]`);
|
||||
* cannot combine w/ `allowedElements`.
|
||||
*/
|
||||
disallowedElements?: ReadonlyArray<string> | null | undefined;
|
||||
/**
|
||||
* List of rehype plugins to use.
|
||||
*/
|
||||
rehypePlugins?: PluggableList | null | undefined;
|
||||
/**
|
||||
* List of remark plugins to use.
|
||||
*/
|
||||
remarkPlugins?: PluggableList | null | undefined;
|
||||
/**
|
||||
* Options to pass through to `remark-rehype`.
|
||||
*/
|
||||
remarkRehypeOptions?: Readonly<RemarkRehypeOptions> | null | undefined;
|
||||
/**
|
||||
* Ignore HTML in markdown completely (default: `false`).
|
||||
*/
|
||||
skipHtml?: boolean | null | undefined;
|
||||
/**
|
||||
* Extract (unwrap) what’s in disallowed elements (default: `false`);
|
||||
* normally when say `strong` is not allowed, it and it’s children are dropped,
|
||||
* with `unwrapDisallowed` the element itself is replaced by its children.
|
||||
*/
|
||||
unwrapDisallowed?: boolean | null | undefined;
|
||||
/**
|
||||
* Change URLs (default: `defaultUrlTransform`)
|
||||
*/
|
||||
urlTransform?: UrlTransform | null | undefined;
|
||||
};
|
||||
/**
|
||||
* Configuration specifically for {@linkcode MarkdownHooks}.
|
||||
*/
|
||||
export type HooksOptionsOnly = {
|
||||
/**
|
||||
* Content to render while the processor processing the markdown (optional).
|
||||
*/
|
||||
fallback?: ReactNode | null | undefined;
|
||||
};
|
||||
/**
|
||||
* Configuration for {@linkcode MarkdownHooks};
|
||||
* extends the regular {@linkcode Options} with a `fallback` prop.
|
||||
*/
|
||||
export type HooksOptions = Options & HooksOptionsOnly;
|
||||
/**
|
||||
* Transform all URLs.
|
||||
*/
|
||||
export type UrlTransform = (url: string, key: string, node: Readonly<Element>) => string | null | undefined;
|
||||
import type { ReactElement } from 'react';
|
||||
import type { ReactNode } from 'react';
|
||||
import type { Element } from 'hast';
|
||||
import type { Parents } from 'hast';
|
||||
import type { JSX } from 'react';
|
||||
import type { ComponentType } from 'react';
|
||||
import type { PluggableList } from 'unified';
|
||||
import type { Options as RemarkRehypeOptions } from 'remark-rehype';
|
||||
//# sourceMappingURL=index.d.ts.map
|
||||
1
node_modules/react-markdown/lib/index.d.ts.map
generated
vendored
Normal file
1
node_modules/react-markdown/lib/index.d.ts.map
generated
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.js"],"names":[],"mappings":"AAkKA;;;;;;;;;;;GAWG;AACH,kCALW,QAAQ,CAAC,OAAO,CAAC,GAEf,YAAY,CAOxB;AAED;;;;;;;;;;;;GAYG;AACH,uCALW,QAAQ,CAAC,OAAO,CAAC,GAEf,OAAO,CAAC,YAAY,CAAC,CAQjC;AAED;;;;;;;;;;;;GAYG;AACH,uCALW,QAAQ,CAAC,YAAY,CAAC,GAEpB,SAAS,CAyCrB;AAgKD;;;;;;;;GAQG;AACH,2CALW,MAAM,GAEJ,MAAM,CA0BlB;;;;qCA/aU,QAAQ,CAAC,OAAO,CAAC,SAEjB,MAAM,UAEN,QAAQ,CAAC,OAAO,CAAC,GAAG,SAAS,KAE3B,OAAO,GAAG,IAAI,GAAG,SAAS;;;;;;;;WAOzB,OAAO,GAAG,SAAS;;;;;yBAKpB,GACP,GAAG,IAAI,MAAM,qBAAqB,CAAC,CAAC,EAAE,cAAc,qBAAqB,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC,GAAG,MAAM,qBAAqB,GAC5H;;;;;;;;UAOU,MAAM;;;;QAEN,MAAM;;;;SAEN,MAAM,OAAO;;;;;;;;;;mBAOb,YAAY,GAAG,IAAI,GAAG,SAAS;;;;;sBAG/B,aAAa,CAAC,MAAM,CAAC,GAAG,IAAI,GAAG,SAAS;;;;eAGxC,MAAM,GAAG,IAAI,GAAG,SAAS;;;;iBAEzB,UAAU,GAAG,IAAI,GAAG,SAAS;;;;;yBAE7B,aAAa,CAAC,MAAM,CAAC,GAAG,IAAI,GAAG,SAAS;;;;oBAGxC,aAAa,GAAG,IAAI,GAAG,SAAS;;;;oBAEhC,aAAa,GAAG,IAAI,GAAG,SAAS;;;;0BAEhC,QAAQ,CAAC,mBAAmB,CAAC,GAAG,IAAI,GAAG,SAAS;;;;eAEhD,OAAO,GAAG,IAAI,GAAG,SAAS;;;;;;uBAE1B,OAAO,GAAG,IAAI,GAAG,SAAS;;;;mBAI1B,YAAY,GAAG,IAAI,GAAG,SAAS;;;;;;;;;eAO/B,SAAS,GAAG,IAAI,GAAG,SAAS;;;;;;2BAK7B,OAAO,GAAG,gBAAgB;;;;iCAQ5B,MAAM,OAEN,MAAM,QAEN,QAAQ,CAAC,OAAO,CAAC,KAEf,MAAM,GAAG,IAAI,GAAG,SAAS;kCAlGwB,OAAO;+BAAP,OAAO;6BAFrB,MAAM;6BAAN,MAAM;yBAEQ,OAAO;mCAAP,OAAO;mCAG1B,SAAS;oDAFH,eAAe"}
|
||||
444
node_modules/react-markdown/lib/index.js
generated
vendored
Normal file
444
node_modules/react-markdown/lib/index.js
generated
vendored
Normal file
|
|
@ -0,0 +1,444 @@
|
|||
/**
|
||||
* @import {Element, Nodes, Parents, Root} from 'hast'
|
||||
* @import {Root as MdastRoot} from 'mdast'
|
||||
* @import {ComponentType, JSX, ReactElement, ReactNode} from 'react'
|
||||
* @import {Options as RemarkRehypeOptions} from 'remark-rehype'
|
||||
* @import {BuildVisitor} from 'unist-util-visit'
|
||||
* @import {PluggableList, Processor} from 'unified'
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback AllowElement
|
||||
* Filter elements.
|
||||
* @param {Readonly<Element>} element
|
||||
* Element to check.
|
||||
* @param {number} index
|
||||
* Index of `element` in `parent`.
|
||||
* @param {Readonly<Parents> | undefined} parent
|
||||
* Parent of `element`.
|
||||
* @returns {boolean | null | undefined}
|
||||
* Whether to allow `element` (default: `false`).
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef ExtraProps
|
||||
* Extra fields we pass.
|
||||
* @property {Element | undefined} [node]
|
||||
* passed when `passNode` is on.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {{
|
||||
* [Key in keyof JSX.IntrinsicElements]?: ComponentType<JSX.IntrinsicElements[Key] & ExtraProps> | keyof JSX.IntrinsicElements
|
||||
* }} Components
|
||||
* Map tag names to components.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef Deprecation
|
||||
* Deprecation.
|
||||
* @property {string} from
|
||||
* Old field.
|
||||
* @property {string} id
|
||||
* ID in readme.
|
||||
* @property {keyof Options} [to]
|
||||
* New field.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef Options
|
||||
* Configuration.
|
||||
* @property {AllowElement | null | undefined} [allowElement]
|
||||
* Filter elements (optional);
|
||||
* `allowedElements` / `disallowedElements` is used first.
|
||||
* @property {ReadonlyArray<string> | null | undefined} [allowedElements]
|
||||
* Tag names to allow (default: all tag names);
|
||||
* cannot combine w/ `disallowedElements`.
|
||||
* @property {string | null | undefined} [children]
|
||||
* Markdown.
|
||||
* @property {Components | null | undefined} [components]
|
||||
* Map tag names to components.
|
||||
* @property {ReadonlyArray<string> | null | undefined} [disallowedElements]
|
||||
* Tag names to disallow (default: `[]`);
|
||||
* cannot combine w/ `allowedElements`.
|
||||
* @property {PluggableList | null | undefined} [rehypePlugins]
|
||||
* List of rehype plugins to use.
|
||||
* @property {PluggableList | null | undefined} [remarkPlugins]
|
||||
* List of remark plugins to use.
|
||||
* @property {Readonly<RemarkRehypeOptions> | null | undefined} [remarkRehypeOptions]
|
||||
* Options to pass through to `remark-rehype`.
|
||||
* @property {boolean | null | undefined} [skipHtml=false]
|
||||
* Ignore HTML in markdown completely (default: `false`).
|
||||
* @property {boolean | null | undefined} [unwrapDisallowed=false]
|
||||
* Extract (unwrap) what’s in disallowed elements (default: `false`);
|
||||
* normally when say `strong` is not allowed, it and it’s children are dropped,
|
||||
* with `unwrapDisallowed` the element itself is replaced by its children.
|
||||
* @property {UrlTransform | null | undefined} [urlTransform]
|
||||
* Change URLs (default: `defaultUrlTransform`)
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef HooksOptionsOnly
|
||||
* Configuration specifically for {@linkcode MarkdownHooks}.
|
||||
* @property {ReactNode | null | undefined} [fallback]
|
||||
* Content to render while the processor processing the markdown (optional).
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Options & HooksOptionsOnly} HooksOptions
|
||||
* Configuration for {@linkcode MarkdownHooks};
|
||||
* extends the regular {@linkcode Options} with a `fallback` prop.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback UrlTransform
|
||||
* Transform all URLs.
|
||||
* @param {string} url
|
||||
* URL.
|
||||
* @param {string} key
|
||||
* Property name (example: `'href'`).
|
||||
* @param {Readonly<Element>} node
|
||||
* Node.
|
||||
* @returns {string | null | undefined}
|
||||
* Transformed URL (optional).
|
||||
*/
|
||||
|
||||
import {unreachable} from 'devlop'
|
||||
import {toJsxRuntime} from 'hast-util-to-jsx-runtime'
|
||||
import {urlAttributes} from 'html-url-attributes'
|
||||
import {Fragment, jsx, jsxs} from 'react/jsx-runtime'
|
||||
import {useEffect, useState} from 'react'
|
||||
import remarkParse from 'remark-parse'
|
||||
import remarkRehype from 'remark-rehype'
|
||||
import {unified} from 'unified'
|
||||
import {visit} from 'unist-util-visit'
|
||||
import {VFile} from 'vfile'
|
||||
|
||||
const changelog =
|
||||
'https://github.com/remarkjs/react-markdown/blob/main/changelog.md'
|
||||
|
||||
/** @type {PluggableList} */
|
||||
const emptyPlugins = []
|
||||
/** @type {Readonly<RemarkRehypeOptions>} */
|
||||
const emptyRemarkRehypeOptions = {allowDangerousHtml: true}
|
||||
const safeProtocol = /^(https?|ircs?|mailto|xmpp)$/i
|
||||
|
||||
// Mutable because we `delete` any time it’s used and a message is sent.
|
||||
/** @type {ReadonlyArray<Readonly<Deprecation>>} */
|
||||
const deprecations = [
|
||||
{from: 'astPlugins', id: 'remove-buggy-html-in-markdown-parser'},
|
||||
{from: 'allowDangerousHtml', id: 'remove-buggy-html-in-markdown-parser'},
|
||||
{
|
||||
from: 'allowNode',
|
||||
id: 'replace-allownode-allowedtypes-and-disallowedtypes',
|
||||
to: 'allowElement'
|
||||
},
|
||||
{
|
||||
from: 'allowedTypes',
|
||||
id: 'replace-allownode-allowedtypes-and-disallowedtypes',
|
||||
to: 'allowedElements'
|
||||
},
|
||||
{from: 'className', id: 'remove-classname'},
|
||||
{
|
||||
from: 'disallowedTypes',
|
||||
id: 'replace-allownode-allowedtypes-and-disallowedtypes',
|
||||
to: 'disallowedElements'
|
||||
},
|
||||
{from: 'escapeHtml', id: 'remove-buggy-html-in-markdown-parser'},
|
||||
{from: 'includeElementIndex', id: '#remove-includeelementindex'},
|
||||
{
|
||||
from: 'includeNodeIndex',
|
||||
id: 'change-includenodeindex-to-includeelementindex'
|
||||
},
|
||||
{from: 'linkTarget', id: 'remove-linktarget'},
|
||||
{from: 'plugins', id: 'change-plugins-to-remarkplugins', to: 'remarkPlugins'},
|
||||
{from: 'rawSourcePos', id: '#remove-rawsourcepos'},
|
||||
{from: 'renderers', id: 'change-renderers-to-components', to: 'components'},
|
||||
{from: 'source', id: 'change-source-to-children', to: 'children'},
|
||||
{from: 'sourcePos', id: '#remove-sourcepos'},
|
||||
{from: 'transformImageUri', id: '#add-urltransform', to: 'urlTransform'},
|
||||
{from: 'transformLinkUri', id: '#add-urltransform', to: 'urlTransform'}
|
||||
]
|
||||
|
||||
/**
|
||||
* Component to render markdown.
|
||||
*
|
||||
* This is a synchronous component.
|
||||
* When using async plugins,
|
||||
* see {@linkcode MarkdownAsync} or {@linkcode MarkdownHooks}.
|
||||
*
|
||||
* @param {Readonly<Options>} options
|
||||
* Props.
|
||||
* @returns {ReactElement}
|
||||
* React element.
|
||||
*/
|
||||
export function Markdown(options) {
|
||||
const processor = createProcessor(options)
|
||||
const file = createFile(options)
|
||||
return post(processor.runSync(processor.parse(file), file), options)
|
||||
}
|
||||
|
||||
/**
|
||||
* Component to render markdown with support for async plugins
|
||||
* through async/await.
|
||||
*
|
||||
* Components returning promises are supported on the server.
|
||||
* For async support on the client,
|
||||
* see {@linkcode MarkdownHooks}.
|
||||
*
|
||||
* @param {Readonly<Options>} options
|
||||
* Props.
|
||||
* @returns {Promise<ReactElement>}
|
||||
* Promise to a React element.
|
||||
*/
|
||||
export async function MarkdownAsync(options) {
|
||||
const processor = createProcessor(options)
|
||||
const file = createFile(options)
|
||||
const tree = await processor.run(processor.parse(file), file)
|
||||
return post(tree, options)
|
||||
}
|
||||
|
||||
/**
|
||||
* Component to render markdown with support for async plugins through hooks.
|
||||
*
|
||||
* This uses `useEffect` and `useState` hooks.
|
||||
* Hooks run on the client and do not immediately render something.
|
||||
* For async support on the server,
|
||||
* see {@linkcode MarkdownAsync}.
|
||||
*
|
||||
* @param {Readonly<HooksOptions>} options
|
||||
* Props.
|
||||
* @returns {ReactNode}
|
||||
* React node.
|
||||
*/
|
||||
export function MarkdownHooks(options) {
|
||||
const processor = createProcessor(options)
|
||||
const [error, setError] = useState(
|
||||
/** @type {Error | undefined} */ (undefined)
|
||||
)
|
||||
const [tree, setTree] = useState(/** @type {Root | undefined} */ (undefined))
|
||||
|
||||
useEffect(
|
||||
function () {
|
||||
let cancelled = false
|
||||
const file = createFile(options)
|
||||
|
||||
processor.run(processor.parse(file), file, function (error, tree) {
|
||||
if (!cancelled) {
|
||||
setError(error)
|
||||
setTree(tree)
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* @returns {undefined}
|
||||
* Nothing.
|
||||
*/
|
||||
return function () {
|
||||
cancelled = true
|
||||
}
|
||||
},
|
||||
[
|
||||
options.children,
|
||||
options.rehypePlugins,
|
||||
options.remarkPlugins,
|
||||
options.remarkRehypeOptions
|
||||
]
|
||||
)
|
||||
|
||||
if (error) throw error
|
||||
|
||||
return tree ? post(tree, options) : options.fallback
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up the `unified` processor.
|
||||
*
|
||||
* @param {Readonly<Options>} options
|
||||
* Props.
|
||||
* @returns {Processor<MdastRoot, MdastRoot, Root, undefined, undefined>}
|
||||
* Result.
|
||||
*/
|
||||
function createProcessor(options) {
|
||||
const rehypePlugins = options.rehypePlugins || emptyPlugins
|
||||
const remarkPlugins = options.remarkPlugins || emptyPlugins
|
||||
const remarkRehypeOptions = options.remarkRehypeOptions
|
||||
? {...options.remarkRehypeOptions, ...emptyRemarkRehypeOptions}
|
||||
: emptyRemarkRehypeOptions
|
||||
|
||||
const processor = unified()
|
||||
.use(remarkParse)
|
||||
.use(remarkPlugins)
|
||||
.use(remarkRehype, remarkRehypeOptions)
|
||||
.use(rehypePlugins)
|
||||
|
||||
return processor
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up the virtual file.
|
||||
*
|
||||
* @param {Readonly<Options>} options
|
||||
* Props.
|
||||
* @returns {VFile}
|
||||
* Result.
|
||||
*/
|
||||
function createFile(options) {
|
||||
const children = options.children || ''
|
||||
const file = new VFile()
|
||||
|
||||
if (typeof children === 'string') {
|
||||
file.value = children
|
||||
} else {
|
||||
unreachable(
|
||||
'Unexpected value `' +
|
||||
children +
|
||||
'` for `children` prop, expected `string`'
|
||||
)
|
||||
}
|
||||
|
||||
return file
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the result from unified some more.
|
||||
*
|
||||
* @param {Nodes} tree
|
||||
* Tree.
|
||||
* @param {Readonly<Options>} options
|
||||
* Props.
|
||||
* @returns {ReactElement}
|
||||
* React element.
|
||||
*/
|
||||
function post(tree, options) {
|
||||
const allowedElements = options.allowedElements
|
||||
const allowElement = options.allowElement
|
||||
const components = options.components
|
||||
const disallowedElements = options.disallowedElements
|
||||
const skipHtml = options.skipHtml
|
||||
const unwrapDisallowed = options.unwrapDisallowed
|
||||
const urlTransform = options.urlTransform || defaultUrlTransform
|
||||
|
||||
for (const deprecation of deprecations) {
|
||||
if (Object.hasOwn(options, deprecation.from)) {
|
||||
unreachable(
|
||||
'Unexpected `' +
|
||||
deprecation.from +
|
||||
'` prop, ' +
|
||||
(deprecation.to
|
||||
? 'use `' + deprecation.to + '` instead'
|
||||
: 'remove it') +
|
||||
' (see <' +
|
||||
changelog +
|
||||
'#' +
|
||||
deprecation.id +
|
||||
'> for more info)'
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (allowedElements && disallowedElements) {
|
||||
unreachable(
|
||||
'Unexpected combined `allowedElements` and `disallowedElements`, expected one or the other'
|
||||
)
|
||||
}
|
||||
|
||||
visit(tree, transform)
|
||||
|
||||
return toJsxRuntime(tree, {
|
||||
Fragment,
|
||||
components,
|
||||
ignoreInvalidStyle: true,
|
||||
jsx,
|
||||
jsxs,
|
||||
passKeys: true,
|
||||
passNode: true
|
||||
})
|
||||
|
||||
/** @type {BuildVisitor<Root>} */
|
||||
function transform(node, index, parent) {
|
||||
if (node.type === 'raw' && parent && typeof index === 'number') {
|
||||
if (skipHtml) {
|
||||
parent.children.splice(index, 1)
|
||||
} else {
|
||||
parent.children[index] = {type: 'text', value: node.value}
|
||||
}
|
||||
|
||||
return index
|
||||
}
|
||||
|
||||
if (node.type === 'element') {
|
||||
/** @type {string} */
|
||||
let key
|
||||
|
||||
for (key in urlAttributes) {
|
||||
if (
|
||||
Object.hasOwn(urlAttributes, key) &&
|
||||
Object.hasOwn(node.properties, key)
|
||||
) {
|
||||
const value = node.properties[key]
|
||||
const test = urlAttributes[key]
|
||||
if (test === null || test.includes(node.tagName)) {
|
||||
node.properties[key] = urlTransform(String(value || ''), key, node)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (node.type === 'element') {
|
||||
let remove = allowedElements
|
||||
? !allowedElements.includes(node.tagName)
|
||||
: disallowedElements
|
||||
? disallowedElements.includes(node.tagName)
|
||||
: false
|
||||
|
||||
if (!remove && allowElement && typeof index === 'number') {
|
||||
remove = !allowElement(node, index, parent)
|
||||
}
|
||||
|
||||
if (remove && parent && typeof index === 'number') {
|
||||
if (unwrapDisallowed && node.children) {
|
||||
parent.children.splice(index, 1, ...node.children)
|
||||
} else {
|
||||
parent.children.splice(index, 1)
|
||||
}
|
||||
|
||||
return index
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a URL safe.
|
||||
*
|
||||
* @satisfies {UrlTransform}
|
||||
* @param {string} value
|
||||
* URL.
|
||||
* @returns {string}
|
||||
* Safe URL.
|
||||
*/
|
||||
export function defaultUrlTransform(value) {
|
||||
// Same as:
|
||||
// <https://github.com/micromark/micromark/blob/929275e/packages/micromark-util-sanitize-uri/dev/index.js#L34>
|
||||
// But without the `encode` part.
|
||||
const colon = value.indexOf(':')
|
||||
const questionMark = value.indexOf('?')
|
||||
const numberSign = value.indexOf('#')
|
||||
const slash = value.indexOf('/')
|
||||
|
||||
if (
|
||||
// If there is no protocol, it’s relative.
|
||||
colon === -1 ||
|
||||
// If the first colon is after a `?`, `#`, or `/`, it’s not a protocol.
|
||||
(slash !== -1 && colon > slash) ||
|
||||
(questionMark !== -1 && colon > questionMark) ||
|
||||
(numberSign !== -1 && colon > numberSign) ||
|
||||
// It is a protocol, it should be allowed.
|
||||
safeProtocol.test(value.slice(0, colon))
|
||||
) {
|
||||
return value
|
||||
}
|
||||
|
||||
return ''
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue