refactor: sanitize schema customize
This commit is contained in:
parent
535d536742
commit
b1e1a5aeb6
|
@ -15,10 +15,8 @@
|
|||
],
|
||||
"dependencies": {
|
||||
"@types/codemirror": "^0.0.96",
|
||||
"@types/lodash-es": "^4.17.3",
|
||||
"@types/lodash.debounce": "^4.0.6",
|
||||
"codemirror": "^5.55.0",
|
||||
"deepmerge": "^4.2.2",
|
||||
"lodash.debounce": "^4.0.8",
|
||||
"rehype-raw": "^4.0.1",
|
||||
"rehype-sanitize": "^3.0.1",
|
||||
|
|
|
@ -3,12 +3,12 @@ import * as bytemd from 'bytemd';
|
|||
|
||||
export interface ViewerProps extends bytemd.ViewerProps {}
|
||||
|
||||
export const Viewer: FC<ViewerProps> = ({ value, plugins }) => {
|
||||
export const Viewer: FC<ViewerProps> = ({ value, sanitize, plugins }) => {
|
||||
const el = useRef<HTMLDivElement>(null);
|
||||
const html = useMemo(() => bytemd.processMarkdown({ value, plugins }), [
|
||||
value,
|
||||
plugins,
|
||||
]);
|
||||
const html = useMemo(
|
||||
() => bytemd.processMarkdown({ value, sanitize, plugins }),
|
||||
[value, sanitize, plugins]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const $ = el.current;
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
export let value = '';
|
||||
export let plugins = [];
|
||||
export let sanitize = null;
|
||||
export let mode = 'split';
|
||||
export let previewDebounce = 300;
|
||||
|
||||
|
@ -82,7 +83,7 @@
|
|||
<div
|
||||
class="bytemd-preview"
|
||||
style={mode === 'tab' && activeTab === 0 ? 'display:none' : undefined}>
|
||||
<Viewer value={viewerValue} {plugins} />
|
||||
<Viewer value={viewerValue} {plugins} {sanitize} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -27,7 +27,6 @@ export interface BytemdPlugin {
|
|||
* https://github.com/rehypejs/rehype/blob/main/doc/plugins.md
|
||||
*/
|
||||
rehype?: UnifiedProcessor;
|
||||
sanitizeSchema?: any;
|
||||
/**
|
||||
* Side effect for editor, triggers when plugin list changes
|
||||
*/
|
||||
|
@ -82,4 +81,12 @@ export interface ViewerProps {
|
|||
* ByteMD plugin list
|
||||
*/
|
||||
plugins?: BytemdPlugin[];
|
||||
/**
|
||||
* An option to change the default sanitize schema.
|
||||
*
|
||||
* Defaults to GitHub style sanitation except that the `class` attribute is allowed
|
||||
*
|
||||
* https://github.com/syntax-tree/hast-util-sanitize/blob/main/lib/github.json
|
||||
*/
|
||||
sanitize?: (schema: any) => any;
|
||||
}
|
||||
|
|
|
@ -7,12 +7,15 @@ import rehypeRaw from 'rehype-raw';
|
|||
// @ts-ignore
|
||||
import rehypeSanitize from 'rehype-sanitize';
|
||||
import stringify from 'rehype-stringify';
|
||||
import merge from 'deepmerge';
|
||||
// @ts-ignore
|
||||
import ghSchema from 'hast-util-sanitize/lib/github.json';
|
||||
import { ViewerProps } from '.';
|
||||
|
||||
export function processMarkdown({ value, plugins = [] }: ViewerProps) {
|
||||
export function processMarkdown({
|
||||
value,
|
||||
sanitize,
|
||||
plugins = [],
|
||||
}: ViewerProps) {
|
||||
let parser = unified().use(remarkParse);
|
||||
|
||||
plugins.forEach(({ remark }) => {
|
||||
|
@ -24,9 +27,8 @@ export function processMarkdown({ value, plugins = [] }: ViewerProps) {
|
|||
.use(rehypeRaw);
|
||||
|
||||
let schema = ghSchema;
|
||||
plugins.forEach(({ sanitizeSchema: markdownSanitizeSchema }) => {
|
||||
if (markdownSanitizeSchema) schema = merge(schema, markdownSanitizeSchema);
|
||||
});
|
||||
schema.attributes['*'].push('className'); // Add className
|
||||
if (sanitize) schema = sanitize(schema);
|
||||
|
||||
parser = parser.use(rehypeSanitize, schema);
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
export let value = '';
|
||||
export let plugins = [];
|
||||
export let sanitize = null;
|
||||
|
||||
let el;
|
||||
const id = Date.now();
|
||||
|
@ -23,7 +24,7 @@
|
|||
}
|
||||
|
||||
onDestroy(off);
|
||||
$: html = processMarkdown({ value, plugins });
|
||||
$: html = processMarkdown({ value, plugins, sanitize });
|
||||
$: if (html != null && plugins) {
|
||||
off();
|
||||
tick().then(() => {
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
import * as bytemd from 'bytemd';
|
||||
|
||||
export default {
|
||||
props: ['value', 'plugins', 'mode', 'previewDebounce'],
|
||||
props: ['value', 'plugins', 'sanitize', 'mode', 'previewDebounce'],
|
||||
mounted() {
|
||||
const editor = new bytemd.Editor({
|
||||
target: this.$el,
|
||||
|
|
|
@ -6,13 +6,13 @@
|
|||
import { processMarkdown } from 'bytemd';
|
||||
|
||||
export default {
|
||||
props: ['value', 'plugins'],
|
||||
props: ['value', 'plugins', 'sanitize'],
|
||||
computed: {
|
||||
html() {
|
||||
return processMarkdown(this.$props);
|
||||
},
|
||||
needUpdate() {
|
||||
return [this.html, this.plugins];
|
||||
return [this.html, this.plugins, this.sanitize];
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
|
|
|
@ -7,11 +7,5 @@ export default function footnotes(options?: {
|
|||
}): BytemdPlugin {
|
||||
return {
|
||||
remark: (u) => u.use(remarkFootnotes, options),
|
||||
sanitizeSchema: {
|
||||
attributes: {
|
||||
div: ['className'],
|
||||
a: ['className'],
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
@ -17,10 +17,5 @@ export default function highlight({
|
|||
}: HighlightOptions = {}): BytemdPlugin {
|
||||
return {
|
||||
rehype: (u) => u.use(rehypeHighlight, { subset, ignoreMissing, ...rest }),
|
||||
sanitizeSchema: {
|
||||
attributes: {
|
||||
code: ['className'],
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
@ -16,11 +16,5 @@ export default function math(options: Options = {}): BytemdPlugin {
|
|||
return {
|
||||
remark: (u) => u.use(remarkMath, options.math),
|
||||
rehype: (u) => u.use(rehypeKatex, options.katex),
|
||||
sanitizeSchema: {
|
||||
attributes: {
|
||||
div: ['className'],
|
||||
span: ['className'],
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
@ -3,11 +3,6 @@ import mermaidAPI from 'mermaid/mermaidAPI';
|
|||
|
||||
export default function mermaid(options?: mermaidAPI.Config): BytemdPlugin {
|
||||
return {
|
||||
sanitizeSchema: {
|
||||
attributes: {
|
||||
code: ['className'],
|
||||
},
|
||||
},
|
||||
viewerEffect(el) {
|
||||
const els = el.querySelectorAll<HTMLElement>('pre>code.language-mermaid');
|
||||
if (els.length === 0) return;
|
||||
|
|
|
@ -2,11 +2,6 @@ import { BytemdPlugin } from 'bytemd';
|
|||
|
||||
export default function vega(): BytemdPlugin {
|
||||
return {
|
||||
sanitizeSchema: {
|
||||
attributes: {
|
||||
code: ['className'],
|
||||
},
|
||||
},
|
||||
viewerEffect(el) {
|
||||
const els = el.querySelectorAll<HTMLElement>('pre>code.language-vega');
|
||||
if (els.length === 0) return;
|
||||
|
|
Loading…
Reference in New Issue