Skip to content

Commit 0fd3aa0

Browse files
authored
feat(options): add CSP support with trustedTypePolicy (#2220)
* CSP based on ideas from #1123 * Use types from html-dom-parser * Lint fixes * Update dom package * Restore gitignore
1 parent 8a562ec commit 0fd3aa0

6 files changed

Lines changed: 45 additions & 12 deletions

File tree

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import htmlToDOM from 'html-dom-parser';
2+
3+
import parse from '../../src';
4+
5+
vi.mock('html-dom-parser', () => ({
6+
default: vi.fn(() => []),
7+
}));
8+
9+
describe('trustedTypePolicy option', () => {
10+
it('passes trustedTypePolicy to html-dom-parser', () => {
11+
const trustedTypePolicy = {
12+
createHTML: vi.fn((input: string) => input),
13+
};
14+
15+
parse('<div>test</div>', { trustedTypePolicy });
16+
17+
expect(htmlToDOM).toHaveBeenCalledWith(
18+
'<div>test</div>',
19+
expect.objectContaining({
20+
lowerCaseAttributeNames: false,
21+
trustedTypePolicy,
22+
}),
23+
);
24+
});
25+
});

examples/webpack/src/index.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,10 @@ import parse from 'html-react-parser';
33

44
const root = createRoot(document.getElementById('root'));
55

6-
root.render(parse('<h1>HTMLReactParser loaded with Webpack</h1>'));
6+
let trustedHtml = (window.trustedTypes && window.trustedTypes.createPolicy)
7+
? window.trustedTypes.createPolicy('csp-react-html', {createHTML: function(s) { return s; }})
8+
: null;
9+
10+
root.render(parse('<h1>HTMLReactParser loaded with Webpack</h1>',{
11+
trustedTypePolicy : trustedHtml
12+
}));

package-lock.json

Lines changed: 4 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@
6161
],
6262
"dependencies": {
6363
"domhandler": "6.0.1",
64-
"html-dom-parser": "7.0.1",
64+
"html-dom-parser": "7.1.0",
6565
"react-property": "2.0.2",
6666
"style-to-js": "1.1.21"
6767
},

src/index.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,10 @@ export default function HTMLReactParser(
3131
return [];
3232
}
3333

34-
return domToReact(
35-
htmlToDOM(html, options?.htmlparser2 ?? domParserOptions),
36-
options,
37-
);
34+
const htmlToDOMOptions = {
35+
...(options?.htmlparser2 ?? domParserOptions),
36+
trustedTypePolicy: options?.trustedTypePolicy,
37+
};
38+
39+
return domToReact(htmlToDOM(html, htmlToDOMOptions), options);
3840
}

src/types.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import type { DomHandlerOptions } from 'domhandler';
2-
import type { DOMNode } from 'html-dom-parser';
2+
import type { DOMNode, TrustedTypePolicy } from 'html-dom-parser';
33
import type { ParserOptions } from 'htmlparser2';
44
import type { JSX, ReactNode } from 'react';
55

66
export interface HTMLReactParserOptions {
77
htmlparser2?: ParserOptions & DomHandlerOptions;
8+
trustedTypePolicy?: TrustedTypePolicy;
89

910
library?: {
1011
/* eslint-disable @typescript-eslint/no-explicit-any */

0 commit comments

Comments
 (0)