@3t-transform/threeteeui 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/{domsanitiser.options-32e670aa.js → domsanitiser.options-55ce2d65.js} +220 -383
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/{tttx-button_1_0_1.cjs.entry.js → tttx-button_1_0_2.cjs.entry.js} +2 -2
- package/dist/cjs/{tttx-checkbox-group-caption_1_0_1.cjs.entry.js → tttx-checkbox-group-caption_1_0_2.cjs.entry.js} +1 -1
- package/dist/cjs/{tttx-checkbox-group-heading_1_0_1.cjs.entry.js → tttx-checkbox-group-heading_1_0_2.cjs.entry.js} +1 -1
- package/dist/cjs/{tttx-checkbox-group_1_0_1.cjs.entry.js → tttx-checkbox-group_1_0_2.cjs.entry.js} +1 -1
- package/dist/cjs/{tttx-checkbox_1_0_1.cjs.entry.js → tttx-checkbox_1_0_2.cjs.entry.js} +2 -2
- package/dist/cjs/{tttx-data-pattern_1_0_1.cjs.entry.js → tttx-data-pattern_1_0_2.cjs.entry.js} +2 -2
- package/dist/cjs/{tttx-dialog-box_1_0_1.cjs.entry.js → tttx-dialog-box_1_0_2.cjs.entry.js} +4 -4
- package/dist/cjs/{tttx-dialog_1_0_1.cjs.entry.js → tttx-dialog_1_0_2.cjs.entry.js} +2 -2
- package/dist/cjs/{tttx-expander_1_0_1.cjs.entry.js → tttx-expander_1_0_2.cjs.entry.js} +2 -2
- package/dist/cjs/{tttx-filter_1_0_1_4.cjs.entry.js → tttx-filter_1_0_2_4.cjs.entry.js} +10 -10
- package/dist/cjs/{tttx-form_1_0_1.cjs.entry.js → tttx-form_1_0_2.cjs.entry.js} +3 -3
- package/dist/cjs/{tttx-icon_1_0_1.cjs.entry.js → tttx-icon_1_0_2.cjs.entry.js} +1 -1
- package/dist/cjs/{tttx-keyvalue-block_1_0_1.cjs.entry.js → tttx-keyvalue-block_1_0_2.cjs.entry.js} +1 -1
- package/dist/cjs/{tttx-loading-spinner_1_0_1.cjs.entry.js → tttx-loading-spinner_1_0_2.cjs.entry.js} +1 -1
- package/dist/cjs/{tttx-multiselect-box_1_0_1.cjs.entry.js → tttx-multiselect-box_1_0_2.cjs.entry.js} +7 -7
- package/dist/cjs/{tttx-percentage-bar_1_0_1.cjs.entry.js → tttx-percentage-bar_1_0_2.cjs.entry.js} +2 -2
- package/dist/cjs/{tttx-qrcode_1_0_1.cjs.entry.js → tttx-qrcode_1_0_2.cjs.entry.js} +1 -1
- package/dist/cjs/{tttx-select-box_1_0_1.cjs.entry.js → tttx-select-box_1_0_2.cjs.entry.js} +4 -4
- package/dist/cjs/tttx-standalone-input_1_0_2.cjs.entry.js +94 -0
- package/dist/cjs/{tttx-tabs_1_0_1.cjs.entry.js → tttx-tabs_1_0_2.cjs.entry.js} +5 -5
- package/dist/cjs/{tttx-tag_1_0_1.cjs.entry.js → tttx-tag_1_0_2.cjs.entry.js} +2 -2
- package/dist/cjs/{tttx-textarea_1_0_1.cjs.entry.js → tttx-textarea_1_0_2.cjs.entry.js} +2 -2
- package/dist/cjs/{tttx-tree-view_1_0_1.cjs.entry.js → tttx-tree-view_1_0_2.cjs.entry.js} +4 -4
- package/dist/cjs/tttx.cjs.js +1 -1
- package/dist/collection/components/atoms/tttx-button/tttx-button.js +2 -2
- package/dist/collection/components/atoms/tttx-button/tttx-button.stories.js +20 -20
- package/dist/collection/components/atoms/tttx-checkbox/tttx-checkbox.js +2 -2
- package/dist/collection/components/atoms/tttx-checkbox/tttx-checkbox.stories.js +1 -1
- package/dist/collection/components/atoms/tttx-icon/tttx-icon.js +1 -1
- package/dist/collection/components/atoms/tttx-icon/tttx-icon.stories.js +1 -1
- package/dist/collection/components/atoms/tttx-keyvalue-block/tttx-keyvalue-block.js +1 -1
- package/dist/collection/components/atoms/tttx-keyvalue-block/tttx-keyvalue-block.stories.js +6 -6
- package/dist/collection/components/atoms/tttx-loading-spinner/tttx-loading-spinner.js +1 -1
- package/dist/collection/components/atoms/tttx-loading-spinner/tttx-loading-spinner.stories.js +1 -1
- package/dist/collection/components/atoms/tttx-percentage-bar/tttx-percentage-bar.js +1 -1
- package/dist/collection/components/atoms/tttx-percentage-bar/tttx-percentage-bar.stories.js +5 -5
- package/dist/collection/components/atoms/tttx-qrcode/tttx-qrcode.js +1 -1
- package/dist/collection/components/atoms/tttx-qrcode/tttx-qrcode.stories.js +1 -1
- package/dist/collection/components/atoms/tttx-tag/tttx-tag.css +1 -0
- package/dist/collection/components/atoms/tttx-tag/tttx-tag.js +1 -1
- package/dist/collection/components/atoms/tttx-tag/tttx-tag.stories.js +6 -6
- package/dist/collection/components/molecules/tttx-checkbox-group/components/tttx-checkbox-group-caption.js +1 -1
- package/dist/collection/components/molecules/tttx-checkbox-group/components/tttx-checkbox-group-heading.js +1 -1
- package/dist/collection/components/molecules/tttx-checkbox-group/tttx-checkbox-group.js +1 -1
- package/dist/collection/components/molecules/tttx-checkbox-group/tttx-checkbox-group.stories.js +10 -10
- package/dist/collection/components/molecules/tttx-dialog/tttx-dialog.js +2 -2
- package/dist/collection/components/molecules/tttx-dialog/tttx-dialog.stories.js +6 -6
- package/dist/collection/components/molecules/tttx-dialog-box/tttx-dialog-box.js +3 -3
- package/dist/collection/components/molecules/tttx-dialog-box/tttx-dialog-box.stories.js +24 -24
- package/dist/collection/components/molecules/tttx-expander/tttx-expander.js +2 -2
- package/dist/collection/components/molecules/tttx-expander/tttx-expander.stories.js +9 -9
- package/dist/collection/components/molecules/tttx-filter/tttx-filter.js +3 -3
- package/dist/collection/components/molecules/tttx-filter/tttx-filter.stories.js +2 -2
- package/dist/collection/components/molecules/tttx-form/tttx-form.js +2 -2
- package/dist/collection/components/molecules/tttx-form/tttx-form.stories.js +5 -5
- package/dist/collection/components/molecules/tttx-list/tttx-list.js +3 -3
- package/dist/collection/components/molecules/tttx-list/tttx-list.stories.js +46 -46
- package/dist/collection/components/molecules/tttx-multiselect-box/tttx-multiselect-box.js +6 -6
- package/dist/collection/components/molecules/tttx-multiselect-box/tttx-multiselect-box.stories.js +33 -33
- package/dist/collection/components/molecules/tttx-select-box/tttx-select-box.js +3 -3
- package/dist/collection/components/molecules/tttx-select-box/tttx-select-box.stories.js +16 -16
- package/dist/collection/components/molecules/tttx-sorter/tttx-sorter.js +2 -2
- package/dist/collection/components/molecules/tttx-sorter/tttx-sorter.stories.js +1 -1
- package/dist/collection/components/molecules/tttx-standalone-input/tttx-standalone-input.js +4 -4
- package/dist/collection/components/molecules/tttx-standalone-input/tttx-standalone-input.stories.js +1 -1
- package/dist/collection/components/molecules/tttx-tabs/tttx-tabs.js +3 -3
- package/dist/collection/components/molecules/tttx-tabs/tttx-tabs.stories.js +4 -4
- package/dist/collection/components/molecules/tttx-textarea/tttx-textarea.js +3 -3
- package/dist/collection/components/molecules/tttx-textarea/tttx-textarea.stories.js +1 -1
- package/dist/collection/components/molecules/tttx-toolbar/tttx-toolbar.js +1 -1
- package/dist/collection/components/molecules/tttx-toolbar/tttx-toolbar.stories.js +37 -37
- package/dist/collection/components/molecules/tttx-tree-view/tttx-tree-view.js +3 -3
- package/dist/collection/components/molecules/tttx-tree-view/tttx-tree-view.stories.js +8 -8
- package/dist/collection/components/organisms/tttx-data-pattern/tttx-data-pattern.js +2 -2
- package/dist/collection/components/organisms/tttx-data-pattern/tttx-data-pattern.stories.js +5 -5
- package/dist/components/domsanitiser.options.js +220 -383
- package/dist/components/index.d.ts +26 -26
- package/dist/components/index.js +26 -26
- package/dist/components/tttx-button.js +5 -5
- package/dist/components/{tttx-button_1_0_1.d.ts → tttx-button_1_0_2.d.ts} +4 -4
- package/dist/components/{tttx-button_1_0_1.js → tttx-button_1_0_2.js} +2 -2
- package/dist/components/tttx-checkbox-group-caption_1_0_2.d.ts +11 -0
- package/dist/components/{tttx-checkbox-group-caption_1_0_1.js → tttx-checkbox-group-caption_1_0_2.js} +5 -5
- package/dist/components/tttx-checkbox-group-heading_1_0_2.d.ts +11 -0
- package/dist/components/{tttx-checkbox-group-heading_1_0_1.js → tttx-checkbox-group-heading_1_0_2.js} +5 -5
- package/dist/components/tttx-checkbox-group_1_0_2.d.ts +11 -0
- package/dist/components/{tttx-checkbox-group_1_0_1.js → tttx-checkbox-group_1_0_2.js} +5 -5
- package/dist/components/{tttx-expander_1_0_1.d.ts → tttx-checkbox_1_0_2.d.ts} +4 -4
- package/dist/components/{tttx-checkbox_1_0_1.js → tttx-checkbox_1_0_2.js} +7 -7
- package/dist/components/tttx-data-pattern_1_0_2.d.ts +11 -0
- package/dist/components/{tttx-data-pattern_1_0_1.js → tttx-data-pattern_1_0_2.js} +13 -13
- package/dist/components/{tttx-dialog-box_1_0_1.d.ts → tttx-dialog-box_1_0_2.d.ts} +4 -4
- package/dist/components/{tttx-dialog-box_1_0_1.js → tttx-dialog-box_1_0_2.js} +9 -9
- package/dist/components/{tttx-filter_1_0_1.d.ts → tttx-dialog_1_0_2.d.ts} +4 -4
- package/dist/components/{tttx-dialog_1_0_1.js → tttx-dialog_1_0_2.js} +8 -8
- package/dist/components/{tttx-checkbox_1_0_1.d.ts → tttx-expander_1_0_2.d.ts} +4 -4
- package/dist/components/{tttx-expander_1_0_1.js → tttx-expander_1_0_2.js} +7 -7
- package/dist/components/tttx-filter.js +6 -6
- package/dist/components/{tttx-qrcode_1_0_1.d.ts → tttx-filter_1_0_2.d.ts} +4 -4
- package/dist/components/{tttx-filter_1_0_1.js → tttx-filter_1_0_2.js} +2 -2
- package/dist/components/{tttx-icon_1_0_1.d.ts → tttx-form_1_0_2.d.ts} +4 -4
- package/dist/components/{tttx-form_1_0_1.js → tttx-form_1_0_2.js} +9 -9
- package/dist/components/tttx-icon.js +3 -3
- package/dist/components/{tttx-list_1_0_1.d.ts → tttx-icon_1_0_2.d.ts} +4 -4
- package/dist/components/{tttx-icon_1_0_1.js → tttx-icon_1_0_2.js} +2 -2
- package/dist/components/tttx-keyvalue-block_1_0_2.d.ts +11 -0
- package/dist/components/{tttx-keyvalue-block_1_0_1.js → tttx-keyvalue-block_1_0_2.js} +5 -5
- package/dist/components/tttx-list.js +6 -6
- package/dist/components/{tttx-form_1_0_1.d.ts → tttx-list_1_0_2.d.ts} +4 -4
- package/dist/components/{tttx-list_1_0_1.js → tttx-list_1_0_2.js} +2 -2
- package/dist/components/tttx-loading-spinner_1_0_2.d.ts +11 -0
- package/dist/components/{tttx-loading-spinner_1_0_1.js → tttx-loading-spinner_1_0_2.js} +5 -5
- package/dist/components/tttx-multiselect-box_1_0_2.d.ts +11 -0
- package/dist/components/{tttx-multiselect-box_1_0_1.js → tttx-multiselect-box_1_0_2.js} +13 -13
- package/dist/components/tttx-percentage-bar_1_0_2.d.ts +11 -0
- package/dist/components/{tttx-percentage-bar_1_0_1.js → tttx-percentage-bar_1_0_2.js} +6 -6
- package/dist/components/{tttx-dialog_1_0_1.d.ts → tttx-qrcode_1_0_2.d.ts} +4 -4
- package/dist/components/{tttx-qrcode_1_0_1.js → tttx-qrcode_1_0_2.js} +5 -5
- package/dist/components/tttx-select-box.js +7 -7
- package/dist/components/tttx-select-box_1_0_2.d.ts +11 -0
- package/dist/components/{tttx-select-box_1_0_1.js → tttx-select-box_1_0_2.js} +2 -2
- package/dist/components/tttx-sorter.js +5 -5
- package/dist/components/tttx-sorter_1_0_2.d.ts +11 -0
- package/dist/components/{tttx-sorter_1_0_1.js → tttx-sorter_1_0_2.js} +2 -2
- package/dist/components/tttx-standalone-input.js +6 -6
- package/dist/components/tttx-standalone-input_1_0_2.d.ts +11 -0
- package/dist/components/{tttx-standalone-input_1_0_1.js → tttx-standalone-input_1_0_2.js} +2 -2
- package/dist/components/{tttx-tabs_1_0_1.d.ts → tttx-tabs_1_0_2.d.ts} +4 -4
- package/dist/components/{tttx-tabs_1_0_1.js → tttx-tabs_1_0_2.js} +9 -9
- package/dist/components/{tttx-tag_1_0_1.d.ts → tttx-tag_1_0_2.d.ts} +4 -4
- package/dist/components/{tttx-tag_1_0_1.js → tttx-tag_1_0_2.js} +6 -6
- package/dist/components/tttx-textarea_1_0_2.d.ts +11 -0
- package/dist/components/{tttx-textarea_1_0_1.js → tttx-textarea_1_0_2.js} +6 -6
- package/dist/components/tttx-toolbar.js +3 -3
- package/dist/components/{tttx-toolbar_1_0_1.d.ts → tttx-toolbar_1_0_2.d.ts} +4 -4
- package/dist/components/{tttx-toolbar_1_0_1.js → tttx-toolbar_1_0_2.js} +2 -2
- package/dist/components/tttx-tree-view_1_0_2.d.ts +11 -0
- package/dist/components/{tttx-tree-view_1_0_1.js → tttx-tree-view_1_0_2.js} +9 -9
- package/dist/esm/{domsanitiser.options-68752a19.js → domsanitiser.options-38a67458.js} +220 -383
- package/dist/esm/loader.js +1 -1
- package/dist/esm/{tttx-button_1_0_1.entry.js → tttx-button_1_0_2.entry.js} +2 -2
- package/dist/esm/{tttx-checkbox-group-caption_1_0_1.entry.js → tttx-checkbox-group-caption_1_0_2.entry.js} +1 -1
- package/dist/esm/{tttx-checkbox-group-heading_1_0_1.entry.js → tttx-checkbox-group-heading_1_0_2.entry.js} +1 -1
- package/dist/esm/{tttx-checkbox-group_1_0_1.entry.js → tttx-checkbox-group_1_0_2.entry.js} +1 -1
- package/dist/esm/{tttx-checkbox_1_0_1.entry.js → tttx-checkbox_1_0_2.entry.js} +2 -2
- package/dist/esm/{tttx-data-pattern_1_0_1.entry.js → tttx-data-pattern_1_0_2.entry.js} +2 -2
- package/dist/esm/{tttx-dialog-box_1_0_1.entry.js → tttx-dialog-box_1_0_2.entry.js} +4 -4
- package/dist/esm/{tttx-dialog_1_0_1.entry.js → tttx-dialog_1_0_2.entry.js} +2 -2
- package/dist/esm/{tttx-expander_1_0_1.entry.js → tttx-expander_1_0_2.entry.js} +2 -2
- package/dist/esm/{tttx-filter_1_0_1_4.entry.js → tttx-filter_1_0_2_4.entry.js} +7 -7
- package/dist/esm/{tttx-form_1_0_1.entry.js → tttx-form_1_0_2.entry.js} +3 -3
- package/dist/esm/{tttx-icon_1_0_1.entry.js → tttx-icon_1_0_2.entry.js} +1 -1
- package/dist/esm/{tttx-keyvalue-block_1_0_1.entry.js → tttx-keyvalue-block_1_0_2.entry.js} +1 -1
- package/dist/esm/{tttx-loading-spinner_1_0_1.entry.js → tttx-loading-spinner_1_0_2.entry.js} +1 -1
- package/dist/esm/{tttx-multiselect-box_1_0_1.entry.js → tttx-multiselect-box_1_0_2.entry.js} +7 -7
- package/dist/esm/{tttx-percentage-bar_1_0_1.entry.js → tttx-percentage-bar_1_0_2.entry.js} +2 -2
- package/dist/esm/{tttx-qrcode_1_0_1.entry.js → tttx-qrcode_1_0_2.entry.js} +1 -1
- package/dist/esm/{tttx-select-box_1_0_1.entry.js → tttx-select-box_1_0_2.entry.js} +4 -4
- package/dist/esm/tttx-standalone-input_1_0_2.entry.js +90 -0
- package/dist/esm/{tttx-tabs_1_0_1.entry.js → tttx-tabs_1_0_2.entry.js} +5 -5
- package/dist/esm/{tttx-tag_1_0_1.entry.js → tttx-tag_1_0_2.entry.js} +2 -2
- package/dist/esm/{tttx-textarea_1_0_1.entry.js → tttx-textarea_1_0_2.entry.js} +2 -2
- package/dist/esm/{tttx-tree-view_1_0_1.entry.js → tttx-tree-view_1_0_2.entry.js} +4 -4
- package/dist/esm/tttx.js +1 -1
- package/dist/tttx/{p-c3d6914a.entry.js → p-0043dad0.entry.js} +1 -1
- package/dist/tttx/p-0e515960.entry.js +1 -1
- package/dist/tttx/{p-1f6cb3c3.entry.js → p-1c2a50d3.entry.js} +1 -1
- package/dist/tttx/p-1e5ff5f8.entry.js +1 -1
- package/dist/tttx/p-23f45005.entry.js +1 -1
- package/dist/tttx/p-55799798.js +3 -0
- package/dist/tttx/p-56c8c353.entry.js +1 -1
- package/dist/tttx/p-59c7b049.entry.js +1 -1
- package/dist/tttx/{p-7a7fb9b3.entry.js → p-5d2706b1.entry.js} +1 -1
- package/dist/tttx/p-63ad6fb7.entry.js +1 -1
- package/dist/tttx/p-796f699a.entry.js +1 -1
- package/dist/tttx/{p-6704ac94.entry.js → p-81aaafa0.entry.js} +1 -1
- package/dist/tttx/p-87481935.entry.js +1 -1
- package/dist/tttx/{p-05c242f0.entry.js → p-884f37d3.entry.js} +1 -1
- package/dist/tttx/p-9434561e.entry.js +1 -1
- package/dist/tttx/{p-5b3e1fae.entry.js → p-983d63ff.entry.js} +1 -1
- package/dist/tttx/p-a01e679a.entry.js +1 -1
- package/dist/tttx/p-a8e76e78.entry.js +1 -1
- package/dist/tttx/p-c170e3b8.entry.js +1 -1
- package/dist/tttx/{p-6abfd043.entry.js → p-c8589436.entry.js} +1 -1
- package/dist/tttx/p-ee358ce4.entry.js +1 -1
- package/dist/tttx/p-f374e293.entry.js +1 -1
- package/dist/tttx/{p-72ede7d8.entry.js → p-f4db1cf2.entry.js} +1 -1
- package/dist/tttx/p-fe967031.entry.js +1 -1
- package/dist/tttx/tttx.esm.js +1 -1
- package/dist/types/components/molecules/tttx-standalone-input/tttx-standalone-input.d.ts +2 -2
- package/dist/types/components/molecules/tttx-textarea/tttx-textarea.d.ts +2 -2
- package/dist/types/components.d.ts +304 -304
- package/package.json +1 -1
- package/readme.md +40 -62
- package/dist/cjs/tttx-standalone-input_1_0_1.cjs.entry.js +0 -94
- package/dist/components/tttx-checkbox-group-caption_1_0_1.d.ts +0 -11
- package/dist/components/tttx-checkbox-group-heading_1_0_1.d.ts +0 -11
- package/dist/components/tttx-checkbox-group_1_0_1.d.ts +0 -11
- package/dist/components/tttx-data-pattern_1_0_1.d.ts +0 -11
- package/dist/components/tttx-keyvalue-block_1_0_1.d.ts +0 -11
- package/dist/components/tttx-loading-spinner_1_0_1.d.ts +0 -11
- package/dist/components/tttx-multiselect-box_1_0_1.d.ts +0 -11
- package/dist/components/tttx-percentage-bar_1_0_1.d.ts +0 -11
- package/dist/components/tttx-select-box_1_0_1.d.ts +0 -11
- package/dist/components/tttx-sorter_1_0_1.d.ts +0 -11
- package/dist/components/tttx-standalone-input_1_0_1.d.ts +0 -11
- package/dist/components/tttx-textarea_1_0_1.d.ts +0 -11
- package/dist/components/tttx-tree-view_1_0_1.d.ts +0 -11
- package/dist/esm/tttx-standalone-input_1_0_1.entry.js +0 -90
- package/dist/tttx/p-88ee2406.js +0 -3
- package/dist/types/components/atoms/tttx-checkbox/tttx-checkbox.stories.d.ts +0 -47
- package/dist/types/components/molecules/tttx-dialog/tttx-dialog.stories.d.ts +0 -42
- package/dist/types/components/molecules/tttx-expander/tttx-expander.stories.d.ts +0 -27
- package/dist/types/components/molecules/tttx-filter/tttx-filter.stories.d.ts +0 -76
- package/dist/types/components/molecules/tttx-form/tttx-form.stories.d.ts +0 -468
- package/dist/types/components/molecules/tttx-list/tttx-list.stories.d.ts +0 -15
- package/dist/types/components/molecules/tttx-multiselect-box/tttx-multiselect-box.stories.d.ts +0 -15
- package/dist/types/components/molecules/tttx-sorter/tttx-sorter.stories.d.ts +0 -30
- package/dist/types/components/molecules/tttx-standalone-input/tttx-standalone-input.stories.d.ts +0 -150
- package/dist/types/components/molecules/tttx-tabs/tttx-tabs.stories.d.ts +0 -13
- package/dist/types/components/molecules/tttx-tree-view/tttx-tree-view.stories.d.ts +0 -21
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
const _commonjsHelpers = require('./_commonjsHelpers-537d719a.js');
|
|
4
4
|
|
|
5
5
|
var purify = _commonjsHelpers.createCommonjsModule(function (module, exports) {
|
|
6
|
-
/*! @license DOMPurify 3.0.
|
|
6
|
+
/*! @license DOMPurify 3.0.8 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.0.8/LICENSE */
|
|
7
7
|
|
|
8
8
|
(function (global, factory) {
|
|
9
9
|
module.exports = factory() ;
|
|
@@ -20,36 +20,30 @@ var purify = _commonjsHelpers.createCommonjsModule(function (module, exports) {
|
|
|
20
20
|
seal,
|
|
21
21
|
create
|
|
22
22
|
} = Object; // eslint-disable-line import/no-mutable-exports
|
|
23
|
-
|
|
24
23
|
let {
|
|
25
24
|
apply,
|
|
26
25
|
construct
|
|
27
26
|
} = typeof Reflect !== 'undefined' && Reflect;
|
|
28
|
-
|
|
29
27
|
if (!freeze) {
|
|
30
28
|
freeze = function freeze(x) {
|
|
31
29
|
return x;
|
|
32
30
|
};
|
|
33
31
|
}
|
|
34
|
-
|
|
35
32
|
if (!seal) {
|
|
36
33
|
seal = function seal(x) {
|
|
37
34
|
return x;
|
|
38
35
|
};
|
|
39
36
|
}
|
|
40
|
-
|
|
41
37
|
if (!apply) {
|
|
42
38
|
apply = function apply(fun, thisValue, args) {
|
|
43
39
|
return fun.apply(thisValue, args);
|
|
44
40
|
};
|
|
45
41
|
}
|
|
46
|
-
|
|
47
42
|
if (!construct) {
|
|
48
43
|
construct = function construct(Func, args) {
|
|
49
44
|
return new Func(...args);
|
|
50
45
|
};
|
|
51
46
|
}
|
|
52
|
-
|
|
53
47
|
const arrayForEach = unapply(Array.prototype.forEach);
|
|
54
48
|
const arrayPop = unapply(Array.prototype.pop);
|
|
55
49
|
const arrayPush = unapply(Array.prototype.push);
|
|
@@ -61,39 +55,37 @@ var purify = _commonjsHelpers.createCommonjsModule(function (module, exports) {
|
|
|
61
55
|
const stringTrim = unapply(String.prototype.trim);
|
|
62
56
|
const regExpTest = unapply(RegExp.prototype.test);
|
|
63
57
|
const typeErrorCreate = unconstruct(TypeError);
|
|
58
|
+
|
|
64
59
|
/**
|
|
65
60
|
* Creates a new function that calls the given function with a specified thisArg and arguments.
|
|
66
61
|
*
|
|
67
62
|
* @param {Function} func - The function to be wrapped and called.
|
|
68
63
|
* @returns {Function} A new function that calls the given function with a specified thisArg and arguments.
|
|
69
64
|
*/
|
|
70
|
-
|
|
71
65
|
function unapply(func) {
|
|
72
66
|
return function (thisArg) {
|
|
73
67
|
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|
74
68
|
args[_key - 1] = arguments[_key];
|
|
75
69
|
}
|
|
76
|
-
|
|
77
70
|
return apply(func, thisArg, args);
|
|
78
71
|
};
|
|
79
72
|
}
|
|
73
|
+
|
|
80
74
|
/**
|
|
81
75
|
* Creates a new function that constructs an instance of the given constructor function with the provided arguments.
|
|
82
76
|
*
|
|
83
77
|
* @param {Function} func - The constructor function to be wrapped and called.
|
|
84
78
|
* @returns {Function} A new function that constructs an instance of the given constructor function with the provided arguments.
|
|
85
79
|
*/
|
|
86
|
-
|
|
87
|
-
|
|
88
80
|
function unconstruct(func) {
|
|
89
81
|
return function () {
|
|
90
82
|
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
|
|
91
83
|
args[_key2] = arguments[_key2];
|
|
92
84
|
}
|
|
93
|
-
|
|
94
85
|
return construct(func, args);
|
|
95
86
|
};
|
|
96
87
|
}
|
|
88
|
+
|
|
97
89
|
/**
|
|
98
90
|
* Add properties to a lookup table
|
|
99
91
|
*
|
|
@@ -102,60 +94,69 @@ var purify = _commonjsHelpers.createCommonjsModule(function (module, exports) {
|
|
|
102
94
|
* @param {Function} transformCaseFunc - An optional function to transform the case of each element before adding to the set.
|
|
103
95
|
* @returns {Object} The modified set with added elements.
|
|
104
96
|
*/
|
|
105
|
-
|
|
106
|
-
|
|
107
97
|
function addToSet(set, array) {
|
|
108
98
|
let transformCaseFunc = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : stringToLowerCase;
|
|
109
|
-
|
|
110
99
|
if (setPrototypeOf) {
|
|
111
100
|
// Make 'in' and truthy checks like Boolean(set.constructor)
|
|
112
101
|
// independent of any properties defined on Object.prototype.
|
|
113
102
|
// Prevent prototype setters from intercepting set as a this value.
|
|
114
103
|
setPrototypeOf(set, null);
|
|
115
104
|
}
|
|
116
|
-
|
|
117
105
|
let l = array.length;
|
|
118
|
-
|
|
119
106
|
while (l--) {
|
|
120
107
|
let element = array[l];
|
|
121
|
-
|
|
122
108
|
if (typeof element === 'string') {
|
|
123
109
|
const lcElement = transformCaseFunc(element);
|
|
124
|
-
|
|
125
110
|
if (lcElement !== element) {
|
|
126
111
|
// Config presets (e.g. tags.js, attrs.js) are immutable.
|
|
127
112
|
if (!isFrozen(array)) {
|
|
128
113
|
array[l] = lcElement;
|
|
129
114
|
}
|
|
130
|
-
|
|
131
115
|
element = lcElement;
|
|
132
116
|
}
|
|
133
117
|
}
|
|
134
|
-
|
|
135
118
|
set[element] = true;
|
|
136
119
|
}
|
|
137
|
-
|
|
138
120
|
return set;
|
|
139
121
|
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Clean up an array to harden against CSPP
|
|
125
|
+
*
|
|
126
|
+
* @param {Array} array - The array to be cleaned.
|
|
127
|
+
* @returns {Array} The cleaned version of the array
|
|
128
|
+
*/
|
|
129
|
+
function cleanArray(array) {
|
|
130
|
+
for (let index = 0; index < array.length; index++) {
|
|
131
|
+
if (getOwnPropertyDescriptor(array, index) === undefined) {
|
|
132
|
+
array[index] = null;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return array;
|
|
136
|
+
}
|
|
137
|
+
|
|
140
138
|
/**
|
|
141
139
|
* Shallow clone an object
|
|
142
140
|
*
|
|
143
141
|
* @param {Object} object - The object to be cloned.
|
|
144
142
|
* @returns {Object} A new object that copies the original.
|
|
145
143
|
*/
|
|
146
|
-
|
|
147
|
-
|
|
148
144
|
function clone(object) {
|
|
149
145
|
const newObject = create(null);
|
|
150
|
-
|
|
151
146
|
for (const [property, value] of entries(object)) {
|
|
152
147
|
if (getOwnPropertyDescriptor(object, property) !== undefined) {
|
|
153
|
-
|
|
148
|
+
if (Array.isArray(value)) {
|
|
149
|
+
newObject[property] = cleanArray(value);
|
|
150
|
+
} else if (value && typeof value === 'object' && value.constructor === Object) {
|
|
151
|
+
newObject[property] = clone(value);
|
|
152
|
+
} else {
|
|
153
|
+
newObject[property] = value;
|
|
154
|
+
}
|
|
154
155
|
}
|
|
155
156
|
}
|
|
156
|
-
|
|
157
157
|
return newObject;
|
|
158
158
|
}
|
|
159
|
+
|
|
159
160
|
/**
|
|
160
161
|
* This method automatically checks if the prop is function or getter and behaves accordingly.
|
|
161
162
|
*
|
|
@@ -163,44 +164,41 @@ var purify = _commonjsHelpers.createCommonjsModule(function (module, exports) {
|
|
|
163
164
|
* @param {String} prop - The property name for which to find the getter function.
|
|
164
165
|
* @returns {Function} The getter function found in the prototype chain or a fallback function.
|
|
165
166
|
*/
|
|
166
|
-
|
|
167
167
|
function lookupGetter(object, prop) {
|
|
168
168
|
while (object !== null) {
|
|
169
169
|
const desc = getOwnPropertyDescriptor(object, prop);
|
|
170
|
-
|
|
171
170
|
if (desc) {
|
|
172
171
|
if (desc.get) {
|
|
173
172
|
return unapply(desc.get);
|
|
174
173
|
}
|
|
175
|
-
|
|
176
174
|
if (typeof desc.value === 'function') {
|
|
177
175
|
return unapply(desc.value);
|
|
178
176
|
}
|
|
179
177
|
}
|
|
180
|
-
|
|
181
178
|
object = getPrototypeOf(object);
|
|
182
179
|
}
|
|
183
|
-
|
|
184
180
|
function fallbackValue(element) {
|
|
185
181
|
console.warn('fallback value for', element);
|
|
186
182
|
return null;
|
|
187
183
|
}
|
|
188
|
-
|
|
189
184
|
return fallbackValue;
|
|
190
185
|
}
|
|
191
186
|
|
|
192
|
-
const html$1 = freeze(['a', 'abbr', 'acronym', 'address', 'area', 'article', 'aside', 'audio', 'b', 'bdi', 'bdo', 'big', 'blink', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'content', 'data', 'datalist', 'dd', 'decorator', 'del', 'details', 'dfn', 'dialog', 'dir', 'div', 'dl', 'dt', 'element', 'em', 'fieldset', 'figcaption', 'figure', 'font', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'i', 'img', 'input', 'ins', 'kbd', 'label', 'legend', 'li', 'main', 'map', 'mark', 'marquee', 'menu', 'menuitem', 'meter', 'nav', 'nobr', 'ol', 'optgroup', 'option', 'output', 'p', 'picture', 'pre', 'progress', 'q', 'rp', 'rt', 'ruby', 's', 'samp', 'section', 'select', 'shadow', 'small', 'source', 'spacer', 'span', 'strike', 'strong', 'style', 'sub', 'summary', 'sup', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'time', 'tr', 'track', 'tt', 'u', 'ul', 'var', 'video', 'wbr']);
|
|
187
|
+
const html$1 = freeze(['a', 'abbr', 'acronym', 'address', 'area', 'article', 'aside', 'audio', 'b', 'bdi', 'bdo', 'big', 'blink', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'content', 'data', 'datalist', 'dd', 'decorator', 'del', 'details', 'dfn', 'dialog', 'dir', 'div', 'dl', 'dt', 'element', 'em', 'fieldset', 'figcaption', 'figure', 'font', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'i', 'img', 'input', 'ins', 'kbd', 'label', 'legend', 'li', 'main', 'map', 'mark', 'marquee', 'menu', 'menuitem', 'meter', 'nav', 'nobr', 'ol', 'optgroup', 'option', 'output', 'p', 'picture', 'pre', 'progress', 'q', 'rp', 'rt', 'ruby', 's', 'samp', 'section', 'select', 'shadow', 'small', 'source', 'spacer', 'span', 'strike', 'strong', 'style', 'sub', 'summary', 'sup', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'time', 'tr', 'track', 'tt', 'u', 'ul', 'var', 'video', 'wbr']);
|
|
193
188
|
|
|
189
|
+
// SVG
|
|
194
190
|
const svg$1 = freeze(['svg', 'a', 'altglyph', 'altglyphdef', 'altglyphitem', 'animatecolor', 'animatemotion', 'animatetransform', 'circle', 'clippath', 'defs', 'desc', 'ellipse', 'filter', 'font', 'g', 'glyph', 'glyphref', 'hkern', 'image', 'line', 'lineargradient', 'marker', 'mask', 'metadata', 'mpath', 'path', 'pattern', 'polygon', 'polyline', 'radialgradient', 'rect', 'stop', 'style', 'switch', 'symbol', 'text', 'textpath', 'title', 'tref', 'tspan', 'view', 'vkern']);
|
|
195
|
-
const svgFilters = freeze(['feBlend', 'feColorMatrix', 'feComponentTransfer', 'feComposite', 'feConvolveMatrix', 'feDiffuseLighting', 'feDisplacementMap', 'feDistantLight', 'feDropShadow', 'feFlood', 'feFuncA', 'feFuncB', 'feFuncG', 'feFuncR', 'feGaussianBlur', 'feImage', 'feMerge', 'feMergeNode', 'feMorphology', 'feOffset', 'fePointLight', 'feSpecularLighting', 'feSpotLight', 'feTile', 'feTurbulence']);
|
|
191
|
+
const svgFilters = freeze(['feBlend', 'feColorMatrix', 'feComponentTransfer', 'feComposite', 'feConvolveMatrix', 'feDiffuseLighting', 'feDisplacementMap', 'feDistantLight', 'feDropShadow', 'feFlood', 'feFuncA', 'feFuncB', 'feFuncG', 'feFuncR', 'feGaussianBlur', 'feImage', 'feMerge', 'feMergeNode', 'feMorphology', 'feOffset', 'fePointLight', 'feSpecularLighting', 'feSpotLight', 'feTile', 'feTurbulence']);
|
|
192
|
+
|
|
193
|
+
// List of SVG elements that are disallowed by default.
|
|
196
194
|
// We still need to know them so that we can do namespace
|
|
197
195
|
// checks properly in case one wants to add them to
|
|
198
196
|
// allow-list.
|
|
199
|
-
|
|
200
197
|
const svgDisallowed = freeze(['animate', 'color-profile', 'cursor', 'discard', 'font-face', 'font-face-format', 'font-face-name', 'font-face-src', 'font-face-uri', 'foreignobject', 'hatch', 'hatchpath', 'mesh', 'meshgradient', 'meshpatch', 'meshrow', 'missing-glyph', 'script', 'set', 'solidcolor', 'unknown', 'use']);
|
|
201
|
-
const mathMl$1 = freeze(['math', 'menclose', 'merror', 'mfenced', 'mfrac', 'mglyph', 'mi', 'mlabeledtr', 'mmultiscripts', 'mn', 'mo', 'mover', 'mpadded', 'mphantom', 'mroot', 'mrow', 'ms', 'mspace', 'msqrt', 'mstyle', 'msub', 'msup', 'msubsup', 'mtable', 'mtd', 'mtext', 'mtr', 'munder', 'munderover', 'mprescripts']);
|
|
202
|
-
// even those that we disallow by default.
|
|
198
|
+
const mathMl$1 = freeze(['math', 'menclose', 'merror', 'mfenced', 'mfrac', 'mglyph', 'mi', 'mlabeledtr', 'mmultiscripts', 'mn', 'mo', 'mover', 'mpadded', 'mphantom', 'mroot', 'mrow', 'ms', 'mspace', 'msqrt', 'mstyle', 'msub', 'msup', 'msubsup', 'mtable', 'mtd', 'mtext', 'mtr', 'munder', 'munderover', 'mprescripts']);
|
|
203
199
|
|
|
200
|
+
// Similarly to SVG, we want to know all MathML elements,
|
|
201
|
+
// even those that we disallow by default.
|
|
204
202
|
const mathMlDisallowed = freeze(['maction', 'maligngroup', 'malignmark', 'mlongdiv', 'mscarries', 'mscarry', 'msgroup', 'mstack', 'msline', 'msrow', 'semantics', 'annotation', 'annotation-xml', 'mprescripts', 'none']);
|
|
205
203
|
const text = freeze(['#text']);
|
|
206
204
|
|
|
@@ -209,19 +207,19 @@ var purify = _commonjsHelpers.createCommonjsModule(function (module, exports) {
|
|
|
209
207
|
const mathMl = freeze(['accent', 'accentunder', 'align', 'bevelled', 'close', 'columnsalign', 'columnlines', 'columnspan', 'denomalign', 'depth', 'dir', 'display', 'displaystyle', 'encoding', 'fence', 'frame', 'height', 'href', 'id', 'largeop', 'length', 'linethickness', 'lspace', 'lquote', 'mathbackground', 'mathcolor', 'mathsize', 'mathvariant', 'maxsize', 'minsize', 'movablelimits', 'notation', 'numalign', 'open', 'rowalign', 'rowlines', 'rowspacing', 'rowspan', 'rspace', 'rquote', 'scriptlevel', 'scriptminsize', 'scriptsizemultiplier', 'selection', 'separator', 'separators', 'stretchy', 'subscriptshift', 'supscriptshift', 'symmetric', 'voffset', 'width', 'xmlns']);
|
|
210
208
|
const xml = freeze(['xlink:href', 'xml:id', 'xlink:title', 'xml:space', 'xmlns:xlink']);
|
|
211
209
|
|
|
210
|
+
// eslint-disable-next-line unicorn/better-regex
|
|
212
211
|
const MUSTACHE_EXPR = seal(/\{\{[\w\W]*|[\w\W]*\}\}/gm); // Specify template detection regex for SAFE_FOR_TEMPLATES mode
|
|
213
|
-
|
|
214
212
|
const ERB_EXPR = seal(/<%[\w\W]*|[\w\W]*%>/gm);
|
|
215
213
|
const TMPLIT_EXPR = seal(/\${[\w\W]*}/gm);
|
|
216
214
|
const DATA_ATTR = seal(/^data-[\-\w.\u00B7-\uFFFF]/); // eslint-disable-line no-useless-escape
|
|
217
|
-
|
|
218
215
|
const ARIA_ATTR = seal(/^aria-[\-\w]+$/); // eslint-disable-line no-useless-escape
|
|
219
|
-
|
|
220
216
|
const IS_ALLOWED_URI = seal(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i // eslint-disable-line no-useless-escape
|
|
221
217
|
);
|
|
218
|
+
|
|
222
219
|
const IS_SCRIPT_OR_DATA = seal(/^(?:\w+script|data):/i);
|
|
223
220
|
const ATTR_WHITESPACE = seal(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g // eslint-disable-line no-control-regex
|
|
224
221
|
);
|
|
222
|
+
|
|
225
223
|
const DOCTYPE_NAME = seal(/^html$/i);
|
|
226
224
|
|
|
227
225
|
var EXPRESSIONS = /*#__PURE__*/Object.freeze({
|
|
@@ -240,43 +238,37 @@ var purify = _commonjsHelpers.createCommonjsModule(function (module, exports) {
|
|
|
240
238
|
const getGlobal = function getGlobal() {
|
|
241
239
|
return typeof window === 'undefined' ? null : window;
|
|
242
240
|
};
|
|
241
|
+
|
|
243
242
|
/**
|
|
244
243
|
* Creates a no-op policy for internal use only.
|
|
245
244
|
* Don't export this function outside this module!
|
|
246
|
-
* @param {
|
|
245
|
+
* @param {TrustedTypePolicyFactory} trustedTypes The policy factory.
|
|
247
246
|
* @param {HTMLScriptElement} purifyHostElement The Script element used to load DOMPurify (to determine policy name suffix).
|
|
248
|
-
* @return {
|
|
247
|
+
* @return {TrustedTypePolicy} The policy created (or null, if Trusted Types
|
|
249
248
|
* are not supported or creating the policy failed).
|
|
250
249
|
*/
|
|
251
|
-
|
|
252
|
-
|
|
253
250
|
const _createTrustedTypesPolicy = function _createTrustedTypesPolicy(trustedTypes, purifyHostElement) {
|
|
254
251
|
if (typeof trustedTypes !== 'object' || typeof trustedTypes.createPolicy !== 'function') {
|
|
255
252
|
return null;
|
|
256
|
-
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// Allow the callers to control the unique policy name
|
|
257
256
|
// by adding a data-tt-policy-suffix to the script element with the DOMPurify.
|
|
258
257
|
// Policy creation with duplicate names throws in Trusted Types.
|
|
259
|
-
|
|
260
|
-
|
|
261
258
|
let suffix = null;
|
|
262
259
|
const ATTR_NAME = 'data-tt-policy-suffix';
|
|
263
|
-
|
|
264
260
|
if (purifyHostElement && purifyHostElement.hasAttribute(ATTR_NAME)) {
|
|
265
261
|
suffix = purifyHostElement.getAttribute(ATTR_NAME);
|
|
266
262
|
}
|
|
267
|
-
|
|
268
263
|
const policyName = 'dompurify' + (suffix ? '#' + suffix : '');
|
|
269
|
-
|
|
270
264
|
try {
|
|
271
265
|
return trustedTypes.createPolicy(policyName, {
|
|
272
266
|
createHTML(html) {
|
|
273
267
|
return html;
|
|
274
268
|
},
|
|
275
|
-
|
|
276
269
|
createScriptURL(scriptUrl) {
|
|
277
270
|
return scriptUrl;
|
|
278
271
|
}
|
|
279
|
-
|
|
280
272
|
});
|
|
281
273
|
} catch (_) {
|
|
282
274
|
// Policy creation failed (most likely another DOMPurify script has
|
|
@@ -286,32 +278,27 @@ var purify = _commonjsHelpers.createCommonjsModule(function (module, exports) {
|
|
|
286
278
|
return null;
|
|
287
279
|
}
|
|
288
280
|
};
|
|
289
|
-
|
|
290
281
|
function createDOMPurify() {
|
|
291
282
|
let window = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getGlobal();
|
|
292
|
-
|
|
293
283
|
const DOMPurify = root => createDOMPurify(root);
|
|
284
|
+
|
|
294
285
|
/**
|
|
295
286
|
* Version label, exposed for easier checks
|
|
296
287
|
* if DOMPurify is up to date or not
|
|
297
288
|
*/
|
|
289
|
+
DOMPurify.version = '3.0.8';
|
|
298
290
|
|
|
299
|
-
|
|
300
|
-
DOMPurify.version = '3.0.6';
|
|
301
291
|
/**
|
|
302
292
|
* Array of elements that DOMPurify removed during sanitation.
|
|
303
293
|
* Empty if nothing was removed.
|
|
304
294
|
*/
|
|
305
|
-
|
|
306
295
|
DOMPurify.removed = [];
|
|
307
|
-
|
|
308
296
|
if (!window || !window.document || window.document.nodeType !== 9) {
|
|
309
297
|
// Not running in a browser, provide a factory function
|
|
310
298
|
// so that you can pass your own Window
|
|
311
299
|
DOMPurify.isSupported = false;
|
|
312
300
|
return DOMPurify;
|
|
313
301
|
}
|
|
314
|
-
|
|
315
302
|
let {
|
|
316
303
|
document
|
|
317
304
|
} = window;
|
|
@@ -332,21 +319,20 @@ var purify = _commonjsHelpers.createCommonjsModule(function (module, exports) {
|
|
|
332
319
|
const cloneNode = lookupGetter(ElementPrototype, 'cloneNode');
|
|
333
320
|
const getNextSibling = lookupGetter(ElementPrototype, 'nextSibling');
|
|
334
321
|
const getChildNodes = lookupGetter(ElementPrototype, 'childNodes');
|
|
335
|
-
const getParentNode = lookupGetter(ElementPrototype, 'parentNode');
|
|
322
|
+
const getParentNode = lookupGetter(ElementPrototype, 'parentNode');
|
|
323
|
+
|
|
324
|
+
// As per issue #47, the web-components registry is inherited by a
|
|
336
325
|
// new document created via createHTMLDocument. As per the spec
|
|
337
326
|
// (http://w3c.github.io/webcomponents/spec/custom/#creating-and-passing-registries)
|
|
338
327
|
// a new empty registry is used when creating a template contents owner
|
|
339
328
|
// document, so we use that as our parent document to ensure nothing
|
|
340
329
|
// is inherited.
|
|
341
|
-
|
|
342
330
|
if (typeof HTMLTemplateElement === 'function') {
|
|
343
331
|
const template = document.createElement('template');
|
|
344
|
-
|
|
345
332
|
if (template.content && template.content.ownerDocument) {
|
|
346
333
|
document = template.content.ownerDocument;
|
|
347
334
|
}
|
|
348
335
|
}
|
|
349
|
-
|
|
350
336
|
let trustedTypesPolicy;
|
|
351
337
|
let emptyHTML = '';
|
|
352
338
|
const {
|
|
@@ -359,10 +345,10 @@ var purify = _commonjsHelpers.createCommonjsModule(function (module, exports) {
|
|
|
359
345
|
importNode
|
|
360
346
|
} = originalDocument;
|
|
361
347
|
let hooks = {};
|
|
348
|
+
|
|
362
349
|
/**
|
|
363
350
|
* Expose whether this browser supports running the full DOMPurify.
|
|
364
351
|
*/
|
|
365
|
-
|
|
366
352
|
DOMPurify.isSupported = typeof entries === 'function' && typeof getParentNode === 'function' && implementation && implementation.createHTMLDocument !== undefined;
|
|
367
353
|
const {
|
|
368
354
|
MUSTACHE_EXPR,
|
|
@@ -376,26 +362,26 @@ var purify = _commonjsHelpers.createCommonjsModule(function (module, exports) {
|
|
|
376
362
|
let {
|
|
377
363
|
IS_ALLOWED_URI: IS_ALLOWED_URI$1
|
|
378
364
|
} = EXPRESSIONS;
|
|
365
|
+
|
|
379
366
|
/**
|
|
380
367
|
* We consider the elements and attributes below to be safe. Ideally
|
|
381
368
|
* don't add any new ones but feel free to remove unwanted ones.
|
|
382
369
|
*/
|
|
383
370
|
|
|
384
371
|
/* allowed element names */
|
|
385
|
-
|
|
386
372
|
let ALLOWED_TAGS = null;
|
|
387
373
|
const DEFAULT_ALLOWED_TAGS = addToSet({}, [...html$1, ...svg$1, ...svgFilters, ...mathMl$1, ...text]);
|
|
388
|
-
/* Allowed attribute names */
|
|
389
374
|
|
|
375
|
+
/* Allowed attribute names */
|
|
390
376
|
let ALLOWED_ATTR = null;
|
|
391
377
|
const DEFAULT_ALLOWED_ATTR = addToSet({}, [...html, ...svg, ...mathMl, ...xml]);
|
|
378
|
+
|
|
392
379
|
/*
|
|
393
380
|
* Configure how DOMPUrify should handle custom elements and their attributes as well as customized built-in elements.
|
|
394
381
|
* @property {RegExp|Function|null} tagNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any custom elements)
|
|
395
382
|
* @property {RegExp|Function|null} attributeNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any attributes not on the allow list)
|
|
396
383
|
* @property {boolean} allowCustomizedBuiltInElements allow custom elements derived from built-ins if they pass CUSTOM_ELEMENT_HANDLING.tagNameCheck. Default: `false`.
|
|
397
384
|
*/
|
|
398
|
-
|
|
399
385
|
let CUSTOM_ELEMENT_HANDLING = Object.seal(create(null, {
|
|
400
386
|
tagNameCheck: {
|
|
401
387
|
writable: true,
|
|
@@ -416,59 +402,60 @@ var purify = _commonjsHelpers.createCommonjsModule(function (module, exports) {
|
|
|
416
402
|
value: false
|
|
417
403
|
}
|
|
418
404
|
}));
|
|
419
|
-
/* Explicitly forbidden tags (overrides ALLOWED_TAGS/ADD_TAGS) */
|
|
420
405
|
|
|
406
|
+
/* Explicitly forbidden tags (overrides ALLOWED_TAGS/ADD_TAGS) */
|
|
421
407
|
let FORBID_TAGS = null;
|
|
422
|
-
/* Explicitly forbidden attributes (overrides ALLOWED_ATTR/ADD_ATTR) */
|
|
423
408
|
|
|
409
|
+
/* Explicitly forbidden attributes (overrides ALLOWED_ATTR/ADD_ATTR) */
|
|
424
410
|
let FORBID_ATTR = null;
|
|
425
|
-
/* Decide if ARIA attributes are okay */
|
|
426
411
|
|
|
412
|
+
/* Decide if ARIA attributes are okay */
|
|
427
413
|
let ALLOW_ARIA_ATTR = true;
|
|
428
|
-
/* Decide if custom data attributes are okay */
|
|
429
414
|
|
|
415
|
+
/* Decide if custom data attributes are okay */
|
|
430
416
|
let ALLOW_DATA_ATTR = true;
|
|
431
|
-
/* Decide if unknown protocols are okay */
|
|
432
417
|
|
|
418
|
+
/* Decide if unknown protocols are okay */
|
|
433
419
|
let ALLOW_UNKNOWN_PROTOCOLS = false;
|
|
420
|
+
|
|
434
421
|
/* Decide if self-closing tags in attributes are allowed.
|
|
435
422
|
* Usually removed due to a mXSS issue in jQuery 3.0 */
|
|
436
|
-
|
|
437
423
|
let ALLOW_SELF_CLOSE_IN_ATTR = true;
|
|
424
|
+
|
|
438
425
|
/* Output should be safe for common template engines.
|
|
439
426
|
* This means, DOMPurify removes data attributes, mustaches and ERB
|
|
440
427
|
*/
|
|
441
|
-
|
|
442
428
|
let SAFE_FOR_TEMPLATES = false;
|
|
443
|
-
/* Decide if document with <html>... should be returned */
|
|
444
429
|
|
|
430
|
+
/* Decide if document with <html>... should be returned */
|
|
445
431
|
let WHOLE_DOCUMENT = false;
|
|
446
|
-
/* Track whether config is already set on this instance of DOMPurify. */
|
|
447
432
|
|
|
433
|
+
/* Track whether config is already set on this instance of DOMPurify. */
|
|
448
434
|
let SET_CONFIG = false;
|
|
435
|
+
|
|
449
436
|
/* Decide if all elements (e.g. style, script) must be children of
|
|
450
437
|
* document.body. By default, browsers might move them to document.head */
|
|
451
|
-
|
|
452
438
|
let FORCE_BODY = false;
|
|
439
|
+
|
|
453
440
|
/* Decide if a DOM `HTMLBodyElement` should be returned, instead of a html
|
|
454
441
|
* string (or a TrustedHTML object if Trusted Types are supported).
|
|
455
442
|
* If `WHOLE_DOCUMENT` is enabled a `HTMLHtmlElement` will be returned instead
|
|
456
443
|
*/
|
|
457
|
-
|
|
458
444
|
let RETURN_DOM = false;
|
|
445
|
+
|
|
459
446
|
/* Decide if a DOM `DocumentFragment` should be returned, instead of a html
|
|
460
447
|
* string (or a TrustedHTML object if Trusted Types are supported) */
|
|
461
|
-
|
|
462
448
|
let RETURN_DOM_FRAGMENT = false;
|
|
449
|
+
|
|
463
450
|
/* Try to return a Trusted Type object instead of a string, return a string in
|
|
464
451
|
* case Trusted Types are not supported */
|
|
465
|
-
|
|
466
452
|
let RETURN_TRUSTED_TYPE = false;
|
|
453
|
+
|
|
467
454
|
/* Output should be free from DOM clobbering attacks?
|
|
468
455
|
* This sanitizes markups named with colliding, clobberable built-in DOM APIs.
|
|
469
456
|
*/
|
|
470
|
-
|
|
471
457
|
let SANITIZE_DOM = true;
|
|
458
|
+
|
|
472
459
|
/* Achieve full DOM Clobbering protection by isolating the namespace of named
|
|
473
460
|
* properties and JS variables, mitigating attacks that abuse the HTML/DOM spec rules.
|
|
474
461
|
*
|
|
@@ -482,100 +469,99 @@ var purify = _commonjsHelpers.createCommonjsModule(function (module, exports) {
|
|
|
482
469
|
* Namespace isolation is implemented by prefixing `id` and `name` attributes
|
|
483
470
|
* with a constant string, i.e., `user-content-`
|
|
484
471
|
*/
|
|
485
|
-
|
|
486
472
|
let SANITIZE_NAMED_PROPS = false;
|
|
487
473
|
const SANITIZE_NAMED_PROPS_PREFIX = 'user-content-';
|
|
488
|
-
/* Keep element content when removing element? */
|
|
489
474
|
|
|
475
|
+
/* Keep element content when removing element? */
|
|
490
476
|
let KEEP_CONTENT = true;
|
|
477
|
+
|
|
491
478
|
/* If a `Node` is passed to sanitize(), then performs sanitization in-place instead
|
|
492
479
|
* of importing it into a new Document and returning a sanitized copy */
|
|
493
|
-
|
|
494
480
|
let IN_PLACE = false;
|
|
495
|
-
/* Allow usage of profiles like html, svg and mathMl */
|
|
496
481
|
|
|
482
|
+
/* Allow usage of profiles like html, svg and mathMl */
|
|
497
483
|
let USE_PROFILES = {};
|
|
498
|
-
/* Tags to ignore content of when KEEP_CONTENT is true */
|
|
499
484
|
|
|
485
|
+
/* Tags to ignore content of when KEEP_CONTENT is true */
|
|
500
486
|
let FORBID_CONTENTS = null;
|
|
501
487
|
const DEFAULT_FORBID_CONTENTS = addToSet({}, ['annotation-xml', 'audio', 'colgroup', 'desc', 'foreignobject', 'head', 'iframe', 'math', 'mi', 'mn', 'mo', 'ms', 'mtext', 'noembed', 'noframes', 'noscript', 'plaintext', 'script', 'style', 'svg', 'template', 'thead', 'title', 'video', 'xmp']);
|
|
502
|
-
/* Tags that are safe for data: URIs */
|
|
503
488
|
|
|
489
|
+
/* Tags that are safe for data: URIs */
|
|
504
490
|
let DATA_URI_TAGS = null;
|
|
505
491
|
const DEFAULT_DATA_URI_TAGS = addToSet({}, ['audio', 'video', 'img', 'source', 'image', 'track']);
|
|
506
|
-
/* Attributes safe for values like "javascript:" */
|
|
507
492
|
|
|
493
|
+
/* Attributes safe for values like "javascript:" */
|
|
508
494
|
let URI_SAFE_ATTRIBUTES = null;
|
|
509
495
|
const DEFAULT_URI_SAFE_ATTRIBUTES = addToSet({}, ['alt', 'class', 'for', 'id', 'label', 'name', 'pattern', 'placeholder', 'role', 'summary', 'title', 'value', 'style', 'xmlns']);
|
|
510
496
|
const MATHML_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';
|
|
511
497
|
const SVG_NAMESPACE = 'http://www.w3.org/2000/svg';
|
|
512
498
|
const HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';
|
|
513
499
|
/* Document namespace */
|
|
514
|
-
|
|
515
500
|
let NAMESPACE = HTML_NAMESPACE;
|
|
516
501
|
let IS_EMPTY_INPUT = false;
|
|
517
|
-
/* Allowed XHTML+XML namespaces */
|
|
518
502
|
|
|
503
|
+
/* Allowed XHTML+XML namespaces */
|
|
519
504
|
let ALLOWED_NAMESPACES = null;
|
|
520
505
|
const DEFAULT_ALLOWED_NAMESPACES = addToSet({}, [MATHML_NAMESPACE, SVG_NAMESPACE, HTML_NAMESPACE], stringToString);
|
|
521
|
-
/* Parsing of strict XHTML documents */
|
|
522
506
|
|
|
507
|
+
/* Parsing of strict XHTML documents */
|
|
523
508
|
let PARSER_MEDIA_TYPE = null;
|
|
524
509
|
const SUPPORTED_PARSER_MEDIA_TYPES = ['application/xhtml+xml', 'text/html'];
|
|
525
510
|
const DEFAULT_PARSER_MEDIA_TYPE = 'text/html';
|
|
526
511
|
let transformCaseFunc = null;
|
|
527
|
-
/* Keep a reference to config to pass to hooks */
|
|
528
512
|
|
|
513
|
+
/* Keep a reference to config to pass to hooks */
|
|
529
514
|
let CONFIG = null;
|
|
530
|
-
/* Ideally, do not touch anything below this line */
|
|
531
515
|
|
|
516
|
+
/* Ideally, do not touch anything below this line */
|
|
532
517
|
/* ______________________________________________ */
|
|
533
518
|
|
|
534
519
|
const formElement = document.createElement('form');
|
|
535
|
-
|
|
536
520
|
const isRegexOrFunction = function isRegexOrFunction(testValue) {
|
|
537
521
|
return testValue instanceof RegExp || testValue instanceof Function;
|
|
538
522
|
};
|
|
523
|
+
|
|
539
524
|
/**
|
|
540
525
|
* _parseConfig
|
|
541
526
|
*
|
|
542
527
|
* @param {Object} cfg optional config literal
|
|
543
528
|
*/
|
|
544
529
|
// eslint-disable-next-line complexity
|
|
545
|
-
|
|
546
|
-
|
|
547
530
|
const _parseConfig = function _parseConfig() {
|
|
548
531
|
let cfg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
549
|
-
|
|
550
532
|
if (CONFIG && CONFIG === cfg) {
|
|
551
533
|
return;
|
|
552
534
|
}
|
|
553
|
-
/* Shield configuration object from tampering */
|
|
554
|
-
|
|
555
535
|
|
|
536
|
+
/* Shield configuration object from tampering */
|
|
556
537
|
if (!cfg || typeof cfg !== 'object') {
|
|
557
538
|
cfg = {};
|
|
558
539
|
}
|
|
559
|
-
/* Shield configuration object from prototype pollution */
|
|
560
|
-
|
|
561
540
|
|
|
541
|
+
/* Shield configuration object from prototype pollution */
|
|
562
542
|
cfg = clone(cfg);
|
|
563
|
-
PARSER_MEDIA_TYPE =
|
|
564
|
-
|
|
543
|
+
PARSER_MEDIA_TYPE =
|
|
544
|
+
// eslint-disable-next-line unicorn/prefer-includes
|
|
545
|
+
SUPPORTED_PARSER_MEDIA_TYPES.indexOf(cfg.PARSER_MEDIA_TYPE) === -1 ? DEFAULT_PARSER_MEDIA_TYPE : cfg.PARSER_MEDIA_TYPE;
|
|
565
546
|
|
|
547
|
+
// HTML tags and attributes are not case-sensitive, converting to lowercase. Keeping XHTML as is.
|
|
566
548
|
transformCaseFunc = PARSER_MEDIA_TYPE === 'application/xhtml+xml' ? stringToString : stringToLowerCase;
|
|
567
|
-
/* Set configuration parameters */
|
|
568
549
|
|
|
550
|
+
/* Set configuration parameters */
|
|
569
551
|
ALLOWED_TAGS = 'ALLOWED_TAGS' in cfg ? addToSet({}, cfg.ALLOWED_TAGS, transformCaseFunc) : DEFAULT_ALLOWED_TAGS;
|
|
570
552
|
ALLOWED_ATTR = 'ALLOWED_ATTR' in cfg ? addToSet({}, cfg.ALLOWED_ATTR, transformCaseFunc) : DEFAULT_ALLOWED_ATTR;
|
|
571
553
|
ALLOWED_NAMESPACES = 'ALLOWED_NAMESPACES' in cfg ? addToSet({}, cfg.ALLOWED_NAMESPACES, stringToString) : DEFAULT_ALLOWED_NAMESPACES;
|
|
572
|
-
URI_SAFE_ATTRIBUTES = 'ADD_URI_SAFE_ATTR' in cfg ? addToSet(clone(DEFAULT_URI_SAFE_ATTRIBUTES),
|
|
573
|
-
|
|
554
|
+
URI_SAFE_ATTRIBUTES = 'ADD_URI_SAFE_ATTR' in cfg ? addToSet(clone(DEFAULT_URI_SAFE_ATTRIBUTES),
|
|
555
|
+
// eslint-disable-line indent
|
|
556
|
+
cfg.ADD_URI_SAFE_ATTR,
|
|
557
|
+
// eslint-disable-line indent
|
|
574
558
|
transformCaseFunc // eslint-disable-line indent
|
|
575
559
|
) // eslint-disable-line indent
|
|
576
560
|
: DEFAULT_URI_SAFE_ATTRIBUTES;
|
|
577
|
-
DATA_URI_TAGS = 'ADD_DATA_URI_TAGS' in cfg ? addToSet(clone(DEFAULT_DATA_URI_TAGS),
|
|
578
|
-
|
|
561
|
+
DATA_URI_TAGS = 'ADD_DATA_URI_TAGS' in cfg ? addToSet(clone(DEFAULT_DATA_URI_TAGS),
|
|
562
|
+
// eslint-disable-line indent
|
|
563
|
+
cfg.ADD_DATA_URI_TAGS,
|
|
564
|
+
// eslint-disable-line indent
|
|
579
565
|
transformCaseFunc // eslint-disable-line indent
|
|
580
566
|
) // eslint-disable-line indent
|
|
581
567
|
: DEFAULT_DATA_URI_TAGS;
|
|
@@ -584,250 +570,207 @@ var purify = _commonjsHelpers.createCommonjsModule(function (module, exports) {
|
|
|
584
570
|
FORBID_ATTR = 'FORBID_ATTR' in cfg ? addToSet({}, cfg.FORBID_ATTR, transformCaseFunc) : {};
|
|
585
571
|
USE_PROFILES = 'USE_PROFILES' in cfg ? cfg.USE_PROFILES : false;
|
|
586
572
|
ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false; // Default true
|
|
587
|
-
|
|
588
573
|
ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false; // Default true
|
|
589
|
-
|
|
590
574
|
ALLOW_UNKNOWN_PROTOCOLS = cfg.ALLOW_UNKNOWN_PROTOCOLS || false; // Default false
|
|
591
|
-
|
|
592
575
|
ALLOW_SELF_CLOSE_IN_ATTR = cfg.ALLOW_SELF_CLOSE_IN_ATTR !== false; // Default true
|
|
593
|
-
|
|
594
576
|
SAFE_FOR_TEMPLATES = cfg.SAFE_FOR_TEMPLATES || false; // Default false
|
|
595
|
-
|
|
596
577
|
WHOLE_DOCUMENT = cfg.WHOLE_DOCUMENT || false; // Default false
|
|
597
|
-
|
|
598
578
|
RETURN_DOM = cfg.RETURN_DOM || false; // Default false
|
|
599
|
-
|
|
600
579
|
RETURN_DOM_FRAGMENT = cfg.RETURN_DOM_FRAGMENT || false; // Default false
|
|
601
|
-
|
|
602
580
|
RETURN_TRUSTED_TYPE = cfg.RETURN_TRUSTED_TYPE || false; // Default false
|
|
603
|
-
|
|
604
581
|
FORCE_BODY = cfg.FORCE_BODY || false; // Default false
|
|
605
|
-
|
|
606
582
|
SANITIZE_DOM = cfg.SANITIZE_DOM !== false; // Default true
|
|
607
|
-
|
|
608
583
|
SANITIZE_NAMED_PROPS = cfg.SANITIZE_NAMED_PROPS || false; // Default false
|
|
609
|
-
|
|
610
584
|
KEEP_CONTENT = cfg.KEEP_CONTENT !== false; // Default true
|
|
611
|
-
|
|
612
585
|
IN_PLACE = cfg.IN_PLACE || false; // Default false
|
|
613
|
-
|
|
614
586
|
IS_ALLOWED_URI$1 = cfg.ALLOWED_URI_REGEXP || IS_ALLOWED_URI;
|
|
615
587
|
NAMESPACE = cfg.NAMESPACE || HTML_NAMESPACE;
|
|
616
588
|
CUSTOM_ELEMENT_HANDLING = cfg.CUSTOM_ELEMENT_HANDLING || {};
|
|
617
|
-
|
|
618
589
|
if (cfg.CUSTOM_ELEMENT_HANDLING && isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck)) {
|
|
619
590
|
CUSTOM_ELEMENT_HANDLING.tagNameCheck = cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck;
|
|
620
591
|
}
|
|
621
|
-
|
|
622
592
|
if (cfg.CUSTOM_ELEMENT_HANDLING && isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)) {
|
|
623
593
|
CUSTOM_ELEMENT_HANDLING.attributeNameCheck = cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck;
|
|
624
594
|
}
|
|
625
|
-
|
|
626
595
|
if (cfg.CUSTOM_ELEMENT_HANDLING && typeof cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements === 'boolean') {
|
|
627
596
|
CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements = cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements;
|
|
628
597
|
}
|
|
629
|
-
|
|
630
598
|
if (SAFE_FOR_TEMPLATES) {
|
|
631
599
|
ALLOW_DATA_ATTR = false;
|
|
632
600
|
}
|
|
633
|
-
|
|
634
601
|
if (RETURN_DOM_FRAGMENT) {
|
|
635
602
|
RETURN_DOM = true;
|
|
636
603
|
}
|
|
637
|
-
/* Parse profile info */
|
|
638
|
-
|
|
639
604
|
|
|
605
|
+
/* Parse profile info */
|
|
640
606
|
if (USE_PROFILES) {
|
|
641
|
-
ALLOWED_TAGS = addToSet({},
|
|
607
|
+
ALLOWED_TAGS = addToSet({}, text);
|
|
642
608
|
ALLOWED_ATTR = [];
|
|
643
|
-
|
|
644
609
|
if (USE_PROFILES.html === true) {
|
|
645
610
|
addToSet(ALLOWED_TAGS, html$1);
|
|
646
611
|
addToSet(ALLOWED_ATTR, html);
|
|
647
612
|
}
|
|
648
|
-
|
|
649
613
|
if (USE_PROFILES.svg === true) {
|
|
650
614
|
addToSet(ALLOWED_TAGS, svg$1);
|
|
651
615
|
addToSet(ALLOWED_ATTR, svg);
|
|
652
616
|
addToSet(ALLOWED_ATTR, xml);
|
|
653
617
|
}
|
|
654
|
-
|
|
655
618
|
if (USE_PROFILES.svgFilters === true) {
|
|
656
619
|
addToSet(ALLOWED_TAGS, svgFilters);
|
|
657
620
|
addToSet(ALLOWED_ATTR, svg);
|
|
658
621
|
addToSet(ALLOWED_ATTR, xml);
|
|
659
622
|
}
|
|
660
|
-
|
|
661
623
|
if (USE_PROFILES.mathMl === true) {
|
|
662
624
|
addToSet(ALLOWED_TAGS, mathMl$1);
|
|
663
625
|
addToSet(ALLOWED_ATTR, mathMl);
|
|
664
626
|
addToSet(ALLOWED_ATTR, xml);
|
|
665
627
|
}
|
|
666
628
|
}
|
|
667
|
-
/* Merge configuration parameters */
|
|
668
|
-
|
|
669
629
|
|
|
630
|
+
/* Merge configuration parameters */
|
|
670
631
|
if (cfg.ADD_TAGS) {
|
|
671
632
|
if (ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) {
|
|
672
633
|
ALLOWED_TAGS = clone(ALLOWED_TAGS);
|
|
673
634
|
}
|
|
674
|
-
|
|
675
635
|
addToSet(ALLOWED_TAGS, cfg.ADD_TAGS, transformCaseFunc);
|
|
676
636
|
}
|
|
677
|
-
|
|
678
637
|
if (cfg.ADD_ATTR) {
|
|
679
638
|
if (ALLOWED_ATTR === DEFAULT_ALLOWED_ATTR) {
|
|
680
639
|
ALLOWED_ATTR = clone(ALLOWED_ATTR);
|
|
681
640
|
}
|
|
682
|
-
|
|
683
641
|
addToSet(ALLOWED_ATTR, cfg.ADD_ATTR, transformCaseFunc);
|
|
684
642
|
}
|
|
685
|
-
|
|
686
643
|
if (cfg.ADD_URI_SAFE_ATTR) {
|
|
687
644
|
addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR, transformCaseFunc);
|
|
688
645
|
}
|
|
689
|
-
|
|
690
646
|
if (cfg.FORBID_CONTENTS) {
|
|
691
647
|
if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) {
|
|
692
648
|
FORBID_CONTENTS = clone(FORBID_CONTENTS);
|
|
693
649
|
}
|
|
694
|
-
|
|
695
650
|
addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS, transformCaseFunc);
|
|
696
651
|
}
|
|
697
|
-
/* Add #text in case KEEP_CONTENT is set to true */
|
|
698
|
-
|
|
699
652
|
|
|
653
|
+
/* Add #text in case KEEP_CONTENT is set to true */
|
|
700
654
|
if (KEEP_CONTENT) {
|
|
701
655
|
ALLOWED_TAGS['#text'] = true;
|
|
702
656
|
}
|
|
703
|
-
/* Add html, head and body to ALLOWED_TAGS in case WHOLE_DOCUMENT is true */
|
|
704
|
-
|
|
705
657
|
|
|
658
|
+
/* Add html, head and body to ALLOWED_TAGS in case WHOLE_DOCUMENT is true */
|
|
706
659
|
if (WHOLE_DOCUMENT) {
|
|
707
660
|
addToSet(ALLOWED_TAGS, ['html', 'head', 'body']);
|
|
708
661
|
}
|
|
709
|
-
/* Add tbody to ALLOWED_TAGS in case tables are permitted, see #286, #365 */
|
|
710
|
-
|
|
711
662
|
|
|
663
|
+
/* Add tbody to ALLOWED_TAGS in case tables are permitted, see #286, #365 */
|
|
712
664
|
if (ALLOWED_TAGS.table) {
|
|
713
665
|
addToSet(ALLOWED_TAGS, ['tbody']);
|
|
714
666
|
delete FORBID_TAGS.tbody;
|
|
715
667
|
}
|
|
716
|
-
|
|
717
668
|
if (cfg.TRUSTED_TYPES_POLICY) {
|
|
718
669
|
if (typeof cfg.TRUSTED_TYPES_POLICY.createHTML !== 'function') {
|
|
719
670
|
throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a "createHTML" hook.');
|
|
720
671
|
}
|
|
721
|
-
|
|
722
672
|
if (typeof cfg.TRUSTED_TYPES_POLICY.createScriptURL !== 'function') {
|
|
723
673
|
throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.');
|
|
724
|
-
}
|
|
725
|
-
|
|
674
|
+
}
|
|
726
675
|
|
|
727
|
-
|
|
676
|
+
// Overwrite existing TrustedTypes policy.
|
|
677
|
+
trustedTypesPolicy = cfg.TRUSTED_TYPES_POLICY;
|
|
728
678
|
|
|
679
|
+
// Sign local variables required by `sanitize`.
|
|
729
680
|
emptyHTML = trustedTypesPolicy.createHTML('');
|
|
730
681
|
} else {
|
|
731
682
|
// Uninitialized policy, attempt to initialize the internal dompurify policy.
|
|
732
683
|
if (trustedTypesPolicy === undefined) {
|
|
733
684
|
trustedTypesPolicy = _createTrustedTypesPolicy(trustedTypes, currentScript);
|
|
734
|
-
}
|
|
735
|
-
|
|
685
|
+
}
|
|
736
686
|
|
|
687
|
+
// If creating the internal policy succeeded sign internal variables.
|
|
737
688
|
if (trustedTypesPolicy !== null && typeof emptyHTML === 'string') {
|
|
738
689
|
emptyHTML = trustedTypesPolicy.createHTML('');
|
|
739
690
|
}
|
|
740
|
-
}
|
|
741
|
-
// Not available in IE8, Safari 5, etc.
|
|
742
|
-
|
|
691
|
+
}
|
|
743
692
|
|
|
693
|
+
// Prevent further manipulation of configuration.
|
|
694
|
+
// Not available in IE8, Safari 5, etc.
|
|
744
695
|
if (freeze) {
|
|
745
696
|
freeze(cfg);
|
|
746
697
|
}
|
|
747
|
-
|
|
748
698
|
CONFIG = cfg;
|
|
749
699
|
};
|
|
750
|
-
|
|
751
700
|
const MATHML_TEXT_INTEGRATION_POINTS = addToSet({}, ['mi', 'mo', 'mn', 'ms', 'mtext']);
|
|
752
|
-
const HTML_INTEGRATION_POINTS = addToSet({}, ['foreignobject', 'desc', 'title', 'annotation-xml']);
|
|
701
|
+
const HTML_INTEGRATION_POINTS = addToSet({}, ['foreignobject', 'desc', 'title', 'annotation-xml']);
|
|
702
|
+
|
|
703
|
+
// Certain elements are allowed in both SVG and HTML
|
|
753
704
|
// namespace. We need to specify them explicitly
|
|
754
705
|
// so that they don't get erroneously deleted from
|
|
755
706
|
// HTML namespace.
|
|
756
|
-
|
|
757
707
|
const COMMON_SVG_AND_HTML_ELEMENTS = addToSet({}, ['title', 'style', 'font', 'a', 'script']);
|
|
708
|
+
|
|
758
709
|
/* Keep track of all possible SVG and MathML tags
|
|
759
710
|
* so that we can perform the namespace checks
|
|
760
711
|
* correctly. */
|
|
712
|
+
const ALL_SVG_TAGS = addToSet({}, [...svg$1, ...svgFilters, ...svgDisallowed]);
|
|
713
|
+
const ALL_MATHML_TAGS = addToSet({}, [...mathMl$1, ...mathMlDisallowed]);
|
|
761
714
|
|
|
762
|
-
const ALL_SVG_TAGS = addToSet({}, svg$1);
|
|
763
|
-
addToSet(ALL_SVG_TAGS, svgFilters);
|
|
764
|
-
addToSet(ALL_SVG_TAGS, svgDisallowed);
|
|
765
|
-
const ALL_MATHML_TAGS = addToSet({}, mathMl$1);
|
|
766
|
-
addToSet(ALL_MATHML_TAGS, mathMlDisallowed);
|
|
767
715
|
/**
|
|
768
716
|
* @param {Element} element a DOM element whose namespace is being checked
|
|
769
717
|
* @returns {boolean} Return false if the element has a
|
|
770
718
|
* namespace that a spec-compliant parser would never
|
|
771
719
|
* return. Return true otherwise.
|
|
772
720
|
*/
|
|
773
|
-
|
|
774
721
|
const _checkValidNamespace = function _checkValidNamespace(element) {
|
|
775
|
-
let parent = getParentNode(element);
|
|
776
|
-
// can be null. We just simulate parent in this case.
|
|
722
|
+
let parent = getParentNode(element);
|
|
777
723
|
|
|
724
|
+
// In JSDOM, if we're inside shadow DOM, then parentNode
|
|
725
|
+
// can be null. We just simulate parent in this case.
|
|
778
726
|
if (!parent || !parent.tagName) {
|
|
779
727
|
parent = {
|
|
780
728
|
namespaceURI: NAMESPACE,
|
|
781
729
|
tagName: 'template'
|
|
782
730
|
};
|
|
783
731
|
}
|
|
784
|
-
|
|
785
732
|
const tagName = stringToLowerCase(element.tagName);
|
|
786
733
|
const parentTagName = stringToLowerCase(parent.tagName);
|
|
787
|
-
|
|
788
734
|
if (!ALLOWED_NAMESPACES[element.namespaceURI]) {
|
|
789
735
|
return false;
|
|
790
736
|
}
|
|
791
|
-
|
|
792
737
|
if (element.namespaceURI === SVG_NAMESPACE) {
|
|
793
738
|
// The only way to switch from HTML namespace to SVG
|
|
794
739
|
// is via <svg>. If it happens via any other tag, then
|
|
795
740
|
// it should be killed.
|
|
796
741
|
if (parent.namespaceURI === HTML_NAMESPACE) {
|
|
797
742
|
return tagName === 'svg';
|
|
798
|
-
}
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
// The only way to switch from MathML to SVG is via`
|
|
799
746
|
// svg if parent is either <annotation-xml> or MathML
|
|
800
747
|
// text integration points.
|
|
801
|
-
|
|
802
|
-
|
|
803
748
|
if (parent.namespaceURI === MATHML_NAMESPACE) {
|
|
804
749
|
return tagName === 'svg' && (parentTagName === 'annotation-xml' || MATHML_TEXT_INTEGRATION_POINTS[parentTagName]);
|
|
805
|
-
}
|
|
806
|
-
// spec. All others are disallowed in SVG namespace.
|
|
807
|
-
|
|
750
|
+
}
|
|
808
751
|
|
|
752
|
+
// We only allow elements that are defined in SVG
|
|
753
|
+
// spec. All others are disallowed in SVG namespace.
|
|
809
754
|
return Boolean(ALL_SVG_TAGS[tagName]);
|
|
810
755
|
}
|
|
811
|
-
|
|
812
756
|
if (element.namespaceURI === MATHML_NAMESPACE) {
|
|
813
757
|
// The only way to switch from HTML namespace to MathML
|
|
814
758
|
// is via <math>. If it happens via any other tag, then
|
|
815
759
|
// it should be killed.
|
|
816
760
|
if (parent.namespaceURI === HTML_NAMESPACE) {
|
|
817
761
|
return tagName === 'math';
|
|
818
|
-
}
|
|
819
|
-
// <math> and HTML integration points
|
|
820
|
-
|
|
762
|
+
}
|
|
821
763
|
|
|
764
|
+
// The only way to switch from SVG to MathML is via
|
|
765
|
+
// <math> and HTML integration points
|
|
822
766
|
if (parent.namespaceURI === SVG_NAMESPACE) {
|
|
823
767
|
return tagName === 'math' && HTML_INTEGRATION_POINTS[parentTagName];
|
|
824
|
-
}
|
|
825
|
-
// spec. All others are disallowed in MathML namespace.
|
|
826
|
-
|
|
768
|
+
}
|
|
827
769
|
|
|
770
|
+
// We only allow elements that are defined in MathML
|
|
771
|
+
// spec. All others are disallowed in MathML namespace.
|
|
828
772
|
return Boolean(ALL_MATHML_TAGS[tagName]);
|
|
829
773
|
}
|
|
830
|
-
|
|
831
774
|
if (element.namespaceURI === HTML_NAMESPACE) {
|
|
832
775
|
// The only way to switch from SVG to HTML is via
|
|
833
776
|
// HTML integration points, and from MathML to HTML
|
|
@@ -835,39 +778,36 @@ var purify = _commonjsHelpers.createCommonjsModule(function (module, exports) {
|
|
|
835
778
|
if (parent.namespaceURI === SVG_NAMESPACE && !HTML_INTEGRATION_POINTS[parentTagName]) {
|
|
836
779
|
return false;
|
|
837
780
|
}
|
|
838
|
-
|
|
839
781
|
if (parent.namespaceURI === MATHML_NAMESPACE && !MATHML_TEXT_INTEGRATION_POINTS[parentTagName]) {
|
|
840
782
|
return false;
|
|
841
|
-
}
|
|
842
|
-
// or SVG and should never appear in HTML namespace
|
|
843
|
-
|
|
783
|
+
}
|
|
844
784
|
|
|
785
|
+
// We disallow tags that are specific for MathML
|
|
786
|
+
// or SVG and should never appear in HTML namespace
|
|
845
787
|
return !ALL_MATHML_TAGS[tagName] && (COMMON_SVG_AND_HTML_ELEMENTS[tagName] || !ALL_SVG_TAGS[tagName]);
|
|
846
|
-
}
|
|
847
|
-
|
|
788
|
+
}
|
|
848
789
|
|
|
790
|
+
// For XHTML and XML documents that support custom namespaces
|
|
849
791
|
if (PARSER_MEDIA_TYPE === 'application/xhtml+xml' && ALLOWED_NAMESPACES[element.namespaceURI]) {
|
|
850
792
|
return true;
|
|
851
|
-
}
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
// The code should never reach this place (this means
|
|
852
796
|
// that the element somehow got namespace that is not
|
|
853
797
|
// HTML, SVG, MathML or allowed via ALLOWED_NAMESPACES).
|
|
854
798
|
// Return false just in case.
|
|
855
|
-
|
|
856
|
-
|
|
857
799
|
return false;
|
|
858
800
|
};
|
|
801
|
+
|
|
859
802
|
/**
|
|
860
803
|
* _forceRemove
|
|
861
804
|
*
|
|
862
805
|
* @param {Node} node a DOM node
|
|
863
806
|
*/
|
|
864
|
-
|
|
865
|
-
|
|
866
807
|
const _forceRemove = function _forceRemove(node) {
|
|
867
808
|
arrayPush(DOMPurify.removed, {
|
|
868
809
|
element: node
|
|
869
810
|
});
|
|
870
|
-
|
|
871
811
|
try {
|
|
872
812
|
// eslint-disable-next-line unicorn/prefer-dom-node-remove
|
|
873
813
|
node.parentNode.removeChild(node);
|
|
@@ -875,14 +815,13 @@ var purify = _commonjsHelpers.createCommonjsModule(function (module, exports) {
|
|
|
875
815
|
node.remove();
|
|
876
816
|
}
|
|
877
817
|
};
|
|
818
|
+
|
|
878
819
|
/**
|
|
879
820
|
* _removeAttribute
|
|
880
821
|
*
|
|
881
822
|
* @param {String} name an Attribute name
|
|
882
823
|
* @param {Node} node a DOM node
|
|
883
824
|
*/
|
|
884
|
-
|
|
885
|
-
|
|
886
825
|
const _removeAttribute = function _removeAttribute(name, node) {
|
|
887
826
|
try {
|
|
888
827
|
arrayPush(DOMPurify.removed, {
|
|
@@ -895,9 +834,9 @@ var purify = _commonjsHelpers.createCommonjsModule(function (module, exports) {
|
|
|
895
834
|
from: node
|
|
896
835
|
});
|
|
897
836
|
}
|
|
837
|
+
node.removeAttribute(name);
|
|
898
838
|
|
|
899
|
-
|
|
900
|
-
|
|
839
|
+
// We void attribute values for unremovable "is"" attributes
|
|
901
840
|
if (name === 'is' && !ALLOWED_ATTR[name]) {
|
|
902
841
|
if (RETURN_DOM || RETURN_DOM_FRAGMENT) {
|
|
903
842
|
try {
|
|
@@ -910,19 +849,17 @@ var purify = _commonjsHelpers.createCommonjsModule(function (module, exports) {
|
|
|
910
849
|
}
|
|
911
850
|
}
|
|
912
851
|
};
|
|
852
|
+
|
|
913
853
|
/**
|
|
914
854
|
* _initDocument
|
|
915
855
|
*
|
|
916
856
|
* @param {String} dirty a string of dirty markup
|
|
917
857
|
* @return {Document} a DOM, filled with the dirty markup
|
|
918
858
|
*/
|
|
919
|
-
|
|
920
|
-
|
|
921
859
|
const _initDocument = function _initDocument(dirty) {
|
|
922
860
|
/* Create a HTML document */
|
|
923
861
|
let doc = null;
|
|
924
862
|
let leadingWhitespace = null;
|
|
925
|
-
|
|
926
863
|
if (FORCE_BODY) {
|
|
927
864
|
dirty = '<remove></remove>' + dirty;
|
|
928
865
|
} else {
|
|
@@ -930,83 +867,74 @@ var purify = _commonjsHelpers.createCommonjsModule(function (module, exports) {
|
|
|
930
867
|
const matches = stringMatch(dirty, /^[\r\n\t ]+/);
|
|
931
868
|
leadingWhitespace = matches && matches[0];
|
|
932
869
|
}
|
|
933
|
-
|
|
934
870
|
if (PARSER_MEDIA_TYPE === 'application/xhtml+xml' && NAMESPACE === HTML_NAMESPACE) {
|
|
935
871
|
// Root of XHTML doc must contain xmlns declaration (see https://www.w3.org/TR/xhtml1/normative.html#strict)
|
|
936
872
|
dirty = '<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body>' + dirty + '</body></html>';
|
|
937
873
|
}
|
|
938
|
-
|
|
939
874
|
const dirtyPayload = trustedTypesPolicy ? trustedTypesPolicy.createHTML(dirty) : dirty;
|
|
940
875
|
/*
|
|
941
876
|
* Use the DOMParser API by default, fallback later if needs be
|
|
942
877
|
* DOMParser not work for svg when has multiple root element.
|
|
943
878
|
*/
|
|
944
|
-
|
|
945
879
|
if (NAMESPACE === HTML_NAMESPACE) {
|
|
946
880
|
try {
|
|
947
881
|
doc = new DOMParser().parseFromString(dirtyPayload, PARSER_MEDIA_TYPE);
|
|
948
882
|
} catch (_) {}
|
|
949
883
|
}
|
|
950
|
-
/* Use createHTMLDocument in case DOMParser is not available */
|
|
951
|
-
|
|
952
884
|
|
|
885
|
+
/* Use createHTMLDocument in case DOMParser is not available */
|
|
953
886
|
if (!doc || !doc.documentElement) {
|
|
954
887
|
doc = implementation.createDocument(NAMESPACE, 'template', null);
|
|
955
|
-
|
|
956
888
|
try {
|
|
957
889
|
doc.documentElement.innerHTML = IS_EMPTY_INPUT ? emptyHTML : dirtyPayload;
|
|
958
|
-
} catch (_) {
|
|
890
|
+
} catch (_) {
|
|
891
|
+
// Syntax error if dirtyPayload is invalid xml
|
|
959
892
|
}
|
|
960
893
|
}
|
|
961
|
-
|
|
962
894
|
const body = doc.body || doc.documentElement;
|
|
963
|
-
|
|
964
895
|
if (dirty && leadingWhitespace) {
|
|
965
896
|
body.insertBefore(document.createTextNode(leadingWhitespace), body.childNodes[0] || null);
|
|
966
897
|
}
|
|
967
|
-
/* Work on whole document or just its body */
|
|
968
|
-
|
|
969
898
|
|
|
899
|
+
/* Work on whole document or just its body */
|
|
970
900
|
if (NAMESPACE === HTML_NAMESPACE) {
|
|
971
901
|
return getElementsByTagName.call(doc, WHOLE_DOCUMENT ? 'html' : 'body')[0];
|
|
972
902
|
}
|
|
973
|
-
|
|
974
903
|
return WHOLE_DOCUMENT ? doc.documentElement : body;
|
|
975
904
|
};
|
|
905
|
+
|
|
976
906
|
/**
|
|
977
907
|
* Creates a NodeIterator object that you can use to traverse filtered lists of nodes or elements in a document.
|
|
978
908
|
*
|
|
979
909
|
* @param {Node} root The root element or node to start traversing on.
|
|
980
910
|
* @return {NodeIterator} The created NodeIterator
|
|
981
911
|
*/
|
|
982
|
-
|
|
983
|
-
|
|
984
912
|
const _createNodeIterator = function _createNodeIterator(root) {
|
|
985
|
-
return createNodeIterator.call(root.ownerDocument || root, root,
|
|
913
|
+
return createNodeIterator.call(root.ownerDocument || root, root,
|
|
914
|
+
// eslint-disable-next-line no-bitwise
|
|
986
915
|
NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT, null);
|
|
987
916
|
};
|
|
917
|
+
|
|
988
918
|
/**
|
|
989
919
|
* _isClobbered
|
|
990
920
|
*
|
|
991
921
|
* @param {Node} elm element to check for clobbering attacks
|
|
992
922
|
* @return {Boolean} true if clobbered, false if safe
|
|
993
923
|
*/
|
|
994
|
-
|
|
995
|
-
|
|
996
924
|
const _isClobbered = function _isClobbered(elm) {
|
|
997
925
|
return elm instanceof HTMLFormElement && (typeof elm.nodeName !== 'string' || typeof elm.textContent !== 'string' || typeof elm.removeChild !== 'function' || !(elm.attributes instanceof NamedNodeMap) || typeof elm.removeAttribute !== 'function' || typeof elm.setAttribute !== 'function' || typeof elm.namespaceURI !== 'string' || typeof elm.insertBefore !== 'function' || typeof elm.hasChildNodes !== 'function');
|
|
998
926
|
};
|
|
927
|
+
|
|
999
928
|
/**
|
|
1000
929
|
* Checks whether the given object is a DOM node.
|
|
1001
930
|
*
|
|
1002
931
|
* @param {Node} object object to check whether it's a DOM node
|
|
1003
932
|
* @return {Boolean} true is object is a DOM node
|
|
1004
933
|
*/
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
934
|
const _isNode = function _isNode(object) {
|
|
1008
935
|
return typeof Node === 'function' && object instanceof Node;
|
|
1009
936
|
};
|
|
937
|
+
|
|
1010
938
|
/**
|
|
1011
939
|
* _executeHook
|
|
1012
940
|
* Execute user configurable hooks
|
|
@@ -1015,17 +943,15 @@ var purify = _commonjsHelpers.createCommonjsModule(function (module, exports) {
|
|
|
1015
943
|
* @param {Node} currentNode node to work on with the hook
|
|
1016
944
|
* @param {Object} data additional hook parameters
|
|
1017
945
|
*/
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
946
|
const _executeHook = function _executeHook(entryPoint, currentNode, data) {
|
|
1021
947
|
if (!hooks[entryPoint]) {
|
|
1022
948
|
return;
|
|
1023
949
|
}
|
|
1024
|
-
|
|
1025
950
|
arrayForEach(hooks[entryPoint], hook => {
|
|
1026
951
|
hook.call(DOMPurify, currentNode, data, CONFIG);
|
|
1027
952
|
});
|
|
1028
953
|
};
|
|
954
|
+
|
|
1029
955
|
/**
|
|
1030
956
|
* _sanitizeElements
|
|
1031
957
|
*
|
|
@@ -1036,99 +962,79 @@ var purify = _commonjsHelpers.createCommonjsModule(function (module, exports) {
|
|
|
1036
962
|
* @param {Node} currentNode to check for permission to exist
|
|
1037
963
|
* @return {Boolean} true if node was killed, false if left alive
|
|
1038
964
|
*/
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
965
|
const _sanitizeElements = function _sanitizeElements(currentNode) {
|
|
1042
966
|
let content = null;
|
|
1043
|
-
/* Execute a hook if present */
|
|
1044
967
|
|
|
968
|
+
/* Execute a hook if present */
|
|
1045
969
|
_executeHook('beforeSanitizeElements', currentNode, null);
|
|
1046
|
-
/* Check if element is clobbered or can clobber */
|
|
1047
|
-
|
|
1048
970
|
|
|
971
|
+
/* Check if element is clobbered or can clobber */
|
|
1049
972
|
if (_isClobbered(currentNode)) {
|
|
1050
973
|
_forceRemove(currentNode);
|
|
1051
|
-
|
|
1052
974
|
return true;
|
|
1053
975
|
}
|
|
1054
|
-
/* Now let's check the element's type and name */
|
|
1055
|
-
|
|
1056
976
|
|
|
977
|
+
/* Now let's check the element's type and name */
|
|
1057
978
|
const tagName = transformCaseFunc(currentNode.nodeName);
|
|
1058
|
-
/* Execute a hook if present */
|
|
1059
979
|
|
|
980
|
+
/* Execute a hook if present */
|
|
1060
981
|
_executeHook('uponSanitizeElement', currentNode, {
|
|
1061
982
|
tagName,
|
|
1062
983
|
allowedTags: ALLOWED_TAGS
|
|
1063
984
|
});
|
|
1064
|
-
/* Detect mXSS attempts abusing namespace confusion */
|
|
1065
|
-
|
|
1066
985
|
|
|
986
|
+
/* Detect mXSS attempts abusing namespace confusion */
|
|
1067
987
|
if (currentNode.hasChildNodes() && !_isNode(currentNode.firstElementChild) && regExpTest(/<[/\w]/g, currentNode.innerHTML) && regExpTest(/<[/\w]/g, currentNode.textContent)) {
|
|
1068
988
|
_forceRemove(currentNode);
|
|
1069
|
-
|
|
1070
989
|
return true;
|
|
1071
990
|
}
|
|
1072
|
-
/* Remove element if anything forbids its presence */
|
|
1073
|
-
|
|
1074
991
|
|
|
992
|
+
/* Remove element if anything forbids its presence */
|
|
1075
993
|
if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {
|
|
1076
994
|
/* Check if we have a custom element to handle */
|
|
1077
995
|
if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName)) {
|
|
1078
996
|
if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)) {
|
|
1079
997
|
return false;
|
|
1080
998
|
}
|
|
1081
|
-
|
|
1082
999
|
if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName)) {
|
|
1083
1000
|
return false;
|
|
1084
1001
|
}
|
|
1085
1002
|
}
|
|
1086
|
-
/* Keep content except for bad-listed elements */
|
|
1087
|
-
|
|
1088
1003
|
|
|
1004
|
+
/* Keep content except for bad-listed elements */
|
|
1089
1005
|
if (KEEP_CONTENT && !FORBID_CONTENTS[tagName]) {
|
|
1090
1006
|
const parentNode = getParentNode(currentNode) || currentNode.parentNode;
|
|
1091
1007
|
const childNodes = getChildNodes(currentNode) || currentNode.childNodes;
|
|
1092
|
-
|
|
1093
1008
|
if (childNodes && parentNode) {
|
|
1094
1009
|
const childCount = childNodes.length;
|
|
1095
|
-
|
|
1096
1010
|
for (let i = childCount - 1; i >= 0; --i) {
|
|
1097
1011
|
parentNode.insertBefore(cloneNode(childNodes[i], true), getNextSibling(currentNode));
|
|
1098
1012
|
}
|
|
1099
1013
|
}
|
|
1100
1014
|
}
|
|
1101
|
-
|
|
1102
1015
|
_forceRemove(currentNode);
|
|
1103
|
-
|
|
1104
1016
|
return true;
|
|
1105
1017
|
}
|
|
1106
|
-
/* Check whether element has a valid namespace */
|
|
1107
|
-
|
|
1108
1018
|
|
|
1019
|
+
/* Check whether element has a valid namespace */
|
|
1109
1020
|
if (currentNode instanceof Element && !_checkValidNamespace(currentNode)) {
|
|
1110
1021
|
_forceRemove(currentNode);
|
|
1111
|
-
|
|
1112
1022
|
return true;
|
|
1113
1023
|
}
|
|
1114
|
-
/* Make sure that older browsers don't get fallback-tag mXSS */
|
|
1115
|
-
|
|
1116
1024
|
|
|
1025
|
+
/* Make sure that older browsers don't get fallback-tag mXSS */
|
|
1117
1026
|
if ((tagName === 'noscript' || tagName === 'noembed' || tagName === 'noframes') && regExpTest(/<\/no(script|embed|frames)/i, currentNode.innerHTML)) {
|
|
1118
1027
|
_forceRemove(currentNode);
|
|
1119
|
-
|
|
1120
1028
|
return true;
|
|
1121
1029
|
}
|
|
1122
|
-
/* Sanitize element content to be template-safe */
|
|
1123
|
-
|
|
1124
1030
|
|
|
1031
|
+
/* Sanitize element content to be template-safe */
|
|
1125
1032
|
if (SAFE_FOR_TEMPLATES && currentNode.nodeType === 3) {
|
|
1126
1033
|
/* Get the element's text content */
|
|
1127
1034
|
content = currentNode.textContent;
|
|
1128
1035
|
arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {
|
|
1129
1036
|
content = stringReplace(content, expr, ' ');
|
|
1130
1037
|
});
|
|
1131
|
-
|
|
1132
1038
|
if (currentNode.textContent !== content) {
|
|
1133
1039
|
arrayPush(DOMPurify.removed, {
|
|
1134
1040
|
element: currentNode.cloneNode()
|
|
@@ -1136,13 +1042,12 @@ var purify = _commonjsHelpers.createCommonjsModule(function (module, exports) {
|
|
|
1136
1042
|
currentNode.textContent = content;
|
|
1137
1043
|
}
|
|
1138
1044
|
}
|
|
1139
|
-
/* Execute a hook if present */
|
|
1140
|
-
|
|
1141
1045
|
|
|
1046
|
+
/* Execute a hook if present */
|
|
1142
1047
|
_executeHook('afterSanitizeElements', currentNode, null);
|
|
1143
|
-
|
|
1144
1048
|
return false;
|
|
1145
1049
|
};
|
|
1050
|
+
|
|
1146
1051
|
/**
|
|
1147
1052
|
* _isValidAttribute
|
|
1148
1053
|
*
|
|
@@ -1152,36 +1057,34 @@ var purify = _commonjsHelpers.createCommonjsModule(function (module, exports) {
|
|
|
1152
1057
|
* @return {Boolean} Returns true if `value` is valid, otherwise false.
|
|
1153
1058
|
*/
|
|
1154
1059
|
// eslint-disable-next-line complexity
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
1060
|
const _isValidAttribute = function _isValidAttribute(lcTag, lcName, value) {
|
|
1158
1061
|
/* Make sure attribute cannot clobber */
|
|
1159
1062
|
if (SANITIZE_DOM && (lcName === 'id' || lcName === 'name') && (value in document || value in formElement)) {
|
|
1160
1063
|
return false;
|
|
1161
1064
|
}
|
|
1065
|
+
|
|
1162
1066
|
/* Allow valid data-* attributes: At least one character after "-"
|
|
1163
1067
|
(https://html.spec.whatwg.org/multipage/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes)
|
|
1164
1068
|
XML-compatible (https://html.spec.whatwg.org/multipage/infrastructure.html#xml-compatible and http://www.w3.org/TR/xml/#d0e804)
|
|
1165
1069
|
We don't need to check the value; it's always URI safe. */
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
1070
|
if (ALLOW_DATA_ATTR && !FORBID_ATTR[lcName] && regExpTest(DATA_ATTR, lcName)) ; else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR, lcName)) ; else if (!ALLOWED_ATTR[lcName] || FORBID_ATTR[lcName]) {
|
|
1169
|
-
if (
|
|
1071
|
+
if (
|
|
1072
|
+
// First condition does a very basic check if a) it's basically a valid custom element tagname AND
|
|
1170
1073
|
// b) if the tagName passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck
|
|
1171
1074
|
// and c) if the attribute name passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.attributeNameCheck
|
|
1172
|
-
_isBasicCustomElement(lcTag) && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, lcTag) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(lcTag)) && (CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.attributeNameCheck, lcName) || CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.attributeNameCheck(lcName)) ||
|
|
1075
|
+
_isBasicCustomElement(lcTag) && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, lcTag) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(lcTag)) && (CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.attributeNameCheck, lcName) || CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.attributeNameCheck(lcName)) ||
|
|
1076
|
+
// Alternative, second condition checks if it's an `is`-attribute, AND
|
|
1173
1077
|
// the value passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck
|
|
1174
1078
|
lcName === 'is' && CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, value) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(value))) ; else {
|
|
1175
1079
|
return false;
|
|
1176
1080
|
}
|
|
1177
1081
|
/* Check value is safe. First, is attr inert? If so, is safe */
|
|
1178
|
-
|
|
1179
1082
|
} else if (URI_SAFE_ATTRIBUTES[lcName]) ; else if (regExpTest(IS_ALLOWED_URI$1, stringReplace(value, ATTR_WHITESPACE, ''))) ; else if ((lcName === 'src' || lcName === 'xlink:href' || lcName === 'href') && lcTag !== 'script' && stringIndexOf(value, 'data:') === 0 && DATA_URI_TAGS[lcTag]) ; else if (ALLOW_UNKNOWN_PROTOCOLS && !regExpTest(IS_SCRIPT_OR_DATA, stringReplace(value, ATTR_WHITESPACE, ''))) ; else if (value) {
|
|
1180
1083
|
return false;
|
|
1181
1084
|
} else ;
|
|
1182
|
-
|
|
1183
1085
|
return true;
|
|
1184
1086
|
};
|
|
1087
|
+
|
|
1185
1088
|
/**
|
|
1186
1089
|
* _isBasicCustomElement
|
|
1187
1090
|
* checks if at least one dash is included in tagName, and it's not the first char
|
|
@@ -1190,11 +1093,10 @@ var purify = _commonjsHelpers.createCommonjsModule(function (module, exports) {
|
|
|
1190
1093
|
* @param {string} tagName name of the tag of the node to sanitize
|
|
1191
1094
|
* @returns {boolean} Returns true if the tag name meets the basic criteria for a custom element, otherwise false.
|
|
1192
1095
|
*/
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
1096
|
const _isBasicCustomElement = function _isBasicCustomElement(tagName) {
|
|
1196
1097
|
return tagName.indexOf('-') > 0;
|
|
1197
1098
|
};
|
|
1099
|
+
|
|
1198
1100
|
/**
|
|
1199
1101
|
* _sanitizeAttributes
|
|
1200
1102
|
*
|
|
@@ -1205,21 +1107,17 @@ var purify = _commonjsHelpers.createCommonjsModule(function (module, exports) {
|
|
|
1205
1107
|
*
|
|
1206
1108
|
* @param {Node} currentNode to sanitize
|
|
1207
1109
|
*/
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
1110
|
const _sanitizeAttributes = function _sanitizeAttributes(currentNode) {
|
|
1211
1111
|
/* Execute a hook if present */
|
|
1212
1112
|
_executeHook('beforeSanitizeAttributes', currentNode, null);
|
|
1213
|
-
|
|
1214
1113
|
const {
|
|
1215
1114
|
attributes
|
|
1216
1115
|
} = currentNode;
|
|
1217
|
-
/* Check if we have attributes; if not we might have a text node */
|
|
1218
1116
|
|
|
1117
|
+
/* Check if we have attributes; if not we might have a text node */
|
|
1219
1118
|
if (!attributes) {
|
|
1220
1119
|
return;
|
|
1221
1120
|
}
|
|
1222
|
-
|
|
1223
1121
|
const hookEvent = {
|
|
1224
1122
|
attrName: '',
|
|
1225
1123
|
attrValue: '',
|
|
@@ -1227,8 +1125,8 @@ var purify = _commonjsHelpers.createCommonjsModule(function (module, exports) {
|
|
|
1227
1125
|
allowedAttributes: ALLOWED_ATTR
|
|
1228
1126
|
};
|
|
1229
1127
|
let l = attributes.length;
|
|
1230
|
-
/* Go backwards over all attributes; safely remove bad ones */
|
|
1231
1128
|
|
|
1129
|
+
/* Go backwards over all attributes; safely remove bad ones */
|
|
1232
1130
|
while (l--) {
|
|
1233
1131
|
const attr = attributes[l];
|
|
1234
1132
|
const {
|
|
@@ -1238,70 +1136,58 @@ var purify = _commonjsHelpers.createCommonjsModule(function (module, exports) {
|
|
|
1238
1136
|
} = attr;
|
|
1239
1137
|
const lcName = transformCaseFunc(name);
|
|
1240
1138
|
let value = name === 'value' ? attrValue : stringTrim(attrValue);
|
|
1241
|
-
/* Execute a hook if present */
|
|
1242
1139
|
|
|
1140
|
+
/* Execute a hook if present */
|
|
1243
1141
|
hookEvent.attrName = lcName;
|
|
1244
1142
|
hookEvent.attrValue = value;
|
|
1245
1143
|
hookEvent.keepAttr = true;
|
|
1246
1144
|
hookEvent.forceKeepAttr = undefined; // Allows developers to see this is a property they can set
|
|
1247
|
-
|
|
1248
1145
|
_executeHook('uponSanitizeAttribute', currentNode, hookEvent);
|
|
1249
|
-
|
|
1250
1146
|
value = hookEvent.attrValue;
|
|
1251
1147
|
/* Did the hooks approve of the attribute? */
|
|
1252
|
-
|
|
1253
1148
|
if (hookEvent.forceKeepAttr) {
|
|
1254
1149
|
continue;
|
|
1255
1150
|
}
|
|
1256
|
-
/* Remove attribute */
|
|
1257
|
-
|
|
1258
1151
|
|
|
1152
|
+
/* Remove attribute */
|
|
1259
1153
|
_removeAttribute(name, currentNode);
|
|
1260
|
-
/* Did the hooks approve of the attribute? */
|
|
1261
|
-
|
|
1262
1154
|
|
|
1155
|
+
/* Did the hooks approve of the attribute? */
|
|
1263
1156
|
if (!hookEvent.keepAttr) {
|
|
1264
1157
|
continue;
|
|
1265
1158
|
}
|
|
1266
|
-
/* Work around a security issue in jQuery 3.0 */
|
|
1267
|
-
|
|
1268
1159
|
|
|
1160
|
+
/* Work around a security issue in jQuery 3.0 */
|
|
1269
1161
|
if (!ALLOW_SELF_CLOSE_IN_ATTR && regExpTest(/\/>/i, value)) {
|
|
1270
1162
|
_removeAttribute(name, currentNode);
|
|
1271
|
-
|
|
1272
1163
|
continue;
|
|
1273
1164
|
}
|
|
1274
|
-
/* Sanitize attribute content to be template-safe */
|
|
1275
|
-
|
|
1276
1165
|
|
|
1166
|
+
/* Sanitize attribute content to be template-safe */
|
|
1277
1167
|
if (SAFE_FOR_TEMPLATES) {
|
|
1278
1168
|
arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {
|
|
1279
1169
|
value = stringReplace(value, expr, ' ');
|
|
1280
1170
|
});
|
|
1281
1171
|
}
|
|
1282
|
-
/* Is `value` valid for this attribute? */
|
|
1283
|
-
|
|
1284
1172
|
|
|
1173
|
+
/* Is `value` valid for this attribute? */
|
|
1285
1174
|
const lcTag = transformCaseFunc(currentNode.nodeName);
|
|
1286
|
-
|
|
1287
1175
|
if (!_isValidAttribute(lcTag, lcName, value)) {
|
|
1288
1176
|
continue;
|
|
1289
1177
|
}
|
|
1178
|
+
|
|
1290
1179
|
/* Full DOM Clobbering protection via namespace isolation,
|
|
1291
1180
|
* Prefix id and name attributes with `user-content-`
|
|
1292
1181
|
*/
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
1182
|
if (SANITIZE_NAMED_PROPS && (lcName === 'id' || lcName === 'name')) {
|
|
1296
1183
|
// Remove the attribute with this value
|
|
1297
|
-
_removeAttribute(name, currentNode);
|
|
1298
|
-
|
|
1184
|
+
_removeAttribute(name, currentNode);
|
|
1299
1185
|
|
|
1186
|
+
// Prefix the value and later re-create the attribute with the sanitized value
|
|
1300
1187
|
value = SANITIZE_NAMED_PROPS_PREFIX + value;
|
|
1301
1188
|
}
|
|
1302
|
-
/* Handle attributes that require Trusted Types */
|
|
1303
|
-
|
|
1304
1189
|
|
|
1190
|
+
/* Handle attributes that require Trusted Types */
|
|
1305
1191
|
if (trustedTypesPolicy && typeof trustedTypes === 'object' && typeof trustedTypes.getAttributeType === 'function') {
|
|
1306
1192
|
if (namespaceURI) ; else {
|
|
1307
1193
|
switch (trustedTypes.getAttributeType(lcTag, lcName)) {
|
|
@@ -1310,7 +1196,6 @@ var purify = _commonjsHelpers.createCommonjsModule(function (module, exports) {
|
|
|
1310
1196
|
value = trustedTypesPolicy.createHTML(value);
|
|
1311
1197
|
break;
|
|
1312
1198
|
}
|
|
1313
|
-
|
|
1314
1199
|
case 'TrustedScriptURL':
|
|
1315
1200
|
{
|
|
1316
1201
|
value = trustedTypesPolicy.createScriptURL(value);
|
|
@@ -1319,9 +1204,8 @@ var purify = _commonjsHelpers.createCommonjsModule(function (module, exports) {
|
|
|
1319
1204
|
}
|
|
1320
1205
|
}
|
|
1321
1206
|
}
|
|
1322
|
-
/* Handle invalid data-* attribute set by try-catching it */
|
|
1323
|
-
|
|
1324
1207
|
|
|
1208
|
+
/* Handle invalid data-* attribute set by try-catching it */
|
|
1325
1209
|
try {
|
|
1326
1210
|
if (namespaceURI) {
|
|
1327
1211
|
currentNode.setAttributeNS(namespaceURI, name, value);
|
|
@@ -1329,56 +1213,47 @@ var purify = _commonjsHelpers.createCommonjsModule(function (module, exports) {
|
|
|
1329
1213
|
/* Fallback to setAttribute() for browser-unrecognized namespaces e.g. "x-schema". */
|
|
1330
1214
|
currentNode.setAttribute(name, value);
|
|
1331
1215
|
}
|
|
1332
|
-
|
|
1333
1216
|
arrayPop(DOMPurify.removed);
|
|
1334
1217
|
} catch (_) {}
|
|
1335
1218
|
}
|
|
1336
|
-
/* Execute a hook if present */
|
|
1337
|
-
|
|
1338
1219
|
|
|
1220
|
+
/* Execute a hook if present */
|
|
1339
1221
|
_executeHook('afterSanitizeAttributes', currentNode, null);
|
|
1340
1222
|
};
|
|
1223
|
+
|
|
1341
1224
|
/**
|
|
1342
1225
|
* _sanitizeShadowDOM
|
|
1343
1226
|
*
|
|
1344
1227
|
* @param {DocumentFragment} fragment to iterate over recursively
|
|
1345
1228
|
*/
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
1229
|
const _sanitizeShadowDOM = function _sanitizeShadowDOM(fragment) {
|
|
1349
1230
|
let shadowNode = null;
|
|
1350
|
-
|
|
1351
1231
|
const shadowIterator = _createNodeIterator(fragment);
|
|
1352
|
-
/* Execute a hook if present */
|
|
1353
|
-
|
|
1354
1232
|
|
|
1233
|
+
/* Execute a hook if present */
|
|
1355
1234
|
_executeHook('beforeSanitizeShadowDOM', fragment, null);
|
|
1356
|
-
|
|
1357
1235
|
while (shadowNode = shadowIterator.nextNode()) {
|
|
1358
1236
|
/* Execute a hook if present */
|
|
1359
1237
|
_executeHook('uponSanitizeShadowNode', shadowNode, null);
|
|
1360
|
-
/* Sanitize tags and elements */
|
|
1361
|
-
|
|
1362
1238
|
|
|
1239
|
+
/* Sanitize tags and elements */
|
|
1363
1240
|
if (_sanitizeElements(shadowNode)) {
|
|
1364
1241
|
continue;
|
|
1365
1242
|
}
|
|
1366
|
-
/* Deep shadow DOM detected */
|
|
1367
|
-
|
|
1368
1243
|
|
|
1244
|
+
/* Deep shadow DOM detected */
|
|
1369
1245
|
if (shadowNode.content instanceof DocumentFragment) {
|
|
1370
1246
|
_sanitizeShadowDOM(shadowNode.content);
|
|
1371
1247
|
}
|
|
1372
|
-
/* Check attributes, sanitize if necessary */
|
|
1373
|
-
|
|
1374
1248
|
|
|
1249
|
+
/* Check attributes, sanitize if necessary */
|
|
1375
1250
|
_sanitizeAttributes(shadowNode);
|
|
1376
1251
|
}
|
|
1377
|
-
/* Execute a hook if present */
|
|
1378
|
-
|
|
1379
1252
|
|
|
1253
|
+
/* Execute a hook if present */
|
|
1380
1254
|
_executeHook('afterSanitizeShadowDOM', fragment, null);
|
|
1381
1255
|
};
|
|
1256
|
+
|
|
1382
1257
|
/**
|
|
1383
1258
|
* Sanitize
|
|
1384
1259
|
* Public method providing core sanitation functionality
|
|
@@ -1387,8 +1262,6 @@ var purify = _commonjsHelpers.createCommonjsModule(function (module, exports) {
|
|
|
1387
1262
|
* @param {Object} cfg object
|
|
1388
1263
|
*/
|
|
1389
1264
|
// eslint-disable-next-line complexity
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
1265
|
DOMPurify.sanitize = function (dirty) {
|
|
1393
1266
|
let cfg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
1394
1267
|
let body = null;
|
|
@@ -1398,19 +1271,15 @@ var purify = _commonjsHelpers.createCommonjsModule(function (module, exports) {
|
|
|
1398
1271
|
/* Make sure we have a string to sanitize.
|
|
1399
1272
|
DO NOT return early, as this will return the wrong type if
|
|
1400
1273
|
the user has requested a DOM object rather than a string */
|
|
1401
|
-
|
|
1402
1274
|
IS_EMPTY_INPUT = !dirty;
|
|
1403
|
-
|
|
1404
1275
|
if (IS_EMPTY_INPUT) {
|
|
1405
1276
|
dirty = '<!-->';
|
|
1406
1277
|
}
|
|
1407
|
-
/* Stringify, in case dirty is an object */
|
|
1408
|
-
|
|
1409
1278
|
|
|
1279
|
+
/* Stringify, in case dirty is an object */
|
|
1410
1280
|
if (typeof dirty !== 'string' && !_isNode(dirty)) {
|
|
1411
1281
|
if (typeof dirty.toString === 'function') {
|
|
1412
1282
|
dirty = dirty.toString();
|
|
1413
|
-
|
|
1414
1283
|
if (typeof dirty !== 'string') {
|
|
1415
1284
|
throw typeErrorCreate('dirty is not a string, aborting');
|
|
1416
1285
|
}
|
|
@@ -1418,33 +1287,28 @@ var purify = _commonjsHelpers.createCommonjsModule(function (module, exports) {
|
|
|
1418
1287
|
throw typeErrorCreate('toString is not a function');
|
|
1419
1288
|
}
|
|
1420
1289
|
}
|
|
1421
|
-
/* Return dirty HTML if DOMPurify cannot run */
|
|
1422
|
-
|
|
1423
1290
|
|
|
1291
|
+
/* Return dirty HTML if DOMPurify cannot run */
|
|
1424
1292
|
if (!DOMPurify.isSupported) {
|
|
1425
1293
|
return dirty;
|
|
1426
1294
|
}
|
|
1427
|
-
/* Assign config vars */
|
|
1428
|
-
|
|
1429
1295
|
|
|
1296
|
+
/* Assign config vars */
|
|
1430
1297
|
if (!SET_CONFIG) {
|
|
1431
1298
|
_parseConfig(cfg);
|
|
1432
1299
|
}
|
|
1433
|
-
/* Clean up removed elements */
|
|
1434
|
-
|
|
1435
1300
|
|
|
1301
|
+
/* Clean up removed elements */
|
|
1436
1302
|
DOMPurify.removed = [];
|
|
1437
|
-
/* Check if dirty is correctly typed for IN_PLACE */
|
|
1438
1303
|
|
|
1304
|
+
/* Check if dirty is correctly typed for IN_PLACE */
|
|
1439
1305
|
if (typeof dirty === 'string') {
|
|
1440
1306
|
IN_PLACE = false;
|
|
1441
1307
|
}
|
|
1442
|
-
|
|
1443
1308
|
if (IN_PLACE) {
|
|
1444
1309
|
/* Do some early pre-sanitization to avoid unsafe root nodes */
|
|
1445
1310
|
if (dirty.nodeName) {
|
|
1446
1311
|
const tagName = transformCaseFunc(dirty.nodeName);
|
|
1447
|
-
|
|
1448
1312
|
if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {
|
|
1449
1313
|
throw typeErrorCreate('root node is forbidden and cannot be sanitized in-place');
|
|
1450
1314
|
}
|
|
@@ -1454,7 +1318,6 @@ var purify = _commonjsHelpers.createCommonjsModule(function (module, exports) {
|
|
|
1454
1318
|
elements being stripped by the parser */
|
|
1455
1319
|
body = _initDocument('<!---->');
|
|
1456
1320
|
importedNode = body.ownerDocument.importNode(dirty, true);
|
|
1457
|
-
|
|
1458
1321
|
if (importedNode.nodeType === 1 && importedNode.nodeName === 'BODY') {
|
|
1459
1322
|
/* Node is already a body, use as is */
|
|
1460
1323
|
body = importedNode;
|
|
@@ -1466,62 +1329,54 @@ var purify = _commonjsHelpers.createCommonjsModule(function (module, exports) {
|
|
|
1466
1329
|
}
|
|
1467
1330
|
} else {
|
|
1468
1331
|
/* Exit directly if we have nothing to do */
|
|
1469
|
-
if (!RETURN_DOM && !SAFE_FOR_TEMPLATES && !WHOLE_DOCUMENT &&
|
|
1332
|
+
if (!RETURN_DOM && !SAFE_FOR_TEMPLATES && !WHOLE_DOCUMENT &&
|
|
1333
|
+
// eslint-disable-next-line unicorn/prefer-includes
|
|
1470
1334
|
dirty.indexOf('<') === -1) {
|
|
1471
1335
|
return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(dirty) : dirty;
|
|
1472
1336
|
}
|
|
1473
|
-
/* Initialize the document to work on */
|
|
1474
|
-
|
|
1475
1337
|
|
|
1338
|
+
/* Initialize the document to work on */
|
|
1476
1339
|
body = _initDocument(dirty);
|
|
1477
|
-
/* Check we have a DOM node from the data */
|
|
1478
1340
|
|
|
1341
|
+
/* Check we have a DOM node from the data */
|
|
1479
1342
|
if (!body) {
|
|
1480
1343
|
return RETURN_DOM ? null : RETURN_TRUSTED_TYPE ? emptyHTML : '';
|
|
1481
1344
|
}
|
|
1482
1345
|
}
|
|
1483
|
-
/* Remove first element node (ours) if FORCE_BODY is set */
|
|
1484
|
-
|
|
1485
1346
|
|
|
1347
|
+
/* Remove first element node (ours) if FORCE_BODY is set */
|
|
1486
1348
|
if (body && FORCE_BODY) {
|
|
1487
1349
|
_forceRemove(body.firstChild);
|
|
1488
1350
|
}
|
|
1489
|
-
/* Get node iterator */
|
|
1490
|
-
|
|
1491
1351
|
|
|
1352
|
+
/* Get node iterator */
|
|
1492
1353
|
const nodeIterator = _createNodeIterator(IN_PLACE ? dirty : body);
|
|
1493
|
-
/* Now start iterating over the created document */
|
|
1494
|
-
|
|
1495
1354
|
|
|
1355
|
+
/* Now start iterating over the created document */
|
|
1496
1356
|
while (currentNode = nodeIterator.nextNode()) {
|
|
1497
1357
|
/* Sanitize tags and elements */
|
|
1498
1358
|
if (_sanitizeElements(currentNode)) {
|
|
1499
1359
|
continue;
|
|
1500
1360
|
}
|
|
1501
|
-
/* Shadow DOM detected, sanitize it */
|
|
1502
|
-
|
|
1503
1361
|
|
|
1362
|
+
/* Shadow DOM detected, sanitize it */
|
|
1504
1363
|
if (currentNode.content instanceof DocumentFragment) {
|
|
1505
1364
|
_sanitizeShadowDOM(currentNode.content);
|
|
1506
1365
|
}
|
|
1507
|
-
/* Check attributes, sanitize if necessary */
|
|
1508
|
-
|
|
1509
1366
|
|
|
1367
|
+
/* Check attributes, sanitize if necessary */
|
|
1510
1368
|
_sanitizeAttributes(currentNode);
|
|
1511
1369
|
}
|
|
1512
|
-
/* If we sanitized `dirty` in-place, return it. */
|
|
1513
|
-
|
|
1514
1370
|
|
|
1371
|
+
/* If we sanitized `dirty` in-place, return it. */
|
|
1515
1372
|
if (IN_PLACE) {
|
|
1516
1373
|
return dirty;
|
|
1517
1374
|
}
|
|
1518
|
-
/* Return sanitized string or DOM */
|
|
1519
|
-
|
|
1520
1375
|
|
|
1376
|
+
/* Return sanitized string or DOM */
|
|
1521
1377
|
if (RETURN_DOM) {
|
|
1522
1378
|
if (RETURN_DOM_FRAGMENT) {
|
|
1523
1379
|
returnNode = createDocumentFragment.call(body.ownerDocument);
|
|
1524
|
-
|
|
1525
1380
|
while (body.firstChild) {
|
|
1526
1381
|
// eslint-disable-next-line unicorn/prefer-dom-node-append
|
|
1527
1382
|
returnNode.appendChild(body.firstChild);
|
|
@@ -1529,7 +1384,6 @@ var purify = _commonjsHelpers.createCommonjsModule(function (module, exports) {
|
|
|
1529
1384
|
} else {
|
|
1530
1385
|
returnNode = body;
|
|
1531
1386
|
}
|
|
1532
|
-
|
|
1533
1387
|
if (ALLOWED_ATTR.shadowroot || ALLOWED_ATTR.shadowrootmode) {
|
|
1534
1388
|
/*
|
|
1535
1389
|
AdoptNode() is not used because internal state is not reset
|
|
@@ -1540,53 +1394,46 @@ var purify = _commonjsHelpers.createCommonjsModule(function (module, exports) {
|
|
|
1540
1394
|
*/
|
|
1541
1395
|
returnNode = importNode.call(originalDocument, returnNode, true);
|
|
1542
1396
|
}
|
|
1543
|
-
|
|
1544
1397
|
return returnNode;
|
|
1545
1398
|
}
|
|
1546
|
-
|
|
1547
1399
|
let serializedHTML = WHOLE_DOCUMENT ? body.outerHTML : body.innerHTML;
|
|
1548
|
-
/* Serialize doctype if allowed */
|
|
1549
1400
|
|
|
1401
|
+
/* Serialize doctype if allowed */
|
|
1550
1402
|
if (WHOLE_DOCUMENT && ALLOWED_TAGS['!doctype'] && body.ownerDocument && body.ownerDocument.doctype && body.ownerDocument.doctype.name && regExpTest(DOCTYPE_NAME, body.ownerDocument.doctype.name)) {
|
|
1551
1403
|
serializedHTML = '<!DOCTYPE ' + body.ownerDocument.doctype.name + '>\n' + serializedHTML;
|
|
1552
1404
|
}
|
|
1553
|
-
/* Sanitize final string template-safe */
|
|
1554
|
-
|
|
1555
1405
|
|
|
1406
|
+
/* Sanitize final string template-safe */
|
|
1556
1407
|
if (SAFE_FOR_TEMPLATES) {
|
|
1557
1408
|
arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {
|
|
1558
1409
|
serializedHTML = stringReplace(serializedHTML, expr, ' ');
|
|
1559
1410
|
});
|
|
1560
1411
|
}
|
|
1561
|
-
|
|
1562
1412
|
return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(serializedHTML) : serializedHTML;
|
|
1563
1413
|
};
|
|
1414
|
+
|
|
1564
1415
|
/**
|
|
1565
1416
|
* Public method to set the configuration once
|
|
1566
1417
|
* setConfig
|
|
1567
1418
|
*
|
|
1568
1419
|
* @param {Object} cfg configuration object
|
|
1569
1420
|
*/
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
1421
|
DOMPurify.setConfig = function () {
|
|
1573
1422
|
let cfg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
1574
|
-
|
|
1575
1423
|
_parseConfig(cfg);
|
|
1576
|
-
|
|
1577
1424
|
SET_CONFIG = true;
|
|
1578
1425
|
};
|
|
1426
|
+
|
|
1579
1427
|
/**
|
|
1580
1428
|
* Public method to remove the configuration
|
|
1581
1429
|
* clearConfig
|
|
1582
1430
|
*
|
|
1583
1431
|
*/
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
1432
|
DOMPurify.clearConfig = function () {
|
|
1587
1433
|
CONFIG = null;
|
|
1588
1434
|
SET_CONFIG = false;
|
|
1589
1435
|
};
|
|
1436
|
+
|
|
1590
1437
|
/**
|
|
1591
1438
|
* Public method to check if an attribute value is valid.
|
|
1592
1439
|
* Uses last set config, if any. Otherwise, uses config defaults.
|
|
@@ -1597,18 +1444,16 @@ var purify = _commonjsHelpers.createCommonjsModule(function (module, exports) {
|
|
|
1597
1444
|
* @param {String} value Attribute value.
|
|
1598
1445
|
* @return {Boolean} Returns true if `value` is valid. Otherwise, returns false.
|
|
1599
1446
|
*/
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
1447
|
DOMPurify.isValidAttribute = function (tag, attr, value) {
|
|
1603
1448
|
/* Initialize shared config vars if necessary. */
|
|
1604
1449
|
if (!CONFIG) {
|
|
1605
1450
|
_parseConfig({});
|
|
1606
1451
|
}
|
|
1607
|
-
|
|
1608
1452
|
const lcTag = transformCaseFunc(tag);
|
|
1609
1453
|
const lcName = transformCaseFunc(attr);
|
|
1610
1454
|
return _isValidAttribute(lcTag, lcName, value);
|
|
1611
1455
|
};
|
|
1456
|
+
|
|
1612
1457
|
/**
|
|
1613
1458
|
* AddHook
|
|
1614
1459
|
* Public method to add DOMPurify hooks
|
|
@@ -1616,16 +1461,14 @@ var purify = _commonjsHelpers.createCommonjsModule(function (module, exports) {
|
|
|
1616
1461
|
* @param {String} entryPoint entry point for the hook to add
|
|
1617
1462
|
* @param {Function} hookFunction function to execute
|
|
1618
1463
|
*/
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
1464
|
DOMPurify.addHook = function (entryPoint, hookFunction) {
|
|
1622
1465
|
if (typeof hookFunction !== 'function') {
|
|
1623
1466
|
return;
|
|
1624
1467
|
}
|
|
1625
|
-
|
|
1626
1468
|
hooks[entryPoint] = hooks[entryPoint] || [];
|
|
1627
1469
|
arrayPush(hooks[entryPoint], hookFunction);
|
|
1628
1470
|
};
|
|
1471
|
+
|
|
1629
1472
|
/**
|
|
1630
1473
|
* RemoveHook
|
|
1631
1474
|
* Public method to remove a DOMPurify hook at a given entryPoint
|
|
@@ -1634,39 +1477,33 @@ var purify = _commonjsHelpers.createCommonjsModule(function (module, exports) {
|
|
|
1634
1477
|
* @param {String} entryPoint entry point for the hook to remove
|
|
1635
1478
|
* @return {Function} removed(popped) hook
|
|
1636
1479
|
*/
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
1480
|
DOMPurify.removeHook = function (entryPoint) {
|
|
1640
1481
|
if (hooks[entryPoint]) {
|
|
1641
1482
|
return arrayPop(hooks[entryPoint]);
|
|
1642
1483
|
}
|
|
1643
1484
|
};
|
|
1485
|
+
|
|
1644
1486
|
/**
|
|
1645
1487
|
* RemoveHooks
|
|
1646
1488
|
* Public method to remove all DOMPurify hooks at a given entryPoint
|
|
1647
1489
|
*
|
|
1648
1490
|
* @param {String} entryPoint entry point for the hooks to remove
|
|
1649
1491
|
*/
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
1492
|
DOMPurify.removeHooks = function (entryPoint) {
|
|
1653
1493
|
if (hooks[entryPoint]) {
|
|
1654
1494
|
hooks[entryPoint] = [];
|
|
1655
1495
|
}
|
|
1656
1496
|
};
|
|
1497
|
+
|
|
1657
1498
|
/**
|
|
1658
1499
|
* RemoveAllHooks
|
|
1659
1500
|
* Public method to remove all DOMPurify hooks
|
|
1660
1501
|
*/
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
1502
|
DOMPurify.removeAllHooks = function () {
|
|
1664
1503
|
hooks = {};
|
|
1665
1504
|
};
|
|
1666
|
-
|
|
1667
1505
|
return DOMPurify;
|
|
1668
1506
|
}
|
|
1669
|
-
|
|
1670
1507
|
var purify = createDOMPurify();
|
|
1671
1508
|
|
|
1672
1509
|
return purify;
|