@oat-sa/tao-core-ui 1.60.2 → 1.62.0
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/LICENSE +339 -339
- package/README.md +23 -18
- package/dist/actionbar.js +393 -410
- package/dist/adder.js +143 -156
- package/dist/animable/absorbable/absorbable.js +208 -211
- package/dist/animable/absorbable/css/absorb.css +7 -8
- package/dist/animable/absorbable/css/absorb.css.map +1 -1
- package/dist/animable/pulsable/css/pulse.css +7 -7
- package/dist/animable/pulsable/css/pulse.css.map +1 -1
- package/dist/animable/pulsable/pulsable.js +174 -174
- package/dist/areaBroker.js +59 -72
- package/dist/autocomplete/css/autocomplete.css +7 -8
- package/dist/autocomplete/css/autocomplete.css.map +1 -1
- package/dist/autocomplete.js +494 -604
- package/dist/autoscroll.js +23 -25
- package/dist/badge/badge.js +201 -199
- package/dist/badge/css/badge.css +7 -8
- package/dist/badge/css/badge.css.map +1 -1
- package/dist/breadcrumbs/css/breadcrumbs.css +7 -7
- package/dist/breadcrumbs/css/breadcrumbs.css.map +1 -1
- package/dist/breadcrumbs.js +286 -285
- package/dist/btngrouper.js +83 -95
- package/dist/bulkActionPopup/css/bulkActionPopup.css +7 -7
- package/dist/bulkActionPopup/css/bulkActionPopup.css.map +1 -1
- package/dist/bulkActionPopup.js +503 -503
- package/dist/button.js +300 -293
- package/dist/calculator/css/calculator.css +10 -10
- package/dist/calculator/css/calculator.css.map +1 -1
- package/dist/calculator.js +59 -72
- package/dist/cascadingComboBox.js +257 -256
- package/dist/ckeditor/ckConfigurator.js +130 -154
- package/dist/ckeditor/dtdHandler.js +305 -345
- package/dist/class/css/selector.css +7 -7
- package/dist/class/css/selector.css.map +1 -1
- package/dist/class/selector.js +437 -470
- package/dist/component/alignable.js +97 -121
- package/dist/component/containable.js +53 -58
- package/dist/component/css/components.css +7 -7
- package/dist/component/css/components.css.map +1 -1
- package/dist/component/css/windowComponent.css +7 -7
- package/dist/component/css/windowComponent.css.map +1 -1
- package/dist/component/draggable.js +34 -36
- package/dist/component/placeable.js +84 -102
- package/dist/component/resizable.js +79 -89
- package/dist/component/stackable.js +21 -27
- package/dist/component/windowed.js +284 -297
- package/dist/component.js +439 -467
- package/dist/container.js +79 -98
- package/dist/contextualPopup/css/contextualPopup.css +7 -7
- package/dist/contextualPopup/css/contextualPopup.css.map +1 -1
- package/dist/contextualPopup.js +417 -436
- package/dist/dashboard/css/dashboard.css +7 -7
- package/dist/dashboard/css/dashboard.css.map +1 -1
- package/dist/dashboard.js +302 -305
- package/dist/datalist/css/datalist.css +7 -7
- package/dist/datalist/css/datalist.css.map +1 -1
- package/dist/datalist.js +783 -791
- package/dist/datatable/css/datatable.css +11 -7
- package/dist/datatable/css/datatable.css.map +1 -1
- package/dist/datatable/filterStrategy/filterStrategy.js +28 -30
- package/dist/datatable/filterStrategy/multiple.js +26 -45
- package/dist/datatable/filterStrategy/single.js +28 -40
- package/dist/datatable.js +1591 -1616
- package/dist/dateRange/css/dateRange.css +7 -7
- package/dist/dateRange/css/dateRange.css.map +1 -1
- package/dist/dateRange/dateRange.js +398 -412
- package/dist/datetime/css/picker.css +7 -7
- package/dist/datetime/css/picker.css.map +1 -1
- package/dist/datetime/picker.js +670 -703
- package/dist/deleter.js +383 -398
- package/dist/destination/css/selector.css +7 -7
- package/dist/destination/css/selector.css.map +1 -1
- package/dist/destination/selector.js +295 -293
- package/dist/dialog/alert.js +30 -32
- package/dist/dialog/confirm.js +29 -32
- package/dist/dialog/confirmDelete.js +223 -221
- package/dist/dialog.js +651 -695
- package/dist/disabler.js +108 -119
- package/dist/documentViewer/css/documentViewer.css +7 -7
- package/dist/documentViewer/css/documentViewer.css.map +1 -1
- package/dist/documentViewer/providers/pdfViewer/fallback/viewer.js +172 -169
- package/dist/documentViewer/providers/pdfViewer/pdfjs/areaBroker.js +32 -29
- package/dist/documentViewer/providers/pdfViewer/pdfjs/findBar.js +523 -564
- package/dist/documentViewer/providers/pdfViewer/pdfjs/pageView.js +376 -393
- package/dist/documentViewer/providers/pdfViewer/pdfjs/pagesManager.js +53 -68
- package/dist/documentViewer/providers/pdfViewer/pdfjs/searchEngine.js +517 -567
- package/dist/documentViewer/providers/pdfViewer/pdfjs/textManager.js +73 -96
- package/dist/documentViewer/providers/pdfViewer/pdfjs/viewer.js +381 -392
- package/dist/documentViewer/providers/pdfViewer/pdfjs/wrapper.js +125 -152
- package/dist/documentViewer/providers/pdfViewer.js +189 -191
- package/dist/documentViewer/viewerFactory.js +76 -81
- package/dist/documentViewer.js +303 -311
- package/dist/dropdown/css/dropdown.css +7 -7
- package/dist/dropdown/css/dropdown.css.map +1 -1
- package/dist/dropdown.js +392 -412
- package/dist/durationer.js +77 -85
- package/dist/dynamicComponent/css/dynamicComponent.css +7 -7
- package/dist/dynamicComponent/css/dynamicComponent.css.map +1 -1
- package/dist/dynamicComponent.js +595 -630
- package/dist/feedback.js +365 -375
- package/dist/figure/FigureStateActive.js +246 -296
- package/dist/filesender.js +44 -54
- package/dist/filter.js +244 -240
- package/dist/form/css/dropdownForm.css +7 -7
- package/dist/form/css/dropdownForm.css.map +1 -1
- package/dist/form/css/form.css +7 -7
- package/dist/form/css/form.css.map +1 -1
- package/dist/form/dropdownForm.js +357 -362
- package/dist/form/form.js +703 -984
- package/dist/form/simpleForm.js +74 -77
- package/dist/form/validator/css/validator.css +7 -7
- package/dist/form/validator/css/validator.css.map +1 -1
- package/dist/form/validator/renderer.js +235 -241
- package/dist/form/validator/validator.js +181 -267
- package/dist/form/widget/css/widget.css +7 -7
- package/dist/form/widget/css/widget.css.map +1 -1
- package/dist/form/widget/definitions.js +27 -28
- package/dist/form/widget/loader.js +16 -16
- package/dist/form/widget/providers/checkBox.js +257 -264
- package/dist/form/widget/providers/comboBox.js +194 -193
- package/dist/form/widget/providers/default.js +44 -50
- package/dist/form/widget/providers/hidden.js +179 -176
- package/dist/form/widget/providers/hiddenBox.js +262 -272
- package/dist/form/widget/providers/radioBox.js +222 -223
- package/dist/form/widget/providers/textArea.js +197 -193
- package/dist/form/widget/providers/textBox.js +36 -37
- package/dist/form/widget/widget.js +480 -508
- package/dist/form.js +12 -17
- package/dist/formValidator/formValidator.js +74 -91
- package/dist/formValidator/highlighters/highlighter.js +43 -51
- package/dist/formValidator/highlighters/message.js +31 -32
- package/dist/formValidator/highlighters/tooltip.js +33 -35
- package/dist/generis/form/css/form.css +7 -7
- package/dist/generis/form/css/form.css.map +1 -1
- package/dist/generis/form/form.js +323 -331
- package/dist/generis/validator/css/validator.css +7 -7
- package/dist/generis/validator/css/validator.css.map +1 -1
- package/dist/generis/validator/validator.js +215 -216
- package/dist/generis/widget/checkBox/checkBox.js +227 -225
- package/dist/generis/widget/comboBox/comboBox.js +189 -183
- package/dist/generis/widget/css/widget.css +7 -7
- package/dist/generis/widget/css/widget.css.map +1 -1
- package/dist/generis/widget/hiddenBox/hiddenBox.js +231 -232
- package/dist/generis/widget/loader.js +21 -23
- package/dist/generis/widget/textBox/textBox.js +178 -172
- package/dist/generis/widget/widget.js +255 -266
- package/dist/groupedComboBox.js +231 -226
- package/dist/groupvalidator.js +30 -34
- package/dist/hider.js +43 -50
- package/dist/highlighter.js +946 -1057
- package/dist/image/ImgStateActive/extractLabel.js +20 -21
- package/dist/image/ImgStateActive/helper.js +21 -25
- package/dist/image/ImgStateActive/initHelper.js +133 -162
- package/dist/image/ImgStateActive/initMediaEditor.js +72 -92
- package/dist/image/ImgStateActive/mediaSizer.js +48 -58
- package/dist/image/ImgStateActive.js +185 -215
- package/dist/incrementer.js +91 -110
- package/dist/inplacer.js +108 -132
- package/dist/interactUtils.js +56 -67
- package/dist/itemButtonList/css/item-button-list.css +23 -24
- package/dist/itemButtonList/css/item-button-list.css.map +1 -1
- package/dist/itemButtonList.js +444 -469
- package/dist/keyNavigation/navigableDomElement.js +124 -158
- package/dist/keyNavigation/navigator.js +235 -312
- package/dist/listbox/css/listbox.css +7 -7
- package/dist/listbox/css/listbox.css.map +1 -1
- package/dist/listbox.js +463 -476
- package/dist/liststyler.js +75 -76
- package/dist/loadingButton/css/button.css +7 -7
- package/dist/loadingButton/css/button.css.map +1 -1
- package/dist/loadingButton/loadingButton.js +219 -218
- package/dist/lock.js +484 -509
- package/dist/login/login.js +471 -486
- package/dist/maths/calculator/basicCalculator.js +247 -242
- package/dist/maths/calculator/calculatorComponent.js +34 -36
- package/dist/maths/calculator/core/areaBroker.js +30 -28
- package/dist/maths/calculator/core/board.js +805 -872
- package/dist/maths/calculator/core/expression.js +500 -518
- package/dist/maths/calculator/core/labels.js +240 -235
- package/dist/maths/calculator/core/plugin.js +20 -20
- package/dist/maths/calculator/core/terms.js +27 -27
- package/dist/maths/calculator/core/tokenizer.js +119 -132
- package/dist/maths/calculator/core/tokens.js +157 -168
- package/dist/maths/calculator/css/calculator.css +7 -7
- package/dist/maths/calculator/css/calculator.css.map +1 -1
- package/dist/maths/calculator/defaultCalculator.js +24 -27
- package/dist/maths/calculator/plugins/core/degrad.js +22 -30
- package/dist/maths/calculator/plugins/core/history.js +55 -67
- package/dist/maths/calculator/plugins/core/remind.js +22 -25
- package/dist/maths/calculator/plugins/core/stepNavigation.js +33 -49
- package/dist/maths/calculator/plugins/keyboard/templateKeyboard/templateKeyboard.js +255 -258
- package/dist/maths/calculator/plugins/modifiers/pow10.js +47 -52
- package/dist/maths/calculator/plugins/modifiers/sign.js +103 -130
- package/dist/maths/calculator/plugins/screen/simpleScreen/simpleScreen.js +288 -293
- package/dist/maths/calculator/pluginsLoader.js +22 -22
- package/dist/maths/calculator/scientificCalculator.js +339 -334
- package/dist/mediaEditor/mediaEditorComponent.js +244 -249
- package/dist/mediaEditor/plugins/mediaAlignment/helper.js +28 -33
- package/dist/mediaEditor/plugins/mediaAlignment/mediaAlignmentComponent.js +228 -236
- package/dist/mediaEditor/plugins/mediaAlignment/style.css +7 -7
- package/dist/mediaEditor/plugins/mediaDimension/helper.js +81 -106
- package/dist/mediaEditor/plugins/mediaDimension/mediaDimensionComponent.js +597 -635
- package/dist/mediaEditor/plugins/mediaDimension/style.css +141 -141
- package/dist/mediaplayer/css/player.css +7 -7
- package/dist/mediaplayer/css/player.css.map +1 -1
- package/dist/mediaplayer/players/html5.js +646 -706
- package/dist/mediaplayer/players/youtube.js +393 -438
- package/dist/mediaplayer/players.js +19 -19
- package/dist/mediaplayer/support.js +66 -79
- package/dist/mediaplayer/utils/reminder.js +117 -128
- package/dist/mediaplayer/utils/timeObserver.js +106 -109
- package/dist/mediaplayer/youtubeManager.js +142 -170
- package/dist/mediaplayer.js +1484 -1774
- package/dist/mediasizer.js +633 -676
- package/dist/modal.js +137 -153
- package/dist/movableComponent.js +37 -37
- package/dist/pageSizeSelector.js +231 -224
- package/dist/pageStatus.js +43 -46
- package/dist/pagination/css/pagination.css +7 -7
- package/dist/pagination/css/pagination.css.map +1 -1
- package/dist/pagination/paginationStrategy.js +24 -25
- package/dist/pagination/providers/pages.js +281 -291
- package/dist/pagination/providers/simple.js +202 -196
- package/dist/pagination.js +49 -72
- package/dist/previewer.js +113 -138
- package/dist/progressbar.js +70 -80
- package/dist/propertySelector/css/propertySelector.css +74 -0
- package/dist/propertySelector/css/propertySelector.css.map +1 -0
- package/dist/propertySelector/propertySelector.js +489 -0
- package/dist/report.js +356 -359
- package/dist/resource/css/selector.css +7 -7
- package/dist/resource/css/selector.css.map +1 -1
- package/dist/resource/filters.js +275 -289
- package/dist/resource/list.js +1589 -1371
- package/dist/resource/selectable.js +101 -136
- package/dist/resource/selector.js +855 -914
- package/dist/resource/tree.js +1796 -1612
- package/dist/resourcemgr/css/resourcemgr.css +7 -7
- package/dist/resourcemgr/css/resourcemgr.css.map +1 -1
- package/dist/resourcemgr/fileBrowser.js +540 -587
- package/dist/resourcemgr/filePreview.js +16 -25
- package/dist/resourcemgr/fileSelector.js +520 -547
- package/dist/resourcemgr/util/updatePermissions.js +10 -18
- package/dist/resourcemgr.js +325 -332
- package/dist/scroller.js +29 -33
- package/dist/searchModal/advancedSearch.js +949 -833
- package/dist/searchModal/css/advancedSearch.css +7 -14
- package/dist/searchModal/css/advancedSearch.css.map +1 -1
- package/dist/searchModal/css/searchModal.css +28 -8
- package/dist/searchModal/css/searchModal.css.map +1 -1
- package/dist/searchModal.js +616 -335
- package/dist/selecter.js +21 -28
- package/dist/stacker.js +52 -60
- package/dist/switch/css/switch.css +7 -7
- package/dist/switch/css/switch.css.map +1 -1
- package/dist/switch/switch.js +305 -311
- package/dist/tableModel.js +39 -49
- package/dist/tabs/css/tabs.css +12 -12
- package/dist/tabs/css/tabs.css.map +1 -1
- package/dist/tabs.js +588 -639
- package/dist/taskQueue/css/taskQueue.css +7 -7
- package/dist/taskQueue/css/taskQueue.css.map +1 -1
- package/dist/taskQueue/status.js +317 -322
- package/dist/taskQueue/table.js +383 -394
- package/dist/taskQueue/taskQueue.js +19 -19
- package/dist/taskQueue/taskQueueModel.js +459 -538
- package/dist/taskQueue.js +49 -67
- package/dist/taskQueueButton/css/taskable.css +7 -7
- package/dist/taskQueueButton/css/taskable.css.map +1 -1
- package/dist/taskQueueButton/css/treeButton.css +7 -7
- package/dist/taskQueueButton/css/treeButton.css.map +1 -1
- package/dist/taskQueueButton/standardButton.js +45 -43
- package/dist/taskQueueButton/taskable.js +267 -272
- package/dist/taskQueueButton/treeButton.js +200 -198
- package/dist/themeLoader.js +109 -129
- package/dist/themes.js +86 -100
- package/dist/toggler.js +76 -88
- package/dist/tooltip.js +296 -311
- package/dist/tooltipster.js +17 -17
- package/dist/transformer.js +140 -169
- package/dist/tristateCheckboxGroup/css/tristateCheckboxGroup.css +7 -7
- package/dist/tristateCheckboxGroup/css/tristateCheckboxGroup.css.map +1 -1
- package/dist/tristateCheckboxGroup.js +319 -325
- package/dist/uploader.js +691 -724
- package/dist/validator/Report.js +1 -2
- package/dist/validator/Validator.js +6 -25
- package/dist/validator/validators.js +66 -80
- package/dist/validator.js +218 -254
- package/dist/waitForMedia.js +45 -51
- package/dist/waitingDialog/css/waitingDialog.css +7 -7
- package/dist/waitingDialog/css/waitingDialog.css.map +1 -1
- package/dist/waitingDialog/waitingDialog.js +59 -77
- package/package.json +109 -107
- package/scss/basic.scss +16 -16
- package/scss/ckeditor/skins/tao/scss/inc/_ck-icons.scss +59 -59
- package/scss/ckeditor/skins/tao/scss/inc/_tao.scss +59 -59
- package/scss/font/tao/tao.svg +234 -234
- package/scss/inc/_base.scss +495 -495
- package/scss/inc/_bootstrap.scss +6 -6
- package/scss/inc/_buttons.scss +114 -114
- package/scss/inc/_colors.scss +93 -88
- package/scss/inc/_feedback.scss +150 -150
- package/scss/inc/_flex-grid.scss +15 -15
- package/scss/inc/_fonts.scss +4 -4
- package/scss/inc/_forms.scss +832 -832
- package/scss/inc/_functions.scss +283 -283
- package/scss/inc/_jquery.nouislider.scss +254 -254
- package/scss/inc/_normalize.scss +528 -528
- package/scss/inc/_report.scss +67 -67
- package/scss/inc/_secondary-properties.scss +89 -89
- package/scss/inc/_select2.scss +634 -634
- package/scss/inc/_toolbars.scss +155 -155
- package/scss/inc/_tooltip.scss +312 -312
- package/scss/inc/_variables.scss +21 -21
- package/scss/inc/base/_highlight.scss +5 -5
- package/scss/inc/base/_list-style.scss +58 -58
- package/scss/inc/base/_svg.scss +3 -3
- package/scss/inc/base/_table.scss +62 -62
- package/scss/inc/fonts/_source-sans-pro.scss +29 -29
- package/scss/inc/fonts/_tao-icon-classes.scss +226 -226
- package/scss/inc/fonts/_tao-icon-def.scss +12 -12
- package/scss/inc/fonts/_tao-icon-vars.scss +240 -240
- package/src/actionbar/tpl/main.tpl +8 -8
- package/src/actionbar.js +251 -251
- package/src/adder.js +250 -250
- package/src/animable/absorbable/absorbable.js +134 -134
- package/src/animable/absorbable/css/absorb.css +7 -8
- package/src/animable/absorbable/css/absorb.css.map +1 -1
- package/src/animable/absorbable/scss/absorb.scss +37 -37
- package/src/animable/pulsable/css/pulse.css +7 -7
- package/src/animable/pulsable/css/pulse.css.map +1 -1
- package/src/animable/pulsable/pulsable.js +90 -90
- package/src/animable/pulsable/scss/pulse.scss +22 -22
- package/src/areaBroker.js +160 -160
- package/src/autocomplete/css/autocomplete.css +7 -8
- package/src/autocomplete/css/autocomplete.css.map +1 -1
- package/src/autocomplete/scss/autocomplete.scss +37 -37
- package/src/autocomplete.js +1029 -1029
- package/src/autoscroll.js +57 -57
- package/src/badge/badge.js +119 -119
- package/src/badge/css/badge.css +7 -8
- package/src/badge/css/badge.css.map +1 -1
- package/src/badge/scss/badge.scss +92 -92
- package/src/badge/tpl/badge.tpl +4 -4
- package/src/breadcrumbs/css/breadcrumbs.css +7 -7
- package/src/breadcrumbs/css/breadcrumbs.css.map +1 -1
- package/src/breadcrumbs/scss/breadcrumbs.scss +52 -52
- package/src/breadcrumbs/tpl/breadcrumbs.tpl +20 -20
- package/src/breadcrumbs.js +99 -99
- package/src/btngrouper.js +213 -213
- package/src/bulkActionPopup/css/bulkActionPopup.css +7 -7
- package/src/bulkActionPopup/css/bulkActionPopup.css.map +1 -1
- package/src/bulkActionPopup/scss/bulkActionPopup.scss +63 -63
- package/src/bulkActionPopup/tpl/layout.tpl +76 -76
- package/src/bulkActionPopup/tpl/select.tpl +8 -8
- package/src/bulkActionPopup.js +274 -274
- package/src/button/tpl/button.tpl +4 -4
- package/src/button.js +135 -135
- package/src/calculator/css/calculator.css +10 -10
- package/src/calculator/css/calculator.css.map +1 -1
- package/src/calculator/scss/calculator.scss +139 -139
- package/src/calculator.js +188 -188
- package/src/cascadingComboBox.js +126 -126
- package/src/ckeditor/ckConfigurator.js +736 -736
- package/src/ckeditor/dtdHandler.js +1030 -1030
- package/src/class/css/selector.css +7 -7
- package/src/class/css/selector.css.map +1 -1
- package/src/class/scss/selector.scss +101 -101
- package/src/class/selector.js +329 -329
- package/src/class/tpl/listItem.tpl +9 -9
- package/src/class/tpl/selector.tpl +10 -10
- package/src/component/alignable.js +274 -274
- package/src/component/containable.js +122 -122
- package/src/component/css/components.css +7 -7
- package/src/component/css/components.css.map +1 -1
- package/src/component/css/windowComponent.css +7 -7
- package/src/component/css/windowComponent.css.map +1 -1
- package/src/component/draggable.js +104 -104
- package/src/component/placeable.js +233 -233
- package/src/component/resizable.js +195 -195
- package/src/component/scss/components.scss +507 -507
- package/src/component/scss/windowComponent.scss +62 -62
- package/src/component/stackable.js +67 -67
- package/src/component/tpl/window.tpl +7 -7
- package/src/component/windowed.js +206 -206
- package/src/component.js +401 -401
- package/src/container.js +200 -200
- package/src/contextualPopup/css/contextualPopup.css +7 -7
- package/src/contextualPopup/css/contextualPopup.css.map +1 -1
- package/src/contextualPopup/scss/contextualPopup.scss +78 -78
- package/src/contextualPopup/tpl/popup.tpl +10 -10
- package/src/contextualPopup.js +297 -297
- package/src/css/basic.css +103 -106
- package/src/css/basic.css.map +1 -1
- package/src/dashboard/css/dashboard.css +7 -7
- package/src/dashboard/css/dashboard.css.map +1 -1
- package/src/dashboard/scss/dashboard.scss +93 -93
- package/src/dashboard/tpl/dashboard.tpl +16 -16
- package/src/dashboard/tpl/dashboardMetricsList.tpl +15 -15
- package/src/dashboard.js +184 -184
- package/src/datalist/css/datalist.css +7 -7
- package/src/datalist/css/datalist.css.map +1 -1
- package/src/datalist/scss/datalist.scss +116 -116
- package/src/datalist/tpl/list.tpl +24 -24
- package/src/datalist/tpl/main.tpl +44 -44
- package/src/datalist.js +500 -500
- package/src/datatable/css/datatable.css +11 -7
- package/src/datatable/css/datatable.css.map +1 -1
- package/src/datatable/filterStrategy/filterStrategy.js +70 -70
- package/src/datatable/filterStrategy/multiple.js +126 -126
- package/src/datatable/filterStrategy/single.js +108 -108
- package/src/datatable/scss/datatable.scss +149 -146
- package/src/datatable/tpl/button.tpl +6 -6
- package/src/datatable/tpl/layout.tpl +158 -158
- package/src/datatable.js +1056 -1056
- package/src/dateRange/css/dateRange.css +7 -7
- package/src/dateRange/css/dateRange.css.map +1 -1
- package/src/dateRange/dateRange.js +341 -341
- package/src/dateRange/scss/dateRange.scss +7 -7
- package/src/dateRange/tpl/select.tpl +18 -18
- package/src/datetime/css/picker.css +7 -7
- package/src/datetime/css/picker.css.map +1 -1
- package/src/datetime/picker.js +576 -576
- package/src/datetime/scss/picker.scss +192 -192
- package/src/datetime/tpl/picker.tpl +18 -18
- package/src/deleter/undo.tpl +6 -6
- package/src/deleter.js +296 -296
- package/src/destination/css/selector.css +7 -7
- package/src/destination/css/selector.css.map +1 -1
- package/src/destination/scss/selector.scss +36 -36
- package/src/destination/selector.js +195 -195
- package/src/destination/tpl/selector.tpl +13 -13
- package/src/dialog/alert.js +70 -70
- package/src/dialog/confirm.js +85 -85
- package/src/dialog/confirmDelete.js +95 -95
- package/src/dialog/tpl/body.tpl +24 -24
- package/src/dialog/tpl/buttons.tpl +6 -6
- package/src/dialog/tpl/checkbox.tpl +5 -5
- package/src/dialog.js +517 -517
- package/src/disabler.js +230 -230
- package/src/documentViewer/css/documentViewer.css +7 -7
- package/src/documentViewer/css/documentViewer.css.map +1 -1
- package/src/documentViewer/providers/pdfViewer/fallback/viewer.js +69 -69
- package/src/documentViewer/providers/pdfViewer/pdfjs/areaBroker.js +41 -41
- package/src/documentViewer/providers/pdfViewer/pdfjs/findBar.js +475 -475
- package/src/documentViewer/providers/pdfViewer/pdfjs/findBar.tpl +20 -20
- package/src/documentViewer/providers/pdfViewer/pdfjs/match.tpl +1 -1
- package/src/documentViewer/providers/pdfViewer/pdfjs/page.tpl +4 -4
- package/src/documentViewer/providers/pdfViewer/pdfjs/pageView.js +318 -318
- package/src/documentViewer/providers/pdfViewer/pdfjs/pagesManager.js +167 -167
- package/src/documentViewer/providers/pdfViewer/pdfjs/searchEngine.js +451 -451
- package/src/documentViewer/providers/pdfViewer/pdfjs/textManager.js +252 -252
- package/src/documentViewer/providers/pdfViewer/pdfjs/viewer.js +299 -299
- package/src/documentViewer/providers/pdfViewer/pdfjs/viewer.tpl +16 -16
- package/src/documentViewer/providers/pdfViewer/pdfjs/wrapper.js +351 -351
- package/src/documentViewer/providers/pdfViewer.js +93 -93
- package/src/documentViewer/scss/documentViewer.scss +184 -184
- package/src/documentViewer/viewerFactory.js +191 -191
- package/src/documentViewer.js +238 -238
- package/src/dropdown/css/dropdown.css +7 -7
- package/src/dropdown/css/dropdown.css.map +1 -1
- package/src/dropdown/scss/dropdown.scss +99 -99
- package/src/dropdown/tpl/dropdown.tpl +8 -8
- package/src/dropdown/tpl/list-item.tpl +4 -4
- package/src/dropdown.js +255 -255
- package/src/durationer.js +222 -222
- package/src/dynamicComponent/css/dynamicComponent.css +7 -7
- package/src/dynamicComponent/css/dynamicComponent.css.map +1 -1
- package/src/dynamicComponent/scss/dynamicComponent.scss +98 -98
- package/src/dynamicComponent/tpl/layout.tpl +17 -17
- package/src/dynamicComponent.js +554 -554
- package/src/feedback/feedback.tpl +7 -7
- package/src/feedback.js +295 -295
- package/src/figure/FigureStateActive.js +174 -174
- package/src/filesender.js +114 -114
- package/src/filter/template.tpl +5 -5
- package/src/filter.js +135 -135
- package/src/form/css/dropdownForm.css +7 -7
- package/src/form/css/dropdownForm.css.map +1 -1
- package/src/form/css/form.css +7 -7
- package/src/form/css/form.css.map +1 -1
- package/src/form/dropdownForm.js +281 -281
- package/src/form/form.js +688 -688
- package/src/form/scss/dropdownForm.scss +60 -60
- package/src/form/scss/form.scss +25 -25
- package/src/form/simpleForm.js +125 -125
- package/src/form/tpl/dropdownForm.tpl +4 -4
- package/src/form/tpl/form.tpl +7 -7
- package/src/form/validator/css/validator.css +7 -7
- package/src/form/validator/css/validator.css.map +1 -1
- package/src/form/validator/renderer.js +118 -118
- package/src/form/validator/scss/validator.scss +14 -14
- package/src/form/validator/tpl/message.tpl +1 -1
- package/src/form/validator/tpl/validator.tpl +1 -1
- package/src/form/validator/validator.js +220 -220
- package/src/form/widget/css/widget.css +7 -7
- package/src/form/widget/css/widget.css.map +1 -1
- package/src/form/widget/definitions.js +51 -51
- package/src/form/widget/loader.js +40 -40
- package/src/form/widget/providers/checkBox.js +138 -138
- package/src/form/widget/providers/comboBox.js +63 -63
- package/src/form/widget/providers/default.js +90 -90
- package/src/form/widget/providers/hidden.js +62 -62
- package/src/form/widget/providers/hiddenBox.js +152 -152
- package/src/form/widget/providers/radioBox.js +99 -99
- package/src/form/widget/providers/textArea.js +52 -52
- package/src/form/widget/providers/textBox.js +48 -48
- package/src/form/widget/scss/widget.scss +55 -55
- package/src/form/widget/tpl/checkBox.tpl +25 -25
- package/src/form/widget/tpl/comboBox.tpl +13 -13
- package/src/form/widget/tpl/hidden.tpl +1 -1
- package/src/form/widget/tpl/hiddenBox.tpl +17 -17
- package/src/form/widget/tpl/label.tpl +6 -6
- package/src/form/widget/tpl/radioBox.tpl +25 -25
- package/src/form/widget/tpl/textArea.tpl +8 -8
- package/src/form/widget/tpl/widget.tpl +8 -8
- package/src/form/widget/widget.js +372 -372
- package/src/form.js +53 -53
- package/src/formValidator/formValidator.js +253 -253
- package/src/formValidator/highlighters/highlighter.js +102 -102
- package/src/formValidator/highlighters/message.js +70 -70
- package/src/formValidator/highlighters/tooltip.js +78 -78
- package/src/generis/form/css/form.css +7 -7
- package/src/generis/form/css/form.css.map +1 -1
- package/src/generis/form/form.js +239 -239
- package/src/generis/form/readme.md +70 -70
- package/src/generis/form/scss/form.scss +23 -23
- package/src/generis/form/tpl/form.tpl +16 -16
- package/src/generis/validator/css/validator.css +7 -7
- package/src/generis/validator/css/validator.css.map +1 -1
- package/src/generis/validator/readme.md +46 -46
- package/src/generis/validator/scss/validator.scss +13 -13
- package/src/generis/validator/validator.js +128 -128
- package/src/generis/widget/checkBox/checkBox.js +112 -112
- package/src/generis/widget/checkBox/checkBox.tpl +18 -18
- package/src/generis/widget/comboBox/comboBox.js +67 -67
- package/src/generis/widget/comboBox/comboBox.tpl +12 -12
- package/src/generis/widget/css/widget.css +7 -7
- package/src/generis/widget/css/widget.css.map +1 -1
- package/src/generis/widget/hiddenBox/hiddenBox.js +132 -132
- package/src/generis/widget/hiddenBox/hiddenBox.tpl +16 -16
- package/src/generis/widget/loader.js +49 -49
- package/src/generis/widget/readme.md +59 -59
- package/src/generis/widget/scss/widget.scss +61 -61
- package/src/generis/widget/textBox/textBox.js +65 -65
- package/src/generis/widget/textBox/textBox.tpl +7 -7
- package/src/generis/widget/widget.js +164 -164
- package/src/generis/widget/widget.tpl +5 -5
- package/src/groupedComboBox.js +99 -99
- package/src/groupvalidator.js +84 -84
- package/src/hider.js +88 -88
- package/src/highlighter.js +1166 -1166
- package/src/image/ImgStateActive/extractLabel.js +29 -29
- package/src/image/ImgStateActive/helper.js +36 -36
- package/src/image/ImgStateActive/initHelper.js +137 -137
- package/src/image/ImgStateActive/initMediaEditor.js +92 -92
- package/src/image/ImgStateActive/mediaSizer.js +63 -63
- package/src/image/ImgStateActive.js +115 -115
- package/src/incrementer.js +319 -319
- package/src/inplacer.js +316 -316
- package/src/interactUtils.js +140 -140
- package/src/itemButtonList/css/item-button-list.css +23 -24
- package/src/itemButtonList/css/item-button-list.css.map +1 -1
- package/src/itemButtonList/scss/item-button-list.scss +236 -236
- package/src/itemButtonList/tpl/itemButtonList.tpl +21 -21
- package/src/itemButtonList.js +274 -274
- package/src/keyNavigation/navigableDomElement.js +282 -282
- package/src/keyNavigation/navigator.js +543 -543
- package/src/listbox/css/listbox.css +7 -7
- package/src/listbox/css/listbox.css.map +1 -1
- package/src/listbox/scss/listbox.scss +116 -116
- package/src/listbox/tpl/list.tpl +14 -14
- package/src/listbox/tpl/main.tpl +9 -9
- package/src/listbox.js +251 -251
- package/src/liststyler.js +155 -155
- package/src/loadingButton/css/button.css +7 -7
- package/src/loadingButton/css/button.css.map +1 -1
- package/src/loadingButton/loadingButton.js +110 -110
- package/src/loadingButton/scss/button.scss +41 -41
- package/src/loadingButton/tpl/button.tpl +5 -5
- package/src/lock/lock.tpl +16 -16
- package/src/lock.js +395 -395
- package/src/login/login.js +322 -322
- package/src/login/tpl/login.tpl +29 -29
- package/src/login/tpl/passwordReveal.tpl +7 -7
- package/src/maths/calculator/basicCalculator.js +55 -55
- package/src/maths/calculator/calculatorComponent.js +128 -128
- package/src/maths/calculator/core/areaBroker.js +38 -38
- package/src/maths/calculator/core/board.js +841 -841
- package/src/maths/calculator/core/expression.js +430 -430
- package/src/maths/calculator/core/labels.js +116 -116
- package/src/maths/calculator/core/plugin.js +40 -40
- package/src/maths/calculator/core/terms.js +459 -459
- package/src/maths/calculator/core/tokenizer.js +245 -245
- package/src/maths/calculator/core/tokens.js +178 -178
- package/src/maths/calculator/core/tpl/board.tpl +4 -4
- package/src/maths/calculator/css/calculator.css +7 -7
- package/src/maths/calculator/css/calculator.css.map +1 -1
- package/src/maths/calculator/defaultCalculator.js +66 -66
- package/src/maths/calculator/plugins/core/degrad.js +90 -90
- package/src/maths/calculator/plugins/core/history.js +166 -166
- package/src/maths/calculator/plugins/core/remind.js +96 -96
- package/src/maths/calculator/plugins/core/stepNavigation.js +175 -175
- package/src/maths/calculator/plugins/keyboard/templateKeyboard/defaultTemplate.tpl +36 -36
- package/src/maths/calculator/plugins/keyboard/templateKeyboard/templateKeyboard.js +91 -91
- package/src/maths/calculator/plugins/modifiers/pow10.js +143 -143
- package/src/maths/calculator/plugins/modifiers/sign.js +339 -339
- package/src/maths/calculator/plugins/screen/simpleScreen/defaultTemplate.tpl +3 -3
- package/src/maths/calculator/plugins/screen/simpleScreen/history.tpl +3 -3
- package/src/maths/calculator/plugins/screen/simpleScreen/simpleScreen.js +191 -191
- package/src/maths/calculator/pluginsLoader.js +46 -46
- package/src/maths/calculator/scientificCalculator.js +74 -74
- package/src/maths/calculator/scss/calculator.scss +396 -396
- package/src/maths/calculator/tpl/basicKeyboard.tpl +37 -37
- package/src/maths/calculator/tpl/basicScreen.tpl +2 -2
- package/src/maths/calculator/tpl/scientificKeyboard.tpl +61 -61
- package/src/maths/calculator/tpl/scientificScreen.tpl +3 -3
- package/src/mediaEditor/mediaEditorComponent.js +141 -141
- package/src/mediaEditor/plugins/mediaAlignment/helper.js +62 -62
- package/src/mediaEditor/plugins/mediaAlignment/mediaAlignmentComponent.js +99 -99
- package/src/mediaEditor/plugins/mediaAlignment/style.css +7 -7
- package/src/mediaEditor/plugins/mediaAlignment/tpl/mediaAlignment.tpl +25 -25
- package/src/mediaEditor/plugins/mediaDimension/helper.js +189 -189
- package/src/mediaEditor/plugins/mediaDimension/mediaDimensionComponent.js +561 -561
- package/src/mediaEditor/plugins/mediaDimension/style.css +141 -141
- package/src/mediaEditor/plugins/mediaDimension/tpl/mediaDimension.tpl +55 -55
- package/src/mediaEditor/tpl/editor.tpl +4 -4
- package/src/mediaplayer/css/player.css +7 -7
- package/src/mediaplayer/css/player.css.map +1 -1
- package/src/mediaplayer/players/html5.js +564 -564
- package/src/mediaplayer/players/youtube.js +323 -323
- package/src/mediaplayer/players.js +29 -29
- package/src/mediaplayer/readme.md +305 -305
- package/src/mediaplayer/scss/player.scss +569 -569
- package/src/mediaplayer/support.js +126 -126
- package/src/mediaplayer/tpl/audio.tpl +6 -6
- package/src/mediaplayer/tpl/player.tpl +37 -37
- package/src/mediaplayer/tpl/source.tpl +1 -1
- package/src/mediaplayer/tpl/video.tpl +6 -6
- package/src/mediaplayer/tpl/youtube.tpl +1 -1
- package/src/mediaplayer/utils/reminder.js +184 -184
- package/src/mediaplayer/utils/timeObserver.js +143 -143
- package/src/mediaplayer/youtubeManager.js +161 -161
- package/src/mediaplayer.js +1606 -1606
- package/src/mediasizer/mediasizer.tpl +55 -55
- package/src/mediasizer.js +635 -635
- package/src/modal.js +365 -365
- package/src/movableComponent.js +78 -78
- package/src/pageSizeSelector/tpl/pageSizeSelector.tpl +9 -9
- package/src/pageSizeSelector.js +107 -107
- package/src/pageStatus.js +147 -147
- package/src/pagination/css/pagination.css +7 -7
- package/src/pagination/css/pagination.css.map +1 -1
- package/src/pagination/paginationStrategy.js +53 -53
- package/src/pagination/providers/pages.js +161 -161
- package/src/pagination/providers/simple.js +74 -74
- package/src/pagination/providers/tpl/pages/page.tpl +1 -1
- package/src/pagination/providers/tpl/pages.tpl +8 -8
- package/src/pagination/providers/tpl/simple.tpl +7 -7
- package/src/pagination/scss/pagination.scss +111 -111
- package/src/pagination.js +237 -237
- package/src/previewer.js +300 -300
- package/src/progressbar.js +165 -165
- package/src/propertySelector/css/propertySelector.css +74 -0
- package/src/propertySelector/css/propertySelector.css.map +1 -0
- package/src/propertySelector/propertySelector.js +286 -0
- package/src/propertySelector/scss/propertySelector.scss +66 -0
- package/src/propertySelector/tpl/highlighted-text.tpl +1 -0
- package/src/propertySelector/tpl/property-description.tpl +13 -0
- package/src/propertySelector/tpl/property-selector.tpl +7 -0
- package/src/report/feedback.tpl +11 -11
- package/src/report/layout.tpl +10 -10
- package/src/report.js +184 -184
- package/src/resource/css/selector.css +7 -7
- package/src/resource/css/selector.css.map +1 -1
- package/src/resource/filters.js +208 -208
- package/src/resource/list.js +200 -200
- package/src/resource/scss/_filters.scss +26 -26
- package/src/resource/scss/_resource-list.scss +107 -107
- package/src/resource/scss/_resource-tree.scss +205 -205
- package/src/resource/scss/selector.scss +187 -187
- package/src/resource/selectable.js +322 -322
- package/src/resource/selector.js +871 -871
- package/src/resource/tpl/filters.tpl +2 -2
- package/src/resource/tpl/list.tpl +7 -7
- package/src/resource/tpl/listNode.tpl +4 -4
- package/src/resource/tpl/selector.tpl +46 -46
- package/src/resource/tpl/tree.tpl +4 -4
- package/src/resource/tpl/treeNode.tpl +30 -30
- package/src/resource/tree.js +400 -400
- package/src/resourcemgr/css/resourcemgr.css +7 -7
- package/src/resourcemgr/css/resourcemgr.css.map +1 -1
- package/src/resourcemgr/fileBrowser.js +381 -381
- package/src/resourcemgr/filePreview.js +73 -73
- package/src/resourcemgr/fileSelector.js +348 -348
- package/src/resourcemgr/scss/resourcemgr.scss +254 -254
- package/src/resourcemgr/tpl/fileSelect.tpl +39 -39
- package/src/resourcemgr/tpl/folder.tpl +11 -11
- package/src/resourcemgr/tpl/layout.tpl +84 -84
- package/src/resourcemgr/tpl/rootFolder.tpl +13 -13
- package/src/resourcemgr/util/updatePermissions.js +53 -53
- package/src/resourcemgr.js +216 -216
- package/src/scroller.js +94 -94
- package/src/scss/basic.scss +16 -16
- package/src/searchModal/advancedSearch.js +638 -601
- package/src/searchModal/css/advancedSearch.css +7 -14
- package/src/searchModal/css/advancedSearch.css.map +1 -1
- package/src/searchModal/css/searchModal.css +28 -8
- package/src/searchModal/css/searchModal.css.map +1 -1
- package/src/searchModal/scss/advancedSearch.scss +171 -177
- package/src/searchModal/scss/searchModal.scss +393 -375
- package/src/searchModal/tpl/advanced-search.tpl +9 -9
- package/src/searchModal/tpl/criteria-alias.tpl +1 -0
- package/src/searchModal/tpl/criteria-class-label.tpl +1 -0
- package/src/searchModal/tpl/criteria-label.tpl +1 -0
- package/src/searchModal/tpl/highlighted-text.tpl +1 -0
- package/src/searchModal/tpl/info-message.tpl +3 -3
- package/src/searchModal/tpl/invalid-criteria-warning.tpl +10 -10
- package/src/searchModal/tpl/layout.tpl +27 -25
- package/src/searchModal/tpl/list-checkbox-criterion.tpl +17 -12
- package/src/searchModal/tpl/list-select-criterion.tpl +12 -6
- package/src/searchModal/tpl/property-select-button.tpl +1 -0
- package/src/searchModal/tpl/results-container.tpl +1 -0
- package/src/searchModal/tpl/text-criterion.tpl +11 -6
- package/src/searchModal.js +761 -496
- package/src/selecter.js +43 -43
- package/src/stacker.js +133 -133
- package/src/switch/css/switch.css +7 -7
- package/src/switch/css/switch.css.map +1 -1
- package/src/switch/scss/switch.scss +83 -83
- package/src/switch/switch.js +195 -195
- package/src/switch/tpl/switch.tpl +7 -7
- package/src/tableModel.js +112 -112
- package/src/tabs/css/tabs.css +12 -12
- package/src/tabs/css/tabs.css.map +1 -1
- package/src/tabs/scss/tabs.scss +50 -50
- package/src/tabs/tpl/panel.tpl +3 -3
- package/src/tabs/tpl/tabs.tpl +10 -10
- package/src/tabs.js +528 -528
- package/src/taskQueue/css/taskQueue.css +7 -7
- package/src/taskQueue/css/taskQueue.css.map +1 -1
- package/src/taskQueue/scss/taskQueue.scss +47 -47
- package/src/taskQueue/status.js +228 -228
- package/src/taskQueue/table.js +350 -350
- package/src/taskQueue/taskQueue.js +33 -33
- package/src/taskQueue/taskQueueModel.js +548 -548
- package/src/taskQueue/tpl/statusMessage.tpl +7 -7
- package/src/taskQueue.js +218 -218
- package/src/taskQueueButton/css/taskable.css +7 -7
- package/src/taskQueueButton/css/taskable.css.map +1 -1
- package/src/taskQueueButton/css/treeButton.css +7 -7
- package/src/taskQueueButton/css/treeButton.css.map +1 -1
- package/src/taskQueueButton/scss/taskable.scss +4 -4
- package/src/taskQueueButton/scss/treeButton.scss +34 -34
- package/src/taskQueueButton/standardButton.js +108 -108
- package/src/taskQueueButton/taskable.js +202 -202
- package/src/taskQueueButton/tpl/report.tpl +5 -5
- package/src/taskQueueButton/tpl/treeButton.tpl +6 -6
- package/src/taskQueueButton/treeButton.js +109 -109
- package/src/themeLoader.js +252 -252
- package/src/themes.js +162 -162
- package/src/toggler.js +200 -200
- package/src/tooltip/default.tpl +3 -3
- package/src/tooltip.js +160 -160
- package/src/tooltipster.js +25 -25
- package/src/transformer.js +327 -327
- package/src/tristateCheckboxGroup/css/tristateCheckboxGroup.css +7 -7
- package/src/tristateCheckboxGroup/css/tristateCheckboxGroup.css.map +1 -1
- package/src/tristateCheckboxGroup/scss/tristateCheckboxGroup.scss +15 -15
- package/src/tristateCheckboxGroup/tpl/li.tpl +6 -6
- package/src/tristateCheckboxGroup.js +207 -207
- package/src/uploader/fileEntry.tpl +6 -6
- package/src/uploader/uploader.tpl +32 -32
- package/src/uploader.js +594 -594
- package/src/validator/Report.js +10 -10
- package/src/validator/Validator.js +108 -108
- package/src/validator/validators.js +220 -220
- package/src/validator.js +264 -264
- package/src/waitForMedia.js +82 -82
- package/src/waitingDialog/css/waitingDialog.css +7 -7
- package/src/waitingDialog/css/waitingDialog.css.map +1 -1
- package/src/waitingDialog/scss/waitingDialog.scss +34 -34
- package/src/waitingDialog/waitingDialog.js +240 -240
package/dist/resource/tree.js
CHANGED
|
@@ -1,1886 +1,2070 @@
|
|
|
1
1
|
define(['jquery', 'lodash', 'ui/component', 'ui/resource/selectable', 'ui/hider', 'handlebars', 'i18n', 'lib/dompurify/purify'], function ($$1, _, component, selectable, hider, Handlebars, __, DOMPurify) { 'use strict';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
function _typeof(obj) {
|
|
13
|
-
"@babel/helpers - typeof";
|
|
14
|
-
|
|
15
|
-
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) {
|
|
16
|
-
return typeof obj;
|
|
17
|
-
} : function (obj) {
|
|
18
|
-
return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
|
|
19
|
-
}, _typeof(obj);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function Helpers0 (hb) {
|
|
23
|
-
//register a i18n helper
|
|
24
|
-
hb.registerHelper('__', function (key) {
|
|
25
|
-
return __(key);
|
|
26
|
-
});
|
|
27
|
-
/**
|
|
28
|
-
* Register dompurify helper
|
|
29
|
-
*
|
|
30
|
-
* https://github.com/cure53/DOMPurify
|
|
31
|
-
* with config SAFE_FOR_TEMPLATES: true
|
|
32
|
-
* to make output safe for template systems
|
|
33
|
-
*/
|
|
3
|
+
$$1 = $$1 && Object.prototype.hasOwnProperty.call($$1, 'default') ? $$1['default'] : $$1;
|
|
4
|
+
_ = _ && Object.prototype.hasOwnProperty.call(_, 'default') ? _['default'] : _;
|
|
5
|
+
component = component && Object.prototype.hasOwnProperty.call(component, 'default') ? component['default'] : component;
|
|
6
|
+
selectable = selectable && Object.prototype.hasOwnProperty.call(selectable, 'default') ? selectable['default'] : selectable;
|
|
7
|
+
hider = hider && Object.prototype.hasOwnProperty.call(hider, 'default') ? hider['default'] : hider;
|
|
8
|
+
Handlebars = Handlebars && Object.prototype.hasOwnProperty.call(Handlebars, 'default') ? Handlebars['default'] : Handlebars;
|
|
9
|
+
__ = __ && Object.prototype.hasOwnProperty.call(__, 'default') ? __['default'] : __;
|
|
10
|
+
DOMPurify = DOMPurify && Object.prototype.hasOwnProperty.call(DOMPurify, 'default') ? DOMPurify['default'] : DOMPurify;
|
|
34
11
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
12
|
+
/**
|
|
13
|
+
* This program is free software; you can redistribute it and/or
|
|
14
|
+
* modify it under the terms of the GNU General Public License
|
|
15
|
+
* as published by the Free Software Foundation; under version 2
|
|
16
|
+
* of the License (non-upgradable).
|
|
17
|
+
*
|
|
18
|
+
* This program is distributed in the hope that it will be useful,
|
|
19
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
20
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
21
|
+
* GNU General Public License for more details.
|
|
22
|
+
*
|
|
23
|
+
* You should have received a copy of the GNU General Public License
|
|
24
|
+
* along with this program; if not, write to the Free Software
|
|
25
|
+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
26
|
+
*
|
|
27
|
+
* Copyright (c) 2013-2019 (original work) Open Assessment Technologies SA (under the project TAO-PRODUCT);
|
|
28
|
+
*
|
|
29
|
+
*
|
|
45
30
|
*/
|
|
31
|
+
function Helpers0 (hb) {
|
|
32
|
+
//register a i18n helper
|
|
33
|
+
hb.registerHelper('__', function (key) {
|
|
34
|
+
return __(key);
|
|
35
|
+
});
|
|
46
36
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
37
|
+
/**
|
|
38
|
+
* Register dompurify helper
|
|
39
|
+
*
|
|
40
|
+
* https://github.com/cure53/DOMPurify
|
|
41
|
+
* with config SAFE_FOR_TEMPLATES: true
|
|
42
|
+
* to make output safe for template systems
|
|
43
|
+
*/
|
|
44
|
+
hb.registerHelper('dompurify', function (context) {
|
|
45
|
+
return DOMPurify.sanitize(context);
|
|
46
|
+
});
|
|
55
47
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
48
|
+
/**
|
|
49
|
+
* Register join helper
|
|
50
|
+
*
|
|
51
|
+
* Example :
|
|
52
|
+
* var values = {a:v1, b:v2, c:v3};
|
|
53
|
+
* Using {{{join attributes '=' ' ' '"'}}} will return : a="v1" b="v2" c="v3"
|
|
54
|
+
* Using {{{join values null ' or ' '*'}}} will return : *v1* or *v2* or *v3*
|
|
55
|
+
*/
|
|
56
|
+
hb.registerHelper('join', function (arr, keyValueGlue, fragmentGlue, wrapper) {
|
|
57
|
+
var fragments = [];
|
|
58
|
+
keyValueGlue = typeof keyValueGlue === 'string' ? keyValueGlue : undefined;
|
|
59
|
+
fragmentGlue = typeof fragmentGlue === 'string' ? fragmentGlue : ' ';
|
|
60
|
+
wrapper = typeof wrapper === 'string' ? wrapper : '"';
|
|
61
|
+
_.forIn(arr, function (value, key) {
|
|
62
|
+
var fragment = '';
|
|
63
|
+
if (value !== null || value !== undefined) {
|
|
64
|
+
if (typeof value === 'boolean') {
|
|
65
|
+
value = value ? 'true' : 'false';
|
|
66
|
+
} else if (typeof value === 'object') {
|
|
67
|
+
value = _.values(value).join(' ');
|
|
68
|
+
}
|
|
69
|
+
} else {
|
|
70
|
+
value = '';
|
|
61
71
|
}
|
|
72
|
+
if (keyValueGlue !== undefined) {
|
|
73
|
+
fragment += key + keyValueGlue;
|
|
74
|
+
}
|
|
75
|
+
fragment += wrapper + value + wrapper;
|
|
76
|
+
fragments.push(fragment);
|
|
77
|
+
});
|
|
78
|
+
return fragments.join(fragmentGlue);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
//register a classic "for loop" helper
|
|
82
|
+
//it also adds a local variable "i" as the index in each iteration loop
|
|
83
|
+
hb.registerHelper('for', function (startIndex, stopIndex, increment, options) {
|
|
84
|
+
var ret = '';
|
|
85
|
+
startIndex = parseInt(startIndex);
|
|
86
|
+
stopIndex = parseInt(stopIndex);
|
|
87
|
+
increment = parseInt(increment);
|
|
88
|
+
for (var i = startIndex; i < stopIndex; i += increment) {
|
|
89
|
+
ret += options.fn(_.extend({}, this, {
|
|
90
|
+
i: i
|
|
91
|
+
}));
|
|
92
|
+
}
|
|
93
|
+
return ret;
|
|
94
|
+
});
|
|
95
|
+
hb.registerHelper('equal', function (var1, var2, options) {
|
|
96
|
+
if (var1 == var2) {
|
|
97
|
+
return options.fn(this);
|
|
62
98
|
} else {
|
|
63
|
-
|
|
99
|
+
return options.inverse(this);
|
|
64
100
|
}
|
|
101
|
+
});
|
|
65
102
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
103
|
+
// register a "get property" helper
|
|
104
|
+
// it gets the named property from the provided context
|
|
105
|
+
hb.registerHelper('property', function (name, context) {
|
|
106
|
+
return context[name] || '';
|
|
107
|
+
});
|
|
69
108
|
|
|
70
|
-
|
|
71
|
-
|
|
109
|
+
// register an 'includes' helper
|
|
110
|
+
// it checks if value is in array
|
|
111
|
+
hb.registerHelper('includes', function (haystack, needle, options) {
|
|
112
|
+
if (_.contains(haystack, needle)) {
|
|
113
|
+
return options.fn(this);
|
|
114
|
+
}
|
|
72
115
|
});
|
|
116
|
+
}
|
|
73
117
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
118
|
+
if (!Helpers0.__initialized) {
|
|
119
|
+
Helpers0(Handlebars);
|
|
120
|
+
Helpers0.__initialized = true;
|
|
121
|
+
}
|
|
122
|
+
var Template = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) {
|
|
123
|
+
this.compilerInfo = [4,'>= 1.0.0'];
|
|
124
|
+
helpers = this.merge(helpers, Handlebars.helpers); data = data || {};
|
|
125
|
+
var buffer = "", stack1, self=this;
|
|
126
|
+
|
|
127
|
+
function program1(depth0,data) {
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
return "multiple";
|
|
131
|
+
}
|
|
77
132
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
133
|
+
buffer += "<div class=\"resource-tree ";
|
|
134
|
+
stack1 = helpers['if'].call(depth0, (depth0 && depth0.multiple), {hash:{},inverse:self.noop,fn:self.program(1, program1, data),data:data});
|
|
135
|
+
if(stack1 || stack1 === 0) { buffer += stack1; }
|
|
136
|
+
buffer += "\">\n <ul></ul>\n</div>\n\n";
|
|
137
|
+
return buffer;
|
|
138
|
+
});
|
|
139
|
+
function treeTpl(data, options, asString) {
|
|
140
|
+
var html = Template(data, options);
|
|
141
|
+
return (asString || true) ? html : $(html);
|
|
142
|
+
}
|
|
83
143
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
144
|
+
if (!Helpers0.__initialized) {
|
|
145
|
+
Helpers0(Handlebars);
|
|
146
|
+
Helpers0.__initialized = true;
|
|
147
|
+
}
|
|
148
|
+
var Template$1 = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) {
|
|
149
|
+
this.compilerInfo = [4,'>= 1.0.0'];
|
|
150
|
+
helpers = this.merge(helpers, Handlebars.helpers); data = data || {};
|
|
151
|
+
var buffer = "", stack1, helper, options, functionType="function", escapeExpression=this.escapeExpression, self=this, helperMissing=helpers.helperMissing;
|
|
152
|
+
|
|
153
|
+
function program1(depth0,data) {
|
|
154
|
+
|
|
155
|
+
var buffer = "", stack1, helper, options;
|
|
156
|
+
buffer += "\n<li data-uri=\"";
|
|
157
|
+
if (helper = helpers.uri) { stack1 = helper.call(depth0, {hash:{},data:data}); }
|
|
158
|
+
else { helper = (depth0 && depth0.uri); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
|
|
159
|
+
buffer += escapeExpression(stack1)
|
|
160
|
+
+ "\" class=\"class";
|
|
161
|
+
stack1 = helpers['if'].call(depth0, (depth0 && depth0.selectable), {hash:{},inverse:self.noop,fn:self.program(2, program2, data),data:data});
|
|
162
|
+
if(stack1 || stack1 === 0) { buffer += stack1; }
|
|
163
|
+
buffer += " ";
|
|
164
|
+
if (helper = helpers.state) { stack1 = helper.call(depth0, {hash:{},data:data}); }
|
|
165
|
+
else { helper = (depth0 && depth0.state); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
|
|
166
|
+
buffer += escapeExpression(stack1)
|
|
167
|
+
+ "\" data-count=\"";
|
|
168
|
+
if (helper = helpers.count) { stack1 = helper.call(depth0, {hash:{},data:data}); }
|
|
169
|
+
else { helper = (depth0 && depth0.count); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
|
|
170
|
+
buffer += escapeExpression(stack1)
|
|
171
|
+
+ "\" ";
|
|
172
|
+
stack1 = helpers['if'].call(depth0, (depth0 && depth0.accessMode), {hash:{},inverse:self.noop,fn:self.program(4, program4, data),data:data});
|
|
173
|
+
if(stack1 || stack1 === 0) { buffer += stack1; }
|
|
174
|
+
buffer += ">\n <a href=\"#\" title=\"";
|
|
175
|
+
if (helper = helpers.label) { stack1 = helper.call(depth0, {hash:{},data:data}); }
|
|
176
|
+
else { helper = (depth0 && depth0.label); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
|
|
177
|
+
if(stack1 || stack1 === 0) { buffer += stack1; }
|
|
178
|
+
buffer += "\">\n <span class=\"class-toggler clickable\" tabindex=\"0\"></span>\n <span class=\"icon-folder\"></span>\n ";
|
|
179
|
+
if (helper = helpers.label) { stack1 = helper.call(depth0, {hash:{},data:data}); }
|
|
180
|
+
else { helper = (depth0 && depth0.label); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
|
|
181
|
+
if(stack1 || stack1 === 0) { buffer += stack1; }
|
|
182
|
+
buffer += "\n <span class=\"selector clickable\" tabindex=\"0\"></span>\n </a>\n <ul>\n ";
|
|
183
|
+
stack1 = helpers['if'].call(depth0, (depth0 && depth0.childList), {hash:{},inverse:self.noop,fn:self.program(6, program6, data),data:data});
|
|
184
|
+
if(stack1 || stack1 === 0) { buffer += stack1; }
|
|
185
|
+
buffer += "\n </ul>\n <div class=\"more hidden\">\n <a href=\"#\" class=\"btn-info small\"><span class=\"icon-download\"></span> "
|
|
186
|
+
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Load more", options) : helperMissing.call(depth0, "__", "Load more", options)))
|
|
187
|
+
+ "</a>\n </div>\n</li>\n";
|
|
188
|
+
return buffer;
|
|
189
|
+
}
|
|
190
|
+
function program2(depth0,data) {
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
return " selectable";
|
|
88
194
|
}
|
|
89
195
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
}
|
|
96
|
-
|
|
196
|
+
function program4(depth0,data) {
|
|
197
|
+
|
|
198
|
+
var buffer = "", stack1, helper;
|
|
199
|
+
buffer += "data-access=\"";
|
|
200
|
+
if (helper = helpers.accessMode) { stack1 = helper.call(depth0, {hash:{},data:data}); }
|
|
201
|
+
else { helper = (depth0 && depth0.accessMode); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
|
|
202
|
+
buffer += escapeExpression(stack1)
|
|
203
|
+
+ "\"";
|
|
204
|
+
return buffer;
|
|
97
205
|
}
|
|
98
|
-
}); // register a "get property" helper
|
|
99
|
-
// it gets the named property from the provided context
|
|
100
206
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
207
|
+
function program6(depth0,data) {
|
|
208
|
+
|
|
209
|
+
var buffer = "", stack1, helper;
|
|
210
|
+
buffer += "\n ";
|
|
211
|
+
if (helper = helpers.childList) { stack1 = helper.call(depth0, {hash:{},data:data}); }
|
|
212
|
+
else { helper = (depth0 && depth0.childList); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
|
|
213
|
+
if(stack1 || stack1 === 0) { buffer += stack1; }
|
|
214
|
+
buffer += "\n ";
|
|
215
|
+
return buffer;
|
|
216
|
+
}
|
|
105
217
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
218
|
+
function program8(depth0,data) {
|
|
219
|
+
|
|
220
|
+
var buffer = "", stack1, helper;
|
|
221
|
+
buffer += "\n<li data-uri=\"";
|
|
222
|
+
if (helper = helpers.uri) { stack1 = helper.call(depth0, {hash:{},data:data}); }
|
|
223
|
+
else { helper = (depth0 && depth0.uri); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
|
|
224
|
+
buffer += escapeExpression(stack1)
|
|
225
|
+
+ "\" class=\"instance";
|
|
226
|
+
stack1 = helpers['if'].call(depth0, (depth0 && depth0.selectable), {hash:{},inverse:self.noop,fn:self.program(2, program2, data),data:data});
|
|
227
|
+
if(stack1 || stack1 === 0) { buffer += stack1; }
|
|
228
|
+
buffer += " ";
|
|
229
|
+
if (helper = helpers.state) { stack1 = helper.call(depth0, {hash:{},data:data}); }
|
|
230
|
+
else { helper = (depth0 && depth0.state); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
|
|
231
|
+
buffer += escapeExpression(stack1)
|
|
232
|
+
+ "\" ";
|
|
233
|
+
stack1 = helpers['if'].call(depth0, (depth0 && depth0.accessMode), {hash:{},inverse:self.noop,fn:self.program(4, program4, data),data:data});
|
|
234
|
+
if(stack1 || stack1 === 0) { buffer += stack1; }
|
|
235
|
+
buffer += ">\n <a href=\"#\" title=\"";
|
|
236
|
+
if (helper = helpers.label) { stack1 = helper.call(depth0, {hash:{},data:data}); }
|
|
237
|
+
else { helper = (depth0 && depth0.label); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
|
|
238
|
+
if(stack1 || stack1 === 0) { buffer += stack1; }
|
|
239
|
+
buffer += "\">\n <span class=\"icon-";
|
|
240
|
+
if (helper = helpers.icon) { stack1 = helper.call(depth0, {hash:{},data:data}); }
|
|
241
|
+
else { helper = (depth0 && depth0.icon); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
|
|
242
|
+
buffer += escapeExpression(stack1)
|
|
243
|
+
+ "\"></span>\n ";
|
|
244
|
+
if (helper = helpers.label) { stack1 = helper.call(depth0, {hash:{},data:data}); }
|
|
245
|
+
else { helper = (depth0 && depth0.label); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
|
|
246
|
+
if(stack1 || stack1 === 0) { buffer += stack1; }
|
|
247
|
+
buffer += "\n <span class=\"selector clickable\" tabindex=\"0\"></span>\n </a>\n</li>\n";
|
|
248
|
+
return buffer;
|
|
109
249
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
function program1(depth0,data) {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
return "multiple";
|
|
250
|
+
|
|
251
|
+
stack1 = (helper = helpers.equal || (depth0 && depth0.equal),options={hash:{},inverse:self.noop,fn:self.program(1, program1, data),data:data},helper ? helper.call(depth0, (depth0 && depth0.type), "class", options) : helperMissing.call(depth0, "equal", (depth0 && depth0.type), "class", options));
|
|
252
|
+
if(stack1 || stack1 === 0) { buffer += stack1; }
|
|
253
|
+
buffer += "\n\n";
|
|
254
|
+
stack1 = (helper = helpers.equal || (depth0 && depth0.equal),options={hash:{},inverse:self.noop,fn:self.program(8, program8, data),data:data},helper ? helper.call(depth0, (depth0 && depth0.type), "instance", options) : helperMissing.call(depth0, "equal", (depth0 && depth0.type), "instance", options));
|
|
255
|
+
if(stack1 || stack1 === 0) { buffer += stack1; }
|
|
256
|
+
buffer += "\n\n\n";
|
|
257
|
+
return buffer;
|
|
258
|
+
});
|
|
259
|
+
function treeNodeTpl(data, options, asString) {
|
|
260
|
+
var html = Template$1(data, options);
|
|
261
|
+
return (asString || true) ? html : $(html);
|
|
126
262
|
}
|
|
127
263
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
if (!Helpers0.__initialized) {
|
|
140
|
-
Helpers0(Handlebars);
|
|
141
|
-
Helpers0.__initialized = true;
|
|
142
|
-
}
|
|
143
|
-
var Template$1 = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) {
|
|
144
|
-
this.compilerInfo = [4,'>= 1.0.0'];
|
|
145
|
-
helpers = this.merge(helpers, Handlebars.helpers); data = data || {};
|
|
146
|
-
var buffer = "", stack1, helper, options, functionType="function", escapeExpression=this.escapeExpression, self=this, helperMissing=helpers.helperMissing;
|
|
147
|
-
|
|
148
|
-
function program1(depth0,data) {
|
|
149
|
-
|
|
150
|
-
var buffer = "", stack1, helper, options;
|
|
151
|
-
buffer += "\r\n<li data-uri=\"";
|
|
152
|
-
if (helper = helpers.uri) { stack1 = helper.call(depth0, {hash:{},data:data}); }
|
|
153
|
-
else { helper = (depth0 && depth0.uri); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
|
|
154
|
-
buffer += escapeExpression(stack1)
|
|
155
|
-
+ "\" class=\"class";
|
|
156
|
-
stack1 = helpers['if'].call(depth0, (depth0 && depth0.selectable), {hash:{},inverse:self.noop,fn:self.program(2, program2, data),data:data});
|
|
157
|
-
if(stack1 || stack1 === 0) { buffer += stack1; }
|
|
158
|
-
buffer += " ";
|
|
159
|
-
if (helper = helpers.state) { stack1 = helper.call(depth0, {hash:{},data:data}); }
|
|
160
|
-
else { helper = (depth0 && depth0.state); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
|
|
161
|
-
buffer += escapeExpression(stack1)
|
|
162
|
-
+ "\" data-count=\"";
|
|
163
|
-
if (helper = helpers.count) { stack1 = helper.call(depth0, {hash:{},data:data}); }
|
|
164
|
-
else { helper = (depth0 && depth0.count); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
|
|
165
|
-
buffer += escapeExpression(stack1)
|
|
166
|
-
+ "\" ";
|
|
167
|
-
stack1 = helpers['if'].call(depth0, (depth0 && depth0.accessMode), {hash:{},inverse:self.noop,fn:self.program(4, program4, data),data:data});
|
|
168
|
-
if(stack1 || stack1 === 0) { buffer += stack1; }
|
|
169
|
-
buffer += ">\r\n <a href=\"#\" title=\"";
|
|
170
|
-
if (helper = helpers.label) { stack1 = helper.call(depth0, {hash:{},data:data}); }
|
|
171
|
-
else { helper = (depth0 && depth0.label); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
|
|
172
|
-
if(stack1 || stack1 === 0) { buffer += stack1; }
|
|
173
|
-
buffer += "\">\r\n <span class=\"class-toggler clickable\" tabindex=\"0\"></span>\r\n <span class=\"icon-folder\"></span>\r\n ";
|
|
174
|
-
if (helper = helpers.label) { stack1 = helper.call(depth0, {hash:{},data:data}); }
|
|
175
|
-
else { helper = (depth0 && depth0.label); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
|
|
176
|
-
if(stack1 || stack1 === 0) { buffer += stack1; }
|
|
177
|
-
buffer += "\r\n <span class=\"selector clickable\" tabindex=\"0\"></span>\r\n </a>\r\n <ul>\r\n ";
|
|
178
|
-
stack1 = helpers['if'].call(depth0, (depth0 && depth0.childList), {hash:{},inverse:self.noop,fn:self.program(6, program6, data),data:data});
|
|
179
|
-
if(stack1 || stack1 === 0) { buffer += stack1; }
|
|
180
|
-
buffer += "\r\n </ul>\r\n <div class=\"more hidden\">\r\n <a href=\"#\" class=\"btn-info small\"><span class=\"icon-download\"></span> "
|
|
181
|
-
+ escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Load more", options) : helperMissing.call(depth0, "__", "Load more", options)))
|
|
182
|
-
+ "</a>\r\n </div>\r\n</li>\r\n";
|
|
183
|
-
return buffer;
|
|
264
|
+
/*! @license DOMPurify 2.4.0 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/2.4.0/LICENSE */
|
|
265
|
+
|
|
266
|
+
function _typeof(obj) {
|
|
267
|
+
"@babel/helpers - typeof";
|
|
268
|
+
|
|
269
|
+
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) {
|
|
270
|
+
return typeof obj;
|
|
271
|
+
} : function (obj) {
|
|
272
|
+
return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
|
|
273
|
+
}, _typeof(obj);
|
|
184
274
|
}
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
275
|
+
function _setPrototypeOf(o, p) {
|
|
276
|
+
_setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
|
|
277
|
+
o.__proto__ = p;
|
|
278
|
+
return o;
|
|
279
|
+
};
|
|
280
|
+
return _setPrototypeOf(o, p);
|
|
189
281
|
}
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
282
|
+
function _isNativeReflectConstruct() {
|
|
283
|
+
if (typeof Reflect === "undefined" || !Reflect.construct) return false;
|
|
284
|
+
if (Reflect.construct.sham) return false;
|
|
285
|
+
if (typeof Proxy === "function") return true;
|
|
286
|
+
try {
|
|
287
|
+
Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
|
|
288
|
+
return true;
|
|
289
|
+
} catch (e) {
|
|
290
|
+
return false;
|
|
291
|
+
}
|
|
200
292
|
}
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
293
|
+
function _construct(Parent, args, Class) {
|
|
294
|
+
if (_isNativeReflectConstruct()) {
|
|
295
|
+
_construct = Reflect.construct;
|
|
296
|
+
} else {
|
|
297
|
+
_construct = function _construct(Parent, args, Class) {
|
|
298
|
+
var a = [null];
|
|
299
|
+
a.push.apply(a, args);
|
|
300
|
+
var Constructor = Function.bind.apply(Parent, a);
|
|
301
|
+
var instance = new Constructor();
|
|
302
|
+
if (Class) _setPrototypeOf(instance, Class.prototype);
|
|
303
|
+
return instance;
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
return _construct.apply(null, arguments);
|
|
211
307
|
}
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
var buffer = "", stack1, helper;
|
|
216
|
-
buffer += "\r\n<li data-uri=\"";
|
|
217
|
-
if (helper = helpers.uri) { stack1 = helper.call(depth0, {hash:{},data:data}); }
|
|
218
|
-
else { helper = (depth0 && depth0.uri); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
|
|
219
|
-
buffer += escapeExpression(stack1)
|
|
220
|
-
+ "\" class=\"instance";
|
|
221
|
-
stack1 = helpers['if'].call(depth0, (depth0 && depth0.selectable), {hash:{},inverse:self.noop,fn:self.program(2, program2, data),data:data});
|
|
222
|
-
if(stack1 || stack1 === 0) { buffer += stack1; }
|
|
223
|
-
buffer += " ";
|
|
224
|
-
if (helper = helpers.state) { stack1 = helper.call(depth0, {hash:{},data:data}); }
|
|
225
|
-
else { helper = (depth0 && depth0.state); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
|
|
226
|
-
buffer += escapeExpression(stack1)
|
|
227
|
-
+ "\" ";
|
|
228
|
-
stack1 = helpers['if'].call(depth0, (depth0 && depth0.accessMode), {hash:{},inverse:self.noop,fn:self.program(4, program4, data),data:data});
|
|
229
|
-
if(stack1 || stack1 === 0) { buffer += stack1; }
|
|
230
|
-
buffer += ">\r\n <a href=\"#\" title=\"";
|
|
231
|
-
if (helper = helpers.label) { stack1 = helper.call(depth0, {hash:{},data:data}); }
|
|
232
|
-
else { helper = (depth0 && depth0.label); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
|
|
233
|
-
if(stack1 || stack1 === 0) { buffer += stack1; }
|
|
234
|
-
buffer += "\">\r\n <span class=\"icon-";
|
|
235
|
-
if (helper = helpers.icon) { stack1 = helper.call(depth0, {hash:{},data:data}); }
|
|
236
|
-
else { helper = (depth0 && depth0.icon); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
|
|
237
|
-
buffer += escapeExpression(stack1)
|
|
238
|
-
+ "\"></span>\r\n ";
|
|
239
|
-
if (helper = helpers.label) { stack1 = helper.call(depth0, {hash:{},data:data}); }
|
|
240
|
-
else { helper = (depth0 && depth0.label); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
|
|
241
|
-
if(stack1 || stack1 === 0) { buffer += stack1; }
|
|
242
|
-
buffer += "\r\n <span class=\"selector clickable\" tabindex=\"0\"></span>\r\n </a>\r\n</li>\r\n";
|
|
243
|
-
return buffer;
|
|
308
|
+
function _toConsumableArray(arr) {
|
|
309
|
+
return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
|
|
244
310
|
}
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
if(stack1 || stack1 === 0) { buffer += stack1; }
|
|
248
|
-
buffer += "\r\n\r\n";
|
|
249
|
-
stack1 = (helper = helpers.equal || (depth0 && depth0.equal),options={hash:{},inverse:self.noop,fn:self.program(8, program8, data),data:data},helper ? helper.call(depth0, (depth0 && depth0.type), "instance", options) : helperMissing.call(depth0, "equal", (depth0 && depth0.type), "instance", options));
|
|
250
|
-
if(stack1 || stack1 === 0) { buffer += stack1; }
|
|
251
|
-
buffer += "\r\n\r\n\r\n";
|
|
252
|
-
return buffer;
|
|
253
|
-
});
|
|
254
|
-
function treeNodeTpl(data, options, asString) {
|
|
255
|
-
var html = Template$1(data, options);
|
|
256
|
-
return (asString || true) ? html : $(html);
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
var freeze$1 = Object.freeze || function (x) {
|
|
260
|
-
return x;
|
|
261
|
-
};
|
|
262
|
-
|
|
263
|
-
var html = freeze$1(['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', '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', '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']); // SVG
|
|
264
|
-
|
|
265
|
-
var svg = freeze$1(['svg', 'a', 'altglyph', 'altglyphdef', 'altglyphitem', 'animatecolor', 'animatemotion', 'animatetransform', 'audio', 'canvas', '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', 'video', 'view', 'vkern']);
|
|
266
|
-
var svgFilters = freeze$1(['feBlend', 'feColorMatrix', 'feComponentTransfer', 'feComposite', 'feConvolveMatrix', 'feDiffuseLighting', 'feDisplacementMap', 'feDistantLight', 'feFlood', 'feFuncA', 'feFuncB', 'feFuncG', 'feFuncR', 'feGaussianBlur', 'feMerge', 'feMergeNode', 'feMorphology', 'feOffset', 'fePointLight', 'feSpecularLighting', 'feSpotLight', 'feTile', 'feTurbulence']);
|
|
267
|
-
var mathMl = freeze$1(['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']);
|
|
268
|
-
var text = freeze$1(['#text']);
|
|
269
|
-
|
|
270
|
-
var freeze$2 = Object.freeze || function (x) {
|
|
271
|
-
return x;
|
|
272
|
-
};
|
|
273
|
-
|
|
274
|
-
var html$1 = freeze$2(['accept', 'action', 'align', 'alt', 'autocomplete', 'background', 'bgcolor', 'border', 'cellpadding', 'cellspacing', 'checked', 'cite', 'class', 'clear', 'color', 'cols', 'colspan', 'controls', 'coords', 'crossorigin', 'datetime', 'default', 'dir', 'disabled', 'download', 'enctype', 'face', 'for', 'headers', 'height', 'hidden', 'high', 'href', 'hreflang', 'id', 'integrity', 'ismap', 'label', 'lang', 'list', 'loop', 'low', 'max', 'maxlength', 'media', 'method', 'min', 'multiple', 'name', 'noshade', 'novalidate', 'nowrap', 'open', 'optimum', 'pattern', 'placeholder', 'poster', 'preload', 'pubdate', 'radiogroup', 'readonly', 'rel', 'required', 'rev', 'reversed', 'role', 'rows', 'rowspan', 'spellcheck', 'scope', 'selected', 'shape', 'size', 'sizes', 'span', 'srclang', 'start', 'src', 'srcset', 'step', 'style', 'summary', 'tabindex', 'title', 'type', 'usemap', 'valign', 'value', 'width', 'xmlns']);
|
|
275
|
-
var svg$1 = freeze$2(['accent-height', 'accumulate', 'additive', 'alignment-baseline', 'ascent', 'attributename', 'attributetype', 'azimuth', 'basefrequency', 'baseline-shift', 'begin', 'bias', 'by', 'class', 'clip', 'clip-path', 'clip-rule', 'color', 'color-interpolation', 'color-interpolation-filters', 'color-profile', 'color-rendering', 'cx', 'cy', 'd', 'dx', 'dy', 'diffuseconstant', 'direction', 'display', 'divisor', 'dur', 'edgemode', 'elevation', 'end', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'filterunits', 'flood-color', 'flood-opacity', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'fx', 'fy', 'g1', 'g2', 'glyph-name', 'glyphref', 'gradientunits', 'gradienttransform', 'height', 'href', 'id', 'image-rendering', 'in', 'in2', 'k', 'k1', 'k2', 'k3', 'k4', 'kerning', 'keypoints', 'keysplines', 'keytimes', 'lang', 'lengthadjust', 'letter-spacing', 'kernelmatrix', 'kernelunitlength', 'lighting-color', 'local', 'marker-end', 'marker-mid', 'marker-start', 'markerheight', 'markerunits', 'markerwidth', 'maskcontentunits', 'maskunits', 'max', 'mask', 'media', 'method', 'mode', 'min', 'name', 'numoctaves', 'offset', 'operator', 'opacity', 'order', 'orient', 'orientation', 'origin', 'overflow', 'paint-order', 'path', 'pathlength', 'patterncontentunits', 'patterntransform', 'patternunits', 'points', 'preservealpha', 'preserveaspectratio', 'primitiveunits', 'r', 'rx', 'ry', 'radius', 'refx', 'refy', 'repeatcount', 'repeatdur', 'restart', 'result', 'rotate', 'scale', 'seed', 'shape-rendering', 'specularconstant', 'specularexponent', 'spreadmethod', 'stddeviation', 'stitchtiles', 'stop-color', 'stop-opacity', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke', 'stroke-width', 'style', 'surfacescale', 'tabindex', 'targetx', 'targety', 'transform', 'text-anchor', 'text-decoration', 'text-rendering', 'textlength', 'type', 'u1', 'u2', 'unicode', 'values', 'viewbox', 'visibility', 'version', 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', 'width', 'word-spacing', 'wrap', 'writing-mode', 'xchannelselector', 'ychannelselector', 'x', 'x1', 'x2', 'xmlns', 'y', 'y1', 'y2', 'z', 'zoomandpan']);
|
|
276
|
-
var mathMl$1 = freeze$2(['accent', 'accentunder', 'align', 'bevelled', 'close', 'columnsalign', 'columnlines', 'columnspan', 'denomalign', 'depth', 'dir', 'display', 'displaystyle', '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']);
|
|
277
|
-
var xml = freeze$2(['xlink:href', 'xml:id', 'xlink:title', 'xml:space', 'xmlns:xlink']);
|
|
278
|
-
var hasOwnProperty = Object.hasOwnProperty;
|
|
279
|
-
var setPrototypeOf = Object.setPrototypeOf;
|
|
280
|
-
|
|
281
|
-
var _ref$1 = typeof Reflect !== 'undefined' && Reflect;
|
|
282
|
-
|
|
283
|
-
var apply$1 = _ref$1.apply;
|
|
284
|
-
|
|
285
|
-
if (!apply$1) {
|
|
286
|
-
apply$1 = function apply(fun, thisValue, args) {
|
|
287
|
-
return fun.apply(thisValue, args);
|
|
288
|
-
};
|
|
289
|
-
}
|
|
290
|
-
/* Add properties to a lookup table */
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
function addToSet(set, array) {
|
|
294
|
-
if (setPrototypeOf) {
|
|
295
|
-
// Make 'in' and truthy checks like Boolean(set.constructor)
|
|
296
|
-
// independent of any properties defined on Object.prototype.
|
|
297
|
-
// Prevent prototype setters from intercepting set as a this value.
|
|
298
|
-
setPrototypeOf(set, null);
|
|
311
|
+
function _arrayWithoutHoles(arr) {
|
|
312
|
+
if (Array.isArray(arr)) return _arrayLikeToArray(arr);
|
|
299
313
|
}
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
314
|
+
function _iterableToArray(iter) {
|
|
315
|
+
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
|
|
316
|
+
}
|
|
317
|
+
function _unsupportedIterableToArray(o, minLen) {
|
|
318
|
+
if (!o) return;
|
|
319
|
+
if (typeof o === "string") return _arrayLikeToArray(o, minLen);
|
|
320
|
+
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
321
|
+
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
322
|
+
if (n === "Map" || n === "Set") return Array.from(o);
|
|
323
|
+
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
|
|
324
|
+
}
|
|
325
|
+
function _arrayLikeToArray(arr, len) {
|
|
326
|
+
if (len == null || len > arr.length) len = arr.length;
|
|
327
|
+
for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
|
|
328
|
+
return arr2;
|
|
329
|
+
}
|
|
330
|
+
function _nonIterableSpread() {
|
|
331
|
+
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
332
|
+
}
|
|
333
|
+
var hasOwnProperty = Object.hasOwnProperty,
|
|
334
|
+
setPrototypeOf = Object.setPrototypeOf,
|
|
335
|
+
isFrozen = Object.isFrozen,
|
|
336
|
+
getPrototypeOf = Object.getPrototypeOf,
|
|
337
|
+
getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
|
|
338
|
+
var freeze = Object.freeze,
|
|
339
|
+
seal = Object.seal,
|
|
340
|
+
create = Object.create; // eslint-disable-line import/no-mutable-exports
|
|
341
|
+
|
|
342
|
+
var _ref = typeof Reflect !== 'undefined' && Reflect,
|
|
343
|
+
apply = _ref.apply,
|
|
344
|
+
construct = _ref.construct;
|
|
345
|
+
if (!apply) {
|
|
346
|
+
apply = function apply(fun, thisValue, args) {
|
|
347
|
+
return fun.apply(thisValue, args);
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
if (!freeze) {
|
|
351
|
+
freeze = function freeze(x) {
|
|
352
|
+
return x;
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
if (!seal) {
|
|
356
|
+
seal = function seal(x) {
|
|
357
|
+
return x;
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
if (!construct) {
|
|
361
|
+
construct = function construct(Func, args) {
|
|
362
|
+
return _construct(Func, _toConsumableArray(args));
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
var arrayForEach = unapply(Array.prototype.forEach);
|
|
366
|
+
var arrayPop = unapply(Array.prototype.pop);
|
|
367
|
+
var arrayPush = unapply(Array.prototype.push);
|
|
368
|
+
var stringToLowerCase = unapply(String.prototype.toLowerCase);
|
|
369
|
+
var stringMatch = unapply(String.prototype.match);
|
|
370
|
+
var stringReplace = unapply(String.prototype.replace);
|
|
371
|
+
var stringIndexOf = unapply(String.prototype.indexOf);
|
|
372
|
+
var stringTrim = unapply(String.prototype.trim);
|
|
373
|
+
var regExpTest = unapply(RegExp.prototype.test);
|
|
374
|
+
var typeErrorCreate = unconstruct(TypeError);
|
|
375
|
+
function unapply(func) {
|
|
376
|
+
return function (thisArg) {
|
|
377
|
+
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|
378
|
+
args[_key - 1] = arguments[_key];
|
|
379
|
+
}
|
|
380
|
+
return apply(func, thisArg, args);
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
function unconstruct(func) {
|
|
384
|
+
return function () {
|
|
385
|
+
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
|
|
386
|
+
args[_key2] = arguments[_key2];
|
|
387
|
+
}
|
|
388
|
+
return construct(func, args);
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
/* Add properties to a lookup table */
|
|
392
|
+
|
|
393
|
+
function addToSet(set, array, transformCaseFunc) {
|
|
394
|
+
transformCaseFunc = transformCaseFunc ? transformCaseFunc : stringToLowerCase;
|
|
395
|
+
if (setPrototypeOf) {
|
|
396
|
+
// Make 'in' and truthy checks like Boolean(set.constructor)
|
|
397
|
+
// independent of any properties defined on Object.prototype.
|
|
398
|
+
// Prevent prototype setters from intercepting set as a this value.
|
|
399
|
+
setPrototypeOf(set, null);
|
|
400
|
+
}
|
|
401
|
+
var l = array.length;
|
|
402
|
+
while (l--) {
|
|
403
|
+
var element = array[l];
|
|
404
|
+
if (typeof element === 'string') {
|
|
405
|
+
var lcElement = transformCaseFunc(element);
|
|
406
|
+
if (lcElement !== element) {
|
|
407
|
+
// Config presets (e.g. tags.js, attrs.js) are immutable.
|
|
408
|
+
if (!isFrozen(array)) {
|
|
409
|
+
array[l] = lcElement;
|
|
410
|
+
}
|
|
411
|
+
element = lcElement;
|
|
313
412
|
}
|
|
314
|
-
|
|
315
|
-
element = lcElement;
|
|
316
413
|
}
|
|
414
|
+
set[element] = true;
|
|
317
415
|
}
|
|
318
|
-
|
|
319
|
-
set[element] = true;
|
|
416
|
+
return set;
|
|
320
417
|
}
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
for (property in object) {
|
|
332
|
-
if (apply$1(hasOwnProperty, object, [property])) {
|
|
333
|
-
newObject[property] = object[property];
|
|
418
|
+
/* Shallow clone an object */
|
|
419
|
+
|
|
420
|
+
function clone(object) {
|
|
421
|
+
var newObject = create(null);
|
|
422
|
+
var property;
|
|
423
|
+
for (property in object) {
|
|
424
|
+
if (apply(hasOwnProperty, object, [property])) {
|
|
425
|
+
newObject[property] = object[property];
|
|
426
|
+
}
|
|
334
427
|
}
|
|
428
|
+
return newObject;
|
|
335
429
|
}
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
var IS_SCRIPT_OR_DATA = seal(/^(?:\w+script|data):/i);
|
|
354
|
-
var ATTR_WHITESPACE = seal(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205f\u3000]/g // eslint-disable-line no-control-regex
|
|
355
|
-
);
|
|
356
|
-
|
|
357
|
-
var _typeof$1 = typeof Symbol === "function" && _typeof(Symbol.iterator) === "symbol" ? function (obj) {
|
|
358
|
-
return _typeof(obj);
|
|
359
|
-
} : function (obj) {
|
|
360
|
-
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : _typeof(obj);
|
|
361
|
-
};
|
|
362
|
-
|
|
363
|
-
function _toConsumableArray(arr) {
|
|
364
|
-
if (Array.isArray(arr)) {
|
|
365
|
-
for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) {
|
|
366
|
-
arr2[i] = arr[i];
|
|
430
|
+
/* IE10 doesn't support __lookupGetter__ so lets'
|
|
431
|
+
* simulate it. It also automatically checks
|
|
432
|
+
* if the prop is function or getter and behaves
|
|
433
|
+
* accordingly. */
|
|
434
|
+
|
|
435
|
+
function lookupGetter(object, prop) {
|
|
436
|
+
while (object !== null) {
|
|
437
|
+
var desc = getOwnPropertyDescriptor(object, prop);
|
|
438
|
+
if (desc) {
|
|
439
|
+
if (desc.get) {
|
|
440
|
+
return unapply(desc.get);
|
|
441
|
+
}
|
|
442
|
+
if (typeof desc.value === 'function') {
|
|
443
|
+
return unapply(desc.value);
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
object = getPrototypeOf(object);
|
|
367
447
|
}
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
448
|
+
function fallbackValue(element) {
|
|
449
|
+
console.warn('fallback value for', element);
|
|
450
|
+
return null;
|
|
451
|
+
}
|
|
452
|
+
return fallbackValue;
|
|
372
453
|
}
|
|
373
|
-
|
|
454
|
+
var 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']); // SVG
|
|
374
455
|
|
|
375
|
-
|
|
456
|
+
var 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']);
|
|
457
|
+
var svgFilters = freeze(['feBlend', 'feColorMatrix', 'feComponentTransfer', 'feComposite', 'feConvolveMatrix', 'feDiffuseLighting', 'feDisplacementMap', 'feDistantLight', 'feFlood', 'feFuncA', 'feFuncB', 'feFuncG', 'feFuncR', 'feGaussianBlur', 'feImage', 'feMerge', 'feMergeNode', 'feMorphology', 'feOffset', 'fePointLight', 'feSpecularLighting', 'feSpotLight', 'feTile', 'feTurbulence']); // List of SVG elements that are disallowed by default.
|
|
458
|
+
// We still need to know them so that we can do namespace
|
|
459
|
+
// checks properly in case one wants to add them to
|
|
460
|
+
// allow-list.
|
|
376
461
|
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
462
|
+
var svgDisallowed = freeze(['animate', 'color-profile', 'cursor', 'discard', 'fedropshadow', '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']);
|
|
463
|
+
var 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']); // Similarly to SVG, we want to know all MathML elements,
|
|
464
|
+
// even those that we disallow by default.
|
|
380
465
|
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
466
|
+
var mathMlDisallowed = freeze(['maction', 'maligngroup', 'malignmark', 'mlongdiv', 'mscarries', 'mscarry', 'msgroup', 'mstack', 'msline', 'msrow', 'semantics', 'annotation', 'annotation-xml', 'mprescripts', 'none']);
|
|
467
|
+
var text = freeze(['#text']);
|
|
468
|
+
var html = freeze(['accept', 'action', 'align', 'alt', 'autocapitalize', 'autocomplete', 'autopictureinpicture', 'autoplay', 'background', 'bgcolor', 'border', 'capture', 'cellpadding', 'cellspacing', 'checked', 'cite', 'class', 'clear', 'color', 'cols', 'colspan', 'controls', 'controlslist', 'coords', 'crossorigin', 'datetime', 'decoding', 'default', 'dir', 'disabled', 'disablepictureinpicture', 'disableremoteplayback', 'download', 'draggable', 'enctype', 'enterkeyhint', 'face', 'for', 'headers', 'height', 'hidden', 'high', 'href', 'hreflang', 'id', 'inputmode', 'integrity', 'ismap', 'kind', 'label', 'lang', 'list', 'loading', 'loop', 'low', 'max', 'maxlength', 'media', 'method', 'min', 'minlength', 'multiple', 'muted', 'name', 'nonce', 'noshade', 'novalidate', 'nowrap', 'open', 'optimum', 'pattern', 'placeholder', 'playsinline', 'poster', 'preload', 'pubdate', 'radiogroup', 'readonly', 'rel', 'required', 'rev', 'reversed', 'role', 'rows', 'rowspan', 'spellcheck', 'scope', 'selected', 'shape', 'size', 'sizes', 'span', 'srclang', 'start', 'src', 'srcset', 'step', 'style', 'summary', 'tabindex', 'title', 'translate', 'type', 'usemap', 'valign', 'value', 'width', 'xmlns', 'slot']);
|
|
469
|
+
var svg = freeze(['accent-height', 'accumulate', 'additive', 'alignment-baseline', 'ascent', 'attributename', 'attributetype', 'azimuth', 'basefrequency', 'baseline-shift', 'begin', 'bias', 'by', 'class', 'clip', 'clippathunits', 'clip-path', 'clip-rule', 'color', 'color-interpolation', 'color-interpolation-filters', 'color-profile', 'color-rendering', 'cx', 'cy', 'd', 'dx', 'dy', 'diffuseconstant', 'direction', 'display', 'divisor', 'dur', 'edgemode', 'elevation', 'end', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'filterunits', 'flood-color', 'flood-opacity', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'fx', 'fy', 'g1', 'g2', 'glyph-name', 'glyphref', 'gradientunits', 'gradienttransform', 'height', 'href', 'id', 'image-rendering', 'in', 'in2', 'k', 'k1', 'k2', 'k3', 'k4', 'kerning', 'keypoints', 'keysplines', 'keytimes', 'lang', 'lengthadjust', 'letter-spacing', 'kernelmatrix', 'kernelunitlength', 'lighting-color', 'local', 'marker-end', 'marker-mid', 'marker-start', 'markerheight', 'markerunits', 'markerwidth', 'maskcontentunits', 'maskunits', 'max', 'mask', 'media', 'method', 'mode', 'min', 'name', 'numoctaves', 'offset', 'operator', 'opacity', 'order', 'orient', 'orientation', 'origin', 'overflow', 'paint-order', 'path', 'pathlength', 'patterncontentunits', 'patterntransform', 'patternunits', 'points', 'preservealpha', 'preserveaspectratio', 'primitiveunits', 'r', 'rx', 'ry', 'radius', 'refx', 'refy', 'repeatcount', 'repeatdur', 'restart', 'result', 'rotate', 'scale', 'seed', 'shape-rendering', 'specularconstant', 'specularexponent', 'spreadmethod', 'startoffset', 'stddeviation', 'stitchtiles', 'stop-color', 'stop-opacity', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke', 'stroke-width', 'style', 'surfacescale', 'systemlanguage', 'tabindex', 'targetx', 'targety', 'transform', 'transform-origin', 'text-anchor', 'text-decoration', 'text-rendering', 'textlength', 'type', 'u1', 'u2', 'unicode', 'values', 'viewbox', 'visibility', 'version', 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', 'width', 'word-spacing', 'wrap', 'writing-mode', 'xchannelselector', 'ychannelselector', 'x', 'x1', 'x2', 'xmlns', 'y', 'y1', 'y2', 'z', 'zoomandpan']);
|
|
470
|
+
var 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']);
|
|
471
|
+
var xml = freeze(['xlink:href', 'xml:id', 'xlink:title', 'xml:space', 'xmlns:xlink']);
|
|
472
|
+
var MUSTACHE_EXPR = seal(/\{\{[\w\W]*|[\w\W]*\}\}/gm); // Specify template detection regex for SAFE_FOR_TEMPLATES mode
|
|
384
473
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
return fun.apply(thisValue, args);
|
|
388
|
-
};
|
|
389
|
-
}
|
|
390
|
-
/**
|
|
391
|
-
* Creates a no-op policy for internal use only.
|
|
392
|
-
* Don't export this function outside this module!
|
|
393
|
-
* @param {?TrustedTypePolicyFactory} trustedTypes The policy factory.
|
|
394
|
-
* @param {Document} document The document object (to determine policy name suffix)
|
|
395
|
-
* @return {?TrustedTypePolicy} The policy created (or null, if Trusted Types
|
|
396
|
-
* are not supported).
|
|
397
|
-
*/
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
var _createTrustedTypesPolicy = function _createTrustedTypesPolicy(trustedTypes, document) {
|
|
401
|
-
if ((typeof trustedTypes === 'undefined' ? 'undefined' : _typeof$1(trustedTypes)) !== 'object' || typeof trustedTypes.createPolicy !== 'function') {
|
|
402
|
-
return null;
|
|
403
|
-
} // Allow the callers to control the unique policy name
|
|
404
|
-
// by adding a data-tt-policy-suffix to the script element with the DOMPurify.
|
|
405
|
-
// Policy creation with duplicate names throws in Trusted Types.
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
var suffix = null;
|
|
409
|
-
var ATTR_NAME = 'data-tt-policy-suffix';
|
|
410
|
-
|
|
411
|
-
if (document.currentScript && document.currentScript.hasAttribute(ATTR_NAME)) {
|
|
412
|
-
suffix = document.currentScript.getAttribute(ATTR_NAME);
|
|
413
|
-
}
|
|
474
|
+
var ERB_EXPR = seal(/<%[\w\W]*|[\w\W]*%>/gm);
|
|
475
|
+
var DATA_ATTR = seal(/^data-[\-\w.\u00B7-\uFFFF]/); // eslint-disable-line no-useless-escape
|
|
414
476
|
|
|
415
|
-
var
|
|
477
|
+
var ARIA_ATTR = seal(/^aria-[\-\w]+$/); // eslint-disable-line no-useless-escape
|
|
416
478
|
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
createHTML: function createHTML(html$$1) {
|
|
420
|
-
return html$$1;
|
|
421
|
-
}
|
|
422
|
-
});
|
|
423
|
-
} catch (error) {
|
|
424
|
-
// Policy creation failed (most likely another DOMPurify script has
|
|
425
|
-
// already run). Skip creating the policy, as this will only cause errors
|
|
426
|
-
// if TT are enforced.
|
|
427
|
-
console.warn('TrustedTypes policy ' + policyName + ' could not be created.');
|
|
428
|
-
return null;
|
|
429
|
-
}
|
|
430
|
-
};
|
|
479
|
+
var IS_ALLOWED_URI = seal(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i // eslint-disable-line no-useless-escape
|
|
480
|
+
);
|
|
431
481
|
|
|
432
|
-
|
|
433
|
-
var
|
|
482
|
+
var IS_SCRIPT_OR_DATA = seal(/^(?:\w+script|data):/i);
|
|
483
|
+
var ATTR_WHITESPACE = seal(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g // eslint-disable-line no-control-regex
|
|
484
|
+
);
|
|
434
485
|
|
|
435
|
-
var
|
|
436
|
-
|
|
486
|
+
var DOCTYPE_NAME = seal(/^html$/i);
|
|
487
|
+
var getGlobal = function getGlobal() {
|
|
488
|
+
return typeof window === 'undefined' ? null : window;
|
|
437
489
|
};
|
|
438
490
|
/**
|
|
439
|
-
*
|
|
440
|
-
*
|
|
491
|
+
* Creates a no-op policy for internal use only.
|
|
492
|
+
* Don't export this function outside this module!
|
|
493
|
+
* @param {?TrustedTypePolicyFactory} trustedTypes The policy factory.
|
|
494
|
+
* @param {Document} document The document object (to determine policy name suffix)
|
|
495
|
+
* @return {?TrustedTypePolicy} The policy created (or null, if Trusted Types
|
|
496
|
+
* are not supported).
|
|
441
497
|
*/
|
|
442
498
|
|
|
499
|
+
var _createTrustedTypesPolicy = function _createTrustedTypesPolicy(trustedTypes, document) {
|
|
500
|
+
if (_typeof(trustedTypes) !== 'object' || typeof trustedTypes.createPolicy !== 'function') {
|
|
501
|
+
return null;
|
|
502
|
+
} // Allow the callers to control the unique policy name
|
|
503
|
+
// by adding a data-tt-policy-suffix to the script element with the DOMPurify.
|
|
504
|
+
// Policy creation with duplicate names throws in Trusted Types.
|
|
505
|
+
|
|
506
|
+
var suffix = null;
|
|
507
|
+
var ATTR_NAME = 'data-tt-policy-suffix';
|
|
508
|
+
if (document.currentScript && document.currentScript.hasAttribute(ATTR_NAME)) {
|
|
509
|
+
suffix = document.currentScript.getAttribute(ATTR_NAME);
|
|
510
|
+
}
|
|
511
|
+
var policyName = 'dompurify' + (suffix ? '#' + suffix : '');
|
|
512
|
+
try {
|
|
513
|
+
return trustedTypes.createPolicy(policyName, {
|
|
514
|
+
createHTML: function createHTML(html) {
|
|
515
|
+
return html;
|
|
516
|
+
},
|
|
517
|
+
createScriptURL: function createScriptURL(scriptUrl) {
|
|
518
|
+
return scriptUrl;
|
|
519
|
+
}
|
|
520
|
+
});
|
|
521
|
+
} catch (_) {
|
|
522
|
+
// Policy creation failed (most likely another DOMPurify script has
|
|
523
|
+
// already run). Skip creating the policy, as this will only cause errors
|
|
524
|
+
// if TT are enforced.
|
|
525
|
+
console.warn('TrustedTypes policy ' + policyName + ' could not be created.');
|
|
526
|
+
return null;
|
|
527
|
+
}
|
|
528
|
+
};
|
|
529
|
+
function createDOMPurify() {
|
|
530
|
+
var window = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getGlobal();
|
|
531
|
+
var DOMPurify = function DOMPurify(root) {
|
|
532
|
+
return createDOMPurify(root);
|
|
533
|
+
};
|
|
534
|
+
/**
|
|
535
|
+
* Version label, exposed for easier checks
|
|
536
|
+
* if DOMPurify is up to date or not
|
|
537
|
+
*/
|
|
443
538
|
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
DOMPurify.removed = [];
|
|
451
|
-
|
|
452
|
-
if (!window || !window.document || window.document.nodeType !== 9) {
|
|
453
|
-
// Not running in a browser, provide a factory function
|
|
454
|
-
// so that you can pass your own Window
|
|
455
|
-
DOMPurify.isSupported = false;
|
|
456
|
-
return DOMPurify;
|
|
457
|
-
}
|
|
539
|
+
DOMPurify.version = '2.4.0';
|
|
540
|
+
/**
|
|
541
|
+
* Array of elements that DOMPurify removed during sanitation.
|
|
542
|
+
* Empty if nothing was removed.
|
|
543
|
+
*/
|
|
458
544
|
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
545
|
+
DOMPurify.removed = [];
|
|
546
|
+
if (!window || !window.document || window.document.nodeType !== 9) {
|
|
547
|
+
// Not running in a browser, provide a factory function
|
|
548
|
+
// so that you can pass your own Window
|
|
549
|
+
DOMPurify.isSupported = false;
|
|
550
|
+
return DOMPurify;
|
|
551
|
+
}
|
|
552
|
+
var originalDocument = window.document;
|
|
553
|
+
var document = window.document;
|
|
554
|
+
var DocumentFragment = window.DocumentFragment,
|
|
464
555
|
HTMLTemplateElement = window.HTMLTemplateElement,
|
|
465
556
|
Node = window.Node,
|
|
557
|
+
Element = window.Element,
|
|
466
558
|
NodeFilter = window.NodeFilter,
|
|
467
559
|
_window$NamedNodeMap = window.NamedNodeMap,
|
|
468
|
-
NamedNodeMap = _window$NamedNodeMap ===
|
|
469
|
-
|
|
470
|
-
Comment = window.Comment,
|
|
560
|
+
NamedNodeMap = _window$NamedNodeMap === void 0 ? window.NamedNodeMap || window.MozNamedAttrMap : _window$NamedNodeMap,
|
|
561
|
+
HTMLFormElement = window.HTMLFormElement,
|
|
471
562
|
DOMParser = window.DOMParser,
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
563
|
+
trustedTypes = window.trustedTypes;
|
|
564
|
+
var ElementPrototype = Element.prototype;
|
|
565
|
+
var cloneNode = lookupGetter(ElementPrototype, 'cloneNode');
|
|
566
|
+
var getNextSibling = lookupGetter(ElementPrototype, 'nextSibling');
|
|
567
|
+
var getChildNodes = lookupGetter(ElementPrototype, 'childNodes');
|
|
568
|
+
var getParentNode = lookupGetter(ElementPrototype, 'parentNode'); // As per issue #47, the web-components registry is inherited by a
|
|
569
|
+
// new document created via createHTMLDocument. As per the spec
|
|
570
|
+
// (http://w3c.github.io/webcomponents/spec/custom/#creating-and-passing-registries)
|
|
571
|
+
// a new empty registry is used when creating a template contents owner
|
|
572
|
+
// document, so we use that as our parent document to ensure nothing
|
|
573
|
+
// is inherited.
|
|
574
|
+
|
|
575
|
+
if (typeof HTMLTemplateElement === 'function') {
|
|
576
|
+
var template = document.createElement('template');
|
|
577
|
+
if (template.content && template.content.ownerDocument) {
|
|
578
|
+
document = template.content.ownerDocument;
|
|
579
|
+
}
|
|
484
580
|
}
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
var emptyHTML = trustedTypesPolicy ? trustedTypesPolicy.createHTML('') : '';
|
|
490
|
-
var _document = document,
|
|
581
|
+
var trustedTypesPolicy = _createTrustedTypesPolicy(trustedTypes, originalDocument);
|
|
582
|
+
var emptyHTML = trustedTypesPolicy ? trustedTypesPolicy.createHTML('') : '';
|
|
583
|
+
var _document = document,
|
|
491
584
|
implementation = _document.implementation,
|
|
492
585
|
createNodeIterator = _document.createNodeIterator,
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
DATA_ATTR$$1 = DATA_ATTR,
|
|
505
|
-
ARIA_ATTR$$1 = ARIA_ATTR,
|
|
506
|
-
IS_SCRIPT_OR_DATA$$1 = IS_SCRIPT_OR_DATA,
|
|
507
|
-
ATTR_WHITESPACE$$1 = ATTR_WHITESPACE;
|
|
508
|
-
var IS_ALLOWED_URI$$1 = IS_ALLOWED_URI;
|
|
509
|
-
/**
|
|
510
|
-
* We consider the elements and attributes below to be safe. Ideally
|
|
511
|
-
* don't add any new ones but feel free to remove unwanted ones.
|
|
512
|
-
*/
|
|
513
|
-
|
|
514
|
-
/* allowed element names */
|
|
586
|
+
createDocumentFragment = _document.createDocumentFragment,
|
|
587
|
+
getElementsByTagName = _document.getElementsByTagName;
|
|
588
|
+
var importNode = originalDocument.importNode;
|
|
589
|
+
var documentMode = {};
|
|
590
|
+
try {
|
|
591
|
+
documentMode = clone(document).documentMode ? document.documentMode : {};
|
|
592
|
+
} catch (_) {}
|
|
593
|
+
var hooks = {};
|
|
594
|
+
/**
|
|
595
|
+
* Expose whether this browser supports running the full DOMPurify.
|
|
596
|
+
*/
|
|
515
597
|
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
598
|
+
DOMPurify.isSupported = typeof getParentNode === 'function' && implementation && typeof implementation.createHTMLDocument !== 'undefined' && documentMode !== 9;
|
|
599
|
+
var MUSTACHE_EXPR$1 = MUSTACHE_EXPR,
|
|
600
|
+
ERB_EXPR$1 = ERB_EXPR,
|
|
601
|
+
DATA_ATTR$1 = DATA_ATTR,
|
|
602
|
+
ARIA_ATTR$1 = ARIA_ATTR,
|
|
603
|
+
IS_SCRIPT_OR_DATA$1 = IS_SCRIPT_OR_DATA,
|
|
604
|
+
ATTR_WHITESPACE$1 = ATTR_WHITESPACE;
|
|
605
|
+
var IS_ALLOWED_URI$1 = IS_ALLOWED_URI;
|
|
606
|
+
/**
|
|
607
|
+
* We consider the elements and attributes below to be safe. Ideally
|
|
608
|
+
* don't add any new ones but feel free to remove unwanted ones.
|
|
609
|
+
*/
|
|
519
610
|
|
|
520
|
-
|
|
521
|
-
var DEFAULT_ALLOWED_ATTR = addToSet({}, [].concat(_toConsumableArray(html$1), _toConsumableArray(svg$1), _toConsumableArray(mathMl$1), _toConsumableArray(xml)));
|
|
522
|
-
/* Explicitly forbidden tags (overrides ALLOWED_TAGS/ADD_TAGS) */
|
|
611
|
+
/* allowed element names */
|
|
523
612
|
|
|
524
|
-
|
|
525
|
-
|
|
613
|
+
var ALLOWED_TAGS = null;
|
|
614
|
+
var DEFAULT_ALLOWED_TAGS = addToSet({}, [].concat(_toConsumableArray(html$1), _toConsumableArray(svg$1), _toConsumableArray(svgFilters), _toConsumableArray(mathMl$1), _toConsumableArray(text)));
|
|
615
|
+
/* Allowed attribute names */
|
|
526
616
|
|
|
527
|
-
|
|
528
|
-
|
|
617
|
+
var ALLOWED_ATTR = null;
|
|
618
|
+
var DEFAULT_ALLOWED_ATTR = addToSet({}, [].concat(_toConsumableArray(html), _toConsumableArray(svg), _toConsumableArray(mathMl), _toConsumableArray(xml)));
|
|
619
|
+
/*
|
|
620
|
+
* Configure how DOMPUrify should handle custom elements and their attributes as well as customized built-in elements.
|
|
621
|
+
* @property {RegExp|Function|null} tagNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any custom elements)
|
|
622
|
+
* @property {RegExp|Function|null} attributeNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any attributes not on the allow list)
|
|
623
|
+
* @property {boolean} allowCustomizedBuiltInElements allow custom elements derived from built-ins if they pass CUSTOM_ELEMENT_HANDLING.tagNameCheck. Default: `false`.
|
|
624
|
+
*/
|
|
529
625
|
|
|
530
|
-
|
|
531
|
-
|
|
626
|
+
var CUSTOM_ELEMENT_HANDLING = Object.seal(Object.create(null, {
|
|
627
|
+
tagNameCheck: {
|
|
628
|
+
writable: true,
|
|
629
|
+
configurable: false,
|
|
630
|
+
enumerable: true,
|
|
631
|
+
value: null
|
|
632
|
+
},
|
|
633
|
+
attributeNameCheck: {
|
|
634
|
+
writable: true,
|
|
635
|
+
configurable: false,
|
|
636
|
+
enumerable: true,
|
|
637
|
+
value: null
|
|
638
|
+
},
|
|
639
|
+
allowCustomizedBuiltInElements: {
|
|
640
|
+
writable: true,
|
|
641
|
+
configurable: false,
|
|
642
|
+
enumerable: true,
|
|
643
|
+
value: false
|
|
644
|
+
}
|
|
645
|
+
}));
|
|
646
|
+
/* Explicitly forbidden tags (overrides ALLOWED_TAGS/ADD_TAGS) */
|
|
532
647
|
|
|
533
|
-
|
|
534
|
-
|
|
648
|
+
var FORBID_TAGS = null;
|
|
649
|
+
/* Explicitly forbidden attributes (overrides ALLOWED_ATTR/ADD_ATTR) */
|
|
535
650
|
|
|
536
|
-
|
|
537
|
-
|
|
651
|
+
var FORBID_ATTR = null;
|
|
652
|
+
/* Decide if ARIA attributes are okay */
|
|
538
653
|
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
* This means, DOMPurify removes data attributes, mustaches and ERB
|
|
542
|
-
*/
|
|
654
|
+
var ALLOW_ARIA_ATTR = true;
|
|
655
|
+
/* Decide if custom data attributes are okay */
|
|
543
656
|
|
|
544
|
-
|
|
545
|
-
|
|
657
|
+
var ALLOW_DATA_ATTR = true;
|
|
658
|
+
/* Decide if unknown protocols are okay */
|
|
546
659
|
|
|
547
|
-
|
|
548
|
-
|
|
660
|
+
var ALLOW_UNKNOWN_PROTOCOLS = false;
|
|
661
|
+
/* Output should be safe for common template engines.
|
|
662
|
+
* This means, DOMPurify removes data attributes, mustaches and ERB
|
|
663
|
+
*/
|
|
549
664
|
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
* document.body. By default, browsers might move them to document.head */
|
|
665
|
+
var SAFE_FOR_TEMPLATES = false;
|
|
666
|
+
/* Decide if document with <html>... should be returned */
|
|
553
667
|
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
* string (or a TrustedHTML object if Trusted Types are supported).
|
|
557
|
-
* If `WHOLE_DOCUMENT` is enabled a `HTMLHtmlElement` will be returned instead
|
|
558
|
-
*/
|
|
668
|
+
var WHOLE_DOCUMENT = false;
|
|
669
|
+
/* Track whether config is already set on this instance of DOMPurify. */
|
|
559
670
|
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
671
|
+
var SET_CONFIG = false;
|
|
672
|
+
/* Decide if all elements (e.g. style, script) must be children of
|
|
673
|
+
* document.body. By default, browsers might move them to document.head */
|
|
563
674
|
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
675
|
+
var FORCE_BODY = false;
|
|
676
|
+
/* Decide if a DOM `HTMLBodyElement` should be returned, instead of a html
|
|
677
|
+
* string (or a TrustedHTML object if Trusted Types are supported).
|
|
678
|
+
* If `WHOLE_DOCUMENT` is enabled a `HTMLHtmlElement` will be returned instead
|
|
679
|
+
*/
|
|
569
680
|
|
|
570
|
-
|
|
571
|
-
|
|
681
|
+
var RETURN_DOM = false;
|
|
682
|
+
/* Decide if a DOM `DocumentFragment` should be returned, instead of a html
|
|
683
|
+
* string (or a TrustedHTML object if Trusted Types are supported) */
|
|
572
684
|
|
|
573
|
-
|
|
574
|
-
|
|
685
|
+
var RETURN_DOM_FRAGMENT = false;
|
|
686
|
+
/* Try to return a Trusted Type object instead of a string, return a string in
|
|
687
|
+
* case Trusted Types are not supported */
|
|
575
688
|
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
689
|
+
var RETURN_TRUSTED_TYPE = false;
|
|
690
|
+
/* Output should be free from DOM clobbering attacks?
|
|
691
|
+
* This sanitizes markups named with colliding, clobberable built-in DOM APIs.
|
|
692
|
+
*/
|
|
579
693
|
|
|
580
|
-
|
|
581
|
-
|
|
694
|
+
var SANITIZE_DOM = true;
|
|
695
|
+
/* Achieve full DOM Clobbering protection by isolating the namespace of named
|
|
696
|
+
* properties and JS variables, mitigating attacks that abuse the HTML/DOM spec rules.
|
|
697
|
+
*
|
|
698
|
+
* HTML/DOM spec rules that enable DOM Clobbering:
|
|
699
|
+
* - Named Access on Window (§7.3.3)
|
|
700
|
+
* - DOM Tree Accessors (§3.1.5)
|
|
701
|
+
* - Form Element Parent-Child Relations (§4.10.3)
|
|
702
|
+
* - Iframe srcdoc / Nested WindowProxies (§4.8.5)
|
|
703
|
+
* - HTMLCollection (§4.2.10.2)
|
|
704
|
+
*
|
|
705
|
+
* Namespace isolation is implemented by prefixing `id` and `name` attributes
|
|
706
|
+
* with a constant string, i.e., `user-content-`
|
|
707
|
+
*/
|
|
582
708
|
|
|
583
|
-
|
|
584
|
-
|
|
709
|
+
var SANITIZE_NAMED_PROPS = false;
|
|
710
|
+
var SANITIZE_NAMED_PROPS_PREFIX = 'user-content-';
|
|
711
|
+
/* Keep element content when removing element? */
|
|
585
712
|
|
|
586
|
-
|
|
587
|
-
|
|
713
|
+
var KEEP_CONTENT = true;
|
|
714
|
+
/* If a `Node` is passed to sanitize(), then performs sanitization in-place instead
|
|
715
|
+
* of importing it into a new Document and returning a sanitized copy */
|
|
588
716
|
|
|
589
|
-
|
|
590
|
-
|
|
717
|
+
var IN_PLACE = false;
|
|
718
|
+
/* Allow usage of profiles like html, svg and mathMl */
|
|
591
719
|
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
/* Keep a reference to config to pass to hooks */
|
|
720
|
+
var USE_PROFILES = {};
|
|
721
|
+
/* Tags to ignore content of when KEEP_CONTENT is true */
|
|
595
722
|
|
|
596
|
-
|
|
597
|
-
|
|
723
|
+
var FORBID_CONTENTS = null;
|
|
724
|
+
var 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']);
|
|
725
|
+
/* Tags that are safe for data: URIs */
|
|
598
726
|
|
|
599
|
-
|
|
727
|
+
var DATA_URI_TAGS = null;
|
|
728
|
+
var DEFAULT_DATA_URI_TAGS = addToSet({}, ['audio', 'video', 'img', 'source', 'image', 'track']);
|
|
729
|
+
/* Attributes safe for values like "javascript:" */
|
|
600
730
|
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
// eslint-disable-next-line complexity
|
|
731
|
+
var URI_SAFE_ATTRIBUTES = null;
|
|
732
|
+
var DEFAULT_URI_SAFE_ATTRIBUTES = addToSet({}, ['alt', 'class', 'for', 'id', 'label', 'name', 'pattern', 'placeholder', 'role', 'summary', 'title', 'value', 'style', 'xmlns']);
|
|
733
|
+
var MATHML_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';
|
|
734
|
+
var SVG_NAMESPACE = 'http://www.w3.org/2000/svg';
|
|
735
|
+
var HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';
|
|
736
|
+
/* Document namespace */
|
|
608
737
|
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
}
|
|
613
|
-
/* Shield configuration object from tampering */
|
|
738
|
+
var NAMESPACE = HTML_NAMESPACE;
|
|
739
|
+
var IS_EMPTY_INPUT = false;
|
|
740
|
+
/* Parsing of strict XHTML documents */
|
|
614
741
|
|
|
742
|
+
var PARSER_MEDIA_TYPE;
|
|
743
|
+
var SUPPORTED_PARSER_MEDIA_TYPES = ['application/xhtml+xml', 'text/html'];
|
|
744
|
+
var DEFAULT_PARSER_MEDIA_TYPE = 'text/html';
|
|
745
|
+
var transformCaseFunc;
|
|
746
|
+
/* Keep a reference to config to pass to hooks */
|
|
615
747
|
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
}
|
|
619
|
-
/* Set configuration parameters */
|
|
748
|
+
var CONFIG = null;
|
|
749
|
+
/* Ideally, do not touch anything below this line */
|
|
620
750
|
|
|
751
|
+
/* ______________________________________________ */
|
|
621
752
|
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
753
|
+
var formElement = document.createElement('form');
|
|
754
|
+
var isRegexOrFunction = function isRegexOrFunction(testValue) {
|
|
755
|
+
return testValue instanceof RegExp || testValue instanceof Function;
|
|
756
|
+
};
|
|
757
|
+
/**
|
|
758
|
+
* _parseConfig
|
|
759
|
+
*
|
|
760
|
+
* @param {Object} cfg optional config literal
|
|
761
|
+
*/
|
|
762
|
+
// eslint-disable-next-line complexity
|
|
629
763
|
|
|
630
|
-
|
|
764
|
+
var _parseConfig = function _parseConfig(cfg) {
|
|
765
|
+
if (CONFIG && CONFIG === cfg) {
|
|
766
|
+
return;
|
|
767
|
+
}
|
|
768
|
+
/* Shield configuration object from tampering */
|
|
631
769
|
|
|
632
|
-
|
|
770
|
+
if (!cfg || _typeof(cfg) !== 'object') {
|
|
771
|
+
cfg = {};
|
|
772
|
+
}
|
|
773
|
+
/* Shield configuration object from prototype pollution */
|
|
633
774
|
|
|
634
|
-
|
|
775
|
+
cfg = clone(cfg);
|
|
776
|
+
PARSER_MEDIA_TYPE =
|
|
777
|
+
// eslint-disable-next-line unicorn/prefer-includes
|
|
778
|
+
SUPPORTED_PARSER_MEDIA_TYPES.indexOf(cfg.PARSER_MEDIA_TYPE) === -1 ? PARSER_MEDIA_TYPE = DEFAULT_PARSER_MEDIA_TYPE : PARSER_MEDIA_TYPE = cfg.PARSER_MEDIA_TYPE; // HTML tags and attributes are not case-sensitive, converting to lowercase. Keeping XHTML as is.
|
|
635
779
|
|
|
636
|
-
|
|
780
|
+
transformCaseFunc = PARSER_MEDIA_TYPE === 'application/xhtml+xml' ? function (x) {
|
|
781
|
+
return x;
|
|
782
|
+
} : stringToLowerCase;
|
|
783
|
+
/* Set configuration parameters */
|
|
637
784
|
|
|
638
|
-
|
|
785
|
+
ALLOWED_TAGS = 'ALLOWED_TAGS' in cfg ? addToSet({}, cfg.ALLOWED_TAGS, transformCaseFunc) : DEFAULT_ALLOWED_TAGS;
|
|
786
|
+
ALLOWED_ATTR = 'ALLOWED_ATTR' in cfg ? addToSet({}, cfg.ALLOWED_ATTR, transformCaseFunc) : DEFAULT_ALLOWED_ATTR;
|
|
787
|
+
URI_SAFE_ATTRIBUTES = 'ADD_URI_SAFE_ATTR' in cfg ? addToSet(clone(DEFAULT_URI_SAFE_ATTRIBUTES),
|
|
788
|
+
// eslint-disable-line indent
|
|
789
|
+
cfg.ADD_URI_SAFE_ATTR,
|
|
790
|
+
// eslint-disable-line indent
|
|
791
|
+
transformCaseFunc // eslint-disable-line indent
|
|
792
|
+
) // eslint-disable-line indent
|
|
793
|
+
: DEFAULT_URI_SAFE_ATTRIBUTES;
|
|
794
|
+
DATA_URI_TAGS = 'ADD_DATA_URI_TAGS' in cfg ? addToSet(clone(DEFAULT_DATA_URI_TAGS),
|
|
795
|
+
// eslint-disable-line indent
|
|
796
|
+
cfg.ADD_DATA_URI_TAGS,
|
|
797
|
+
// eslint-disable-line indent
|
|
798
|
+
transformCaseFunc // eslint-disable-line indent
|
|
799
|
+
) // eslint-disable-line indent
|
|
800
|
+
: DEFAULT_DATA_URI_TAGS;
|
|
801
|
+
FORBID_CONTENTS = 'FORBID_CONTENTS' in cfg ? addToSet({}, cfg.FORBID_CONTENTS, transformCaseFunc) : DEFAULT_FORBID_CONTENTS;
|
|
802
|
+
FORBID_TAGS = 'FORBID_TAGS' in cfg ? addToSet({}, cfg.FORBID_TAGS, transformCaseFunc) : {};
|
|
803
|
+
FORBID_ATTR = 'FORBID_ATTR' in cfg ? addToSet({}, cfg.FORBID_ATTR, transformCaseFunc) : {};
|
|
804
|
+
USE_PROFILES = 'USE_PROFILES' in cfg ? cfg.USE_PROFILES : false;
|
|
805
|
+
ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false; // Default true
|
|
639
806
|
|
|
640
|
-
|
|
807
|
+
ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false; // Default true
|
|
641
808
|
|
|
642
|
-
|
|
809
|
+
ALLOW_UNKNOWN_PROTOCOLS = cfg.ALLOW_UNKNOWN_PROTOCOLS || false; // Default false
|
|
643
810
|
|
|
644
|
-
|
|
811
|
+
SAFE_FOR_TEMPLATES = cfg.SAFE_FOR_TEMPLATES || false; // Default false
|
|
645
812
|
|
|
646
|
-
|
|
813
|
+
WHOLE_DOCUMENT = cfg.WHOLE_DOCUMENT || false; // Default false
|
|
647
814
|
|
|
648
|
-
|
|
815
|
+
RETURN_DOM = cfg.RETURN_DOM || false; // Default false
|
|
649
816
|
|
|
650
|
-
|
|
817
|
+
RETURN_DOM_FRAGMENT = cfg.RETURN_DOM_FRAGMENT || false; // Default false
|
|
651
818
|
|
|
652
|
-
|
|
819
|
+
RETURN_TRUSTED_TYPE = cfg.RETURN_TRUSTED_TYPE || false; // Default false
|
|
653
820
|
|
|
654
|
-
|
|
821
|
+
FORCE_BODY = cfg.FORCE_BODY || false; // Default false
|
|
655
822
|
|
|
656
|
-
|
|
657
|
-
ALLOW_DATA_ATTR = false;
|
|
658
|
-
}
|
|
823
|
+
SANITIZE_DOM = cfg.SANITIZE_DOM !== false; // Default true
|
|
659
824
|
|
|
660
|
-
|
|
661
|
-
RETURN_DOM = true;
|
|
662
|
-
}
|
|
663
|
-
/* Parse profile info */
|
|
825
|
+
SANITIZE_NAMED_PROPS = cfg.SANITIZE_NAMED_PROPS || false; // Default false
|
|
664
826
|
|
|
827
|
+
KEEP_CONTENT = cfg.KEEP_CONTENT !== false; // Default true
|
|
665
828
|
|
|
666
|
-
|
|
667
|
-
ALLOWED_TAGS = addToSet({}, [].concat(_toConsumableArray(text)));
|
|
668
|
-
ALLOWED_ATTR = [];
|
|
829
|
+
IN_PLACE = cfg.IN_PLACE || false; // Default false
|
|
669
830
|
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
831
|
+
IS_ALLOWED_URI$1 = cfg.ALLOWED_URI_REGEXP || IS_ALLOWED_URI$1;
|
|
832
|
+
NAMESPACE = cfg.NAMESPACE || HTML_NAMESPACE;
|
|
833
|
+
if (cfg.CUSTOM_ELEMENT_HANDLING && isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck)) {
|
|
834
|
+
CUSTOM_ELEMENT_HANDLING.tagNameCheck = cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck;
|
|
673
835
|
}
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
addToSet(ALLOWED_TAGS, svg);
|
|
677
|
-
addToSet(ALLOWED_ATTR, svg$1);
|
|
678
|
-
addToSet(ALLOWED_ATTR, xml);
|
|
836
|
+
if (cfg.CUSTOM_ELEMENT_HANDLING && isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)) {
|
|
837
|
+
CUSTOM_ELEMENT_HANDLING.attributeNameCheck = cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck;
|
|
679
838
|
}
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
839
|
+
if (cfg.CUSTOM_ELEMENT_HANDLING && typeof cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements === 'boolean') {
|
|
840
|
+
CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements = cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements;
|
|
841
|
+
}
|
|
842
|
+
if (SAFE_FOR_TEMPLATES) {
|
|
843
|
+
ALLOW_DATA_ATTR = false;
|
|
844
|
+
}
|
|
845
|
+
if (RETURN_DOM_FRAGMENT) {
|
|
846
|
+
RETURN_DOM = true;
|
|
847
|
+
}
|
|
848
|
+
/* Parse profile info */
|
|
849
|
+
|
|
850
|
+
if (USE_PROFILES) {
|
|
851
|
+
ALLOWED_TAGS = addToSet({}, _toConsumableArray(text));
|
|
852
|
+
ALLOWED_ATTR = [];
|
|
853
|
+
if (USE_PROFILES.html === true) {
|
|
854
|
+
addToSet(ALLOWED_TAGS, html$1);
|
|
855
|
+
addToSet(ALLOWED_ATTR, html);
|
|
856
|
+
}
|
|
857
|
+
if (USE_PROFILES.svg === true) {
|
|
858
|
+
addToSet(ALLOWED_TAGS, svg$1);
|
|
859
|
+
addToSet(ALLOWED_ATTR, svg);
|
|
860
|
+
addToSet(ALLOWED_ATTR, xml);
|
|
861
|
+
}
|
|
862
|
+
if (USE_PROFILES.svgFilters === true) {
|
|
863
|
+
addToSet(ALLOWED_TAGS, svgFilters);
|
|
864
|
+
addToSet(ALLOWED_ATTR, svg);
|
|
865
|
+
addToSet(ALLOWED_ATTR, xml);
|
|
866
|
+
}
|
|
867
|
+
if (USE_PROFILES.mathMl === true) {
|
|
868
|
+
addToSet(ALLOWED_TAGS, mathMl$1);
|
|
869
|
+
addToSet(ALLOWED_ATTR, mathMl);
|
|
870
|
+
addToSet(ALLOWED_ATTR, xml);
|
|
871
|
+
}
|
|
685
872
|
}
|
|
873
|
+
/* Merge configuration parameters */
|
|
686
874
|
|
|
687
|
-
if (
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
875
|
+
if (cfg.ADD_TAGS) {
|
|
876
|
+
if (ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) {
|
|
877
|
+
ALLOWED_TAGS = clone(ALLOWED_TAGS);
|
|
878
|
+
}
|
|
879
|
+
addToSet(ALLOWED_TAGS, cfg.ADD_TAGS, transformCaseFunc);
|
|
691
880
|
}
|
|
692
|
-
|
|
693
|
-
|
|
881
|
+
if (cfg.ADD_ATTR) {
|
|
882
|
+
if (ALLOWED_ATTR === DEFAULT_ALLOWED_ATTR) {
|
|
883
|
+
ALLOWED_ATTR = clone(ALLOWED_ATTR);
|
|
884
|
+
}
|
|
885
|
+
addToSet(ALLOWED_ATTR, cfg.ADD_ATTR, transformCaseFunc);
|
|
886
|
+
}
|
|
887
|
+
if (cfg.ADD_URI_SAFE_ATTR) {
|
|
888
|
+
addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR, transformCaseFunc);
|
|
889
|
+
}
|
|
890
|
+
if (cfg.FORBID_CONTENTS) {
|
|
891
|
+
if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) {
|
|
892
|
+
FORBID_CONTENTS = clone(FORBID_CONTENTS);
|
|
893
|
+
}
|
|
894
|
+
addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS, transformCaseFunc);
|
|
895
|
+
}
|
|
896
|
+
/* Add #text in case KEEP_CONTENT is set to true */
|
|
694
897
|
|
|
898
|
+
if (KEEP_CONTENT) {
|
|
899
|
+
ALLOWED_TAGS['#text'] = true;
|
|
900
|
+
}
|
|
901
|
+
/* Add html, head and body to ALLOWED_TAGS in case WHOLE_DOCUMENT is true */
|
|
695
902
|
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
ALLOWED_TAGS = clone(ALLOWED_TAGS);
|
|
903
|
+
if (WHOLE_DOCUMENT) {
|
|
904
|
+
addToSet(ALLOWED_TAGS, ['html', 'head', 'body']);
|
|
699
905
|
}
|
|
906
|
+
/* Add tbody to ALLOWED_TAGS in case tables are permitted, see #286, #365 */
|
|
700
907
|
|
|
701
|
-
|
|
702
|
-
|
|
908
|
+
if (ALLOWED_TAGS.table) {
|
|
909
|
+
addToSet(ALLOWED_TAGS, ['tbody']);
|
|
910
|
+
delete FORBID_TAGS.tbody;
|
|
911
|
+
} // Prevent further manipulation of configuration.
|
|
912
|
+
// Not available in IE8, Safari 5, etc.
|
|
703
913
|
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
ALLOWED_ATTR = clone(ALLOWED_ATTR);
|
|
914
|
+
if (freeze) {
|
|
915
|
+
freeze(cfg);
|
|
707
916
|
}
|
|
917
|
+
CONFIG = cfg;
|
|
918
|
+
};
|
|
919
|
+
var MATHML_TEXT_INTEGRATION_POINTS = addToSet({}, ['mi', 'mo', 'mn', 'ms', 'mtext']);
|
|
920
|
+
var HTML_INTEGRATION_POINTS = addToSet({}, ['foreignobject', 'desc', 'title', 'annotation-xml']); // Certain elements are allowed in both SVG and HTML
|
|
921
|
+
// namespace. We need to specify them explicitly
|
|
922
|
+
// so that they don't get erroneously deleted from
|
|
923
|
+
// HTML namespace.
|
|
924
|
+
|
|
925
|
+
var COMMON_SVG_AND_HTML_ELEMENTS = addToSet({}, ['title', 'style', 'font', 'a', 'script']);
|
|
926
|
+
/* Keep track of all possible SVG and MathML tags
|
|
927
|
+
* so that we can perform the namespace checks
|
|
928
|
+
* correctly. */
|
|
929
|
+
|
|
930
|
+
var ALL_SVG_TAGS = addToSet({}, svg$1);
|
|
931
|
+
addToSet(ALL_SVG_TAGS, svgFilters);
|
|
932
|
+
addToSet(ALL_SVG_TAGS, svgDisallowed);
|
|
933
|
+
var ALL_MATHML_TAGS = addToSet({}, mathMl$1);
|
|
934
|
+
addToSet(ALL_MATHML_TAGS, mathMlDisallowed);
|
|
935
|
+
/**
|
|
936
|
+
*
|
|
937
|
+
*
|
|
938
|
+
* @param {Element} element a DOM element whose namespace is being checked
|
|
939
|
+
* @returns {boolean} Return false if the element has a
|
|
940
|
+
* namespace that a spec-compliant parser would never
|
|
941
|
+
* return. Return true otherwise.
|
|
942
|
+
*/
|
|
708
943
|
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
if (cfg.ADD_URI_SAFE_ATTR) {
|
|
713
|
-
addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR);
|
|
714
|
-
}
|
|
715
|
-
/* Add #text in case KEEP_CONTENT is set to true */
|
|
944
|
+
var _checkValidNamespace = function _checkValidNamespace(element) {
|
|
945
|
+
var parent = getParentNode(element); // In JSDOM, if we're inside shadow DOM, then parentNode
|
|
946
|
+
// can be null. We just simulate parent in this case.
|
|
716
947
|
|
|
948
|
+
if (!parent || !parent.tagName) {
|
|
949
|
+
parent = {
|
|
950
|
+
namespaceURI: HTML_NAMESPACE,
|
|
951
|
+
tagName: 'template'
|
|
952
|
+
};
|
|
953
|
+
}
|
|
954
|
+
var tagName = stringToLowerCase(element.tagName);
|
|
955
|
+
var parentTagName = stringToLowerCase(parent.tagName);
|
|
956
|
+
if (element.namespaceURI === SVG_NAMESPACE) {
|
|
957
|
+
// The only way to switch from HTML namespace to SVG
|
|
958
|
+
// is via <svg>. If it happens via any other tag, then
|
|
959
|
+
// it should be killed.
|
|
960
|
+
if (parent.namespaceURI === HTML_NAMESPACE) {
|
|
961
|
+
return tagName === 'svg';
|
|
962
|
+
} // The only way to switch from MathML to SVG is via
|
|
963
|
+
// svg if parent is either <annotation-xml> or MathML
|
|
964
|
+
// text integration points.
|
|
965
|
+
|
|
966
|
+
if (parent.namespaceURI === MATHML_NAMESPACE) {
|
|
967
|
+
return tagName === 'svg' && (parentTagName === 'annotation-xml' || MATHML_TEXT_INTEGRATION_POINTS[parentTagName]);
|
|
968
|
+
} // We only allow elements that are defined in SVG
|
|
969
|
+
// spec. All others are disallowed in SVG namespace.
|
|
970
|
+
|
|
971
|
+
return Boolean(ALL_SVG_TAGS[tagName]);
|
|
972
|
+
}
|
|
973
|
+
if (element.namespaceURI === MATHML_NAMESPACE) {
|
|
974
|
+
// The only way to switch from HTML namespace to MathML
|
|
975
|
+
// is via <math>. If it happens via any other tag, then
|
|
976
|
+
// it should be killed.
|
|
977
|
+
if (parent.namespaceURI === HTML_NAMESPACE) {
|
|
978
|
+
return tagName === 'math';
|
|
979
|
+
} // The only way to switch from SVG to MathML is via
|
|
980
|
+
// <math> and HTML integration points
|
|
981
|
+
|
|
982
|
+
if (parent.namespaceURI === SVG_NAMESPACE) {
|
|
983
|
+
return tagName === 'math' && HTML_INTEGRATION_POINTS[parentTagName];
|
|
984
|
+
} // We only allow elements that are defined in MathML
|
|
985
|
+
// spec. All others are disallowed in MathML namespace.
|
|
986
|
+
|
|
987
|
+
return Boolean(ALL_MATHML_TAGS[tagName]);
|
|
988
|
+
}
|
|
989
|
+
if (element.namespaceURI === HTML_NAMESPACE) {
|
|
990
|
+
// The only way to switch from SVG to HTML is via
|
|
991
|
+
// HTML integration points, and from MathML to HTML
|
|
992
|
+
// is via MathML text integration points
|
|
993
|
+
if (parent.namespaceURI === SVG_NAMESPACE && !HTML_INTEGRATION_POINTS[parentTagName]) {
|
|
994
|
+
return false;
|
|
995
|
+
}
|
|
996
|
+
if (parent.namespaceURI === MATHML_NAMESPACE && !MATHML_TEXT_INTEGRATION_POINTS[parentTagName]) {
|
|
997
|
+
return false;
|
|
998
|
+
} // We disallow tags that are specific for MathML
|
|
999
|
+
// or SVG and should never appear in HTML namespace
|
|
717
1000
|
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
1001
|
+
return !ALL_MATHML_TAGS[tagName] && (COMMON_SVG_AND_HTML_ELEMENTS[tagName] || !ALL_SVG_TAGS[tagName]);
|
|
1002
|
+
} // The code should never reach this place (this means
|
|
1003
|
+
// that the element somehow got namespace that is not
|
|
1004
|
+
// HTML, SVG or MathML). Return false just in case.
|
|
722
1005
|
|
|
1006
|
+
return false;
|
|
1007
|
+
};
|
|
1008
|
+
/**
|
|
1009
|
+
* _forceRemove
|
|
1010
|
+
*
|
|
1011
|
+
* @param {Node} node a DOM node
|
|
1012
|
+
*/
|
|
723
1013
|
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
1014
|
+
var _forceRemove = function _forceRemove(node) {
|
|
1015
|
+
arrayPush(DOMPurify.removed, {
|
|
1016
|
+
element: node
|
|
1017
|
+
});
|
|
1018
|
+
try {
|
|
1019
|
+
// eslint-disable-next-line unicorn/prefer-dom-node-remove
|
|
1020
|
+
node.parentNode.removeChild(node);
|
|
1021
|
+
} catch (_) {
|
|
1022
|
+
try {
|
|
1023
|
+
node.outerHTML = emptyHTML;
|
|
1024
|
+
} catch (_) {
|
|
1025
|
+
node.remove();
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
};
|
|
1029
|
+
/**
|
|
1030
|
+
* _removeAttribute
|
|
1031
|
+
*
|
|
1032
|
+
* @param {String} name an Attribute name
|
|
1033
|
+
* @param {Node} node a DOM node
|
|
1034
|
+
*/
|
|
728
1035
|
|
|
1036
|
+
var _removeAttribute = function _removeAttribute(name, node) {
|
|
1037
|
+
try {
|
|
1038
|
+
arrayPush(DOMPurify.removed, {
|
|
1039
|
+
attribute: node.getAttributeNode(name),
|
|
1040
|
+
from: node
|
|
1041
|
+
});
|
|
1042
|
+
} catch (_) {
|
|
1043
|
+
arrayPush(DOMPurify.removed, {
|
|
1044
|
+
attribute: null,
|
|
1045
|
+
from: node
|
|
1046
|
+
});
|
|
1047
|
+
}
|
|
1048
|
+
node.removeAttribute(name); // We void attribute values for unremovable "is"" attributes
|
|
729
1049
|
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
1050
|
+
if (name === 'is' && !ALLOWED_ATTR[name]) {
|
|
1051
|
+
if (RETURN_DOM || RETURN_DOM_FRAGMENT) {
|
|
1052
|
+
try {
|
|
1053
|
+
_forceRemove(node);
|
|
1054
|
+
} catch (_) {}
|
|
1055
|
+
} else {
|
|
1056
|
+
try {
|
|
1057
|
+
node.setAttribute(name, '');
|
|
1058
|
+
} catch (_) {}
|
|
1059
|
+
}
|
|
1060
|
+
}
|
|
1061
|
+
};
|
|
1062
|
+
/**
|
|
1063
|
+
* _initDocument
|
|
1064
|
+
*
|
|
1065
|
+
* @param {String} dirty a string of dirty markup
|
|
1066
|
+
* @return {Document} a DOM, filled with the dirty markup
|
|
1067
|
+
*/
|
|
734
1068
|
|
|
1069
|
+
var _initDocument = function _initDocument(dirty) {
|
|
1070
|
+
/* Create a HTML document */
|
|
1071
|
+
var doc;
|
|
1072
|
+
var leadingWhitespace;
|
|
1073
|
+
if (FORCE_BODY) {
|
|
1074
|
+
dirty = '<remove></remove>' + dirty;
|
|
1075
|
+
} else {
|
|
1076
|
+
/* If FORCE_BODY isn't used, leading whitespace needs to be preserved manually */
|
|
1077
|
+
var matches = stringMatch(dirty, /^[\r\n\t ]+/);
|
|
1078
|
+
leadingWhitespace = matches && matches[0];
|
|
1079
|
+
}
|
|
1080
|
+
if (PARSER_MEDIA_TYPE === 'application/xhtml+xml') {
|
|
1081
|
+
// Root of XHTML doc must contain xmlns declaration (see https://www.w3.org/TR/xhtml1/normative.html#strict)
|
|
1082
|
+
dirty = '<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body>' + dirty + '</body></html>';
|
|
1083
|
+
}
|
|
1084
|
+
var dirtyPayload = trustedTypesPolicy ? trustedTypesPolicy.createHTML(dirty) : dirty;
|
|
1085
|
+
/*
|
|
1086
|
+
* Use the DOMParser API by default, fallback later if needs be
|
|
1087
|
+
* DOMParser not work for svg when has multiple root element.
|
|
1088
|
+
*/
|
|
735
1089
|
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
1090
|
+
if (NAMESPACE === HTML_NAMESPACE) {
|
|
1091
|
+
try {
|
|
1092
|
+
doc = new DOMParser().parseFromString(dirtyPayload, PARSER_MEDIA_TYPE);
|
|
1093
|
+
} catch (_) {}
|
|
1094
|
+
}
|
|
1095
|
+
/* Use createHTMLDocument in case DOMParser is not available */
|
|
739
1096
|
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
1097
|
+
if (!doc || !doc.documentElement) {
|
|
1098
|
+
doc = implementation.createDocument(NAMESPACE, 'template', null);
|
|
1099
|
+
try {
|
|
1100
|
+
doc.documentElement.innerHTML = IS_EMPTY_INPUT ? '' : dirtyPayload;
|
|
1101
|
+
} catch (_) {// Syntax error if dirtyPayload is invalid xml
|
|
1102
|
+
}
|
|
1103
|
+
}
|
|
1104
|
+
var body = doc.body || doc.documentElement;
|
|
1105
|
+
if (dirty && leadingWhitespace) {
|
|
1106
|
+
body.insertBefore(document.createTextNode(leadingWhitespace), body.childNodes[0] || null);
|
|
1107
|
+
}
|
|
1108
|
+
/* Work on whole document or just its body */
|
|
747
1109
|
|
|
1110
|
+
if (NAMESPACE === HTML_NAMESPACE) {
|
|
1111
|
+
return getElementsByTagName.call(doc, WHOLE_DOCUMENT ? 'html' : 'body')[0];
|
|
1112
|
+
}
|
|
1113
|
+
return WHOLE_DOCUMENT ? doc.documentElement : body;
|
|
1114
|
+
};
|
|
1115
|
+
/**
|
|
1116
|
+
* _createIterator
|
|
1117
|
+
*
|
|
1118
|
+
* @param {Document} root document/fragment to create iterator for
|
|
1119
|
+
* @return {Iterator} iterator instance
|
|
1120
|
+
*/
|
|
748
1121
|
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
1122
|
+
var _createIterator = function _createIterator(root) {
|
|
1123
|
+
return createNodeIterator.call(root.ownerDocument || root, root,
|
|
1124
|
+
// eslint-disable-next-line no-bitwise
|
|
1125
|
+
NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT, null, false);
|
|
1126
|
+
};
|
|
1127
|
+
/**
|
|
1128
|
+
* _isClobbered
|
|
1129
|
+
*
|
|
1130
|
+
* @param {Node} elm element to check for clobbering attacks
|
|
1131
|
+
* @return {Boolean} true if clobbered, false if safe
|
|
1132
|
+
*/
|
|
753
1133
|
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
}
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
* @param {String} name an Attribute name
|
|
764
|
-
* @param {Node} node a DOM node
|
|
765
|
-
*/
|
|
1134
|
+
var _isClobbered = function _isClobbered(elm) {
|
|
1135
|
+
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');
|
|
1136
|
+
};
|
|
1137
|
+
/**
|
|
1138
|
+
* _isNode
|
|
1139
|
+
*
|
|
1140
|
+
* @param {Node} obj object to check whether it's a DOM node
|
|
1141
|
+
* @return {Boolean} true is object is a DOM node
|
|
1142
|
+
*/
|
|
766
1143
|
|
|
1144
|
+
var _isNode = function _isNode(object) {
|
|
1145
|
+
return _typeof(Node) === 'object' ? object instanceof Node : object && _typeof(object) === 'object' && typeof object.nodeType === 'number' && typeof object.nodeName === 'string';
|
|
1146
|
+
};
|
|
1147
|
+
/**
|
|
1148
|
+
* _executeHook
|
|
1149
|
+
* Execute user configurable hooks
|
|
1150
|
+
*
|
|
1151
|
+
* @param {String} entryPoint Name of the hook's entry point
|
|
1152
|
+
* @param {Node} currentNode node to work on with the hook
|
|
1153
|
+
* @param {Object} data additional hook parameters
|
|
1154
|
+
*/
|
|
767
1155
|
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
} catch (error) {
|
|
775
|
-
DOMPurify.removed.push({
|
|
776
|
-
attribute: null,
|
|
777
|
-
from: node
|
|
1156
|
+
var _executeHook = function _executeHook(entryPoint, currentNode, data) {
|
|
1157
|
+
if (!hooks[entryPoint]) {
|
|
1158
|
+
return;
|
|
1159
|
+
}
|
|
1160
|
+
arrayForEach(hooks[entryPoint], function (hook) {
|
|
1161
|
+
hook.call(DOMPurify, currentNode, data, CONFIG);
|
|
778
1162
|
});
|
|
779
|
-
}
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
1163
|
+
};
|
|
1164
|
+
/**
|
|
1165
|
+
* _sanitizeElements
|
|
1166
|
+
*
|
|
1167
|
+
* @protect nodeName
|
|
1168
|
+
* @protect textContent
|
|
1169
|
+
* @protect removeChild
|
|
1170
|
+
*
|
|
1171
|
+
* @param {Node} currentNode to check for permission to exist
|
|
1172
|
+
* @return {Boolean} true if node was killed, false if left alive
|
|
1173
|
+
*/
|
|
790
1174
|
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
var leadingWhitespace = void 0;
|
|
1175
|
+
var _sanitizeElements = function _sanitizeElements(currentNode) {
|
|
1176
|
+
var content;
|
|
1177
|
+
/* Execute a hook if present */
|
|
795
1178
|
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
} else {
|
|
799
|
-
/* If FORCE_BODY isn't used, leading whitespace needs to be preserved manually */
|
|
800
|
-
var matches = dirty.match(/^[\s]+/);
|
|
801
|
-
leadingWhitespace = matches && matches[0];
|
|
1179
|
+
_executeHook('beforeSanitizeElements', currentNode, null);
|
|
1180
|
+
/* Check if element is clobbered or can clobber */
|
|
802
1181
|
|
|
803
|
-
if (
|
|
804
|
-
|
|
1182
|
+
if (_isClobbered(currentNode)) {
|
|
1183
|
+
_forceRemove(currentNode);
|
|
1184
|
+
return true;
|
|
805
1185
|
}
|
|
806
|
-
|
|
807
|
-
/* Use DOMParser to workaround Firefox bug (see comment below) */
|
|
1186
|
+
/* Check if tagname contains Unicode */
|
|
808
1187
|
|
|
1188
|
+
if (regExpTest(/[\u0080-\uFFFF]/, currentNode.nodeName)) {
|
|
1189
|
+
_forceRemove(currentNode);
|
|
1190
|
+
return true;
|
|
1191
|
+
}
|
|
1192
|
+
/* Now let's check the element's type and name */
|
|
809
1193
|
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
doc = new DOMParser().parseFromString(dirty, 'text/html');
|
|
813
|
-
} catch (error) {}
|
|
814
|
-
}
|
|
815
|
-
/* Remove title to fix a mXSS bug in older MS Edge */
|
|
1194
|
+
var tagName = transformCaseFunc(currentNode.nodeName);
|
|
1195
|
+
/* Execute a hook if present */
|
|
816
1196
|
|
|
1197
|
+
_executeHook('uponSanitizeElement', currentNode, {
|
|
1198
|
+
tagName: tagName,
|
|
1199
|
+
allowedTags: ALLOWED_TAGS
|
|
1200
|
+
});
|
|
1201
|
+
/* Detect mXSS attempts abusing namespace confusion */
|
|
817
1202
|
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
1203
|
+
if (currentNode.hasChildNodes() && !_isNode(currentNode.firstElementChild) && (!_isNode(currentNode.content) || !_isNode(currentNode.content.firstElementChild)) && regExpTest(/<[/\w]/g, currentNode.innerHTML) && regExpTest(/<[/\w]/g, currentNode.textContent)) {
|
|
1204
|
+
_forceRemove(currentNode);
|
|
1205
|
+
return true;
|
|
1206
|
+
}
|
|
1207
|
+
/* Mitigate a problem with templates inside select */
|
|
823
1208
|
|
|
1209
|
+
if (tagName === 'select' && regExpTest(/<template/i, currentNode.innerHTML)) {
|
|
1210
|
+
_forceRemove(currentNode);
|
|
1211
|
+
return true;
|
|
1212
|
+
}
|
|
1213
|
+
/* Remove element if anything forbids its presence */
|
|
824
1214
|
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
body.outerHTML = trustedTypesPolicy ? trustedTypesPolicy.createHTML(dirty) : dirty;
|
|
831
|
-
}
|
|
832
|
-
|
|
833
|
-
if (leadingWhitespace) {
|
|
834
|
-
doc.body.insertBefore(document.createTextNode(leadingWhitespace), doc.body.childNodes[0] || null);
|
|
835
|
-
}
|
|
836
|
-
/* Work on whole document or just its body */
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
return getElementsByTagName.call(doc, WHOLE_DOCUMENT ? 'html' : 'body')[0];
|
|
840
|
-
}; // Firefox uses a different parser for innerHTML rather than
|
|
841
|
-
// DOMParser (see https://bugzilla.mozilla.org/show_bug.cgi?id=1205631)
|
|
842
|
-
// which means that you *must* use DOMParser, otherwise the output may
|
|
843
|
-
// not be safe if used in a document.write context later.
|
|
844
|
-
//
|
|
845
|
-
// So we feature detect the Firefox bug and use the DOMParser if necessary.
|
|
846
|
-
//
|
|
847
|
-
// MS Edge, in older versions, is affected by an mXSS behavior. The second
|
|
848
|
-
// check tests for the behavior and fixes it if necessary.
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
if (DOMPurify.isSupported) {
|
|
852
|
-
(function () {
|
|
853
|
-
try {
|
|
854
|
-
var doc = _initDocument('<svg><p><style><img src="</style><img src=x onerror=1//">');
|
|
855
|
-
|
|
856
|
-
if (doc.querySelector('svg img')) {
|
|
857
|
-
useDOMParser = true;
|
|
1215
|
+
if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {
|
|
1216
|
+
/* Check if we have a custom element to handle */
|
|
1217
|
+
if (!FORBID_TAGS[tagName] && _basicCustomElementTest(tagName)) {
|
|
1218
|
+
if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)) return false;
|
|
1219
|
+
if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName)) return false;
|
|
858
1220
|
}
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
1221
|
+
/* Keep content except for bad-listed elements */
|
|
1222
|
+
|
|
1223
|
+
if (KEEP_CONTENT && !FORBID_CONTENTS[tagName]) {
|
|
1224
|
+
var parentNode = getParentNode(currentNode) || currentNode.parentNode;
|
|
1225
|
+
var childNodes = getChildNodes(currentNode) || currentNode.childNodes;
|
|
1226
|
+
if (childNodes && parentNode) {
|
|
1227
|
+
var childCount = childNodes.length;
|
|
1228
|
+
for (var i = childCount - 1; i >= 0; --i) {
|
|
1229
|
+
parentNode.insertBefore(cloneNode(childNodes[i], true), getNextSibling(currentNode));
|
|
1230
|
+
}
|
|
1231
|
+
}
|
|
868
1232
|
}
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
* _createIterator
|
|
874
|
-
*
|
|
875
|
-
* @param {Document} root document/fragment to create iterator for
|
|
876
|
-
* @return {Iterator} iterator instance
|
|
877
|
-
*/
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
var _createIterator = function _createIterator(root) {
|
|
881
|
-
return createNodeIterator.call(root.ownerDocument || root, root, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT, function () {
|
|
882
|
-
return NodeFilter.FILTER_ACCEPT;
|
|
883
|
-
}, false);
|
|
884
|
-
};
|
|
885
|
-
/**
|
|
886
|
-
* _isClobbered
|
|
887
|
-
*
|
|
888
|
-
* @param {Node} elm element to check for clobbering attacks
|
|
889
|
-
* @return {Boolean} true if clobbered, false if safe
|
|
890
|
-
*/
|
|
1233
|
+
_forceRemove(currentNode);
|
|
1234
|
+
return true;
|
|
1235
|
+
}
|
|
1236
|
+
/* Check whether element has a valid namespace */
|
|
891
1237
|
|
|
1238
|
+
if (currentNode instanceof Element && !_checkValidNamespace(currentNode)) {
|
|
1239
|
+
_forceRemove(currentNode);
|
|
1240
|
+
return true;
|
|
1241
|
+
}
|
|
1242
|
+
if ((tagName === 'noscript' || tagName === 'noembed') && regExpTest(/<\/no(script|embed)/i, currentNode.innerHTML)) {
|
|
1243
|
+
_forceRemove(currentNode);
|
|
1244
|
+
return true;
|
|
1245
|
+
}
|
|
1246
|
+
/* Sanitize element content to be template-safe */
|
|
1247
|
+
|
|
1248
|
+
if (SAFE_FOR_TEMPLATES && currentNode.nodeType === 3) {
|
|
1249
|
+
/* Get the element's text content */
|
|
1250
|
+
content = currentNode.textContent;
|
|
1251
|
+
content = stringReplace(content, MUSTACHE_EXPR$1, ' ');
|
|
1252
|
+
content = stringReplace(content, ERB_EXPR$1, ' ');
|
|
1253
|
+
if (currentNode.textContent !== content) {
|
|
1254
|
+
arrayPush(DOMPurify.removed, {
|
|
1255
|
+
element: currentNode.cloneNode()
|
|
1256
|
+
});
|
|
1257
|
+
currentNode.textContent = content;
|
|
1258
|
+
}
|
|
1259
|
+
}
|
|
1260
|
+
/* Execute a hook if present */
|
|
892
1261
|
|
|
893
|
-
|
|
894
|
-
if (elm instanceof Text || elm instanceof Comment) {
|
|
1262
|
+
_executeHook('afterSanitizeElements', currentNode, null);
|
|
895
1263
|
return false;
|
|
896
|
-
}
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
*
|
|
907
|
-
* @param {Node} obj object to check whether it's a DOM node
|
|
908
|
-
* @return {Boolean} true is object is a DOM node
|
|
909
|
-
*/
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
var _isNode = function _isNode(obj) {
|
|
913
|
-
return (typeof Node === 'undefined' ? 'undefined' : _typeof$1(Node)) === 'object' ? obj instanceof Node : obj && (typeof obj === 'undefined' ? 'undefined' : _typeof$1(obj)) === 'object' && typeof obj.nodeType === 'number' && typeof obj.nodeName === 'string';
|
|
914
|
-
};
|
|
915
|
-
/**
|
|
916
|
-
* _executeHook
|
|
917
|
-
* Execute user configurable hooks
|
|
918
|
-
*
|
|
919
|
-
* @param {String} entryPoint Name of the hook's entry point
|
|
920
|
-
* @param {Node} currentNode node to work on with the hook
|
|
921
|
-
* @param {Object} data additional hook parameters
|
|
922
|
-
*/
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
var _executeHook = function _executeHook(entryPoint, currentNode, data) {
|
|
926
|
-
if (!hooks[entryPoint]) {
|
|
927
|
-
return;
|
|
928
|
-
}
|
|
929
|
-
|
|
930
|
-
hooks[entryPoint].forEach(function (hook) {
|
|
931
|
-
hook.call(DOMPurify, currentNode, data, CONFIG);
|
|
932
|
-
});
|
|
933
|
-
};
|
|
934
|
-
/**
|
|
935
|
-
* _sanitizeElements
|
|
936
|
-
*
|
|
937
|
-
* @protect nodeName
|
|
938
|
-
* @protect textContent
|
|
939
|
-
* @protect removeChild
|
|
940
|
-
*
|
|
941
|
-
* @param {Node} currentNode to check for permission to exist
|
|
942
|
-
* @return {Boolean} true if node was killed, false if left alive
|
|
943
|
-
*/
|
|
944
|
-
// eslint-disable-next-line complexity
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
var _sanitizeElements = function _sanitizeElements(currentNode) {
|
|
948
|
-
var content = void 0;
|
|
949
|
-
/* Execute a hook if present */
|
|
950
|
-
|
|
951
|
-
_executeHook('beforeSanitizeElements', currentNode, null);
|
|
952
|
-
/* Check if element is clobbered or can clobber */
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
if (_isClobbered(currentNode)) {
|
|
956
|
-
_forceRemove(currentNode);
|
|
957
|
-
|
|
958
|
-
return true;
|
|
959
|
-
}
|
|
960
|
-
/* Now let's check the element's type and name */
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
var tagName = currentNode.nodeName.toLowerCase();
|
|
964
|
-
/* Execute a hook if present */
|
|
965
|
-
|
|
966
|
-
_executeHook('uponSanitizeElement', currentNode, {
|
|
967
|
-
tagName: tagName,
|
|
968
|
-
allowedTags: ALLOWED_TAGS
|
|
969
|
-
});
|
|
970
|
-
/* Remove element if anything forbids its presence */
|
|
971
|
-
|
|
1264
|
+
};
|
|
1265
|
+
/**
|
|
1266
|
+
* _isValidAttribute
|
|
1267
|
+
*
|
|
1268
|
+
* @param {string} lcTag Lowercase tag name of containing element.
|
|
1269
|
+
* @param {string} lcName Lowercase attribute name.
|
|
1270
|
+
* @param {string} value Attribute value.
|
|
1271
|
+
* @return {Boolean} Returns true if `value` is valid, otherwise false.
|
|
1272
|
+
*/
|
|
1273
|
+
// eslint-disable-next-line complexity
|
|
972
1274
|
|
|
973
|
-
|
|
974
|
-
/*
|
|
975
|
-
if (
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
1275
|
+
var _isValidAttribute = function _isValidAttribute(lcTag, lcName, value) {
|
|
1276
|
+
/* Make sure attribute cannot clobber */
|
|
1277
|
+
if (SANITIZE_DOM && (lcName === 'id' || lcName === 'name') && (value in document || value in formElement)) {
|
|
1278
|
+
return false;
|
|
1279
|
+
}
|
|
1280
|
+
/* Allow valid data-* attributes: At least one character after "-"
|
|
1281
|
+
(https://html.spec.whatwg.org/multipage/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes)
|
|
1282
|
+
XML-compatible (https://html.spec.whatwg.org/multipage/infrastructure.html#xml-compatible and http://www.w3.org/TR/xml/#d0e804)
|
|
1283
|
+
We don't need to check the value; it's always URI safe. */
|
|
1284
|
+
|
|
1285
|
+
if (ALLOW_DATA_ATTR && !FORBID_ATTR[lcName] && regExpTest(DATA_ATTR$1, lcName)) ;else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR$1, lcName)) ;else if (!ALLOWED_ATTR[lcName] || FORBID_ATTR[lcName]) {
|
|
1286
|
+
if (
|
|
1287
|
+
// First condition does a very basic check if a) it's basically a valid custom element tagname AND
|
|
1288
|
+
// b) if the tagName passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck
|
|
1289
|
+
// and c) if the attribute name passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.attributeNameCheck
|
|
1290
|
+
_basicCustomElementTest(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)) ||
|
|
1291
|
+
// Alternative, second condition checks if it's an `is`-attribute, AND
|
|
1292
|
+
// the value passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck
|
|
1293
|
+
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 {
|
|
1294
|
+
return false;
|
|
1295
|
+
}
|
|
1296
|
+
/* Check value is safe. First, is attr inert? If so, is safe */
|
|
1297
|
+
} else if (URI_SAFE_ATTRIBUTES[lcName]) ;else if (regExpTest(IS_ALLOWED_URI$1, stringReplace(value, ATTR_WHITESPACE$1, ''))) ;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$1, stringReplace(value, ATTR_WHITESPACE$1, ''))) ;else if (!value) ;else {
|
|
1298
|
+
return false;
|
|
980
1299
|
}
|
|
981
|
-
|
|
982
|
-
_forceRemove(currentNode);
|
|
983
|
-
|
|
984
|
-
return true;
|
|
985
|
-
}
|
|
986
|
-
/* Remove in case a noscript/noembed XSS is suspected */
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
if (tagName === 'noscript' && currentNode.innerHTML.match(/<\/noscript/i)) {
|
|
990
|
-
_forceRemove(currentNode);
|
|
991
|
-
|
|
992
|
-
return true;
|
|
993
|
-
}
|
|
994
|
-
|
|
995
|
-
if (tagName === 'noembed' && currentNode.innerHTML.match(/<\/noembed/i)) {
|
|
996
|
-
_forceRemove(currentNode);
|
|
997
|
-
|
|
998
1300
|
return true;
|
|
999
|
-
}
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
});
|
|
1301
|
+
};
|
|
1302
|
+
/**
|
|
1303
|
+
* _basicCustomElementCheck
|
|
1304
|
+
* checks if at least one dash is included in tagName, and it's not the first char
|
|
1305
|
+
* for more sophisticated checking see https://github.com/sindresorhus/validate-element-name
|
|
1306
|
+
* @param {string} tagName name of the tag of the node to sanitize
|
|
1307
|
+
*/
|
|
1007
1308
|
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1309
|
+
var _basicCustomElementTest = function _basicCustomElementTest(tagName) {
|
|
1310
|
+
return tagName.indexOf('-') > 0;
|
|
1311
|
+
};
|
|
1312
|
+
/**
|
|
1313
|
+
* _sanitizeAttributes
|
|
1314
|
+
*
|
|
1315
|
+
* @protect attributes
|
|
1316
|
+
* @protect nodeName
|
|
1317
|
+
* @protect removeAttribute
|
|
1318
|
+
* @protect setAttribute
|
|
1319
|
+
*
|
|
1320
|
+
* @param {Node} currentNode to sanitize
|
|
1321
|
+
*/
|
|
1015
1322
|
|
|
1323
|
+
var _sanitizeAttributes = function _sanitizeAttributes(currentNode) {
|
|
1324
|
+
var attr;
|
|
1325
|
+
var value;
|
|
1326
|
+
var lcName;
|
|
1327
|
+
var l;
|
|
1328
|
+
/* Execute a hook if present */
|
|
1016
1329
|
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
content = content.replace(MUSTACHE_EXPR$$1, ' ');
|
|
1021
|
-
content = content.replace(ERB_EXPR$$1, ' ');
|
|
1330
|
+
_executeHook('beforeSanitizeAttributes', currentNode, null);
|
|
1331
|
+
var attributes = currentNode.attributes;
|
|
1332
|
+
/* Check if we have attributes; if not we might have a text node */
|
|
1022
1333
|
|
|
1023
|
-
if (
|
|
1024
|
-
|
|
1025
|
-
element: currentNode.cloneNode()
|
|
1026
|
-
});
|
|
1027
|
-
currentNode.textContent = content;
|
|
1334
|
+
if (!attributes) {
|
|
1335
|
+
return;
|
|
1028
1336
|
}
|
|
1029
|
-
|
|
1030
|
-
|
|
1337
|
+
var hookEvent = {
|
|
1338
|
+
attrName: '',
|
|
1339
|
+
attrValue: '',
|
|
1340
|
+
keepAttr: true,
|
|
1341
|
+
allowedAttributes: ALLOWED_ATTR
|
|
1342
|
+
};
|
|
1343
|
+
l = attributes.length;
|
|
1344
|
+
/* Go backwards over all attributes; safely remove bad ones */
|
|
1345
|
+
|
|
1346
|
+
while (l--) {
|
|
1347
|
+
attr = attributes[l];
|
|
1348
|
+
var _attr = attr,
|
|
1349
|
+
name = _attr.name,
|
|
1350
|
+
namespaceURI = _attr.namespaceURI;
|
|
1351
|
+
value = name === 'value' ? attr.value : stringTrim(attr.value);
|
|
1352
|
+
lcName = transformCaseFunc(name);
|
|
1353
|
+
/* Execute a hook if present */
|
|
1031
1354
|
|
|
1355
|
+
hookEvent.attrName = lcName;
|
|
1356
|
+
hookEvent.attrValue = value;
|
|
1357
|
+
hookEvent.keepAttr = true;
|
|
1358
|
+
hookEvent.forceKeepAttr = undefined; // Allows developers to see this is a property they can set
|
|
1032
1359
|
|
|
1033
|
-
|
|
1360
|
+
_executeHook('uponSanitizeAttribute', currentNode, hookEvent);
|
|
1361
|
+
value = hookEvent.attrValue;
|
|
1362
|
+
/* Did the hooks approve of the attribute? */
|
|
1034
1363
|
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
*
|
|
1040
|
-
* @param {string} lcTag Lowercase tag name of containing element.
|
|
1041
|
-
* @param {string} lcName Lowercase attribute name.
|
|
1042
|
-
* @param {string} value Attribute value.
|
|
1043
|
-
* @return {Boolean} Returns true if `value` is valid, otherwise false.
|
|
1044
|
-
*/
|
|
1045
|
-
// eslint-disable-next-line complexity
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
var _isValidAttribute = function _isValidAttribute(lcTag, lcName, value) {
|
|
1049
|
-
/* Make sure attribute cannot clobber */
|
|
1050
|
-
if (SANITIZE_DOM && (lcName === 'id' || lcName === 'name') && (value in document || value in formElement)) {
|
|
1051
|
-
return false;
|
|
1052
|
-
}
|
|
1053
|
-
/* Allow valid data-* attributes: At least one character after "-"
|
|
1054
|
-
(https://html.spec.whatwg.org/multipage/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes)
|
|
1055
|
-
XML-compatible (https://html.spec.whatwg.org/multipage/infrastructure.html#xml-compatible and http://www.w3.org/TR/xml/#d0e804)
|
|
1056
|
-
We don't need to check the value; it's always URI safe. */
|
|
1364
|
+
if (hookEvent.forceKeepAttr) {
|
|
1365
|
+
continue;
|
|
1366
|
+
}
|
|
1367
|
+
/* Remove attribute */
|
|
1057
1368
|
|
|
1369
|
+
_removeAttribute(name, currentNode);
|
|
1370
|
+
/* Did the hooks approve of the attribute? */
|
|
1058
1371
|
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
return false;
|
|
1064
|
-
}
|
|
1372
|
+
if (!hookEvent.keepAttr) {
|
|
1373
|
+
continue;
|
|
1374
|
+
}
|
|
1375
|
+
/* Work around a security issue in jQuery 3.0 */
|
|
1065
1376
|
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
* @protect attributes
|
|
1072
|
-
* @protect nodeName
|
|
1073
|
-
* @protect removeAttribute
|
|
1074
|
-
* @protect setAttribute
|
|
1075
|
-
*
|
|
1076
|
-
* @param {Node} currentNode to sanitize
|
|
1077
|
-
*/
|
|
1377
|
+
if (regExpTest(/\/>/i, value)) {
|
|
1378
|
+
_removeAttribute(name, currentNode);
|
|
1379
|
+
continue;
|
|
1380
|
+
}
|
|
1381
|
+
/* Sanitize attribute content to be template-safe */
|
|
1078
1382
|
|
|
1383
|
+
if (SAFE_FOR_TEMPLATES) {
|
|
1384
|
+
value = stringReplace(value, MUSTACHE_EXPR$1, ' ');
|
|
1385
|
+
value = stringReplace(value, ERB_EXPR$1, ' ');
|
|
1386
|
+
}
|
|
1387
|
+
/* Is `value` valid for this attribute? */
|
|
1079
1388
|
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1389
|
+
var lcTag = transformCaseFunc(currentNode.nodeName);
|
|
1390
|
+
if (!_isValidAttribute(lcTag, lcName, value)) {
|
|
1391
|
+
continue;
|
|
1392
|
+
}
|
|
1393
|
+
/* Full DOM Clobbering protection via namespace isolation,
|
|
1394
|
+
* Prefix id and name attributes with `user-content-`
|
|
1395
|
+
*/
|
|
1087
1396
|
|
|
1088
|
-
|
|
1397
|
+
if (SANITIZE_NAMED_PROPS && (lcName === 'id' || lcName === 'name')) {
|
|
1398
|
+
// Remove the attribute with this value
|
|
1399
|
+
_removeAttribute(name, currentNode); // Prefix the value and later re-create the attribute with the sanitized value
|
|
1089
1400
|
|
|
1090
|
-
|
|
1091
|
-
|
|
1401
|
+
value = SANITIZE_NAMED_PROPS_PREFIX + value;
|
|
1402
|
+
}
|
|
1403
|
+
/* Handle attributes that require Trusted Types */
|
|
1404
|
+
|
|
1405
|
+
if (trustedTypesPolicy && _typeof(trustedTypes) === 'object' && typeof trustedTypes.getAttributeType === 'function') {
|
|
1406
|
+
if (namespaceURI) ;else {
|
|
1407
|
+
switch (trustedTypes.getAttributeType(lcTag, lcName)) {
|
|
1408
|
+
case 'TrustedHTML':
|
|
1409
|
+
value = trustedTypesPolicy.createHTML(value);
|
|
1410
|
+
break;
|
|
1411
|
+
case 'TrustedScriptURL':
|
|
1412
|
+
value = trustedTypesPolicy.createScriptURL(value);
|
|
1413
|
+
break;
|
|
1414
|
+
}
|
|
1415
|
+
}
|
|
1416
|
+
}
|
|
1417
|
+
/* Handle invalid data-* attribute set by try-catching it */
|
|
1092
1418
|
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1419
|
+
try {
|
|
1420
|
+
if (namespaceURI) {
|
|
1421
|
+
currentNode.setAttributeNS(namespaceURI, name, value);
|
|
1422
|
+
} else {
|
|
1423
|
+
/* Fallback to setAttribute() for browser-unrecognized namespaces e.g. "x-schema". */
|
|
1424
|
+
currentNode.setAttribute(name, value);
|
|
1425
|
+
}
|
|
1426
|
+
arrayPop(DOMPurify.removed);
|
|
1427
|
+
} catch (_) {}
|
|
1428
|
+
}
|
|
1429
|
+
/* Execute a hook if present */
|
|
1096
1430
|
|
|
1097
|
-
|
|
1098
|
-
attrName: '',
|
|
1099
|
-
attrValue: '',
|
|
1100
|
-
keepAttr: true,
|
|
1101
|
-
allowedAttributes: ALLOWED_ATTR
|
|
1431
|
+
_executeHook('afterSanitizeAttributes', currentNode, null);
|
|
1102
1432
|
};
|
|
1103
|
-
|
|
1104
|
-
|
|
1433
|
+
/**
|
|
1434
|
+
* _sanitizeShadowDOM
|
|
1435
|
+
*
|
|
1436
|
+
* @param {DocumentFragment} fragment to iterate over recursively
|
|
1437
|
+
*/
|
|
1105
1438
|
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
var
|
|
1109
|
-
name = _attr.name,
|
|
1110
|
-
namespaceURI = _attr.namespaceURI;
|
|
1111
|
-
value = attr.value.trim();
|
|
1112
|
-
lcName = name.toLowerCase();
|
|
1439
|
+
var _sanitizeShadowDOM = function _sanitizeShadowDOM(fragment) {
|
|
1440
|
+
var shadowNode;
|
|
1441
|
+
var shadowIterator = _createIterator(fragment);
|
|
1113
1442
|
/* Execute a hook if present */
|
|
1114
1443
|
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1444
|
+
_executeHook('beforeSanitizeShadowDOM', fragment, null);
|
|
1445
|
+
while (shadowNode = shadowIterator.nextNode()) {
|
|
1446
|
+
/* Execute a hook if present */
|
|
1447
|
+
_executeHook('uponSanitizeShadowNode', shadowNode, null);
|
|
1448
|
+
/* Sanitize tags and elements */
|
|
1120
1449
|
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
// Safari (iOS + Mac), last tested v8.0.5, crashes if you try to
|
|
1124
|
-
// remove a "name" attribute from an <img> tag that has an "id"
|
|
1125
|
-
// attribute at the time.
|
|
1126
|
-
|
|
1127
|
-
if (lcName === 'name' && currentNode.nodeName === 'IMG' && attributes.id) {
|
|
1128
|
-
idAttr = attributes.id;
|
|
1129
|
-
attributes = apply(arraySlice, attributes, []);
|
|
1130
|
-
|
|
1131
|
-
_removeAttribute('id', currentNode);
|
|
1132
|
-
|
|
1133
|
-
_removeAttribute(name, currentNode);
|
|
1134
|
-
|
|
1135
|
-
if (attributes.indexOf(idAttr) > l) {
|
|
1136
|
-
currentNode.setAttribute('id', idAttr.value);
|
|
1450
|
+
if (_sanitizeElements(shadowNode)) {
|
|
1451
|
+
continue;
|
|
1137
1452
|
}
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
} else {
|
|
1143
|
-
// This avoids a crash in Safari v9.0 with double-ids.
|
|
1144
|
-
// The trick is to first set the id to be empty and then to
|
|
1145
|
-
// remove the attribute
|
|
1146
|
-
if (name === 'id') {
|
|
1147
|
-
currentNode.setAttribute(name, '');
|
|
1453
|
+
/* Deep shadow DOM detected */
|
|
1454
|
+
|
|
1455
|
+
if (shadowNode.content instanceof DocumentFragment) {
|
|
1456
|
+
_sanitizeShadowDOM(shadowNode.content);
|
|
1148
1457
|
}
|
|
1458
|
+
/* Check attributes, sanitize if necessary */
|
|
1149
1459
|
|
|
1150
|
-
|
|
1460
|
+
_sanitizeAttributes(shadowNode);
|
|
1151
1461
|
}
|
|
1152
|
-
/*
|
|
1153
|
-
|
|
1462
|
+
/* Execute a hook if present */
|
|
1154
1463
|
|
|
1155
|
-
|
|
1156
|
-
|
|
1464
|
+
_executeHook('afterSanitizeShadowDOM', fragment, null);
|
|
1465
|
+
};
|
|
1466
|
+
/**
|
|
1467
|
+
* Sanitize
|
|
1468
|
+
* Public method providing core sanitation functionality
|
|
1469
|
+
*
|
|
1470
|
+
* @param {String|Node} dirty string or DOM node
|
|
1471
|
+
* @param {Object} configuration object
|
|
1472
|
+
*/
|
|
1473
|
+
// eslint-disable-next-line complexity
|
|
1474
|
+
|
|
1475
|
+
DOMPurify.sanitize = function (dirty) {
|
|
1476
|
+
var cfg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
1477
|
+
var body;
|
|
1478
|
+
var importedNode;
|
|
1479
|
+
var currentNode;
|
|
1480
|
+
var oldNode;
|
|
1481
|
+
var returnNode;
|
|
1482
|
+
/* Make sure we have a string to sanitize.
|
|
1483
|
+
DO NOT return early, as this will return the wrong type if
|
|
1484
|
+
the user has requested a DOM object rather than a string */
|
|
1485
|
+
|
|
1486
|
+
IS_EMPTY_INPUT = !dirty;
|
|
1487
|
+
if (IS_EMPTY_INPUT) {
|
|
1488
|
+
dirty = '<!-->';
|
|
1157
1489
|
}
|
|
1158
|
-
/*
|
|
1490
|
+
/* Stringify, in case dirty is an object */
|
|
1159
1491
|
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1492
|
+
if (typeof dirty !== 'string' && !_isNode(dirty)) {
|
|
1493
|
+
// eslint-disable-next-line no-negated-condition
|
|
1494
|
+
if (typeof dirty.toString !== 'function') {
|
|
1495
|
+
throw typeErrorCreate('toString is not a function');
|
|
1496
|
+
} else {
|
|
1497
|
+
dirty = dirty.toString();
|
|
1498
|
+
if (typeof dirty !== 'string') {
|
|
1499
|
+
throw typeErrorCreate('dirty is not a string, aborting');
|
|
1500
|
+
}
|
|
1501
|
+
}
|
|
1164
1502
|
}
|
|
1165
|
-
/*
|
|
1166
|
-
|
|
1503
|
+
/* Check we can run. Otherwise fall back or ignore */
|
|
1167
1504
|
|
|
1168
|
-
|
|
1505
|
+
if (!DOMPurify.isSupported) {
|
|
1506
|
+
if (_typeof(window.toStaticHTML) === 'object' || typeof window.toStaticHTML === 'function') {
|
|
1507
|
+
if (typeof dirty === 'string') {
|
|
1508
|
+
return window.toStaticHTML(dirty);
|
|
1509
|
+
}
|
|
1510
|
+
if (_isNode(dirty)) {
|
|
1511
|
+
return window.toStaticHTML(dirty.outerHTML);
|
|
1512
|
+
}
|
|
1513
|
+
}
|
|
1514
|
+
return dirty;
|
|
1515
|
+
}
|
|
1516
|
+
/* Assign config vars */
|
|
1169
1517
|
|
|
1170
|
-
if (!
|
|
1171
|
-
|
|
1518
|
+
if (!SET_CONFIG) {
|
|
1519
|
+
_parseConfig(cfg);
|
|
1172
1520
|
}
|
|
1173
|
-
/*
|
|
1521
|
+
/* Clean up removed elements */
|
|
1174
1522
|
|
|
1523
|
+
DOMPurify.removed = [];
|
|
1524
|
+
/* Check if dirty is correctly typed for IN_PLACE */
|
|
1175
1525
|
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1526
|
+
if (typeof dirty === 'string') {
|
|
1527
|
+
IN_PLACE = false;
|
|
1528
|
+
}
|
|
1529
|
+
if (IN_PLACE) {
|
|
1530
|
+
/* Do some early pre-sanitization to avoid unsafe root nodes */
|
|
1531
|
+
if (dirty.nodeName) {
|
|
1532
|
+
var tagName = transformCaseFunc(dirty.nodeName);
|
|
1533
|
+
if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {
|
|
1534
|
+
throw typeErrorCreate('root node is forbidden and cannot be sanitized in-place');
|
|
1535
|
+
}
|
|
1536
|
+
}
|
|
1537
|
+
} else if (dirty instanceof Node) {
|
|
1538
|
+
/* If dirty is a DOM element, append to an empty document to avoid
|
|
1539
|
+
elements being stripped by the parser */
|
|
1540
|
+
body = _initDocument('<!---->');
|
|
1541
|
+
importedNode = body.ownerDocument.importNode(dirty, true);
|
|
1542
|
+
if (importedNode.nodeType === 1 && importedNode.nodeName === 'BODY') {
|
|
1543
|
+
/* Node is already a body, use as is */
|
|
1544
|
+
body = importedNode;
|
|
1545
|
+
} else if (importedNode.nodeName === 'HTML') {
|
|
1546
|
+
body = importedNode;
|
|
1179
1547
|
} else {
|
|
1180
|
-
|
|
1181
|
-
|
|
1548
|
+
// eslint-disable-next-line unicorn/prefer-dom-node-append
|
|
1549
|
+
body.appendChild(importedNode);
|
|
1182
1550
|
}
|
|
1551
|
+
} else {
|
|
1552
|
+
/* Exit directly if we have nothing to do */
|
|
1553
|
+
if (!RETURN_DOM && !SAFE_FOR_TEMPLATES && !WHOLE_DOCUMENT &&
|
|
1554
|
+
// eslint-disable-next-line unicorn/prefer-includes
|
|
1555
|
+
dirty.indexOf('<') === -1) {
|
|
1556
|
+
return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(dirty) : dirty;
|
|
1557
|
+
}
|
|
1558
|
+
/* Initialize the document to work on */
|
|
1183
1559
|
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
}
|
|
1187
|
-
/* Execute a hook if present */
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
_executeHook('afterSanitizeAttributes', currentNode, null);
|
|
1191
|
-
};
|
|
1192
|
-
/**
|
|
1193
|
-
* _sanitizeShadowDOM
|
|
1194
|
-
*
|
|
1195
|
-
* @param {DocumentFragment} fragment to iterate over recursively
|
|
1196
|
-
*/
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
var _sanitizeShadowDOM = function _sanitizeShadowDOM(fragment) {
|
|
1200
|
-
var shadowNode = void 0;
|
|
1201
|
-
|
|
1202
|
-
var shadowIterator = _createIterator(fragment);
|
|
1203
|
-
/* Execute a hook if present */
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
_executeHook('beforeSanitizeShadowDOM', fragment, null);
|
|
1207
|
-
|
|
1208
|
-
while (shadowNode = shadowIterator.nextNode()) {
|
|
1209
|
-
/* Execute a hook if present */
|
|
1210
|
-
_executeHook('uponSanitizeShadowNode', shadowNode, null);
|
|
1211
|
-
/* Sanitize tags and elements */
|
|
1212
|
-
|
|
1560
|
+
body = _initDocument(dirty);
|
|
1561
|
+
/* Check we have a DOM node from the data */
|
|
1213
1562
|
|
|
1214
|
-
|
|
1215
|
-
|
|
1563
|
+
if (!body) {
|
|
1564
|
+
return RETURN_DOM ? null : RETURN_TRUSTED_TYPE ? emptyHTML : '';
|
|
1565
|
+
}
|
|
1216
1566
|
}
|
|
1217
|
-
/*
|
|
1218
|
-
|
|
1567
|
+
/* Remove first element node (ours) if FORCE_BODY is set */
|
|
1219
1568
|
|
|
1220
|
-
if (
|
|
1221
|
-
|
|
1569
|
+
if (body && FORCE_BODY) {
|
|
1570
|
+
_forceRemove(body.firstChild);
|
|
1222
1571
|
}
|
|
1223
|
-
/*
|
|
1572
|
+
/* Get node iterator */
|
|
1224
1573
|
|
|
1574
|
+
var nodeIterator = _createIterator(IN_PLACE ? dirty : body);
|
|
1575
|
+
/* Now start iterating over the created document */
|
|
1225
1576
|
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
_executeHook('afterSanitizeShadowDOM', fragment, null);
|
|
1232
|
-
};
|
|
1233
|
-
/**
|
|
1234
|
-
* Sanitize
|
|
1235
|
-
* Public method providing core sanitation functionality
|
|
1236
|
-
*
|
|
1237
|
-
* @param {String|Node} dirty string or DOM node
|
|
1238
|
-
* @param {Object} configuration object
|
|
1239
|
-
*/
|
|
1240
|
-
// eslint-disable-next-line complexity
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
DOMPurify.sanitize = function (dirty, cfg) {
|
|
1244
|
-
var body = void 0;
|
|
1245
|
-
var importedNode = void 0;
|
|
1246
|
-
var currentNode = void 0;
|
|
1247
|
-
var oldNode = void 0;
|
|
1248
|
-
var returnNode = void 0;
|
|
1249
|
-
/* Make sure we have a string to sanitize.
|
|
1250
|
-
DO NOT return early, as this will return the wrong type if
|
|
1251
|
-
the user has requested a DOM object rather than a string */
|
|
1252
|
-
|
|
1253
|
-
if (!dirty) {
|
|
1254
|
-
dirty = '<!-->';
|
|
1255
|
-
}
|
|
1256
|
-
/* Stringify, in case dirty is an object */
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
if (typeof dirty !== 'string' && !_isNode(dirty)) {
|
|
1260
|
-
// eslint-disable-next-line no-negated-condition
|
|
1261
|
-
if (typeof dirty.toString !== 'function') {
|
|
1262
|
-
throw new TypeError('toString is not a function');
|
|
1263
|
-
} else {
|
|
1264
|
-
dirty = dirty.toString();
|
|
1265
|
-
|
|
1266
|
-
if (typeof dirty !== 'string') {
|
|
1267
|
-
throw new TypeError('dirty is not a string, aborting');
|
|
1577
|
+
while (currentNode = nodeIterator.nextNode()) {
|
|
1578
|
+
/* Fix IE's strange behavior with manipulated textNodes #89 */
|
|
1579
|
+
if (currentNode.nodeType === 3 && currentNode === oldNode) {
|
|
1580
|
+
continue;
|
|
1268
1581
|
}
|
|
1269
|
-
|
|
1270
|
-
}
|
|
1271
|
-
/* Check we can run. Otherwise fall back or ignore */
|
|
1582
|
+
/* Sanitize tags and elements */
|
|
1272
1583
|
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
if (_typeof$1(window.toStaticHTML) === 'object' || typeof window.toStaticHTML === 'function') {
|
|
1276
|
-
if (typeof dirty === 'string') {
|
|
1277
|
-
return window.toStaticHTML(dirty);
|
|
1584
|
+
if (_sanitizeElements(currentNode)) {
|
|
1585
|
+
continue;
|
|
1278
1586
|
}
|
|
1587
|
+
/* Shadow DOM detected, sanitize it */
|
|
1279
1588
|
|
|
1280
|
-
if (
|
|
1281
|
-
|
|
1589
|
+
if (currentNode.content instanceof DocumentFragment) {
|
|
1590
|
+
_sanitizeShadowDOM(currentNode.content);
|
|
1282
1591
|
}
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
return dirty;
|
|
1286
|
-
}
|
|
1287
|
-
/* Assign config vars */
|
|
1288
|
-
|
|
1592
|
+
/* Check attributes, sanitize if necessary */
|
|
1289
1593
|
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
}
|
|
1293
|
-
/* Clean up removed elements */
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
DOMPurify.removed = [];
|
|
1297
|
-
|
|
1298
|
-
if (IN_PLACE) ; else if (dirty instanceof Node) {
|
|
1299
|
-
/* If dirty is a DOM element, append to an empty document to avoid
|
|
1300
|
-
elements being stripped by the parser */
|
|
1301
|
-
body = _initDocument('<!-->');
|
|
1302
|
-
importedNode = body.ownerDocument.importNode(dirty, true);
|
|
1303
|
-
|
|
1304
|
-
if (importedNode.nodeType === 1 && importedNode.nodeName === 'BODY') {
|
|
1305
|
-
/* Node is already a body, use as is */
|
|
1306
|
-
body = importedNode;
|
|
1307
|
-
} else if (importedNode.nodeName === 'HTML') {
|
|
1308
|
-
body = importedNode;
|
|
1309
|
-
} else {
|
|
1310
|
-
// eslint-disable-next-line unicorn/prefer-node-append
|
|
1311
|
-
body.appendChild(importedNode);
|
|
1594
|
+
_sanitizeAttributes(currentNode);
|
|
1595
|
+
oldNode = currentNode;
|
|
1312
1596
|
}
|
|
1313
|
-
|
|
1314
|
-
/*
|
|
1315
|
-
if (!RETURN_DOM && !SAFE_FOR_TEMPLATES && !WHOLE_DOCUMENT && dirty.indexOf('<') === -1) {
|
|
1316
|
-
return trustedTypesPolicy ? trustedTypesPolicy.createHTML(dirty) : dirty;
|
|
1317
|
-
}
|
|
1318
|
-
/* Initialize the document to work on */
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
body = _initDocument(dirty);
|
|
1322
|
-
/* Check we have a DOM node from the data */
|
|
1597
|
+
oldNode = null;
|
|
1598
|
+
/* If we sanitized `dirty` in-place, return it. */
|
|
1323
1599
|
|
|
1324
|
-
if (
|
|
1325
|
-
return
|
|
1600
|
+
if (IN_PLACE) {
|
|
1601
|
+
return dirty;
|
|
1326
1602
|
}
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1603
|
+
/* Return sanitized string or DOM */
|
|
1604
|
+
|
|
1605
|
+
if (RETURN_DOM) {
|
|
1606
|
+
if (RETURN_DOM_FRAGMENT) {
|
|
1607
|
+
returnNode = createDocumentFragment.call(body.ownerDocument);
|
|
1608
|
+
while (body.firstChild) {
|
|
1609
|
+
// eslint-disable-next-line unicorn/prefer-dom-node-append
|
|
1610
|
+
returnNode.appendChild(body.firstChild);
|
|
1611
|
+
}
|
|
1612
|
+
} else {
|
|
1613
|
+
returnNode = body;
|
|
1614
|
+
}
|
|
1615
|
+
if (ALLOWED_ATTR.shadowroot) {
|
|
1616
|
+
/*
|
|
1617
|
+
AdoptNode() is not used because internal state is not reset
|
|
1618
|
+
(e.g. the past names map of a HTMLFormElement), this is safe
|
|
1619
|
+
in theory but we would rather not risk another attack vector.
|
|
1620
|
+
The state that is cloned by importNode() is explicitly defined
|
|
1621
|
+
by the specs.
|
|
1622
|
+
*/
|
|
1623
|
+
returnNode = importNode.call(originalDocument, returnNode, true);
|
|
1624
|
+
}
|
|
1625
|
+
return returnNode;
|
|
1345
1626
|
}
|
|
1346
|
-
|
|
1347
|
-
|
|
1627
|
+
var serializedHTML = WHOLE_DOCUMENT ? body.outerHTML : body.innerHTML;
|
|
1628
|
+
/* Serialize doctype if allowed */
|
|
1348
1629
|
|
|
1349
|
-
if (
|
|
1350
|
-
|
|
1630
|
+
if (WHOLE_DOCUMENT && ALLOWED_TAGS['!doctype'] && body.ownerDocument && body.ownerDocument.doctype && body.ownerDocument.doctype.name && regExpTest(DOCTYPE_NAME, body.ownerDocument.doctype.name)) {
|
|
1631
|
+
serializedHTML = '<!DOCTYPE ' + body.ownerDocument.doctype.name + '>\n' + serializedHTML;
|
|
1351
1632
|
}
|
|
1352
|
-
/*
|
|
1633
|
+
/* Sanitize final string template-safe */
|
|
1353
1634
|
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1635
|
+
if (SAFE_FOR_TEMPLATES) {
|
|
1636
|
+
serializedHTML = stringReplace(serializedHTML, MUSTACHE_EXPR$1, ' ');
|
|
1637
|
+
serializedHTML = stringReplace(serializedHTML, ERB_EXPR$1, ' ');
|
|
1357
1638
|
}
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
oldNode = null;
|
|
1367
|
-
/* If we sanitized `dirty` in-place, return it. */
|
|
1368
|
-
|
|
1369
|
-
if (IN_PLACE) {
|
|
1370
|
-
return dirty;
|
|
1371
|
-
}
|
|
1372
|
-
/* Return sanitized string or DOM */
|
|
1639
|
+
return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(serializedHTML) : serializedHTML;
|
|
1640
|
+
};
|
|
1641
|
+
/**
|
|
1642
|
+
* Public method to set the configuration once
|
|
1643
|
+
* setConfig
|
|
1644
|
+
*
|
|
1645
|
+
* @param {Object} cfg configuration object
|
|
1646
|
+
*/
|
|
1373
1647
|
|
|
1648
|
+
DOMPurify.setConfig = function (cfg) {
|
|
1649
|
+
_parseConfig(cfg);
|
|
1650
|
+
SET_CONFIG = true;
|
|
1651
|
+
};
|
|
1652
|
+
/**
|
|
1653
|
+
* Public method to remove the configuration
|
|
1654
|
+
* clearConfig
|
|
1655
|
+
*
|
|
1656
|
+
*/
|
|
1374
1657
|
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1658
|
+
DOMPurify.clearConfig = function () {
|
|
1659
|
+
CONFIG = null;
|
|
1660
|
+
SET_CONFIG = false;
|
|
1661
|
+
};
|
|
1662
|
+
/**
|
|
1663
|
+
* Public method to check if an attribute value is valid.
|
|
1664
|
+
* Uses last set config, if any. Otherwise, uses config defaults.
|
|
1665
|
+
* isValidAttribute
|
|
1666
|
+
*
|
|
1667
|
+
* @param {string} tag Tag name of containing element.
|
|
1668
|
+
* @param {string} attr Attribute name.
|
|
1669
|
+
* @param {string} value Attribute value.
|
|
1670
|
+
* @return {Boolean} Returns true if `value` is valid. Otherwise, returns false.
|
|
1671
|
+
*/
|
|
1378
1672
|
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
}
|
|
1383
|
-
} else {
|
|
1384
|
-
returnNode = body;
|
|
1673
|
+
DOMPurify.isValidAttribute = function (tag, attr, value) {
|
|
1674
|
+
/* Initialize shared config vars if necessary. */
|
|
1675
|
+
if (!CONFIG) {
|
|
1676
|
+
_parseConfig({});
|
|
1385
1677
|
}
|
|
1678
|
+
var lcTag = transformCaseFunc(tag);
|
|
1679
|
+
var lcName = transformCaseFunc(attr);
|
|
1680
|
+
return _isValidAttribute(lcTag, lcName, value);
|
|
1681
|
+
};
|
|
1682
|
+
/**
|
|
1683
|
+
* AddHook
|
|
1684
|
+
* Public method to add DOMPurify hooks
|
|
1685
|
+
*
|
|
1686
|
+
* @param {String} entryPoint entry point for the hook to add
|
|
1687
|
+
* @param {Function} hookFunction function to execute
|
|
1688
|
+
*/
|
|
1386
1689
|
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
in theory but we would rather not risk another attack vector.
|
|
1391
|
-
The state that is cloned by importNode() is explicitly defined
|
|
1392
|
-
by the specs. */
|
|
1393
|
-
returnNode = importNode.call(originalDocument, returnNode, true);
|
|
1690
|
+
DOMPurify.addHook = function (entryPoint, hookFunction) {
|
|
1691
|
+
if (typeof hookFunction !== 'function') {
|
|
1692
|
+
return;
|
|
1394
1693
|
}
|
|
1694
|
+
hooks[entryPoint] = hooks[entryPoint] || [];
|
|
1695
|
+
arrayPush(hooks[entryPoint], hookFunction);
|
|
1696
|
+
};
|
|
1697
|
+
/**
|
|
1698
|
+
* RemoveHook
|
|
1699
|
+
* Public method to remove a DOMPurify hook at a given entryPoint
|
|
1700
|
+
* (pops it from the stack of hooks if more are present)
|
|
1701
|
+
*
|
|
1702
|
+
* @param {String} entryPoint entry point for the hook to remove
|
|
1703
|
+
* @return {Function} removed(popped) hook
|
|
1704
|
+
*/
|
|
1395
1705
|
|
|
1396
|
-
|
|
1397
|
-
|
|
1706
|
+
DOMPurify.removeHook = function (entryPoint) {
|
|
1707
|
+
if (hooks[entryPoint]) {
|
|
1708
|
+
return arrayPop(hooks[entryPoint]);
|
|
1709
|
+
}
|
|
1710
|
+
};
|
|
1711
|
+
/**
|
|
1712
|
+
* RemoveHooks
|
|
1713
|
+
* Public method to remove all DOMPurify hooks at a given entryPoint
|
|
1714
|
+
*
|
|
1715
|
+
* @param {String} entryPoint entry point for the hooks to remove
|
|
1716
|
+
*/
|
|
1398
1717
|
|
|
1399
|
-
|
|
1400
|
-
|
|
1718
|
+
DOMPurify.removeHooks = function (entryPoint) {
|
|
1719
|
+
if (hooks[entryPoint]) {
|
|
1720
|
+
hooks[entryPoint] = [];
|
|
1721
|
+
}
|
|
1722
|
+
};
|
|
1723
|
+
/**
|
|
1724
|
+
* RemoveAllHooks
|
|
1725
|
+
* Public method to remove all DOMPurify hooks
|
|
1726
|
+
*
|
|
1727
|
+
*/
|
|
1401
1728
|
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1729
|
+
DOMPurify.removeAllHooks = function () {
|
|
1730
|
+
hooks = {};
|
|
1731
|
+
};
|
|
1732
|
+
return DOMPurify;
|
|
1733
|
+
}
|
|
1734
|
+
var purify = createDOMPurify();
|
|
1406
1735
|
|
|
1407
|
-
return trustedTypesPolicy ? trustedTypesPolicy.createHTML(serializedHTML) : serializedHTML;
|
|
1408
|
-
};
|
|
1409
1736
|
/**
|
|
1410
|
-
*
|
|
1411
|
-
*
|
|
1737
|
+
* This program is free software; you can redistribute it and/or
|
|
1738
|
+
* modify it under the terms of the GNU General Public License
|
|
1739
|
+
* as published by the Free Software Foundation; under version 2
|
|
1740
|
+
* of the License (non-upgradable).
|
|
1412
1741
|
*
|
|
1413
|
-
*
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
DOMPurify.setConfig = function (cfg) {
|
|
1418
|
-
_parseConfig(cfg);
|
|
1419
|
-
|
|
1420
|
-
SET_CONFIG = true;
|
|
1421
|
-
};
|
|
1422
|
-
/**
|
|
1423
|
-
* Public method to remove the configuration
|
|
1424
|
-
* clearConfig
|
|
1742
|
+
* This program is distributed in the hope that it will be useful,
|
|
1743
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
1744
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
1745
|
+
* GNU General Public License for more details.
|
|
1425
1746
|
*
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
DOMPurify.clearConfig = function () {
|
|
1430
|
-
CONFIG = null;
|
|
1431
|
-
SET_CONFIG = false;
|
|
1432
|
-
};
|
|
1433
|
-
/**
|
|
1434
|
-
* Public method to check if an attribute value is valid.
|
|
1435
|
-
* Uses last set config, if any. Otherwise, uses config defaults.
|
|
1436
|
-
* isValidAttribute
|
|
1747
|
+
* You should have received a copy of the GNU General Public License
|
|
1748
|
+
* along with this program; if not, write to the Free Software
|
|
1749
|
+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
1437
1750
|
*
|
|
1438
|
-
*
|
|
1439
|
-
* @param {string} attr Attribute name.
|
|
1440
|
-
* @param {string} value Attribute value.
|
|
1441
|
-
* @return {Boolean} Returns true if `value` is valid. Otherwise, returns false.
|
|
1751
|
+
* Copyright (c) 2017-2019 (original work) Open Assessment Technologies SA ;
|
|
1442
1752
|
*/
|
|
1443
1753
|
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
_parseConfig({});
|
|
1449
|
-
}
|
|
1450
|
-
|
|
1451
|
-
var lcTag = tag.toLowerCase();
|
|
1452
|
-
var lcName = attr.toLowerCase();
|
|
1453
|
-
return _isValidAttribute(lcTag, lcName, value);
|
|
1754
|
+
//yes indent isn't handle by css
|
|
1755
|
+
var indentStep = 15;
|
|
1756
|
+
var defaultConfig = {
|
|
1757
|
+
multiple: true
|
|
1454
1758
|
};
|
|
1759
|
+
|
|
1455
1760
|
/**
|
|
1456
|
-
*
|
|
1457
|
-
*
|
|
1458
|
-
*
|
|
1459
|
-
* @param {
|
|
1460
|
-
* @param {Function} hookFunction function to execute
|
|
1761
|
+
* The actual CSS suffers from a limitation,
|
|
1762
|
+
* this function is used to fix the nested indents.
|
|
1763
|
+
* @param {jQueryElement} $list - the list element
|
|
1764
|
+
* @param {Number} level - the nesting level
|
|
1461
1765
|
*/
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1766
|
+
var indentChildren = function indentChildren($list, level) {
|
|
1767
|
+
var indent;
|
|
1768
|
+
if ($list.length) {
|
|
1769
|
+
indent = level * indentStep;
|
|
1770
|
+
level++;
|
|
1771
|
+
$list.children('li').each(function () {
|
|
1772
|
+
var $target = $$1(this);
|
|
1773
|
+
$target.children('a').css('padding-left', indent + 'px');
|
|
1774
|
+
indentChildren($target.children('ul'), level);
|
|
1775
|
+
});
|
|
1776
|
+
$list.siblings('.more').css('padding-left', indent + 'px');
|
|
1467
1777
|
}
|
|
1468
|
-
|
|
1469
|
-
hooks[entryPoint] = hooks[entryPoint] || [];
|
|
1470
|
-
hooks[entryPoint].push(hookFunction);
|
|
1471
1778
|
};
|
|
1779
|
+
|
|
1472
1780
|
/**
|
|
1473
|
-
*
|
|
1474
|
-
*
|
|
1475
|
-
*
|
|
1476
|
-
*
|
|
1477
|
-
* @param {String} entryPoint entry point for the hook to remove
|
|
1781
|
+
* Toggle the "more" button if the node is incomplete.
|
|
1782
|
+
* Parse the whole tree from the given node.
|
|
1783
|
+
* @param {jQueryElement} $node - the class node
|
|
1478
1784
|
*/
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1785
|
+
var needMore = function needMore($node) {
|
|
1786
|
+
var $more = $node.children('.more');
|
|
1787
|
+
var totalCount = $node.data('count');
|
|
1788
|
+
var instancesCount = $node.children('ul').children('.instance').length;
|
|
1789
|
+
if (totalCount > 0 && instancesCount > 0 && instancesCount < totalCount) {
|
|
1790
|
+
hider.show($more);
|
|
1791
|
+
} else {
|
|
1792
|
+
hider.hide($more);
|
|
1484
1793
|
}
|
|
1794
|
+
$node.children('ul').find('.class').each(function () {
|
|
1795
|
+
needMore($$1(this));
|
|
1796
|
+
});
|
|
1485
1797
|
};
|
|
1798
|
+
|
|
1486
1799
|
/**
|
|
1487
|
-
*
|
|
1488
|
-
*
|
|
1489
|
-
*
|
|
1490
|
-
* @param
|
|
1800
|
+
* Manually update the count value of a class node.
|
|
1801
|
+
* useful when the nodes are added or removed directly.
|
|
1802
|
+
* @param {jQueryElement} $classNode - the node to update
|
|
1803
|
+
* @param {Number} update - the value to add to the count
|
|
1491
1804
|
*/
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1805
|
+
var updateCount = function updateCount($classNode, update) {
|
|
1806
|
+
var count = 0;
|
|
1807
|
+
if ($classNode && $classNode.length && $classNode.hasClass('class')) {
|
|
1808
|
+
count = $classNode.data('count');
|
|
1809
|
+
count += update;
|
|
1810
|
+
if (count < 0) {
|
|
1811
|
+
count = 0;
|
|
1812
|
+
}
|
|
1813
|
+
$classNode.attr('data-count', count).data('count', count);
|
|
1497
1814
|
}
|
|
1498
1815
|
};
|
|
1816
|
+
|
|
1499
1817
|
/**
|
|
1500
|
-
*
|
|
1501
|
-
* Public method to remove all DOMPurify hooks
|
|
1818
|
+
* The factory that creates the resource tree component
|
|
1502
1819
|
*
|
|
1820
|
+
* @param {jQueryElement} $container - where to append the component
|
|
1821
|
+
* @param {Object} config - the component config
|
|
1822
|
+
* @param {String} config.classUri - the root Class URI
|
|
1823
|
+
* @param {Object[]} [config.nodes] - the nodes to preload
|
|
1824
|
+
* @param {String} [config.icon] - the icon class to show close to the resources
|
|
1825
|
+
* @param {Boolean} [config.multiple = true] - multiple vs unique selection
|
|
1826
|
+
* @returns {resourceTree} the component
|
|
1503
1827
|
*/
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
return DOMPurify;
|
|
1511
|
-
}
|
|
1512
|
-
|
|
1513
|
-
var purify = createDOMPurify();
|
|
1514
|
-
|
|
1515
|
-
/**
|
|
1516
|
-
* This program is free software; you can redistribute it and/or
|
|
1517
|
-
* modify it under the terms of the GNU General Public License
|
|
1518
|
-
* as published by the Free Software Foundation; under version 2
|
|
1519
|
-
* of the License (non-upgradable).
|
|
1520
|
-
*
|
|
1521
|
-
* This program is distributed in the hope that it will be useful,
|
|
1522
|
-
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
1523
|
-
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
1524
|
-
* GNU General Public License for more details.
|
|
1525
|
-
*
|
|
1526
|
-
* You should have received a copy of the GNU General Public License
|
|
1527
|
-
* along with this program; if not, write to the Free Software
|
|
1528
|
-
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
1529
|
-
*
|
|
1530
|
-
* Copyright (c) 2017-2019 (original work) Open Assessment Technologies SA ;
|
|
1531
|
-
*/
|
|
1532
|
-
|
|
1533
|
-
var indentStep = 15;
|
|
1534
|
-
var defaultConfig = {
|
|
1535
|
-
multiple: true
|
|
1536
|
-
};
|
|
1537
|
-
/**
|
|
1538
|
-
* The actual CSS suffers from a limitation,
|
|
1539
|
-
* this function is used to fix the nested indents.
|
|
1540
|
-
* @param {jQueryElement} $list - the list element
|
|
1541
|
-
* @param {Number} level - the nesting level
|
|
1542
|
-
*/
|
|
1543
|
-
|
|
1544
|
-
var indentChildren = function indentChildren($list, level) {
|
|
1545
|
-
var indent;
|
|
1546
|
-
|
|
1547
|
-
if ($list.length) {
|
|
1548
|
-
indent = level * indentStep;
|
|
1549
|
-
level++;
|
|
1550
|
-
$list.children('li').each(function () {
|
|
1551
|
-
var $target = $$1(this);
|
|
1552
|
-
$target.children('a').css('padding-left', indent + 'px');
|
|
1553
|
-
indentChildren($target.children('ul'), level);
|
|
1554
|
-
});
|
|
1555
|
-
$list.siblings('.more').css('padding-left', indent + 'px');
|
|
1556
|
-
}
|
|
1557
|
-
};
|
|
1558
|
-
/**
|
|
1559
|
-
* Toggle the "more" button if the node is incomplete.
|
|
1560
|
-
* Parse the whole tree from the given node.
|
|
1561
|
-
* @param {jQueryElement} $node - the class node
|
|
1562
|
-
*/
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
var needMore = function needMore($node) {
|
|
1566
|
-
var $more = $node.children('.more');
|
|
1567
|
-
var totalCount = $node.data('count');
|
|
1568
|
-
var instancesCount = $node.children('ul').children('.instance').length;
|
|
1569
|
-
|
|
1570
|
-
if (totalCount > 0 && instancesCount > 0 && instancesCount < totalCount) {
|
|
1571
|
-
hider.show($more);
|
|
1572
|
-
} else {
|
|
1573
|
-
hider.hide($more);
|
|
1574
|
-
}
|
|
1575
|
-
|
|
1576
|
-
$node.children('ul').find('.class').each(function () {
|
|
1577
|
-
needMore($$1(this));
|
|
1578
|
-
});
|
|
1579
|
-
};
|
|
1580
|
-
/**
|
|
1581
|
-
* Manually update the count value of a class node.
|
|
1582
|
-
* useful when the nodes are added or removed directly.
|
|
1583
|
-
* @param {jQueryElement} $classNode - the node to update
|
|
1584
|
-
* @param {Number} update - the value to add to the count
|
|
1585
|
-
*/
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
var updateCount = function updateCount($classNode, update) {
|
|
1589
|
-
var count = 0;
|
|
1590
|
-
|
|
1591
|
-
if ($classNode && $classNode.length && $classNode.hasClass('class')) {
|
|
1592
|
-
count = $classNode.data('count');
|
|
1593
|
-
count += update;
|
|
1594
|
-
|
|
1595
|
-
if (count < 0) {
|
|
1596
|
-
count = 0;
|
|
1597
|
-
}
|
|
1598
|
-
|
|
1599
|
-
$classNode.attr('data-count', count).data('count', count);
|
|
1600
|
-
}
|
|
1601
|
-
};
|
|
1602
|
-
/**
|
|
1603
|
-
* The factory that creates the resource tree component
|
|
1604
|
-
*
|
|
1605
|
-
* @param {jQueryElement} $container - where to append the component
|
|
1606
|
-
* @param {Object} config - the component config
|
|
1607
|
-
* @param {String} config.classUri - the root Class URI
|
|
1608
|
-
* @param {Object[]} [config.nodes] - the nodes to preload
|
|
1609
|
-
* @param {String} [config.icon] - the icon class to show close to the resources
|
|
1610
|
-
* @param {Boolean} [config.multiple = true] - multiple vs unique selection
|
|
1611
|
-
* @returns {resourceTree} the component
|
|
1612
|
-
*/
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
function resourceTreeFactory($container, config) {
|
|
1616
|
-
/**
|
|
1617
|
-
* A selectable component
|
|
1618
|
-
* @typedef {ui/component} resourceTree
|
|
1619
|
-
* @augments {ui/resource/selectable}
|
|
1620
|
-
*/
|
|
1621
|
-
var resourceTree = selectable(component({
|
|
1622
|
-
/**
|
|
1623
|
-
* Ask for a query (forward the event)
|
|
1624
|
-
* @param {Object} [params] - the query parameters
|
|
1625
|
-
* @param {String} [params.classUri] - the current node class URI
|
|
1626
|
-
* @param {Number} [params.offset = 0] - for paging
|
|
1627
|
-
* @param {Number} [params.limit] - for paging
|
|
1628
|
-
* @returns {resourceTree} chains
|
|
1629
|
-
* @fires resourceTree#query
|
|
1828
|
+
function resourceTreeFactory($container, config) {
|
|
1829
|
+
/**
|
|
1830
|
+
* A selectable component
|
|
1831
|
+
* @typedef {ui/component} resourceTree
|
|
1832
|
+
* @augments {ui/resource/selectable}
|
|
1630
1833
|
*/
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
* @returns {resourceTree} chains
|
|
1652
|
-
* @fires resourceTree#update
|
|
1653
|
-
*/
|
|
1654
|
-
update: function update(nodes, params) {
|
|
1655
|
-
var self = this;
|
|
1656
|
-
var $root;
|
|
1657
|
-
var $component;
|
|
1658
|
-
|
|
1659
|
-
function reduceNode(acc, node) {
|
|
1660
|
-
node.selectable = false;
|
|
1661
|
-
node.label = purify.sanitize(node.label); //filter already added nodes or classes when loading "more"
|
|
1662
|
-
|
|
1663
|
-
if (self.hasNode(node.uri) || params && params.offset > 0 && node.type === 'class' || node.type === 'class' && !node.state && !self.config.selectClass) {
|
|
1664
|
-
return acc;
|
|
1834
|
+
var resourceTree = selectable(component({
|
|
1835
|
+
/**
|
|
1836
|
+
* Ask for a query (forward the event)
|
|
1837
|
+
* @param {Object} [params] - the query parameters
|
|
1838
|
+
* @param {String} [params.classUri] - the current node class URI
|
|
1839
|
+
* @param {Number} [params.offset = 0] - for paging
|
|
1840
|
+
* @param {Number} [params.limit] - for paging
|
|
1841
|
+
* @returns {resourceTree} chains
|
|
1842
|
+
* @fires resourceTree#query
|
|
1843
|
+
*/
|
|
1844
|
+
query: function query(params) {
|
|
1845
|
+
if (!this.is('loading')) {
|
|
1846
|
+
/**
|
|
1847
|
+
* Formulate the query
|
|
1848
|
+
* @event resourceTree#query
|
|
1849
|
+
* @param {Object} params - see format above
|
|
1850
|
+
*/
|
|
1851
|
+
this.trigger('query', _.defaults(params || {}, {
|
|
1852
|
+
classUri: this.classUri
|
|
1853
|
+
}));
|
|
1665
1854
|
}
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1855
|
+
return this;
|
|
1856
|
+
},
|
|
1857
|
+
/**
|
|
1858
|
+
* Update the component with the given nodes
|
|
1859
|
+
* @param {Object[]} nodes - the tree nodes, with at least a URI as key and as property
|
|
1860
|
+
* @param {Object} params - the query parameters
|
|
1861
|
+
* @param {Number|false} params.updateCount - force the update of the parent class count
|
|
1862
|
+
* @returns {resourceTree} chains
|
|
1863
|
+
* @fires resourceTree#update
|
|
1864
|
+
*/
|
|
1865
|
+
update: function update(nodes, params) {
|
|
1866
|
+
var self = this;
|
|
1867
|
+
var $root;
|
|
1868
|
+
var $component;
|
|
1869
|
+
function reduceNode(acc, node) {
|
|
1870
|
+
node.selectable = false;
|
|
1871
|
+
node.label = purify.sanitize(node.label);
|
|
1872
|
+
|
|
1873
|
+
//filter already added nodes or classes when loading "more"
|
|
1874
|
+
if (self.hasNode(node.uri) || params && params.offset > 0 && node.type === 'class' || node.type === 'class' && !node.state && !self.config.selectClass) {
|
|
1875
|
+
return acc;
|
|
1673
1876
|
}
|
|
1674
|
-
|
|
1675
|
-
|
|
1877
|
+
if (node.type === 'class' && self.config.selectClass) {
|
|
1878
|
+
node.classUri = node.uri;
|
|
1879
|
+
node.selectable = true;
|
|
1880
|
+
if (!node.state) {
|
|
1881
|
+
node.state = 'empty';
|
|
1882
|
+
}
|
|
1883
|
+
self.addNode(node.uri, _.omit(node, ['count', 'children']));
|
|
1884
|
+
}
|
|
1885
|
+
if (node.type === 'instance') {
|
|
1886
|
+
node.selectable = true;
|
|
1887
|
+
self.addNode(node.uri, _.omit(node, ['count', 'children']));
|
|
1888
|
+
node.icon = config.icon;
|
|
1889
|
+
}
|
|
1890
|
+
if (node.children && node.children.length) {
|
|
1891
|
+
node.childList = reduceNodes(node.children);
|
|
1892
|
+
}
|
|
1893
|
+
acc += treeNodeTpl(node);
|
|
1894
|
+
return acc;
|
|
1676
1895
|
}
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
node.icon = config.icon;
|
|
1896
|
+
function reduceNodes(nodeList) {
|
|
1897
|
+
return _.sortBy(nodeList, function (a, b) {
|
|
1898
|
+
return b.label - a.label;
|
|
1899
|
+
}).reduce(reduceNode, '');
|
|
1682
1900
|
}
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1901
|
+
if (this.is('rendered')) {
|
|
1902
|
+
$component = this.getElement();
|
|
1903
|
+
if (params && params.classUri) {
|
|
1904
|
+
$root = $$1('.class[data-uri="' + params.classUri + '"]', $component);
|
|
1905
|
+
}
|
|
1906
|
+
if (!$root || !$root.length) {
|
|
1907
|
+
$root = $component;
|
|
1908
|
+
}
|
|
1909
|
+
if (nodes[0].uri === $root.data('uri')) {
|
|
1910
|
+
nodes = nodes[0].children || [];
|
|
1911
|
+
}
|
|
1912
|
+
$root.children('ul').append(reduceNodes(nodes));
|
|
1913
|
+
if (params && _.isNumber(params.updateCount)) {
|
|
1914
|
+
updateCount($root, params.updateCount);
|
|
1915
|
+
}
|
|
1916
|
+
needMore($root);
|
|
1917
|
+
indentChildren($component.children('ul'), 0);
|
|
1918
|
+
$root.removeClass('closed').toggleClass('empty', !$root.children('ul').children('li').length);
|
|
1919
|
+
|
|
1920
|
+
/**
|
|
1921
|
+
* The tree has been updated
|
|
1922
|
+
* @event resourceTree#update
|
|
1923
|
+
*/
|
|
1924
|
+
this.trigger('update');
|
|
1686
1925
|
}
|
|
1687
|
-
|
|
1688
|
-
acc += treeNodeTpl(node);
|
|
1689
|
-
return acc;
|
|
1926
|
+
return this;
|
|
1690
1927
|
}
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1928
|
+
}, defaultConfig));
|
|
1929
|
+
resourceTree.setTemplate(treeTpl).on('init', function () {
|
|
1930
|
+
this.classUri = this.config.classUri;
|
|
1931
|
+
this.setState('multiple', !!this.config.multiple);
|
|
1932
|
+
this.render($container);
|
|
1933
|
+
}).on('render', function () {
|
|
1934
|
+
var self = this;
|
|
1935
|
+
var $component = this.getElement();
|
|
1936
|
+
|
|
1937
|
+
/**
|
|
1938
|
+
* Open a class node
|
|
1939
|
+
* @param {jQueryElement} $class
|
|
1940
|
+
*/
|
|
1941
|
+
var openClass = function openClass($class) {
|
|
1942
|
+
var node = self.getNode($class.data('uri'));
|
|
1943
|
+
if (!$class.children('ul').children('li').length) {
|
|
1944
|
+
self.query({
|
|
1945
|
+
classUri: $class.data('uri')
|
|
1946
|
+
});
|
|
1703
1947
|
}
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
$root = $component;
|
|
1948
|
+
if (node) {
|
|
1949
|
+
node.state = 'open';
|
|
1707
1950
|
}
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1951
|
+
$class.addClass('open').removeClass('closed');
|
|
1952
|
+
};
|
|
1953
|
+
|
|
1954
|
+
/**
|
|
1955
|
+
* Close a class node
|
|
1956
|
+
* @param {jQueryElement} $class
|
|
1957
|
+
*/
|
|
1958
|
+
var closeClass = function closeClass($class) {
|
|
1959
|
+
var node = self.getNode($class.data('uri'));
|
|
1960
|
+
if (node) {
|
|
1961
|
+
node.state = 'closed';
|
|
1711
1962
|
}
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1963
|
+
$class.removeClass('open').addClass('closed');
|
|
1964
|
+
};
|
|
1965
|
+
|
|
1966
|
+
/**
|
|
1967
|
+
* Toggle a class node
|
|
1968
|
+
* @param {jQueryElement} $class
|
|
1969
|
+
*/
|
|
1970
|
+
var toggleClass = function toggleClass($class) {
|
|
1971
|
+
if (!$class.hasClass('closed')) {
|
|
1972
|
+
closeClass($class);
|
|
1973
|
+
} else {
|
|
1974
|
+
openClass($class);
|
|
1717
1975
|
}
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
var $component = this.getElement();
|
|
1740
|
-
/**
|
|
1741
|
-
* Open a class node
|
|
1742
|
-
* @param {jQueryElement} $class
|
|
1743
|
-
*/
|
|
1744
|
-
|
|
1745
|
-
var openClass = function openClass($class) {
|
|
1746
|
-
var node = self.getNode($class.data('uri'));
|
|
1747
|
-
|
|
1748
|
-
if (!$class.children('ul').children('li').length) {
|
|
1749
|
-
self.query({
|
|
1750
|
-
classUri: $class.data('uri')
|
|
1976
|
+
};
|
|
1977
|
+
|
|
1978
|
+
//Browse hierarchy
|
|
1979
|
+
if (self.config.selectClass) {
|
|
1980
|
+
//if we can
|
|
1981
|
+
|
|
1982
|
+
$component.on('click', '.class', function (e) {
|
|
1983
|
+
const $class = $$1(e.currentTarget);
|
|
1984
|
+
e.preventDefault();
|
|
1985
|
+
e.stopPropagation();
|
|
1986
|
+
if ($$1(e.target).hasClass('class-toggler')) {
|
|
1987
|
+
if (!$class.hasClass('empty')) {
|
|
1988
|
+
toggleClass($class);
|
|
1989
|
+
}
|
|
1990
|
+
} else {
|
|
1991
|
+
if ($class.hasClass('selected')) {
|
|
1992
|
+
self.unselect($class.data('uri'));
|
|
1993
|
+
} else if ($class.data('access') !== 'denied') {
|
|
1994
|
+
self.select($class.data('uri'), !self.is('multiple'), false, true); // include children
|
|
1995
|
+
}
|
|
1996
|
+
}
|
|
1751
1997
|
});
|
|
1752
|
-
}
|
|
1753
|
-
|
|
1754
|
-
if (node) {
|
|
1755
|
-
node.state = 'open';
|
|
1756
|
-
}
|
|
1757
|
-
|
|
1758
|
-
$class.addClass('open').removeClass('closed');
|
|
1759
|
-
};
|
|
1760
|
-
/**
|
|
1761
|
-
* Close a class node
|
|
1762
|
-
* @param {jQueryElement} $class
|
|
1763
|
-
*/
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
var closeClass = function closeClass($class) {
|
|
1767
|
-
var node = self.getNode($class.data('uri'));
|
|
1768
|
-
|
|
1769
|
-
if (node) {
|
|
1770
|
-
node.state = 'closed';
|
|
1771
|
-
}
|
|
1772
|
-
|
|
1773
|
-
$class.removeClass('open').addClass('closed');
|
|
1774
|
-
};
|
|
1775
|
-
/**
|
|
1776
|
-
* Toggle a class node
|
|
1777
|
-
* @param {jQueryElement} $class
|
|
1778
|
-
*/
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
var toggleClass = function toggleClass($class) {
|
|
1782
|
-
if (!$class.hasClass('closed')) {
|
|
1783
|
-
closeClass($class);
|
|
1784
1998
|
} else {
|
|
1785
|
-
|
|
1999
|
+
$component.on('click', '.class', function (e) {
|
|
2000
|
+
const $class = $$1(e.currentTarget);
|
|
2001
|
+
e.preventDefault();
|
|
2002
|
+
e.stopPropagation();
|
|
2003
|
+
if (!$class.hasClass('empty')) {
|
|
2004
|
+
toggleClass($class);
|
|
2005
|
+
}
|
|
2006
|
+
});
|
|
1786
2007
|
}
|
|
1787
|
-
}; //Browse hierarchy
|
|
1788
2008
|
|
|
2009
|
+
//selection
|
|
2010
|
+
$component.on('click', '.instance', function (e) {
|
|
2011
|
+
const $instance = $$1(e.currentTarget);
|
|
1789
2012
|
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
$component.on('click', '.class', function (e) {
|
|
1793
|
-
var $class = $$1(e.currentTarget);
|
|
2013
|
+
// all instances should be not clickable because in the tree if it is child node - it will close
|
|
2014
|
+
// parent node
|
|
1794
2015
|
e.preventDefault();
|
|
1795
2016
|
e.stopPropagation();
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
} else {
|
|
1802
|
-
if ($class.hasClass('selected')) {
|
|
1803
|
-
self.unselect($class.data('uri'));
|
|
1804
|
-
} else if ($class.data('access') !== 'denied') {
|
|
1805
|
-
self.select($class.data('uri'), !self.is('multiple'), false, true); // include children
|
|
2017
|
+
if ($instance.data('access') !== 'denied') {
|
|
2018
|
+
if ($instance.hasClass('selected')) {
|
|
2019
|
+
self.unselect($instance.data('uri'));
|
|
2020
|
+
} else {
|
|
2021
|
+
self.select($instance.data('uri'), !self.is('multiple'));
|
|
1806
2022
|
}
|
|
1807
2023
|
}
|
|
1808
2024
|
});
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
var $class = $$1(e.currentTarget);
|
|
2025
|
+
$component.on('click', '.more', function (e) {
|
|
2026
|
+
var $root = $$1(e.currentTarget).parent('.class');
|
|
1812
2027
|
e.preventDefault();
|
|
1813
2028
|
e.stopPropagation();
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
}
|
|
2029
|
+
self.query({
|
|
2030
|
+
classUri: $root.data('uri'),
|
|
2031
|
+
offset: $root.children('ul').children('.instance').length
|
|
2032
|
+
});
|
|
1818
2033
|
});
|
|
1819
|
-
} //selection
|
|
1820
|
-
|
|
1821
2034
|
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
2035
|
+
//initial data loading
|
|
2036
|
+
if (this.config.nodes) {
|
|
2037
|
+
this.update(this.config.nodes);
|
|
2038
|
+
} else {
|
|
2039
|
+
this.query();
|
|
2040
|
+
}
|
|
2041
|
+
}).on('query', function () {
|
|
2042
|
+
this.setState('loading', true);
|
|
2043
|
+
}).on('update', function () {
|
|
2044
|
+
this.setState('loading', false);
|
|
2045
|
+
}).on('remove', function (uri) {
|
|
2046
|
+
var $node, $parents, $parent;
|
|
2047
|
+
if (this.is('rendered') && uri) {
|
|
2048
|
+
$node = $$1('[data-uri="' + uri + '"]', this.getElement());
|
|
2049
|
+
$parents = $node.parents('.class');
|
|
2050
|
+
if ($node.hasClass('instance')) {
|
|
2051
|
+
updateCount($parents, -1);
|
|
2052
|
+
}
|
|
2053
|
+
$parent = $parents.first();
|
|
2054
|
+
if ($parent.children('ul').children('li').length === 1) {
|
|
2055
|
+
$parent.removeClass('closed').addClass('empty');
|
|
1834
2056
|
}
|
|
2057
|
+
$node.remove();
|
|
1835
2058
|
}
|
|
1836
2059
|
});
|
|
1837
|
-
$component.on('click', '.more', function (e) {
|
|
1838
|
-
var $root = $$1(e.currentTarget).parent('.class');
|
|
1839
|
-
e.preventDefault();
|
|
1840
|
-
e.stopPropagation();
|
|
1841
|
-
self.query({
|
|
1842
|
-
classUri: $root.data('uri'),
|
|
1843
|
-
offset: $root.children('ul').children('.instance').length
|
|
1844
|
-
});
|
|
1845
|
-
}); //initial data loading
|
|
1846
2060
|
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
}
|
|
1853
|
-
this.setState('loading', true);
|
|
1854
|
-
}).on('update', function () {
|
|
1855
|
-
this.setState('loading', false);
|
|
1856
|
-
}).on('remove', function (uri) {
|
|
1857
|
-
var $node, $parents, $parent;
|
|
1858
|
-
|
|
1859
|
-
if (this.is('rendered') && uri) {
|
|
1860
|
-
$node = $$1('[data-uri="' + uri + '"]', this.getElement());
|
|
1861
|
-
$parents = $node.parents('.class');
|
|
1862
|
-
|
|
1863
|
-
if ($node.hasClass('instance')) {
|
|
1864
|
-
updateCount($parents, -1);
|
|
1865
|
-
}
|
|
1866
|
-
|
|
1867
|
-
$parent = $parents.first();
|
|
1868
|
-
|
|
1869
|
-
if ($parent.children('ul').children('li').length === 1) {
|
|
1870
|
-
$parent.removeClass('closed').addClass('empty');
|
|
1871
|
-
}
|
|
1872
|
-
|
|
1873
|
-
$node.remove();
|
|
1874
|
-
}
|
|
1875
|
-
}); //always defer the initialization to let consumers listen for init and render events.
|
|
1876
|
-
|
|
1877
|
-
_.defer(function () {
|
|
1878
|
-
resourceTree.init(config);
|
|
1879
|
-
});
|
|
1880
|
-
|
|
1881
|
-
return resourceTree;
|
|
1882
|
-
}
|
|
2061
|
+
//always defer the initialization to let consumers listen for init and render events.
|
|
2062
|
+
_.defer(function () {
|
|
2063
|
+
resourceTree.init(config);
|
|
2064
|
+
});
|
|
2065
|
+
return resourceTree;
|
|
2066
|
+
}
|
|
1883
2067
|
|
|
1884
|
-
|
|
2068
|
+
return resourceTreeFactory;
|
|
1885
2069
|
|
|
1886
2070
|
});
|