refactor: 简化Markdown白名单构建
This commit is contained in:
parent
add0dc3a8c
commit
f74bd14c34
@ -24,6 +24,34 @@ const MARKDOWN_SOURCE_PATTERN =
|
||||
/<!--\s*kt-markdown-source:([A-Za-z0-9+/=]+)\s*-->/;
|
||||
const CONTENT_CLASS_PATTERN =
|
||||
/^(kt-md-|wp-|align|size-|is-|has-|language-|attachment-)/;
|
||||
const CONTENT_CLASS_ATTRIBUTE = ['className', CONTENT_CLASS_PATTERN];
|
||||
const EXTRA_TAG_NAMES = ['figcaption', 'figure'];
|
||||
const CONTENT_CLASS_TAG_NAMES = [
|
||||
'a',
|
||||
'blockquote',
|
||||
'code',
|
||||
'div',
|
||||
'figcaption',
|
||||
'figure',
|
||||
'h1',
|
||||
'h2',
|
||||
'h3',
|
||||
'h4',
|
||||
'h5',
|
||||
'h6',
|
||||
'li',
|
||||
'ol',
|
||||
'p',
|
||||
'pre',
|
||||
'span',
|
||||
'table',
|
||||
'tbody',
|
||||
'td',
|
||||
'th',
|
||||
'thead',
|
||||
'tr',
|
||||
'ul',
|
||||
];
|
||||
|
||||
@Injectable()
|
||||
export class MarkdownService {
|
||||
@ -185,49 +213,27 @@ export class MarkdownService {
|
||||
|
||||
private createSanitizeSchema(defaultSchema: unknown) {
|
||||
const schema = defaultSchema as Record<string, any>;
|
||||
const attributes = schema.attributes || {};
|
||||
const classNameAttribute = ['className', CONTENT_CLASS_PATTERN];
|
||||
const attributes = (schema.attributes || {}) as Record<string, any[]>;
|
||||
const classAttributes = Object.fromEntries(
|
||||
CONTENT_CLASS_TAG_NAMES.map((tagName) => [
|
||||
tagName,
|
||||
[...(attributes[tagName] || []), CONTENT_CLASS_ATTRIBUTE],
|
||||
]),
|
||||
);
|
||||
|
||||
return {
|
||||
...schema,
|
||||
tagNames: [
|
||||
...new Set([
|
||||
...(schema.tagNames || []),
|
||||
'figcaption',
|
||||
'figure',
|
||||
...EXTRA_TAG_NAMES,
|
||||
]),
|
||||
],
|
||||
attributes: {
|
||||
...attributes,
|
||||
a: [...(attributes.a || []), 'target', 'rel', classNameAttribute],
|
||||
blockquote: [...(attributes.blockquote || []), classNameAttribute],
|
||||
code: [...(attributes.code || []), classNameAttribute],
|
||||
div: [...(attributes.div || []), classNameAttribute],
|
||||
figcaption: [...(attributes.figcaption || []), classNameAttribute],
|
||||
figure: [...(attributes.figure || []), classNameAttribute],
|
||||
h1: [...(attributes.h1 || []), classNameAttribute],
|
||||
h2: [...(attributes.h2 || []), classNameAttribute],
|
||||
h3: [...(attributes.h3 || []), classNameAttribute],
|
||||
h4: [...(attributes.h4 || []), classNameAttribute],
|
||||
h5: [...(attributes.h5 || []), classNameAttribute],
|
||||
h6: [...(attributes.h6 || []), classNameAttribute],
|
||||
img: [
|
||||
...(attributes.img || []),
|
||||
'loading',
|
||||
classNameAttribute,
|
||||
],
|
||||
li: [...(attributes.li || []), classNameAttribute],
|
||||
ol: [...(attributes.ol || []), classNameAttribute],
|
||||
p: [...(attributes.p || []), classNameAttribute],
|
||||
pre: [...(attributes.pre || []), classNameAttribute],
|
||||
span: [...(attributes.span || []), classNameAttribute],
|
||||
table: [...(attributes.table || []), classNameAttribute],
|
||||
tbody: [...(attributes.tbody || []), classNameAttribute],
|
||||
td: [...(attributes.td || []), classNameAttribute],
|
||||
th: [...(attributes.th || []), classNameAttribute],
|
||||
thead: [...(attributes.thead || []), classNameAttribute],
|
||||
tr: [...(attributes.tr || []), classNameAttribute],
|
||||
ul: [...(attributes.ul || []), classNameAttribute],
|
||||
...classAttributes,
|
||||
a: [...(attributes.a || []), 'target', 'rel', CONTENT_CLASS_ATTRIBUTE],
|
||||
img: [...(attributes.img || []), 'loading', CONTENT_CLASS_ATTRIBUTE],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@ -35,4 +35,30 @@ describe('MarkdownService', () => {
|
||||
expect(html).not.toContain('onclick');
|
||||
expect(html).not.toContain('<script>');
|
||||
});
|
||||
|
||||
it('builds sanitizer schema for content classes and image loading', () => {
|
||||
const schema = (service as any).createSanitizeSchema({
|
||||
attributes: {
|
||||
a: ['href'],
|
||||
img: ['src'],
|
||||
},
|
||||
tagNames: ['p'],
|
||||
});
|
||||
|
||||
expect(schema.tagNames).toEqual(['p', 'figcaption', 'figure']);
|
||||
expect(schema.attributes.a).toEqual([
|
||||
'href',
|
||||
'target',
|
||||
'rel',
|
||||
['className', /^(kt-md-|wp-|align|size-|is-|has-|language-|attachment-)/],
|
||||
]);
|
||||
expect(schema.attributes.figure).toEqual([
|
||||
['className', /^(kt-md-|wp-|align|size-|is-|has-|language-|attachment-)/],
|
||||
]);
|
||||
expect(schema.attributes.img).toEqual([
|
||||
'src',
|
||||
'loading',
|
||||
['className', /^(kt-md-|wp-|align|size-|is-|has-|language-|attachment-)/],
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
Loading…
Reference in New Issue
Block a user