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