// rehype-sanitize 白名单 schema(§8.2 渲染管线): // - 默认 GitHub schema 之上扩展:任务列表 checkbox 所需属性、 // highlight.js 纯 class 高亮所需 className 白名单 // - 禁 script/iframe/style 属性/事件属性;链接协议白名单(javascript: 被剥除) // - 链接 target/rel 由 组件强制(schema 不支持条件属性) import { defaultSchema } from 'rehype-sanitize' import rehypeSanitize from 'rehype-sanitize' import type { Schema } from 'hast-util-sanitize' import type { Pluggable } from 'unified' export const sanitizeSchema: Schema = { ...defaultSchema, tagNames: [ ...(defaultSchema.tagNames ?? []), // 允许任务列表所需的 input(GitHub schema 已含,显式声明以防上游变化) 'input', ], attributes: { ...defaultSchema.attributes, // 任务列表 checkbox:默认 schema 已含 ['type','checkbox'] 与 ['disabled',true], // 显式补 'checked' input: [ ...(defaultSchema.attributes?.input ?? []), ['checked', true], ], // highlight.js 输出纯 class(零内联样式,§3.2) code: [ ...(defaultSchema.attributes?.code ?? []), ['className', /^language-./, 'hljs'], ], span: [ ...(defaultSchema.attributes?.span ?? []), ['className', /^hljs(-\w+)?$/], ], }, // 危险协议由默认 protocols 白名单(http/https/mailto/irc/xmpp…)剥除 clobberPrefix: defaultSchema.clobberPrefix ?? 'user-content-', } // rehypePlugins 元组:[rehypeSanitize, sanitizeSchema] export const sanitizePlugin: Pluggable = [rehypeSanitize, sanitizeSchema]