suneditor 3.0.0-beta.9 → 3.0.0-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +65 -57
- package/dist/suneditor-contents.min.css +1 -0
- package/dist/suneditor.min.css +1 -1
- package/dist/suneditor.min.js +1 -1
- package/package.json +110 -61
- package/src/assets/design/color.css +36 -17
- package/src/assets/design/size.css +2 -0
- package/src/assets/icons/defaultIcons.js +17 -2
- package/src/assets/suneditor-contents.css +51 -16
- package/src/assets/suneditor.css +116 -43
- package/src/core/config/contextProvider.js +288 -0
- package/src/core/config/eventManager.js +188 -0
- package/src/core/config/instanceCheck.js +59 -0
- package/src/core/config/optionProvider.js +452 -0
- package/src/core/editor.js +166 -1637
- package/src/core/event/actions/index.js +229 -0
- package/src/core/event/effects/common.registry.js +74 -0
- package/src/core/event/effects/keydown.registry.js +573 -0
- package/src/core/event/effects/ruleHelpers.js +148 -0
- package/src/core/event/eventOrchestrator.js +944 -0
- package/src/core/event/executor.js +27 -0
- package/src/core/{base/eventHandlers → event/handlers}/handler_toolbar.js +27 -28
- package/src/core/{base/eventHandlers → event/handlers}/handler_ww_clipboard.js +10 -8
- package/src/core/{base/eventHandlers → event/handlers}/handler_ww_dragDrop.js +22 -23
- package/src/core/event/handlers/handler_ww_input.js +75 -0
- package/src/core/event/handlers/handler_ww_key.js +228 -0
- package/src/core/event/handlers/handler_ww_mouse.js +166 -0
- package/src/core/event/ports.js +211 -0
- package/src/core/event/reducers/keydown.reducer.js +97 -0
- package/src/core/event/rules/keydown.rule.arrow.js +63 -0
- package/src/core/event/rules/keydown.rule.backspace.js +208 -0
- package/src/core/event/rules/keydown.rule.delete.js +132 -0
- package/src/core/event/rules/keydown.rule.enter.js +150 -0
- package/src/core/event/rules/keydown.rule.tab.js +35 -0
- package/src/core/event/support/defaultLineManager.js +136 -0
- package/src/core/event/support/selectionState.js +204 -0
- package/src/core/kernel/coreKernel.js +320 -0
- package/src/core/kernel/kernelInjector.js +19 -0
- package/src/core/kernel/store.js +173 -0
- package/src/core/{class → logic/dom}/char.js +42 -45
- package/src/core/logic/dom/format.js +1075 -0
- package/src/core/{class → logic/dom}/html.js +743 -624
- package/src/core/logic/dom/inline.js +1847 -0
- package/src/core/logic/dom/listFormat.js +601 -0
- package/src/core/{class → logic/dom}/nodeTransform.js +92 -72
- package/src/core/{class → logic/dom}/offset.js +254 -317
- package/src/core/logic/dom/selection.js +754 -0
- package/src/core/logic/panel/menu.js +389 -0
- package/src/core/logic/panel/toolbar.js +449 -0
- package/src/core/logic/panel/viewer.js +761 -0
- package/src/core/logic/shell/_commandExecutor.js +380 -0
- package/src/core/logic/shell/commandDispatcher.js +241 -0
- package/src/core/logic/shell/component.js +970 -0
- package/src/core/logic/shell/focusManager.js +110 -0
- package/src/core/{base → logic/shell}/history.js +110 -60
- package/src/core/logic/shell/pluginManager.js +363 -0
- package/src/core/logic/shell/shortcuts.js +130 -0
- package/src/core/logic/shell/ui.js +904 -0
- package/src/core/schema/context.js +66 -0
- package/src/core/schema/frameContext.js +160 -0
- package/src/core/schema/options.js +628 -0
- package/src/core/section/constructor.js +194 -500
- package/src/core/section/documentType.js +297 -222
- package/src/events.js +808 -543
- package/src/helper/clipboard.js +27 -16
- package/src/helper/converter.js +100 -78
- package/src/helper/dom/domCheck.js +56 -30
- package/src/helper/dom/domQuery.js +159 -89
- package/src/helper/dom/domUtils.js +114 -49
- package/src/helper/dom/index.js +5 -1
- package/src/helper/env.js +26 -26
- package/src/helper/index.js +1 -1
- package/src/helper/keyCodeMap.js +25 -28
- package/src/helper/numbers.js +4 -8
- package/src/helper/unicode.js +4 -8
- package/src/hooks/base.js +307 -0
- package/src/hooks/params.js +130 -0
- package/src/interfaces/contracts.js +227 -0
- package/src/interfaces/index.js +7 -0
- package/src/interfaces/plugins.js +239 -0
- package/src/langs/ckb.js +4 -4
- package/src/langs/cs.js +4 -4
- package/src/langs/da.js +4 -4
- package/src/langs/de.js +4 -4
- package/src/langs/en.js +4 -4
- package/src/langs/es.js +4 -4
- package/src/langs/fa.js +4 -4
- package/src/langs/fr.js +4 -4
- package/src/langs/he.js +4 -4
- package/src/langs/hu.js +4 -4
- package/src/langs/it.js +4 -4
- package/src/langs/ja.js +4 -4
- package/src/langs/km.js +4 -4
- package/src/langs/ko.js +4 -4
- package/src/langs/lv.js +4 -4
- package/src/langs/nl.js +4 -4
- package/src/langs/pl.js +4 -4
- package/src/langs/pt_br.js +13 -13
- package/src/langs/ro.js +4 -4
- package/src/langs/ru.js +4 -4
- package/src/langs/se.js +4 -4
- package/src/langs/tr.js +4 -4
- package/src/langs/uk.js +4 -4
- package/src/langs/ur.js +4 -4
- package/src/langs/zh_cn.js +4 -4
- package/src/modules/{Browser.js → contract/Browser.js} +119 -128
- package/src/modules/{ColorPicker.js → contract/ColorPicker.js} +132 -142
- package/src/modules/contract/Controller.js +589 -0
- package/src/modules/{Figure.js → contract/Figure.js} +591 -411
- package/src/modules/{HueSlider.js → contract/HueSlider.js} +125 -86
- package/src/modules/contract/Modal.js +357 -0
- package/src/modules/contract/index.js +9 -0
- package/src/modules/manager/ApiManager.js +197 -0
- package/src/modules/{FileManager.js → manager/FileManager.js} +128 -160
- package/src/modules/manager/index.js +5 -0
- package/src/modules/{ModalAnchorEditor.js → ui/ModalAnchorEditor.js} +108 -138
- package/src/modules/{SelectMenu.js → ui/SelectMenu.js} +119 -120
- package/src/modules/{_DragHandle.js → ui/_DragHandle.js} +1 -1
- package/src/modules/ui/index.js +6 -0
- package/src/plugins/browser/audioGallery.js +23 -26
- package/src/plugins/browser/fileBrowser.js +25 -28
- package/src/plugins/browser/fileGallery.js +20 -23
- package/src/plugins/browser/imageGallery.js +24 -23
- package/src/plugins/browser/videoGallery.js +27 -29
- package/src/plugins/command/blockquote.js +11 -17
- package/src/plugins/command/exportPDF.js +26 -26
- package/src/plugins/command/fileUpload.js +138 -133
- package/src/plugins/command/list_bulleted.js +48 -44
- package/src/plugins/command/list_numbered.js +48 -44
- package/src/plugins/dropdown/align.js +64 -50
- package/src/plugins/dropdown/backgroundColor.js +34 -35
- package/src/plugins/dropdown/{formatBlock.js → blockStyle.js} +43 -37
- package/src/plugins/dropdown/font.js +50 -36
- package/src/plugins/dropdown/fontColor.js +34 -35
- package/src/plugins/dropdown/hr.js +55 -50
- package/src/plugins/dropdown/layout.js +20 -15
- package/src/plugins/dropdown/lineHeight.js +46 -30
- package/src/plugins/dropdown/list.js +32 -33
- package/src/plugins/dropdown/paragraphStyle.js +40 -34
- package/src/plugins/dropdown/table/index.js +915 -0
- package/src/plugins/dropdown/table/render/table.html.js +308 -0
- package/src/plugins/dropdown/table/render/table.menu.js +121 -0
- package/src/plugins/dropdown/table/services/table.cell.js +465 -0
- package/src/plugins/dropdown/table/services/table.clipboard.js +414 -0
- package/src/plugins/dropdown/table/services/table.grid.js +504 -0
- package/src/plugins/dropdown/table/services/table.resize.js +463 -0
- package/src/plugins/dropdown/table/services/table.selection.js +466 -0
- package/src/plugins/dropdown/table/services/table.style.js +844 -0
- package/src/plugins/dropdown/table/shared/table.constants.js +109 -0
- package/src/plugins/dropdown/table/shared/table.utils.js +219 -0
- package/src/plugins/dropdown/template.js +20 -15
- package/src/plugins/dropdown/textStyle.js +28 -22
- package/src/plugins/field/mention.js +54 -49
- package/src/plugins/index.js +5 -5
- package/src/plugins/input/fontSize.js +100 -97
- package/src/plugins/input/pageNavigator.js +13 -10
- package/src/plugins/modal/audio.js +208 -219
- package/src/plugins/modal/drawing.js +99 -104
- package/src/plugins/modal/embed.js +323 -312
- package/src/plugins/modal/image/index.js +942 -0
- package/src/plugins/modal/image/render/image.html.js +150 -0
- package/src/plugins/modal/image/services/image.size.js +198 -0
- package/src/plugins/modal/image/services/image.upload.js +216 -0
- package/src/plugins/modal/image/shared/image.constants.js +20 -0
- package/src/plugins/modal/link.js +74 -54
- package/src/plugins/modal/math.js +126 -119
- package/src/plugins/modal/video/index.js +858 -0
- package/src/plugins/modal/video/render/video.html.js +131 -0
- package/src/plugins/modal/video/services/video.size.js +281 -0
- package/src/plugins/modal/video/services/video.upload.js +92 -0
- package/src/plugins/popup/anchor.js +57 -49
- package/src/suneditor.js +73 -61
- package/src/themes/cobalt.css +155 -0
- package/src/themes/dark.css +143 -120
- package/src/typedef.js +214 -63
- package/types/assets/icons/defaultIcons.d.ts +8 -0
- package/types/assets/suneditor-contents.css.d.ts +1 -0
- package/types/assets/suneditor.css.d.ts +1 -0
- package/types/core/config/contextProvider.d.ts +148 -0
- package/types/core/config/eventManager.d.ts +68 -0
- package/types/core/config/instanceCheck.d.ts +33 -0
- package/types/core/config/optionProvider.d.ts +147 -0
- package/types/core/editor.d.ts +27 -586
- package/types/core/event/actions/index.d.ts +50 -0
- package/types/core/event/effects/common.registry.d.ts +56 -0
- package/types/core/event/effects/keydown.registry.d.ts +80 -0
- package/types/core/event/effects/ruleHelpers.d.ts +36 -0
- package/types/core/event/eventOrchestrator.d.ts +191 -0
- package/types/core/event/executor.d.ts +13 -0
- package/types/core/event/handlers/handler_toolbar.d.ts +38 -0
- package/types/core/event/handlers/handler_ww_clipboard.d.ts +36 -0
- package/types/core/event/handlers/handler_ww_dragDrop.d.ts +26 -0
- package/types/core/event/handlers/handler_ww_input.d.ts +38 -0
- package/types/core/event/handlers/handler_ww_key.d.ts +40 -0
- package/types/core/event/handlers/handler_ww_mouse.d.ts +47 -0
- package/types/core/event/ports.d.ts +256 -0
- package/types/core/event/reducers/keydown.reducer.d.ts +84 -0
- package/types/core/event/rules/keydown.rule.arrow.d.ts +19 -0
- package/types/core/event/rules/keydown.rule.backspace.d.ts +18 -0
- package/types/core/event/rules/keydown.rule.delete.d.ts +18 -0
- package/types/core/event/rules/keydown.rule.enter.d.ts +18 -0
- package/types/core/event/rules/keydown.rule.tab.d.ts +18 -0
- package/types/core/event/support/defaultLineManager.d.ts +22 -0
- package/types/core/event/support/selectionState.d.ts +29 -0
- package/types/core/kernel/coreKernel.d.ts +219 -0
- package/types/core/kernel/kernelInjector.d.ts +16 -0
- package/types/core/kernel/store.d.ts +170 -0
- package/types/core/logic/dom/char.d.ts +46 -0
- package/types/core/logic/dom/format.d.ts +234 -0
- package/types/core/logic/dom/html.d.ts +290 -0
- package/types/core/logic/dom/inline.d.ts +93 -0
- package/types/core/logic/dom/listFormat.d.ts +101 -0
- package/types/core/logic/dom/nodeTransform.d.ts +110 -0
- package/types/core/logic/dom/offset.d.ts +335 -0
- package/types/core/logic/dom/selection.d.ts +165 -0
- package/types/core/logic/panel/menu.d.ts +93 -0
- package/types/core/logic/panel/toolbar.d.ts +128 -0
- package/types/core/logic/panel/viewer.d.ts +89 -0
- package/types/core/logic/shell/_commandExecutor.d.ts +18 -0
- package/types/core/logic/shell/commandDispatcher.d.ts +65 -0
- package/types/core/logic/shell/component.d.ts +182 -0
- package/types/core/logic/shell/focusManager.d.ts +31 -0
- package/types/core/{base → logic/shell}/history.d.ts +13 -12
- package/types/core/logic/shell/pluginManager.d.ts +115 -0
- package/types/core/logic/shell/shortcuts.d.ts +131 -0
- package/types/core/logic/shell/ui.d.ts +261 -0
- package/types/core/schema/context.d.ts +104 -0
- package/types/core/schema/frameContext.d.ts +320 -0
- package/types/core/schema/options.d.ts +1241 -0
- package/types/core/section/constructor.d.ts +117 -652
- package/types/core/section/documentType.d.ts +43 -61
- package/types/events.d.ts +796 -65
- package/types/helper/clipboard.d.ts +5 -4
- package/types/helper/converter.d.ts +55 -43
- package/types/helper/dom/domCheck.d.ts +27 -19
- package/types/helper/dom/domQuery.d.ts +76 -57
- package/types/helper/dom/domUtils.d.ts +62 -39
- package/types/helper/dom/index.d.ts +87 -1
- package/types/helper/env.d.ts +16 -13
- package/types/helper/index.d.ts +8 -2
- package/types/helper/keyCodeMap.d.ts +24 -23
- package/types/helper/numbers.d.ts +4 -6
- package/types/helper/unicode.d.ts +4 -3
- package/types/hooks/base.d.ts +239 -0
- package/types/hooks/params.d.ts +65 -0
- package/types/index.d.ts +20 -117
- package/types/interfaces/contracts.d.ts +183 -0
- package/types/interfaces/index.d.ts +3 -0
- package/types/interfaces/plugins.d.ts +168 -0
- package/types/langs/_Lang.d.ts +2 -2
- package/types/langs/index.d.ts +2 -2
- package/types/modules/contract/Browser.d.ts +262 -0
- package/types/modules/contract/ColorPicker.d.ts +99 -0
- package/types/modules/contract/Controller.d.ts +204 -0
- package/types/modules/contract/Figure.d.ts +529 -0
- package/types/modules/{HueSlider.d.ts → contract/HueSlider.d.ts} +39 -28
- package/types/modules/contract/Modal.d.ts +62 -0
- package/types/modules/contract/index.d.ts +7 -0
- package/types/modules/manager/ApiManager.d.ts +106 -0
- package/types/modules/manager/FileManager.d.ts +124 -0
- package/types/modules/manager/index.d.ts +3 -0
- package/types/modules/ui/ModalAnchorEditor.d.ts +152 -0
- package/types/modules/ui/SelectMenu.d.ts +107 -0
- package/types/modules/{_DragHandle.d.ts → ui/_DragHandle.d.ts} +1 -0
- package/types/modules/ui/index.d.ts +4 -0
- package/types/plugins/browser/audioGallery.d.ts +33 -41
- package/types/plugins/browser/fileBrowser.d.ts +42 -50
- package/types/plugins/browser/fileGallery.d.ts +33 -41
- package/types/plugins/browser/imageGallery.d.ts +30 -37
- package/types/plugins/browser/videoGallery.d.ts +33 -41
- package/types/plugins/command/blockquote.d.ts +4 -21
- package/types/plugins/command/exportPDF.d.ts +23 -33
- package/types/plugins/command/fileUpload.d.ts +80 -100
- package/types/plugins/command/list_bulleted.d.ts +9 -35
- package/types/plugins/command/list_numbered.d.ts +9 -35
- package/types/plugins/dropdown/align.d.ts +23 -46
- package/types/plugins/dropdown/backgroundColor.d.ts +35 -53
- package/types/plugins/dropdown/blockStyle.d.ts +45 -0
- package/types/plugins/dropdown/font.d.ts +18 -41
- package/types/plugins/dropdown/fontColor.d.ts +35 -53
- package/types/plugins/dropdown/hr.d.ts +26 -52
- package/types/plugins/dropdown/layout.d.ts +19 -25
- package/types/plugins/dropdown/lineHeight.d.ts +21 -39
- package/types/plugins/dropdown/list.d.ts +6 -34
- package/types/plugins/dropdown/paragraphStyle.d.ts +34 -45
- package/types/plugins/dropdown/table/index.d.ts +158 -0
- package/types/plugins/dropdown/table/render/table.html.d.ts +71 -0
- package/types/plugins/dropdown/table/render/table.menu.d.ts +59 -0
- package/types/plugins/dropdown/table/services/table.cell.d.ts +76 -0
- package/types/plugins/dropdown/table/services/table.clipboard.d.ts +26 -0
- package/types/plugins/dropdown/table/services/table.grid.d.ts +77 -0
- package/types/plugins/dropdown/table/services/table.resize.d.ts +72 -0
- package/types/plugins/dropdown/table/services/table.selection.d.ts +59 -0
- package/types/plugins/dropdown/table/services/table.style.d.ts +162 -0
- package/types/plugins/dropdown/table/shared/table.constants.d.ts +134 -0
- package/types/plugins/dropdown/table/shared/table.utils.d.ts +91 -0
- package/types/plugins/dropdown/template.d.ts +19 -25
- package/types/plugins/dropdown/textStyle.d.ts +23 -30
- package/types/plugins/field/mention.d.ts +66 -72
- package/types/plugins/index.d.ts +41 -40
- package/types/plugins/input/fontSize.d.ts +57 -96
- package/types/plugins/input/pageNavigator.d.ts +5 -8
- package/types/plugins/modal/audio.d.ts +60 -153
- package/types/plugins/modal/drawing.d.ts +16 -118
- package/types/plugins/modal/embed.d.ts +46 -166
- package/types/plugins/modal/image/index.d.ts +281 -0
- package/types/plugins/modal/image/render/image.html.d.ts +45 -0
- package/types/plugins/modal/image/services/image.size.d.ts +55 -0
- package/types/plugins/modal/image/services/image.upload.d.ts +24 -0
- package/types/plugins/modal/image/shared/image.constants.d.ts +17 -0
- package/types/plugins/modal/link.d.ts +46 -66
- package/types/plugins/modal/math.d.ts +17 -86
- package/types/plugins/modal/{video.d.ts → video/index.d.ts} +89 -221
- package/types/plugins/modal/video/render/video.html.d.ts +37 -0
- package/types/plugins/modal/video/services/video.size.d.ts +74 -0
- package/types/plugins/modal/video/services/video.upload.d.ts +19 -0
- package/types/plugins/popup/anchor.d.ts +8 -38
- package/types/suneditor.d.ts +55 -24
- package/types/typedef.d.ts +344 -228
- package/CONTRIBUTING.md +0 -186
- package/src/core/base/eventHandlers/handler_ww_key_input.js +0 -1200
- package/src/core/base/eventHandlers/handler_ww_mouse.js +0 -194
- package/src/core/base/eventManager.js +0 -1523
- package/src/core/class/component.js +0 -856
- package/src/core/class/format.js +0 -3433
- package/src/core/class/menu.js +0 -346
- package/src/core/class/selection.js +0 -610
- package/src/core/class/shortcuts.js +0 -98
- package/src/core/class/toolbar.js +0 -431
- package/src/core/class/ui.js +0 -424
- package/src/core/class/viewer.js +0 -750
- package/src/core/section/actives.js +0 -266
- package/src/core/section/context.js +0 -102
- package/src/editorInjector/_classes.js +0 -36
- package/src/editorInjector/_core.js +0 -87
- package/src/editorInjector/index.js +0 -73
- package/src/modules/ApiManager.js +0 -191
- package/src/modules/Controller.js +0 -474
- package/src/modules/Modal.js +0 -346
- package/src/modules/index.js +0 -14
- package/src/plugins/dropdown/table.js +0 -4034
- package/src/plugins/modal/image.js +0 -1376
- package/src/plugins/modal/video.js +0 -1226
- package/types/core/base/eventHandlers/handler_toolbar.d.ts +0 -41
- package/types/core/base/eventHandlers/handler_ww_clipboard.d.ts +0 -40
- package/types/core/base/eventHandlers/handler_ww_dragDrop.d.ts +0 -35
- package/types/core/base/eventHandlers/handler_ww_key_input.d.ts +0 -45
- package/types/core/base/eventHandlers/handler_ww_mouse.d.ts +0 -39
- package/types/core/base/eventManager.d.ts +0 -401
- package/types/core/class/char.d.ts +0 -61
- package/types/core/class/component.d.ts +0 -213
- package/types/core/class/format.d.ts +0 -623
- package/types/core/class/html.d.ts +0 -430
- package/types/core/class/menu.d.ts +0 -126
- package/types/core/class/nodeTransform.d.ts +0 -93
- package/types/core/class/offset.d.ts +0 -522
- package/types/core/class/selection.d.ts +0 -188
- package/types/core/class/shortcuts.d.ts +0 -142
- package/types/core/class/toolbar.d.ts +0 -189
- package/types/core/class/ui.d.ts +0 -164
- package/types/core/class/viewer.d.ts +0 -140
- package/types/core/section/actives.d.ts +0 -46
- package/types/core/section/context.d.ts +0 -45
- package/types/editorInjector/_classes.d.ts +0 -41
- package/types/editorInjector/_core.d.ts +0 -87
- package/types/editorInjector/index.d.ts +0 -69
- package/types/modules/ApiManager.d.ts +0 -125
- package/types/modules/Browser.d.ts +0 -326
- package/types/modules/ColorPicker.d.ts +0 -135
- package/types/modules/Controller.d.ts +0 -251
- package/types/modules/Figure.d.ts +0 -517
- package/types/modules/FileManager.d.ts +0 -202
- package/types/modules/Modal.d.ts +0 -111
- package/types/modules/ModalAnchorEditor.d.ts +0 -236
- package/types/modules/SelectMenu.d.ts +0 -194
- package/types/modules/index.d.ts +0 -26
- package/types/plugins/dropdown/formatBlock.d.ts +0 -55
- package/types/plugins/dropdown/table.d.ts +0 -627
- package/types/plugins/modal/image.d.ts +0 -451
- /package/{LICENSE → LICENSE.txt} +0 -0
package/src/core/editor.js
CHANGED
|
@@ -1,1692 +1,264 @@
|
|
|
1
|
-
import { env, converter, dom
|
|
2
|
-
import Constructor
|
|
3
|
-
import { UpdateStatusbarContext } from './section/context';
|
|
4
|
-
import { BASIC_COMMANDS, ACTIVE_EVENT_COMMANDS, SELECT_ALL, DIR_BTN_ACTIVE, SAVE, COPY_FORMAT, FONT_STYLE, PAGE_BREAK } from './section/actives';
|
|
5
|
-
import History from './base/history';
|
|
6
|
-
import EventManager from './base/eventManager';
|
|
7
|
-
import Events from '../events';
|
|
8
|
-
import DocumentType from './section/documentType';
|
|
9
|
-
|
|
10
|
-
// class injector
|
|
11
|
-
import ClassInjector from '../editorInjector/_classes';
|
|
12
|
-
|
|
13
|
-
// classes
|
|
14
|
-
import Char from './class/char';
|
|
15
|
-
import Component from './class/component';
|
|
16
|
-
import Format from './class/format';
|
|
17
|
-
import HTML from './class/html';
|
|
18
|
-
import Menu from './class/menu';
|
|
19
|
-
import NodeTransform from './class/nodeTransform';
|
|
20
|
-
import Offset from './class/offset';
|
|
21
|
-
import Selection_ from './class/selection';
|
|
22
|
-
import Shortcuts from './class/shortcuts';
|
|
23
|
-
import Toolbar from './class/toolbar';
|
|
24
|
-
import UI from './class/ui';
|
|
25
|
-
import Viewer from './class/viewer';
|
|
26
|
-
|
|
27
|
-
const COMMAND_BUTTONS = '.se-menu-list .se-toolbar-btn[data-command]';
|
|
28
|
-
const DISABLE_BUTTONS_CODEVIEW = `${COMMAND_BUTTONS}:not([class~="se-code-view-enabled"]):not([data-type="MORE"])`;
|
|
29
|
-
const DISABLE_BUTTONS_CONTROLLER = `${COMMAND_BUTTONS}:not([class~="se-component-enabled"]):not([data-type="MORE"])`;
|
|
1
|
+
import { env, converter, dom } from '../helper';
|
|
2
|
+
import Constructor from './section/constructor';
|
|
30
3
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
*/
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* @typedef {import('./section/constructor').EditorFrameOptions} EditorFrameOptions_editor
|
|
37
|
-
*/
|
|
4
|
+
// type
|
|
5
|
+
import DocumentType from './section/documentType';
|
|
38
6
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
*/
|
|
7
|
+
// kernel
|
|
8
|
+
import CoreKernel from './kernel/coreKernel';
|
|
42
9
|
|
|
43
10
|
/**
|
|
44
|
-
* @
|
|
45
|
-
* @description SunEditor constructor function.
|
|
46
|
-
* @param {Array<{target: Element, key: *, options: EditorFrameOptions_editor}>} multiTargets Target element
|
|
47
|
-
* @param {EditorInitOptions_editor} options options
|
|
11
|
+
* @description SunEditor class.
|
|
48
12
|
*/
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
const _w = _d.defaultView || env._w;
|
|
52
|
-
const product = Constructor(multiTargets, options);
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* @description Frame root key array
|
|
56
|
-
* @type {Array<*>}
|
|
57
|
-
*/
|
|
58
|
-
this.rootKeys = product.rootKeys;
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* @description Frame root map
|
|
62
|
-
* @type {Map<*, __se__FrameContext>}
|
|
63
|
-
*/
|
|
64
|
-
this.frameRoots = product.frameRoots;
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* @description Editor context object
|
|
68
|
-
* @type {__se__Context}
|
|
69
|
-
*/
|
|
70
|
-
this.context = product.context;
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* @description Current focusing frame context
|
|
74
|
-
* @type {__se__FrameContext}
|
|
75
|
-
*/
|
|
76
|
-
this.frameContext = new Map();
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* @description Current focusing frame context options
|
|
80
|
-
* @type {__se__FrameOptions}
|
|
81
|
-
*/
|
|
82
|
-
this.frameOptions = new Map();
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* @description Document object
|
|
86
|
-
* @type {Document}
|
|
87
|
-
*/
|
|
88
|
-
this._d = _d;
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* @description Window object
|
|
92
|
-
* @type {Window}
|
|
93
|
-
*/
|
|
94
|
-
this._w = _w;
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* @description Controllers carrier
|
|
98
|
-
* @type {HTMLElement}
|
|
99
|
-
*/
|
|
100
|
-
this.carrierWrapper = product.carrierWrapper;
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* @description Editor options
|
|
104
|
-
* @type {Map<string, *>}
|
|
105
|
-
*/
|
|
106
|
-
this.options = product.options;
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* @description Plugins
|
|
110
|
-
* @type {Object<string, *>}
|
|
111
|
-
*/
|
|
112
|
-
this.plugins = product.plugins || {};
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* @description Events object, call by triggerEvent function
|
|
116
|
-
* @type {Object<string, *>}
|
|
117
|
-
*/
|
|
118
|
-
this.events = null;
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* @description Call the event function by injecting self: this.
|
|
122
|
-
* @type {(eventName: string, ...args: *) => Promise<*>}
|
|
123
|
-
*/
|
|
124
|
-
this.triggerEvent = null;
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* @description Default icons object
|
|
128
|
-
* @type {Object<string, string>}
|
|
129
|
-
*/
|
|
130
|
-
this.icons = product.icons;
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* @description loaded language
|
|
134
|
-
* @type {Object<string, *>}
|
|
135
|
-
*/
|
|
136
|
-
this.lang = product.lang;
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* @description Variables used internally in editor operation
|
|
140
|
-
* @type {__se__EditorStatus}
|
|
141
|
-
*/
|
|
142
|
-
this.status = {
|
|
143
|
-
hasFocus: false,
|
|
144
|
-
tabSize: 4,
|
|
145
|
-
indentSize: 25,
|
|
146
|
-
codeIndentSize: 2,
|
|
147
|
-
currentNodes: [],
|
|
148
|
-
currentNodesMap: [],
|
|
149
|
-
onSelected: false,
|
|
150
|
-
rootKey: product.rootId,
|
|
151
|
-
_range: null,
|
|
152
|
-
_onMousedown: false
|
|
153
|
-
};
|
|
154
|
-
|
|
155
|
-
/**
|
|
156
|
-
* @description Is classic mode?
|
|
157
|
-
* @type {boolean}
|
|
158
|
-
*/
|
|
159
|
-
this.isClassic = false;
|
|
160
|
-
|
|
161
|
-
/**
|
|
162
|
-
* @description Is inline mode?
|
|
163
|
-
* @type {boolean}
|
|
164
|
-
*/
|
|
165
|
-
this.isInline = false;
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
* @description Is balloon|balloon-always mode?
|
|
169
|
-
* @type {boolean}
|
|
170
|
-
*/
|
|
171
|
-
this.isBalloon = false;
|
|
172
|
-
|
|
173
|
-
/**
|
|
174
|
-
* @description Is balloon-always mode?
|
|
175
|
-
* @type {boolean}
|
|
176
|
-
*/
|
|
177
|
-
this.isBalloonAlways = false;
|
|
178
|
-
|
|
179
|
-
/**
|
|
180
|
-
* @description Is subToolbar balloon|balloon-always mode?
|
|
181
|
-
* @type {boolean}
|
|
182
|
-
*/
|
|
183
|
-
this.isSubBalloon = false;
|
|
184
|
-
|
|
185
|
-
/**
|
|
186
|
-
* @description Is subToolbar balloon-always mode?
|
|
187
|
-
* @type {boolean}
|
|
188
|
-
*/
|
|
189
|
-
this.isSubBalloonAlways = false;
|
|
190
|
-
|
|
191
|
-
/**
|
|
192
|
-
* @description All command buttons map
|
|
193
|
-
* @type {Map<string, HTMLElement>}
|
|
194
|
-
*/
|
|
195
|
-
this.allCommandButtons = new Map();
|
|
196
|
-
|
|
197
|
-
/**
|
|
198
|
-
* @description All command buttons map
|
|
199
|
-
* @type {Map<string, HTMLElement>}
|
|
200
|
-
*/
|
|
201
|
-
this.subAllCommandButtons = new Map();
|
|
202
|
-
|
|
203
|
-
/**
|
|
204
|
-
* @description Shoutcuts key map
|
|
205
|
-
* @type {Map<string, *>}
|
|
206
|
-
*/
|
|
207
|
-
this.shortcutsKeyMap = new Map();
|
|
208
|
-
|
|
209
|
-
/**
|
|
210
|
-
* @description Shoutcuts reverse key array
|
|
211
|
-
* - An array of key codes generated with the reverseButtons option, used to reverse the action for a specific key combination.
|
|
212
|
-
* @type {Array<string>}
|
|
213
|
-
*/
|
|
214
|
-
this.reverseKeys = [];
|
|
215
|
-
|
|
216
|
-
/**
|
|
217
|
-
* @description A map with the plugin's buttons having an "active" method and the default command buttons with an "active" action.
|
|
218
|
-
* - Each button is contained in an array.
|
|
219
|
-
* @type {Map<string, Array<HTMLButtonElement>>}
|
|
220
|
-
*/
|
|
221
|
-
this.commandTargets = new Map();
|
|
222
|
-
|
|
223
|
-
/**
|
|
224
|
-
* @description Plugins array with "active" method.
|
|
225
|
-
* - "activeCommands" runs the "add" method when creating the editor.
|
|
226
|
-
* @type {Array<string>}
|
|
227
|
-
*/
|
|
228
|
-
this.activeCommands = null;
|
|
229
|
-
|
|
230
|
-
/**
|
|
231
|
-
* @description The selection node (selection.getNode()) to which the effect was last applied
|
|
232
|
-
* @type {Node|null}
|
|
233
|
-
*/
|
|
234
|
-
this.effectNode = null;
|
|
235
|
-
|
|
236
|
-
/**
|
|
237
|
-
* @description Currently open "Modal" instance
|
|
238
|
-
* @type {*}
|
|
239
|
-
*/
|
|
240
|
-
this.opendModal = null;
|
|
241
|
-
|
|
242
|
-
/**
|
|
243
|
-
* @description Currently open "Controller" info array
|
|
244
|
-
* @type {Array<ControllerInfo_editor>}
|
|
245
|
-
*/
|
|
246
|
-
this.opendControllers = [];
|
|
247
|
-
|
|
248
|
-
/**
|
|
249
|
-
* @description Currently open "Controller" caller plugin name
|
|
250
|
-
*/
|
|
251
|
-
this.currentControllerName = '';
|
|
252
|
-
|
|
253
|
-
/**
|
|
254
|
-
* @description Currently open "Browser" instance
|
|
255
|
-
* @type {*}
|
|
256
|
-
*/
|
|
257
|
-
this.opendBrowser = null;
|
|
258
|
-
|
|
259
|
-
/**
|
|
260
|
-
* @description Whether "SelectMenu" is open
|
|
261
|
-
* @type {boolean}
|
|
262
|
-
*/
|
|
263
|
-
this.selectMenuOn = false;
|
|
264
|
-
|
|
265
|
-
// ------ base ------
|
|
266
|
-
/** @description History class instance @type {ReturnType<typeof import('./base/history').default>} */
|
|
267
|
-
this.history = null;
|
|
268
|
-
/** @description EventManager class instance @type {import('./base/eventManager').default} */
|
|
269
|
-
this.eventManager = null;
|
|
270
|
-
|
|
271
|
-
// ------ class ------
|
|
272
|
-
/** @description Toolbar class instance @type {import('./class/toolbar').default} */
|
|
273
|
-
this.toolbar = null;
|
|
274
|
-
/** @description Sub-Toolbar class instance @type {import('./class/toolbar').default|null} */
|
|
275
|
-
this.subToolbar = null;
|
|
276
|
-
/** @description Char class instance @type {import('./class/char').default} */
|
|
277
|
-
this.char = null;
|
|
278
|
-
/** @description Component class instance @type {import('./class/component').default} */
|
|
279
|
-
this.component = null;
|
|
280
|
-
/** @description Format class instance @type {import('./class/format').default} */
|
|
281
|
-
this.format = null;
|
|
282
|
-
/** @description HTML class instance @type {import('./class/html').default} */
|
|
283
|
-
this.html = null;
|
|
284
|
-
/** @description Menu class instance @type {import('./class/menu').default} */
|
|
285
|
-
this.menu = null;
|
|
286
|
-
/** @description NodeTransform class instance @type {import('./class/nodeTransform').default} */
|
|
287
|
-
this.nodeTransform = null;
|
|
288
|
-
/** @description Offset class instance @type {import('./class/offset').default} */
|
|
289
|
-
this.offset = null;
|
|
290
|
-
/** @description Selection class instance @type {import('./class/selection').default} */
|
|
291
|
-
this.selection = null;
|
|
292
|
-
/** @description Shortcuts class instance @type {import('./class/shortcuts').default} */
|
|
293
|
-
this.shortcuts = null;
|
|
294
|
-
/** @description UI class instance @type {import('./class/ui').default} */
|
|
295
|
-
this.ui = null;
|
|
296
|
-
/** @description Viewer class instance @type {import('./class/viewer').default} */
|
|
297
|
-
this.viewer = null;
|
|
298
|
-
|
|
299
|
-
// ------------------------------------------------------- private properties -------------------------------------------------------
|
|
300
|
-
/**
|
|
301
|
-
* @description Line breaker (top)
|
|
302
|
-
* @type {HTMLElement}
|
|
303
|
-
*/
|
|
304
|
-
this._lineBreaker_t = null;
|
|
305
|
-
|
|
306
|
-
/**
|
|
307
|
-
* @description Line breaker (bottom)
|
|
308
|
-
* @type {HTMLElement}
|
|
309
|
-
*/
|
|
310
|
-
this._lineBreaker_b = null;
|
|
311
|
-
|
|
312
|
-
/**
|
|
313
|
-
* @description Closest ShadowRoot to editor if found
|
|
314
|
-
* @type {ShadowRoot & { getSelection?: () => Selection }} - Chromium-based browsers (Chrome, Edge, etc.) has a getSelection method on the ShadowRoot
|
|
315
|
-
*/
|
|
316
|
-
this._shadowRoot = null;
|
|
317
|
-
|
|
318
|
-
/**
|
|
319
|
-
* @description Plugin call event map
|
|
320
|
-
* @type {Map<string, Array<((...args: *) => *) & { index: number }>>}
|
|
321
|
-
*/
|
|
322
|
-
this._onPluginEvents = null;
|
|
323
|
-
|
|
324
|
-
/**
|
|
325
|
-
* @description Copy format info
|
|
326
|
-
* - eventManager.__cacheStyleNodes copied
|
|
327
|
-
* @type {Array<Node>|null}
|
|
328
|
-
*/
|
|
329
|
-
this._onCopyFormatInfo = null;
|
|
330
|
-
|
|
331
|
-
/**
|
|
332
|
-
* @description Copy format init method
|
|
333
|
-
* @type {(...args: *) => *|null}
|
|
334
|
-
*/
|
|
335
|
-
this._onCopyFormatInitMethod = null;
|
|
336
|
-
|
|
337
|
-
/**
|
|
338
|
-
* @description Controller target's frame div (editor.frameContext.get('topArea'))
|
|
339
|
-
* @type {HTMLElement|null}
|
|
340
|
-
*/
|
|
341
|
-
this._controllerTargetContext = null;
|
|
342
|
-
|
|
343
|
-
/**
|
|
344
|
-
* @description List of buttons that are disabled when "controller" is opened
|
|
345
|
-
* @type {Array<HTMLButtonElement|HTMLInputElement>}
|
|
346
|
-
*/
|
|
347
|
-
this._controllerOnDisabledButtons = [];
|
|
348
|
-
|
|
349
|
-
/**
|
|
350
|
-
* @description List of buttons that are disabled when "codeView" mode opened
|
|
351
|
-
* @type {Array<HTMLButtonElement|HTMLInputElement>}
|
|
352
|
-
*/
|
|
353
|
-
this._codeViewDisabledButtons = [];
|
|
354
|
-
|
|
355
|
-
/**
|
|
356
|
-
* @description List of buttons to run plugins in the toolbar
|
|
357
|
-
* @type {Array<HTMLElement>}
|
|
358
|
-
*/
|
|
359
|
-
this._pluginCallButtons = product.pluginCallButtons;
|
|
360
|
-
|
|
361
|
-
/**
|
|
362
|
-
* @description List of buttons to run plugins in the Sub-Toolbar
|
|
363
|
-
* @type {Array<HTMLElement>}
|
|
364
|
-
*/
|
|
365
|
-
this._pluginCallButtons_sub = product.pluginCallButtons_sub;
|
|
366
|
-
|
|
367
|
-
/**
|
|
368
|
-
* @description Responsive Toolbar Button Structure array
|
|
369
|
-
* @type {Array<*>}
|
|
370
|
-
*/
|
|
371
|
-
this._responsiveButtons = product.responsiveButtons;
|
|
372
|
-
|
|
373
|
-
/**
|
|
374
|
-
* @description Responsive Sub-Toolbar Button Structure array
|
|
375
|
-
* @type {Array<*>}
|
|
376
|
-
*/
|
|
377
|
-
this._responsiveButtons_sub = product.responsiveButtons_sub;
|
|
378
|
-
|
|
379
|
-
/**
|
|
380
|
-
* @description Variable that controls the "blur" event in the editor of inline or balloon mode when the focus is moved to dropdown
|
|
381
|
-
* @type {boolean}
|
|
382
|
-
*/
|
|
383
|
-
this._notHideToolbar = false;
|
|
384
|
-
|
|
385
|
-
/**
|
|
386
|
-
* @description Variables for controlling blur events
|
|
387
|
-
* @type {boolean}
|
|
388
|
-
*/
|
|
389
|
-
this._preventBlur = false;
|
|
390
|
-
|
|
391
|
-
/**
|
|
392
|
-
* @description Variables for controlling focus events
|
|
393
|
-
* @type {boolean}
|
|
394
|
-
*/
|
|
395
|
-
this._preventFocus = false;
|
|
396
|
-
|
|
397
|
-
/**
|
|
398
|
-
* @description Variables for controlling selection change events
|
|
399
|
-
*/
|
|
400
|
-
this._preventSelection = false;
|
|
401
|
-
|
|
402
|
-
/**
|
|
403
|
-
* @description If true, initialize all indexes of image, video information
|
|
404
|
-
* @type {boolean}
|
|
405
|
-
*/
|
|
406
|
-
this._componentsInfoInit = true;
|
|
407
|
-
|
|
408
|
-
/**
|
|
409
|
-
* @description If true, reset all indexes of image, video information
|
|
410
|
-
* @type {boolean}
|
|
411
|
-
*/
|
|
412
|
-
this._componentsInfoReset = false;
|
|
413
|
-
|
|
414
|
-
/**
|
|
415
|
-
* @description plugin retainFormat info Map()
|
|
416
|
-
* @type {Map<string, ((...args: *) => *)>}
|
|
417
|
-
*/
|
|
418
|
-
this._MELInfo = null;
|
|
419
|
-
|
|
420
|
-
/**
|
|
421
|
-
* @description Properties for managing files in the "FileManager" module
|
|
422
|
-
* @type {Array<*>}
|
|
423
|
-
*/
|
|
424
|
-
this._fileInfoPluginsCheck = null;
|
|
425
|
-
|
|
426
|
-
/**
|
|
427
|
-
* @description Properties for managing files in the "FileManager" module
|
|
428
|
-
* @type {Array<*>}
|
|
429
|
-
*/
|
|
430
|
-
this._fileInfoPluginsReset = null;
|
|
431
|
-
|
|
432
|
-
/**
|
|
433
|
-
* @description Variables for file component management
|
|
434
|
-
* @type {Object<string, *>}
|
|
435
|
-
*/
|
|
436
|
-
this._fileManager = {
|
|
437
|
-
tags: null,
|
|
438
|
-
regExp: null,
|
|
439
|
-
pluginRegExp: null,
|
|
440
|
-
pluginMap: null
|
|
441
|
-
};
|
|
442
|
-
|
|
443
|
-
/**
|
|
444
|
-
* @description Variables for managing the components
|
|
445
|
-
* @type {Array<*>}
|
|
446
|
-
*/
|
|
447
|
-
this._componentManager = [];
|
|
448
|
-
|
|
449
|
-
/**
|
|
450
|
-
* @description Current Figure container.
|
|
451
|
-
* @type {HTMLElement|null}
|
|
452
|
-
*/
|
|
453
|
-
this._figureContainer = null;
|
|
454
|
-
|
|
455
|
-
/**
|
|
456
|
-
* @description Origin options
|
|
457
|
-
* @type {EditorInitOptions_editor}
|
|
458
|
-
*/
|
|
459
|
-
this._originOptions = options;
|
|
460
|
-
|
|
461
|
-
/** ----- Create editor ------------------------------------------------------------ */
|
|
462
|
-
this.__Create(options);
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
Editor.prototype = {
|
|
466
|
-
/**
|
|
467
|
-
* @description If the plugin is not added, add the plugin and call the 'add' function.
|
|
468
|
-
* - If the plugin is added call callBack function.
|
|
469
|
-
* @param {string} pluginName The name of the plugin to call
|
|
470
|
-
* @param {?Array<HTMLElement>} targets Plugin target button (This is not necessary if you have a button list when creating the editor)
|
|
471
|
-
* @param {?Object<string, *>} pluginOptions Plugin's options
|
|
472
|
-
*/
|
|
473
|
-
registerPlugin(pluginName, targets, pluginOptions) {
|
|
474
|
-
let plugin = this.plugins[pluginName];
|
|
475
|
-
if (!plugin) {
|
|
476
|
-
throw Error(`[SUNEDITOR.registerPlugin.fail] The called plugin does not exist or is in an invalid format. (pluginName: "${pluginName}")`);
|
|
477
|
-
} else if (typeof this.plugins[pluginName] === 'function') {
|
|
478
|
-
plugin = this.plugins[pluginName] = new this.plugins[pluginName](this, pluginOptions || {});
|
|
479
|
-
if (typeof plugin.init === 'function') plugin.init();
|
|
480
|
-
}
|
|
13
|
+
class Editor {
|
|
14
|
+
#kernel;
|
|
481
15
|
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
UpdateButton(targets[i], plugin, this.icons, this.lang);
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
if (!this.activeCommands.includes(pluginName) && typeof this.plugins[pluginName].active === 'function') {
|
|
488
|
-
this.activeCommands.push(pluginName);
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
},
|
|
16
|
+
/** @type {SunEditor.Deps} */
|
|
17
|
+
$;
|
|
492
18
|
|
|
493
19
|
/**
|
|
494
|
-
* @
|
|
495
|
-
* @
|
|
496
|
-
* @param {
|
|
497
|
-
* @param {
|
|
20
|
+
* @constructor
|
|
21
|
+
* @description SunEditor constructor function.
|
|
22
|
+
* @param {Array<{target: Element, key: *, options: SunEditor.InitFrameOptions}>} multiTargets Target element
|
|
23
|
+
* @param {SunEditor.InitOptions} options options
|
|
498
24
|
*/
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
if (/more/i.test(type)) {
|
|
502
|
-
const toolbar = dom.query.getParentElement(button, '.se-toolbar');
|
|
503
|
-
const toolInst = dom.utils.hasClass(toolbar, 'se-toolbar-sub') ? this.subToolbar : this.toolbar;
|
|
504
|
-
if (button !== toolInst.currentMoreLayerActiveButton) {
|
|
505
|
-
const layer = toolbar.querySelector('.' + command);
|
|
506
|
-
if (layer) {
|
|
507
|
-
toolInst._moreLayerOn(button, layer);
|
|
508
|
-
toolInst._showBalloon();
|
|
509
|
-
toolInst._showInline();
|
|
510
|
-
}
|
|
511
|
-
dom.utils.addClass(button, 'on');
|
|
512
|
-
} else if (toolInst.currentMoreLayerActiveButton) {
|
|
513
|
-
toolInst._moreLayerOff();
|
|
514
|
-
toolInst._showBalloon();
|
|
515
|
-
toolInst._showInline();
|
|
516
|
-
}
|
|
25
|
+
constructor(multiTargets, options) {
|
|
26
|
+
const product = Constructor(multiTargets, options);
|
|
517
27
|
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
28
|
+
// CoreKernel
|
|
29
|
+
const kernel = new CoreKernel(this, { product, options });
|
|
30
|
+
this.#kernel = kernel;
|
|
521
31
|
|
|
522
|
-
|
|
523
|
-
this.menu.containerOn(button);
|
|
524
|
-
return;
|
|
525
|
-
}
|
|
32
|
+
this.$ = kernel.$;
|
|
526
33
|
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
} else if (/modal/.test(type)) {
|
|
532
|
-
this.plugins[command].open(button);
|
|
533
|
-
return;
|
|
534
|
-
} else if (/command/.test(type)) {
|
|
535
|
-
this.plugins[command].action(button);
|
|
536
|
-
} else if (/browser/.test(type)) {
|
|
537
|
-
this.plugins[command].open(null);
|
|
538
|
-
} else if (/popup/.test(type)) {
|
|
539
|
-
this.plugins[command].show();
|
|
540
|
-
}
|
|
541
|
-
} else if (command) {
|
|
542
|
-
this.commandHandler(command, button);
|
|
543
|
-
}
|
|
544
|
-
|
|
545
|
-
if (/dropdown/.test(type)) {
|
|
546
|
-
this.menu.dropdownOff();
|
|
547
|
-
} else if (!/command/.test(type)) {
|
|
548
|
-
this.menu.dropdownOff();
|
|
549
|
-
this.menu.containerOff();
|
|
550
|
-
}
|
|
551
|
-
},
|
|
552
|
-
|
|
553
|
-
/**
|
|
554
|
-
* @description Execute default command of command button
|
|
555
|
-
* - (selectAll, codeView, fullScreen, indent, outdent, undo, redo, removeFormat, print, preview, showBlocks, save, bold, underline, italic, strike, subscript, superscript, copy, cut, paste)
|
|
556
|
-
* @param {string} command Property of command button (data-value)
|
|
557
|
-
* @param {?Node=} button Command button
|
|
558
|
-
* @returns {Promise<void>}
|
|
559
|
-
*/
|
|
560
|
-
async commandHandler(command, button) {
|
|
561
|
-
if (this.frameContext.get('isReadOnly') && !/copy|cut|selectAll|codeView|fullScreen|print|preview|showBlocks/.test(command)) return;
|
|
562
|
-
|
|
563
|
-
switch (command) {
|
|
564
|
-
case 'selectAll':
|
|
565
|
-
SELECT_ALL(this);
|
|
566
|
-
break;
|
|
567
|
-
case 'copy': {
|
|
568
|
-
const range = this.selection.getRange();
|
|
569
|
-
if (range.collapsed) break;
|
|
570
|
-
|
|
571
|
-
const container = dom.utils.createElement('div', null, range.cloneContents());
|
|
572
|
-
await this.html.copy(container.innerHTML);
|
|
573
|
-
|
|
574
|
-
break;
|
|
575
|
-
}
|
|
576
|
-
case 'newDocument':
|
|
577
|
-
this.html.set(`<${this.options.get('defaultLine')}><br></${this.options.get('defaultLine')}>`);
|
|
578
|
-
this.focus();
|
|
579
|
-
this.history.push(false);
|
|
580
|
-
break;
|
|
581
|
-
case 'codeView':
|
|
582
|
-
this.viewer.codeView(!this.frameContext.get('isCodeView'));
|
|
583
|
-
break;
|
|
584
|
-
case 'fullScreen':
|
|
585
|
-
this.viewer.fullScreen(!this.frameContext.get('isFullScreen'));
|
|
586
|
-
break;
|
|
587
|
-
case 'indent':
|
|
588
|
-
this.format.indent();
|
|
589
|
-
break;
|
|
590
|
-
case 'outdent':
|
|
591
|
-
this.format.outdent();
|
|
592
|
-
break;
|
|
593
|
-
case 'undo':
|
|
594
|
-
this.history.undo();
|
|
595
|
-
break;
|
|
596
|
-
case 'redo':
|
|
597
|
-
this.history.redo();
|
|
598
|
-
break;
|
|
599
|
-
case 'removeFormat':
|
|
600
|
-
this.format.removeInlineElement();
|
|
601
|
-
this.focus();
|
|
602
|
-
break;
|
|
603
|
-
case 'print':
|
|
604
|
-
this.viewer.print();
|
|
605
|
-
break;
|
|
606
|
-
case 'preview':
|
|
607
|
-
this.viewer.preview();
|
|
608
|
-
break;
|
|
609
|
-
case 'showBlocks':
|
|
610
|
-
this.viewer.showBlocks(!this.frameContext.get('isShowBlocks'));
|
|
611
|
-
break;
|
|
612
|
-
case 'dir':
|
|
613
|
-
this.setDir(this.options.get('_rtl') ? 'ltr' : 'rtl');
|
|
614
|
-
break;
|
|
615
|
-
case 'dir_ltr':
|
|
616
|
-
this.setDir('ltr');
|
|
617
|
-
break;
|
|
618
|
-
case 'dir_rtl':
|
|
619
|
-
this.setDir('rtl');
|
|
620
|
-
break;
|
|
621
|
-
case 'save':
|
|
622
|
-
await SAVE(this);
|
|
623
|
-
break;
|
|
624
|
-
case 'copyFormat':
|
|
625
|
-
COPY_FORMAT(this, button);
|
|
626
|
-
break;
|
|
627
|
-
case 'pageBreak':
|
|
628
|
-
PAGE_BREAK(this);
|
|
629
|
-
break;
|
|
630
|
-
case 'pageUp':
|
|
631
|
-
this.frameContext.get('documentType').pageUp();
|
|
632
|
-
break;
|
|
633
|
-
case 'pageDown':
|
|
634
|
-
this.frameContext.get('documentType').pageDown();
|
|
635
|
-
break;
|
|
636
|
-
default:
|
|
637
|
-
FONT_STYLE(this, command);
|
|
638
|
-
}
|
|
639
|
-
},
|
|
640
|
-
|
|
641
|
-
/**
|
|
642
|
-
* @description Execute "editor.run" with command button.
|
|
643
|
-
* @param {Node} target Command target
|
|
644
|
-
*/
|
|
645
|
-
runFromTarget(target) {
|
|
646
|
-
if (dom.check.isInputElement(target)) return;
|
|
647
|
-
|
|
648
|
-
const targetBtn = /** @type {HTMLButtonElement} */ (dom.query.getCommandTarget(target));
|
|
649
|
-
if (!targetBtn) return;
|
|
650
|
-
|
|
651
|
-
const command = targetBtn.getAttribute('data-command');
|
|
652
|
-
const type = targetBtn.getAttribute('data-type');
|
|
653
|
-
|
|
654
|
-
if (!command && !type) return;
|
|
655
|
-
if (targetBtn.disabled) return;
|
|
656
|
-
|
|
657
|
-
this.run(command, type, target);
|
|
658
|
-
},
|
|
659
|
-
|
|
660
|
-
/**
|
|
661
|
-
* @description It is executed by inserting the button of commandTargets as the argument value of the "f" function.
|
|
662
|
-
* - "func" is called as long as the button array's length.
|
|
663
|
-
* @param {string} cmd data-command
|
|
664
|
-
* @param {(...args: *) => *} func Function.
|
|
665
|
-
*/
|
|
666
|
-
applyCommandTargets(cmd, func) {
|
|
667
|
-
if (this.commandTargets.has(cmd)) {
|
|
668
|
-
this.commandTargets.get(cmd).forEach(func);
|
|
669
|
-
}
|
|
670
|
-
},
|
|
671
|
-
|
|
672
|
-
/**
|
|
673
|
-
* @description Execute a function by traversing all root targets.
|
|
674
|
-
* @param {(...args: *) => *} f Function
|
|
675
|
-
*/
|
|
676
|
-
applyFrameRoots(f) {
|
|
677
|
-
this.frameRoots.forEach(f);
|
|
678
|
-
},
|
|
34
|
+
this.#Create(options).catch((e) => {
|
|
35
|
+
console.error('[SUNEDITOR:E_CREATE_FAIL] Failed to create editor instance.', e);
|
|
36
|
+
});
|
|
37
|
+
}
|
|
679
38
|
|
|
680
39
|
/**
|
|
681
40
|
* @description Checks if the content of the editor is empty.
|
|
682
41
|
* - Display criteria for "placeholder".
|
|
683
|
-
* @param {?
|
|
42
|
+
* @param {?SunEditor.FrameContext} [fc] Frame context, if not present, currently selected frame context.
|
|
684
43
|
* @returns {boolean}
|
|
685
44
|
*/
|
|
686
45
|
isEmpty(fc) {
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
},
|
|
691
|
-
|
|
692
|
-
/**
|
|
693
|
-
* @description Set direction to "rtl" or "ltr".
|
|
694
|
-
* @param {string} dir "rtl" or "ltr"
|
|
695
|
-
*/
|
|
696
|
-
setDir(dir) {
|
|
697
|
-
const rtl = dir === 'rtl';
|
|
698
|
-
if (this.options.get('_rtl') === rtl) return;
|
|
699
|
-
|
|
700
|
-
try {
|
|
701
|
-
this.options.set('_rtl', rtl);
|
|
702
|
-
this.ui._offCurrentController();
|
|
703
|
-
|
|
704
|
-
const fc = this.frameContext;
|
|
705
|
-
const plugins = this.plugins;
|
|
706
|
-
for (const k in plugins) {
|
|
707
|
-
if (typeof plugins[k].setDir === 'function') plugins[k].setDir(dir);
|
|
708
|
-
}
|
|
709
|
-
|
|
710
|
-
const toolbarWrapper = this.context.get('toolbar._wrapper');
|
|
711
|
-
const statusbarWrapper = this.context.get('statusbar._wrapper');
|
|
712
|
-
if (rtl) {
|
|
713
|
-
this.applyFrameRoots((e) => {
|
|
714
|
-
dom.utils.addClass([e.get('topArea'), e.get('wysiwyg'), e.get('documentTypePageMirror')], 'se-rtl');
|
|
715
|
-
});
|
|
716
|
-
dom.utils.addClass([this.carrierWrapper, toolbarWrapper, statusbarWrapper], 'se-rtl');
|
|
717
|
-
} else {
|
|
718
|
-
this.applyFrameRoots((e) => {
|
|
719
|
-
dom.utils.removeClass([e.get('topArea'), e.get('wysiwyg'), e.get('documentTypePageMirror')], 'se-rtl');
|
|
720
|
-
});
|
|
721
|
-
dom.utils.removeClass([this.carrierWrapper, toolbarWrapper, statusbarWrapper], 'se-rtl');
|
|
722
|
-
}
|
|
723
|
-
|
|
724
|
-
const lineNodes = dom.query.getListChildren(fc.get('wysiwyg'), (current) => {
|
|
725
|
-
return this.format.isLine(current) && !!(current.style.marginRight || current.style.marginLeft || current.style.textAlign);
|
|
726
|
-
});
|
|
727
|
-
|
|
728
|
-
for (let i = 0, n, l, r; (n = lineNodes[i]); i++) {
|
|
729
|
-
n = lineNodes[i];
|
|
730
|
-
// indent margin
|
|
731
|
-
r = n.style.marginRight;
|
|
732
|
-
l = n.style.marginLeft;
|
|
733
|
-
if (r || l) {
|
|
734
|
-
n.style.marginRight = l;
|
|
735
|
-
n.style.marginLeft = r;
|
|
736
|
-
}
|
|
737
|
-
// text align
|
|
738
|
-
r = n.style.textAlign;
|
|
739
|
-
if (r === 'left') n.style.textAlign = 'right';
|
|
740
|
-
else if (r === 'right') n.style.textAlign = 'left';
|
|
741
|
-
}
|
|
742
|
-
|
|
743
|
-
DIR_BTN_ACTIVE(this, rtl);
|
|
744
|
-
|
|
745
|
-
// document type
|
|
746
|
-
if (fc.has('documentType-use-header')) {
|
|
747
|
-
if (rtl) fc.get('wrapper').appendChild(fc.get('documentTypeInner'));
|
|
748
|
-
else fc.get('wrapper').insertBefore(fc.get('documentTypeInner'), fc.get('wysiwygFrame'));
|
|
749
|
-
}
|
|
750
|
-
if (fc.has('documentType-use-page')) {
|
|
751
|
-
if (rtl) fc.get('wrapper').insertBefore(fc.get('documentTypePage'), fc.get('wysiwygFrame'));
|
|
752
|
-
else fc.get('wrapper').appendChild(fc.get('documentTypePage'));
|
|
753
|
-
}
|
|
754
|
-
|
|
755
|
-
if (this.isBalloon) this.toolbar._showBalloon();
|
|
756
|
-
else if (this.isSubBalloon) this.subToolbar._showBalloon();
|
|
757
|
-
} catch (e) {
|
|
758
|
-
this.options.set('_rtl', !rtl);
|
|
759
|
-
console.warn(`[SUNEDITOR.setDir.fail] ${e.toString()}`);
|
|
760
|
-
}
|
|
761
|
-
|
|
762
|
-
this.effectNode = null;
|
|
763
|
-
this.eventManager.applyTagEffect();
|
|
764
|
-
},
|
|
46
|
+
const wysiwyg = (fc || this.$.frameContext).get('wysiwyg');
|
|
47
|
+
return dom.check.isZeroWidth(wysiwyg.textContent) && !wysiwyg.querySelector(this.$.options.get('allowedEmptyTags')) && (wysiwyg.innerText.match(/\n/g) || '').length <= 1;
|
|
48
|
+
}
|
|
765
49
|
|
|
766
50
|
/**
|
|
767
51
|
* @description Add or reset option property (Editor is reloaded)
|
|
768
|
-
* @
|
|
52
|
+
* @example
|
|
53
|
+
* // Change toolbar buttons and height
|
|
54
|
+
* editor.resetOptions({
|
|
55
|
+
* buttonList: [['bold', 'italic'], ['image']],
|
|
56
|
+
* height: '500px',
|
|
57
|
+
* });
|
|
58
|
+
* @param {SunEditor.InitOptions} newOptions Options
|
|
769
59
|
*/
|
|
770
60
|
resetOptions(newOptions) {
|
|
771
|
-
this.
|
|
772
|
-
this.viewer.showBlocks(false);
|
|
61
|
+
this.$.optionProvider.reset(newOptions);
|
|
773
62
|
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
const newRoots = [];
|
|
777
|
-
const newRootKeys = new Map();
|
|
63
|
+
this.$.store.set('_lastSelectionNode', null);
|
|
64
|
+
this.#setFrameInfo(this.$.frameRoots.get(this.$.store.get('rootKey')));
|
|
778
65
|
|
|
779
|
-
//
|
|
780
|
-
const
|
|
781
|
-
|
|
782
|
-
if (OPTION_FRAME_FIXED_FLAG[k] === undefined) continue;
|
|
783
|
-
nRoot[k] = newOptions[k];
|
|
784
|
-
delete newOptions[k];
|
|
66
|
+
// plugin hook
|
|
67
|
+
for (const plugin of Object.values(this.$.plugins)) {
|
|
68
|
+
plugin.init?.();
|
|
785
69
|
}
|
|
786
|
-
|
|
787
|
-
newOptions[rootKey || ''] = { ...nRoot, ...newOptions[rootKey || ''] };
|
|
788
|
-
}
|
|
789
|
-
|
|
790
|
-
// check reoption validation
|
|
791
|
-
const newOptionKeys = Object.keys(newOptions);
|
|
792
|
-
CheckResetKeys(newOptionKeys, this.plugins, '');
|
|
793
|
-
if (newOptionKeys.length === 0) return;
|
|
794
|
-
|
|
795
|
-
if (frameRoots.size === 1) {
|
|
796
|
-
newOptionKeys.unshift(null);
|
|
797
|
-
}
|
|
798
|
-
|
|
799
|
-
// option merge
|
|
800
|
-
const _originOptions = [this._originOptions, newOptions].reduce((init, option) => {
|
|
801
|
-
for (const key in option) {
|
|
802
|
-
if (frameRoots.has(key || null)) {
|
|
803
|
-
RestoreFrameOptions(key, option, frameRoots, rootDiff, newRootKeys, newRoots);
|
|
804
|
-
} else {
|
|
805
|
-
init[key] = option[key];
|
|
806
|
-
}
|
|
807
|
-
}
|
|
808
|
-
return init;
|
|
809
|
-
}, {});
|
|
810
|
-
|
|
811
|
-
// init options
|
|
812
|
-
const options = this.options;
|
|
813
|
-
const newO = InitOptions(_originOptions, newRoots, this.plugins);
|
|
814
|
-
const newOptionMap = newO.o;
|
|
815
|
-
const newFrameMap = newO.frameMap;
|
|
816
|
-
/** --------- [root start] --------- */
|
|
817
|
-
for (let i = 0, len = newOptionKeys.length, k; i < len; i++) {
|
|
818
|
-
k = newOptionKeys[i] || null;
|
|
819
|
-
|
|
820
|
-
if (newRootKeys.has(k)) {
|
|
821
|
-
const diff = rootDiff.get(k);
|
|
822
|
-
const fc = frameRoots.get(k);
|
|
823
|
-
const originOptions = fc.get('options');
|
|
824
|
-
const newRootOptions = newFrameMap.get(k);
|
|
825
|
-
|
|
826
|
-
// --- set options : fc ---
|
|
827
|
-
fc.set('options', newRootOptions);
|
|
828
|
-
|
|
829
|
-
// statusbar-changed
|
|
830
|
-
if (diff.has('statusbar-changed')) {
|
|
831
|
-
// statusbar
|
|
832
|
-
dom.utils.removeItem(fc.get('statusbar'));
|
|
833
|
-
if (newRootOptions.get('statusbar')) {
|
|
834
|
-
const statusbar = CreateStatusbar(newRootOptions, null).statusbar;
|
|
835
|
-
fc.get('container').appendChild(statusbar);
|
|
836
|
-
UpdateStatusbarContext(statusbar, fc);
|
|
837
|
-
this.eventManager.__addStatusbarEvent(fc, newRootOptions);
|
|
838
|
-
} else {
|
|
839
|
-
this.eventManager.removeEvent(originOptions.get('__statusbarEvent'));
|
|
840
|
-
newRootOptions.set('__statusbarEvent', null);
|
|
841
|
-
UpdateStatusbarContext(null, fc);
|
|
842
|
-
}
|
|
843
|
-
// charCounter
|
|
844
|
-
if (fc.get('statusbar')) {
|
|
845
|
-
this.char.display(fc);
|
|
846
|
-
}
|
|
847
|
-
}
|
|
848
|
-
|
|
849
|
-
// iframe's options
|
|
850
|
-
if (diff.has('iframe_attributes')) {
|
|
851
|
-
const frame = fc.get('wysiwygFrame');
|
|
852
|
-
const originAttr = originOptions.get('iframe_attributes');
|
|
853
|
-
const newAttr = newRootOptions.get('iframe_attributes');
|
|
854
|
-
for (const origin_k in originAttr) frame.removeAttribute(origin_k, originAttr[origin_k]);
|
|
855
|
-
for (const new_k in newAttr) frame.setAttribute(new_k, newAttr[new_k]);
|
|
856
|
-
}
|
|
857
|
-
|
|
858
|
-
if (diff.has('iframe_cssFileName')) {
|
|
859
|
-
const docHead = fc.get('_wd').head;
|
|
860
|
-
const links = docHead.getElementsByTagName('link');
|
|
861
|
-
while (links[0]) docHead.removeChild(links[0]);
|
|
862
|
-
const parseDocument = new DOMParser().parseFromString(converter._setIframeStyleLinks(newRootOptions.get('iframe_cssFileName')), 'text/html');
|
|
863
|
-
const newLinks = parseDocument.head.children;
|
|
864
|
-
const sTag = docHead.querySelector('style');
|
|
865
|
-
while (newLinks[0]) docHead.insertBefore(newLinks[0], sTag);
|
|
866
|
-
}
|
|
867
|
-
|
|
868
|
-
if (diff.has('placeholder')) {
|
|
869
|
-
fc.get('placeholder').textContent = newRootOptions.get('placeholder');
|
|
870
|
-
}
|
|
871
|
-
|
|
872
|
-
// frame styles
|
|
873
|
-
this.ui.setEditorStyle(newRootOptions.get('editorStyle'), fc);
|
|
874
|
-
|
|
875
|
-
// frame attributes
|
|
876
|
-
const frame = fc.get('wysiwyg');
|
|
877
|
-
const originAttr = originOptions.get('editableFrameAttributes');
|
|
878
|
-
const newAttr = newRootOptions.get('editableFrameAttributes');
|
|
879
|
-
for (const origin_k in originAttr) frame.removeAttribute(origin_k, originAttr[origin_k]);
|
|
880
|
-
for (const new_k in newAttr) frame.setAttribute(new_k, newAttr[new_k]);
|
|
881
|
-
|
|
882
|
-
continue;
|
|
883
|
-
}
|
|
884
|
-
/** --------- [root end] --------- */
|
|
885
|
-
|
|
886
|
-
// --- set options ---
|
|
887
|
-
options.set(k, newOptionMap.get(k));
|
|
888
|
-
|
|
889
|
-
/** Options that require a function call */
|
|
890
|
-
switch (k) {
|
|
891
|
-
case 'theme': {
|
|
892
|
-
this.ui.setTheme(options.get('theme'));
|
|
893
|
-
break;
|
|
894
|
-
}
|
|
895
|
-
case 'events': {
|
|
896
|
-
const events = options.get('events');
|
|
897
|
-
for (const name in events) {
|
|
898
|
-
this.events[name] = events[name];
|
|
899
|
-
}
|
|
900
|
-
break;
|
|
901
|
-
}
|
|
902
|
-
case 'autoStyleify': {
|
|
903
|
-
this.html.__resetAutoStyleify(options.get('autoStyleify'));
|
|
904
|
-
break;
|
|
905
|
-
}
|
|
906
|
-
case 'textDirection': {
|
|
907
|
-
this.setDir(options.get('_rtl') ? 'ltr' : 'rtl');
|
|
908
|
-
break;
|
|
909
|
-
}
|
|
910
|
-
case 'historyStackDelayTime': {
|
|
911
|
-
this.history.resetDelayTime(options.get('historyStackDelayTime'));
|
|
912
|
-
break;
|
|
913
|
-
}
|
|
914
|
-
case 'defaultLineBreakFormat': {
|
|
915
|
-
this.format.__resetBrLineBreak(options.get('defaultLineBreakFormat'));
|
|
916
|
-
}
|
|
917
|
-
}
|
|
918
|
-
}
|
|
919
|
-
|
|
920
|
-
/** apply options */
|
|
921
|
-
// _origin
|
|
922
|
-
this._originOptions = _originOptions;
|
|
923
|
-
|
|
924
|
-
// --- [toolbar] ---
|
|
925
|
-
const toolbar = this.context.get('toolbar.main');
|
|
926
|
-
// width
|
|
927
|
-
if (/inline|balloon/i.test(options.get('mode')) && newOptionKeys.includes('toolbar_width')) {
|
|
928
|
-
toolbar.style.width = options.get('toolbar_width');
|
|
929
|
-
}
|
|
930
|
-
// hide
|
|
931
|
-
if (options.get('toolbar_hide')) {
|
|
932
|
-
toolbar.style.display = 'none';
|
|
933
|
-
} else {
|
|
934
|
-
toolbar.style.display = '';
|
|
935
|
-
}
|
|
936
|
-
// shortcuts hint
|
|
937
|
-
if (options.get('shortcutsHint')) {
|
|
938
|
-
dom.utils.removeClass(toolbar, 'se-shortcut-hide');
|
|
939
|
-
} else {
|
|
940
|
-
dom.utils.addClass(toolbar, 'se-shortcut-hide');
|
|
941
|
-
}
|
|
942
|
-
|
|
943
|
-
this.effectNode = null;
|
|
944
|
-
this._setFrameInfo(this.frameRoots.get(this.status.rootKey));
|
|
945
|
-
},
|
|
70
|
+
}
|
|
946
71
|
|
|
947
72
|
/**
|
|
948
73
|
* @description Change the current root index.
|
|
949
|
-
* @
|
|
74
|
+
* @example
|
|
75
|
+
* // Switch to the 'body' frame in a multi-root editor
|
|
76
|
+
* editor.changeFrameContext('body');
|
|
77
|
+
*
|
|
78
|
+
* // Switch back to the 'header' frame
|
|
79
|
+
* editor.changeFrameContext('header');
|
|
80
|
+
* @param {*} rootKey Root frame key.
|
|
950
81
|
*/
|
|
951
82
|
changeFrameContext(rootKey) {
|
|
952
|
-
if (rootKey === this.
|
|
83
|
+
if (rootKey === this.$.store.get('rootKey')) return;
|
|
953
84
|
|
|
954
|
-
this.
|
|
955
|
-
this
|
|
956
|
-
this
|
|
957
|
-
}
|
|
85
|
+
this.$.store.set('rootKey', rootKey);
|
|
86
|
+
this.#setFrameInfo(this.$.frameRoots.get(rootKey));
|
|
87
|
+
this.$.toolbar._resetSticky();
|
|
88
|
+
}
|
|
958
89
|
|
|
959
90
|
/**
|
|
960
|
-
* @description
|
|
961
|
-
* @param {string} command javascript execCommand function property
|
|
962
|
-
* @param {boolean=} showDefaultUI javascript execCommand function property
|
|
963
|
-
* @param {string=} value javascript execCommand function property
|
|
91
|
+
* @description Destroy the suneditor
|
|
964
92
|
*/
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
this.
|
|
968
|
-
|
|
93
|
+
destroy() {
|
|
94
|
+
/** destroy external library */
|
|
95
|
+
if (this.$.options.get('hasCodeMirror')) {
|
|
96
|
+
this.$.contextProvider.applyToRoots((e) => {
|
|
97
|
+
const opts = e.get('options');
|
|
98
|
+
const cm6 = opts.get('codeMirror6Editor');
|
|
99
|
+
const cm5 = opts.get('codeMirror5Editor');
|
|
100
|
+
if (cm6) cm6.destroy();
|
|
101
|
+
else if (cm5) cm5.toTextArea();
|
|
102
|
+
});
|
|
103
|
+
}
|
|
969
104
|
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
focus(rootKey) {
|
|
975
|
-
if (rootKey) this.changeFrameContext(rootKey);
|
|
976
|
-
if (this.frameContext.get('wysiwygFrame').style.display === 'none') return;
|
|
977
|
-
this._preventBlur = false;
|
|
105
|
+
/** remove DOM elements */
|
|
106
|
+
dom.utils.removeItem(this.$.context.get('toolbar_wrapper'));
|
|
107
|
+
dom.utils.removeItem(this.$.context.get('toolbar_sub_wrapper'));
|
|
108
|
+
dom.utils.removeItem(this.$.context.get('statusbar_wrapper'));
|
|
978
109
|
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
try {
|
|
983
|
-
const range = this.selection.getRange();
|
|
984
|
-
if (range.startContainer === range.endContainer && dom.check.isWysiwygFrame(range.startContainer)) {
|
|
985
|
-
const currentNode = /** @type {HTMLElement} */ (range.commonAncestorContainer).children[range.startOffset];
|
|
986
|
-
if (!this.format.isLine(currentNode) && !this.component.is(currentNode)) {
|
|
987
|
-
const br = dom.utils.createElement('BR');
|
|
988
|
-
const format = dom.utils.createElement(this.options.get('defaultLine'), null, br);
|
|
989
|
-
this.frameContext.get('wysiwyg').insertBefore(format, currentNode);
|
|
990
|
-
this.selection.setRange(br, 0, br, 0);
|
|
991
|
-
return;
|
|
992
|
-
}
|
|
993
|
-
}
|
|
994
|
-
this.selection.setRange(range.startContainer, range.startOffset, range.endContainer, range.endOffset);
|
|
995
|
-
} catch (e) {
|
|
996
|
-
console.warn('[SUNEDITOR.focus.warn] ', e);
|
|
997
|
-
this._nativeFocus();
|
|
998
|
-
}
|
|
110
|
+
/** clear events */
|
|
111
|
+
for (const k in this.events) {
|
|
112
|
+
this.events[k] = null;
|
|
999
113
|
}
|
|
114
|
+
this.events = null;
|
|
1000
115
|
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
/**
|
|
1005
|
-
* @description If "focusEl" is a component, then that component is selected; if it is a format element, the last text is selected
|
|
1006
|
-
* - If "focusEdge" is null, then selected last element
|
|
1007
|
-
* @param {?Node=} focusEl Focus element
|
|
1008
|
-
*/
|
|
1009
|
-
focusEdge(focusEl) {
|
|
1010
|
-
this._preventBlur = false;
|
|
1011
|
-
if (!focusEl) focusEl = this.frameContext.get('wysiwyg').lastElementChild;
|
|
116
|
+
/** destroy kernel (handles all internal cleanup) */
|
|
117
|
+
this.#kernel._destroy();
|
|
1012
118
|
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
this.component.select(fileComponentInfo.target, fileComponentInfo.pluginName);
|
|
1016
|
-
} else if (focusEl) {
|
|
1017
|
-
if (focusEl.nodeType !== 3) {
|
|
1018
|
-
focusEl = dom.query.getEdgeChild(
|
|
1019
|
-
focusEl,
|
|
1020
|
-
function (current) {
|
|
1021
|
-
return current.childNodes.length === 0 || current.nodeType === 3;
|
|
1022
|
-
},
|
|
1023
|
-
true
|
|
1024
|
-
);
|
|
1025
|
-
}
|
|
1026
|
-
if (!focusEl) this._nativeFocus();
|
|
1027
|
-
else this.selection.setRange(focusEl, focusEl.textContent.length, focusEl, focusEl.textContent.length);
|
|
1028
|
-
} else {
|
|
1029
|
-
this.focus();
|
|
1030
|
-
}
|
|
1031
|
-
},
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
1032
121
|
|
|
1033
122
|
/**
|
|
1034
|
-
* @description
|
|
123
|
+
* @description Set frameContext, frameOptions
|
|
124
|
+
* @param {SunEditor.FrameContext} rt Root target[key] FrameContext
|
|
1035
125
|
*/
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
}
|
|
1042
|
-
},
|
|
126
|
+
#setFrameInfo(rt) {
|
|
127
|
+
this.$.contextProvider.reset(rt);
|
|
128
|
+
this.$.optionProvider.resetFrame(rt.get('options'));
|
|
129
|
+
this.$.ui.reset(rt);
|
|
130
|
+
}
|
|
1043
131
|
|
|
1044
132
|
/**
|
|
1045
|
-
* @description
|
|
133
|
+
* @description Initializ editor
|
|
134
|
+
* @param {SunEditor.InitOptions} options Options
|
|
1046
135
|
*/
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
this.
|
|
1050
|
-
|
|
1051
|
-
/** remove event listeners */
|
|
1052
|
-
this.eventManager._removeAllEvents();
|
|
136
|
+
#editorInit(options) {
|
|
137
|
+
this.$.store.set('initViewportHeight', env._w.visualViewport.height);
|
|
138
|
+
this.#kernel._eventOrchestrator.__setViewportSize();
|
|
1053
139
|
|
|
1054
|
-
|
|
1055
|
-
if (this.options.get('codeMirror6Editor')) {
|
|
1056
|
-
this.options.get('codeMirror6Editor').destroy();
|
|
1057
|
-
}
|
|
140
|
+
this.$.contextProvider.init();
|
|
1058
141
|
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
e.get('options').
|
|
1067
|
-
|
|
142
|
+
// initialize core and add event listeners
|
|
143
|
+
this.#setFrameInfo(this.$.frameRoots.get(this.$.store.get('rootKey')));
|
|
144
|
+
this.#init(options);
|
|
145
|
+
|
|
146
|
+
this.$.contextProvider.applyToRoots((e) => {
|
|
147
|
+
this.#kernel._eventOrchestrator._addFrameEvents(e);
|
|
148
|
+
this.#initWysiwygArea(e, e.get('options').get('value'));
|
|
149
|
+
if (e.get('options').get('iframe') && e.get('options').get('height') === 'auto') {
|
|
150
|
+
this.$.ui._emitResizeEvent(e, e.get('wysiwygFrame').offsetHeight, null);
|
|
151
|
+
}
|
|
1068
152
|
});
|
|
1069
153
|
|
|
1070
|
-
|
|
1071
|
-
this.
|
|
1072
|
-
this.
|
|
154
|
+
this.#kernel._eventOrchestrator.__eventDoc = null;
|
|
155
|
+
this.$.store._editorInitFinished = true;
|
|
156
|
+
this.$.pluginManager.checkFileInfo(true);
|
|
1073
157
|
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
const p = obj[k];
|
|
1077
|
-
if (typeof p._destroy === 'function') p._destroy();
|
|
1078
|
-
for (const pk in p) {
|
|
1079
|
-
delete p[pk];
|
|
1080
|
-
}
|
|
1081
|
-
delete obj[k];
|
|
1082
|
-
}
|
|
1083
|
-
obj = this.events;
|
|
1084
|
-
for (const k in obj) {
|
|
1085
|
-
delete obj[k];
|
|
1086
|
-
}
|
|
158
|
+
// history reset
|
|
159
|
+
this.$.history.reset();
|
|
1087
160
|
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
}
|
|
1095
|
-
obj = this.subToolbar;
|
|
1096
|
-
if (obj) {
|
|
1097
|
-
for (const k in obj) {
|
|
1098
|
-
delete obj[k];
|
|
161
|
+
// Defer post-init tasks (observers, history reset, plugin init, onload) to allow DOM to settle after iframe/wysiwyg insertion
|
|
162
|
+
env._w.setTimeout(() => {
|
|
163
|
+
// Check if instance was destroyed (e.g., in SSR with dynamic imports mistake)
|
|
164
|
+
if (!this.$.context?.size) {
|
|
165
|
+
console.warn('[SUNEDITOR:E_INIT_FAIL] Editor instance was destroyed before initialization completed. Check if destroy() was called.');
|
|
166
|
+
return;
|
|
1099
167
|
}
|
|
1100
|
-
}
|
|
1101
|
-
|
|
1102
|
-
obj = null;
|
|
1103
|
-
for (const k in this) {
|
|
1104
|
-
delete this[k];
|
|
1105
|
-
}
|
|
1106
|
-
|
|
1107
|
-
return null;
|
|
1108
|
-
},
|
|
1109
168
|
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
this._lineBreaker_t = rt.get('lineBreaker_t');
|
|
1121
|
-
this._lineBreaker_b = rt.get('lineBreaker_b');
|
|
1122
|
-
},
|
|
1123
|
-
|
|
1124
|
-
/**
|
|
1125
|
-
* @private
|
|
1126
|
-
* @description Focus to wysiwyg area using "native focus function"
|
|
1127
|
-
*/
|
|
1128
|
-
_nativeFocus() {
|
|
1129
|
-
this.selection.__focus();
|
|
1130
|
-
this.selection._init();
|
|
1131
|
-
},
|
|
169
|
+
// toolbar visibility
|
|
170
|
+
this.$.context.get('toolbar_main').style.visibility = '';
|
|
171
|
+
// roots
|
|
172
|
+
this.$.contextProvider.applyToRoots((e) => {
|
|
173
|
+
// observer
|
|
174
|
+
if (this.#kernel._eventOrchestrator._wwFrameObserver) this.#kernel._eventOrchestrator._wwFrameObserver.observe(e.get('wysiwygFrame'));
|
|
175
|
+
if (this.#kernel._eventOrchestrator._toolbarObserver) this.#kernel._eventOrchestrator._toolbarObserver.observe(e.get('_toolbarShadow'));
|
|
176
|
+
// resource state
|
|
177
|
+
this.$.ui._syncFrameState(e);
|
|
178
|
+
});
|
|
1132
179
|
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
for (let i = 0, len = this._fileInfoPluginsCheck.length; i < len; i++) {
|
|
1140
|
-
this._fileInfoPluginsCheck[i](loaded);
|
|
1141
|
-
}
|
|
1142
|
-
},
|
|
180
|
+
// plugin hook
|
|
181
|
+
for (const plugin of Object.values(this.$.plugins)) {
|
|
182
|
+
plugin.init?.();
|
|
183
|
+
}
|
|
184
|
+
// class init
|
|
185
|
+
this.$.selection.__init();
|
|
1143
186
|
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
_resetComponents() {
|
|
1149
|
-
for (let i = 0, len = this._fileInfoPluginsReset.length; i < len; i++) {
|
|
1150
|
-
this._fileInfoPluginsReset[i]();
|
|
1151
|
-
}
|
|
1152
|
-
},
|
|
187
|
+
// user event
|
|
188
|
+
this.$.eventManager.triggerEvent('onload', {});
|
|
189
|
+
}, 0);
|
|
190
|
+
}
|
|
1153
191
|
|
|
1154
192
|
/**
|
|
1155
|
-
* @private
|
|
1156
193
|
* @description Initializ wysiwyg area (Only called from core._init)
|
|
1157
|
-
* @param {
|
|
194
|
+
* @param {SunEditor.FrameContext} e frameContext
|
|
1158
195
|
* @param {string} value initial html string
|
|
1159
196
|
*/
|
|
1160
|
-
|
|
197
|
+
#initWysiwygArea(e, value) {
|
|
1161
198
|
// set content
|
|
1162
199
|
e.get('wysiwyg').innerHTML =
|
|
1163
|
-
this
|
|
200
|
+
this.$.html.clean(typeof value === 'string' ? value : (/^TEXTAREA$/i.test(e.get('originElement').nodeName) ? e.get('originElement').value : e.get('originElement').innerHTML) || '', {
|
|
1164
201
|
forceFormat: true,
|
|
1165
202
|
whitelist: null,
|
|
1166
203
|
blacklist: null,
|
|
1167
|
-
_freeCodeViewMode: this
|
|
1168
|
-
}) || '<' + this
|
|
204
|
+
_freeCodeViewMode: this.$.options.get('freeCodeViewMode'),
|
|
205
|
+
}) || '<' + this.$.options.get('defaultLine') + '><br></' + this.$.options.get('defaultLine') + '>';
|
|
1169
206
|
|
|
1170
207
|
// char counter
|
|
1171
|
-
if (e.has('charCounter')) e.get('charCounter').textContent = this
|
|
208
|
+
if (e.has('charCounter')) e.get('charCounter').textContent = String(this.$.char.getLength());
|
|
1172
209
|
|
|
1173
210
|
// document type init
|
|
1174
|
-
if (this
|
|
1175
|
-
e.set('documentType', new DocumentType(this, e));
|
|
211
|
+
if (this.$.options.get('type') === 'document') {
|
|
212
|
+
e.set('documentType', new DocumentType(this.#kernel, e));
|
|
1176
213
|
if (e.get('documentType').useHeader) {
|
|
1177
|
-
e.set('
|
|
214
|
+
e.set('documentType_use_header', true);
|
|
1178
215
|
}
|
|
1179
216
|
if (e.get('documentType').usePage) {
|
|
1180
|
-
e.set('
|
|
217
|
+
e.set('documentType_use_page', true);
|
|
1181
218
|
e.get('documentTypePageMirror').innerHTML = e.get('wysiwyg').innerHTML;
|
|
1182
219
|
}
|
|
1183
220
|
}
|
|
1184
|
-
}
|
|
1185
|
-
|
|
1186
|
-
/**
|
|
1187
|
-
* @private
|
|
1188
|
-
* @description Called when there are changes to tags in the wysiwyg region.
|
|
1189
|
-
* @param {__se__FrameContext} fc - Frame context object
|
|
1190
|
-
*/
|
|
1191
|
-
_resourcesStateChange(fc) {
|
|
1192
|
-
this._iframeAutoHeight(fc);
|
|
1193
|
-
this._checkPlaceholder(fc);
|
|
1194
|
-
if (this.options.get('type') === 'document' && fc.get('documentType').usePage) {
|
|
1195
|
-
fc.get('documentTypePageMirror').innerHTML = fc.get('wysiwyg').innerHTML;
|
|
1196
|
-
}
|
|
1197
|
-
},
|
|
1198
|
-
|
|
1199
|
-
/**
|
|
1200
|
-
* @private
|
|
1201
|
-
* @description Modify the height value of the iframe when the height of the iframe is automatic.
|
|
1202
|
-
* @param {__se__FrameContext} fc - Frame context object
|
|
1203
|
-
*/
|
|
1204
|
-
_iframeAutoHeight(fc) {
|
|
1205
|
-
const autoFrame = fc.get('_iframeAuto');
|
|
1206
|
-
|
|
1207
|
-
if (autoFrame) {
|
|
1208
|
-
this._w.setTimeout(() => {
|
|
1209
|
-
const h = autoFrame.offsetHeight;
|
|
1210
|
-
fc.get('wysiwygFrame').style.height = h + 'px';
|
|
1211
|
-
if (!env.isResizeObserverSupported) this.__callResizeFunction(fc, h, null);
|
|
1212
|
-
}, 0);
|
|
1213
|
-
} else if (!env.isResizeObserverSupported) {
|
|
1214
|
-
this.__callResizeFunction(fc, fc.get('wysiwygFrame').offsetHeight, null);
|
|
1215
|
-
}
|
|
1216
|
-
},
|
|
1217
|
-
|
|
1218
|
-
/**
|
|
1219
|
-
* @private
|
|
1220
|
-
* @description Call the "onResizeEditor" event
|
|
1221
|
-
* @param {__se__FrameContext} fc - Frame context object
|
|
1222
|
-
* @param {number} h - Height value
|
|
1223
|
-
* @param {ResizeObserverEntry} resizeObserverEntry - ResizeObserverEntry object
|
|
1224
|
-
*/
|
|
1225
|
-
__callResizeFunction(fc, h, resizeObserverEntry) {
|
|
1226
|
-
h =
|
|
1227
|
-
h === -1
|
|
1228
|
-
? resizeObserverEntry?.borderBoxSize && resizeObserverEntry.borderBoxSize[0]
|
|
1229
|
-
? resizeObserverEntry.borderBoxSize[0].blockSize
|
|
1230
|
-
: resizeObserverEntry.contentRect.height + numbers.get(fc.get('wwComputedStyle').getPropertyValue('padding-left')) + numbers.get(fc.get('wwComputedStyle').getPropertyValue('padding-right'))
|
|
1231
|
-
: h;
|
|
1232
|
-
if (fc.get('_editorHeight') !== h) {
|
|
1233
|
-
this.triggerEvent('onResizeEditor', { height: h, prevHeight: fc.get('_editorHeight'), frameContext: fc, observerEntry: resizeObserverEntry });
|
|
1234
|
-
fc.set('_editorHeight', h);
|
|
1235
|
-
}
|
|
1236
|
-
|
|
1237
|
-
// document type page
|
|
1238
|
-
if (fc.has('documentType-use-page')) {
|
|
1239
|
-
fc.get('documentType').resizePage();
|
|
1240
|
-
}
|
|
1241
|
-
},
|
|
1242
|
-
|
|
1243
|
-
/**
|
|
1244
|
-
* @private
|
|
1245
|
-
* @description Set display property when there is placeholder.
|
|
1246
|
-
* @param {?__se__FrameContext=} fc - Frame context object, If null fc is this.frameContext
|
|
1247
|
-
*/
|
|
1248
|
-
_checkPlaceholder(fc) {
|
|
1249
|
-
fc = fc || this.frameContext;
|
|
1250
|
-
const placeholder = fc.get('placeholder');
|
|
1251
|
-
|
|
1252
|
-
if (placeholder) {
|
|
1253
|
-
if (fc.get('isCodeView')) {
|
|
1254
|
-
placeholder.style.display = 'none';
|
|
1255
|
-
return;
|
|
1256
|
-
}
|
|
1257
|
-
|
|
1258
|
-
if (this.isEmpty(fc)) {
|
|
1259
|
-
placeholder.style.display = 'block';
|
|
1260
|
-
} else {
|
|
1261
|
-
placeholder.style.display = 'none';
|
|
1262
|
-
}
|
|
1263
|
-
}
|
|
1264
|
-
},
|
|
1265
|
-
|
|
1266
|
-
/**
|
|
1267
|
-
* @private
|
|
1268
|
-
* @description Initializ editor
|
|
1269
|
-
* @param {EditorInitOptions_editor} options Options
|
|
1270
|
-
*/
|
|
1271
|
-
__editorInit(options) {
|
|
1272
|
-
this.applyFrameRoots((e) => {
|
|
1273
|
-
this.__setEditorParams(e);
|
|
1274
|
-
});
|
|
1275
|
-
|
|
1276
|
-
// initialize core and add event listeners
|
|
1277
|
-
this._setFrameInfo(this.frameRoots.get(this.status.rootKey));
|
|
1278
|
-
this.__init(options);
|
|
1279
|
-
for (const v of this._onPluginEvents.values()) {
|
|
1280
|
-
v.sort((a, b) => a.index - b.index);
|
|
1281
|
-
}
|
|
1282
|
-
|
|
1283
|
-
this.applyFrameRoots((e) => {
|
|
1284
|
-
this.eventManager._addFrameEvents(e);
|
|
1285
|
-
this._initWysiwygArea(e, e.get('options').get('value'));
|
|
1286
|
-
});
|
|
1287
|
-
|
|
1288
|
-
this.eventManager.__eventDoc = null;
|
|
1289
|
-
this._componentsInfoInit = false;
|
|
1290
|
-
this._componentsInfoReset = false;
|
|
1291
|
-
this._checkComponents(true);
|
|
1292
|
-
|
|
1293
|
-
this._w.setTimeout(() => {
|
|
1294
|
-
// toolbar visibility
|
|
1295
|
-
this.context.get('toolbar.main').style.visibility = '';
|
|
1296
|
-
// roots
|
|
1297
|
-
this.applyFrameRoots((e) => {
|
|
1298
|
-
if (typeof this._resourcesStateChange !== 'function') return;
|
|
1299
|
-
// observer
|
|
1300
|
-
if (this.eventManager._wwFrameObserver) this.eventManager._wwFrameObserver.observe(e.get('wysiwygFrame'));
|
|
1301
|
-
if (this.eventManager._toolbarObserver) this.eventManager._toolbarObserver.observe(e.get('_toolbarShadow'));
|
|
1302
|
-
// resource state
|
|
1303
|
-
this._resourcesStateChange(e);
|
|
1304
|
-
});
|
|
1305
|
-
// history reset
|
|
1306
|
-
this.history.reset();
|
|
1307
|
-
// user event
|
|
1308
|
-
this.triggerEvent('onload', {});
|
|
1309
|
-
}, 0);
|
|
1310
|
-
},
|
|
221
|
+
}
|
|
1311
222
|
|
|
1312
223
|
/**
|
|
1313
|
-
* @private
|
|
1314
224
|
* @description Initializ core variable
|
|
1315
|
-
* @param {
|
|
225
|
+
* @param {SunEditor.InitOptions} options Options
|
|
1316
226
|
*/
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
this.
|
|
1320
|
-
this.
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
this._MELInfo = new Map();
|
|
1324
|
-
|
|
1325
|
-
// Command and file plugins registration
|
|
1326
|
-
this.activeCommands = ACTIVE_EVENT_COMMANDS;
|
|
1327
|
-
this._onPluginEvents = new Map([
|
|
1328
|
-
['onMouseMove', []],
|
|
1329
|
-
['onMouseLeave', []],
|
|
1330
|
-
['onMouseDown', []],
|
|
1331
|
-
['onMouseUp', []],
|
|
1332
|
-
['onScroll', []],
|
|
1333
|
-
['onClick', []],
|
|
1334
|
-
['onInput', []],
|
|
1335
|
-
['onKeyDown', []],
|
|
1336
|
-
['onKeyUp', []],
|
|
1337
|
-
['onFocus', []],
|
|
1338
|
-
['onBlur', []],
|
|
1339
|
-
['onPaste', []],
|
|
1340
|
-
['onFilePasteAndDrop', []]
|
|
1341
|
-
]);
|
|
1342
|
-
this._fileManager.tags = [];
|
|
1343
|
-
this._fileManager.pluginMap = {};
|
|
1344
|
-
this._fileManager.tagAttrs = {};
|
|
1345
|
-
|
|
1346
|
-
const plugins = this.plugins;
|
|
1347
|
-
const filePluginRegExp = [];
|
|
1348
|
-
let plugin;
|
|
1349
|
-
for (const key in plugins) {
|
|
1350
|
-
this.registerPlugin(key, this._pluginCallButtons[key], options[key]);
|
|
1351
|
-
this.registerPlugin(key, this._pluginCallButtons_sub[key], options[key]);
|
|
1352
|
-
plugin = this.plugins[key];
|
|
1353
|
-
|
|
1354
|
-
// Filemanager
|
|
1355
|
-
if (typeof plugin.__fileManagement === 'object') {
|
|
1356
|
-
const fm = plugin.__fileManagement;
|
|
1357
|
-
this._fileInfoPluginsCheck.push(fm._checkInfo.bind(fm));
|
|
1358
|
-
this._fileInfoPluginsReset.push(fm._resetInfo.bind(fm));
|
|
1359
|
-
if (Array.isArray(fm.tagNames)) {
|
|
1360
|
-
const tagNames = fm.tagNames;
|
|
1361
|
-
this._fileManager.tags = this._fileManager.tags.concat(tagNames);
|
|
1362
|
-
filePluginRegExp.push(key);
|
|
1363
|
-
for (let tag = 0, tLen = tagNames.length, t; tag < tLen; tag++) {
|
|
1364
|
-
t = tagNames[tag].toLowerCase();
|
|
1365
|
-
this._fileManager.pluginMap[t] = key;
|
|
1366
|
-
if (fm.tagAttrs) {
|
|
1367
|
-
this._fileManager.tagAttrs[t] = fm.tagAttrs;
|
|
1368
|
-
}
|
|
1369
|
-
}
|
|
1370
|
-
}
|
|
1371
|
-
}
|
|
1372
|
-
|
|
1373
|
-
// Not file component
|
|
1374
|
-
if (typeof plugin.constructor.component === 'function') {
|
|
1375
|
-
this._componentManager.push(
|
|
1376
|
-
function (launcher, element) {
|
|
1377
|
-
if (!element || !(element = launcher.component?.call(this, element))) return null;
|
|
1378
|
-
return {
|
|
1379
|
-
target: element,
|
|
1380
|
-
pluginName: launcher.key,
|
|
1381
|
-
options: launcher.options
|
|
1382
|
-
};
|
|
1383
|
-
}.bind(plugin, plugin.constructor)
|
|
1384
|
-
);
|
|
1385
|
-
}
|
|
1386
|
-
|
|
1387
|
-
// plugin event
|
|
1388
|
-
const pluginOptions = plugin.constructor.options || {};
|
|
1389
|
-
this._onPluginEvents.forEach((v, k) => {
|
|
1390
|
-
if (typeof plugin[k] === 'function') {
|
|
1391
|
-
const f = plugin[k].bind(plugin);
|
|
1392
|
-
f.index = pluginOptions[`eventIndex_${k}`] || pluginOptions.eventIndex || 0;
|
|
1393
|
-
v.push(f);
|
|
1394
|
-
}
|
|
1395
|
-
});
|
|
1396
|
-
|
|
1397
|
-
// plugin maintain
|
|
1398
|
-
if (plugin.retainFormat) {
|
|
1399
|
-
const info = plugin.retainFormat();
|
|
1400
|
-
this._MELInfo.set(info.query, info.method);
|
|
1401
|
-
}
|
|
1402
|
-
}
|
|
1403
|
-
|
|
1404
|
-
if (this.options.get('buttons').has('pageBreak') || this.options.get('buttons_sub')?.has('pageBreak')) {
|
|
1405
|
-
this._componentManager.push((element) => {
|
|
1406
|
-
if (!element || !dom.utils.hasClass(element, 'se-page-break')) return null;
|
|
1407
|
-
return {
|
|
1408
|
-
target: element,
|
|
1409
|
-
launcher: {
|
|
1410
|
-
destroy: (target) => {
|
|
1411
|
-
const focusEl = target.previousElementSibling || target.nextElementSibling;
|
|
1412
|
-
dom.utils.removeItem(target);
|
|
1413
|
-
// focus
|
|
1414
|
-
this.focusEdge(focusEl);
|
|
1415
|
-
this.history.push(false);
|
|
1416
|
-
}
|
|
1417
|
-
}
|
|
1418
|
-
};
|
|
1419
|
-
});
|
|
1420
|
-
}
|
|
1421
|
-
|
|
1422
|
-
this._fileManager.regExp = new RegExp(`^(${this._fileManager.tags.join('|') || '\\^'})$`, 'i');
|
|
1423
|
-
this._fileManager.pluginRegExp = new RegExp(`^(${filePluginRegExp.length === 0 ? '\\^' : filePluginRegExp.join('|')})$`, 'i');
|
|
1424
|
-
|
|
1425
|
-
delete this._pluginCallButtons;
|
|
1426
|
-
delete this._pluginCallButtons_sub;
|
|
1427
|
-
|
|
1428
|
-
this.__cachingButtons();
|
|
1429
|
-
this.__cachingShortcuts();
|
|
1430
|
-
},
|
|
1431
|
-
|
|
1432
|
-
/**
|
|
1433
|
-
* @private
|
|
1434
|
-
* @description Caching basic buttons to use
|
|
1435
|
-
*/
|
|
1436
|
-
__cachingButtons() {
|
|
1437
|
-
const ctx = this.context;
|
|
1438
|
-
this.__setDisabledButtons();
|
|
1439
|
-
this.__saveCommandButtons(this.allCommandButtons, ctx.get('toolbar.buttonTray'));
|
|
1440
|
-
if (this.options.has('_subMode')) {
|
|
1441
|
-
this.__saveCommandButtons(this.subAllCommandButtons, ctx.get('toolbar.sub.buttonTray'));
|
|
1442
|
-
}
|
|
1443
|
-
},
|
|
1444
|
-
|
|
1445
|
-
/**
|
|
1446
|
-
* @private
|
|
1447
|
-
* @description Set the disabled button list
|
|
1448
|
-
* - this._codeViewDisabledButtons, this._controllerOnDisabledButtons
|
|
1449
|
-
*/
|
|
1450
|
-
__setDisabledButtons() {
|
|
1451
|
-
const ctx = this.context;
|
|
1452
|
-
|
|
1453
|
-
this._codeViewDisabledButtons = converter.nodeListToArray(ctx.get('toolbar.buttonTray').querySelectorAll(DISABLE_BUTTONS_CODEVIEW));
|
|
1454
|
-
this._controllerOnDisabledButtons = converter.nodeListToArray(ctx.get('toolbar.buttonTray').querySelectorAll(DISABLE_BUTTONS_CONTROLLER));
|
|
1455
|
-
|
|
1456
|
-
if (this.options.has('_subMode')) {
|
|
1457
|
-
this._codeViewDisabledButtons = this._codeViewDisabledButtons.concat(converter.nodeListToArray(ctx.get('toolbar.sub.buttonTray').querySelectorAll(DISABLE_BUTTONS_CODEVIEW)));
|
|
1458
|
-
this._controllerOnDisabledButtons = this._controllerOnDisabledButtons.concat(converter.nodeListToArray(ctx.get('toolbar.sub.buttonTray').querySelectorAll(DISABLE_BUTTONS_CONTROLLER)));
|
|
1459
|
-
}
|
|
1460
|
-
},
|
|
1461
|
-
|
|
1462
|
-
/**
|
|
1463
|
-
* @private
|
|
1464
|
-
* @description Save the current buttons
|
|
1465
|
-
* @param {Map<string, Element>} cmdButtons Command button map
|
|
1466
|
-
* @param {Element} tray Button tray
|
|
1467
|
-
*/
|
|
1468
|
-
__saveCommandButtons(cmdButtons, tray) {
|
|
1469
|
-
const currentButtons = tray.querySelectorAll(COMMAND_BUTTONS);
|
|
1470
|
-
const shortcuts = this.options.get('shortcuts');
|
|
1471
|
-
const reverseCommandArray = this.options.get('_reverseCommandArray');
|
|
1472
|
-
const keyMap = this.shortcutsKeyMap;
|
|
1473
|
-
const reverseKeys = this.reverseKeys;
|
|
1474
|
-
|
|
1475
|
-
for (let i = 0, len = currentButtons.length, e, c; i < len; i++) {
|
|
1476
|
-
e = /** @type {HTMLButtonElement} */ (currentButtons[i]);
|
|
1477
|
-
c = e.getAttribute('data-command');
|
|
1478
|
-
// command set
|
|
1479
|
-
cmdButtons.set(c, e);
|
|
1480
|
-
this.__setCommandTargets(c, e);
|
|
1481
|
-
// shortcuts
|
|
1482
|
-
CreateShortcuts(c, e, shortcuts[c], keyMap, reverseCommandArray, reverseKeys);
|
|
1483
|
-
}
|
|
1484
|
-
},
|
|
1485
|
-
|
|
1486
|
-
/**
|
|
1487
|
-
* @private
|
|
1488
|
-
* @description Caches custom(starts with "_") shortcut keys for commands.
|
|
1489
|
-
*/
|
|
1490
|
-
__cachingShortcuts() {
|
|
1491
|
-
const shortcuts = this.options.get('shortcuts');
|
|
1492
|
-
const reverseCommandArray = this.options.get('_reverseCommandArray');
|
|
1493
|
-
const keyMap = this.shortcutsKeyMap;
|
|
1494
|
-
const reverseKeys = this.reverseKeys;
|
|
1495
|
-
for (const key of Object.keys(shortcuts)) {
|
|
1496
|
-
if (!key.startsWith('_')) continue;
|
|
1497
|
-
CreateShortcuts('', null, shortcuts[key], keyMap, reverseCommandArray, reverseKeys);
|
|
1498
|
-
}
|
|
1499
|
-
},
|
|
1500
|
-
|
|
1501
|
-
/**
|
|
1502
|
-
* @private
|
|
1503
|
-
* @description Sets command target elements.
|
|
1504
|
-
* @param {string} cmd - The command identifier.
|
|
1505
|
-
* @param {HTMLButtonElement} target - The associated command button.
|
|
1506
|
-
*/
|
|
1507
|
-
__setCommandTargets(cmd, target) {
|
|
1508
|
-
if (!cmd || !target) return;
|
|
1509
|
-
|
|
1510
|
-
const isBasicCmd = BASIC_COMMANDS.includes(cmd);
|
|
1511
|
-
if (!isBasicCmd && !this.plugins[cmd]) return;
|
|
1512
|
-
|
|
1513
|
-
if (!this.commandTargets.get(cmd)) {
|
|
1514
|
-
this.commandTargets.set(cmd, [target]);
|
|
1515
|
-
} else if (!this.commandTargets.get(cmd).includes(target)) {
|
|
1516
|
-
this.commandTargets.get(cmd).push(target);
|
|
1517
|
-
}
|
|
1518
|
-
},
|
|
227
|
+
#init(options) {
|
|
228
|
+
this.$.pluginManager.init(options);
|
|
229
|
+
this.$.shortcuts._registerCustomShortcuts();
|
|
230
|
+
this.$.commandDispatcher._initCommandButtons();
|
|
231
|
+
this.$.ui.init();
|
|
232
|
+
}
|
|
1519
233
|
|
|
1520
234
|
/**
|
|
1521
|
-
* @private
|
|
1522
235
|
* @description Configures the document properties of an iframe editor.
|
|
1523
236
|
* @param {HTMLIFrameElement} frame - The editor iframe.
|
|
1524
|
-
* @param {
|
|
1525
|
-
* @param {
|
|
237
|
+
* @param {SunEditor.Options} originOptions - The original options.
|
|
238
|
+
* @param {SunEditor.FrameOptions} targetOptions - The new options.
|
|
1526
239
|
*/
|
|
1527
|
-
|
|
1528
|
-
frame.
|
|
240
|
+
#setIframeDocument(frame, originOptions, targetOptions) {
|
|
241
|
+
frame.contentDocument.documentElement.className = 'sun-editor';
|
|
1529
242
|
frame.contentDocument.head.innerHTML =
|
|
1530
243
|
'<meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">' +
|
|
1531
244
|
converter._setIframeStyleLinks(targetOptions.get('iframe_cssFileName')) +
|
|
1532
245
|
converter._setAutoHeightStyle(targetOptions.get('height'));
|
|
1533
246
|
frame.contentDocument.body.className = originOptions.get('_editableClass');
|
|
1534
247
|
frame.contentDocument.body.setAttribute('contenteditable', 'true');
|
|
1535
|
-
}
|
|
1536
|
-
|
|
1537
|
-
/**
|
|
1538
|
-
* @private
|
|
1539
|
-
* @description Set the FrameContext parameters and options
|
|
1540
|
-
* @param {__se__FrameContext} e - Frame context object
|
|
1541
|
-
*/
|
|
1542
|
-
__setEditorParams(e) {
|
|
1543
|
-
const frameOptions = e.get('options');
|
|
1544
|
-
const _w = this._w;
|
|
1545
|
-
|
|
1546
|
-
e.set('wwComputedStyle', _w.getComputedStyle(e.get('wysiwyg')));
|
|
1547
|
-
|
|
1548
|
-
if (!frameOptions.get('iframe') && typeof ShadowRoot === 'function') {
|
|
1549
|
-
let child = e.get('wysiwygFrame');
|
|
1550
|
-
while (child) {
|
|
1551
|
-
if (child.shadowRoot) {
|
|
1552
|
-
this._shadowRoot = child.shadowRoot;
|
|
1553
|
-
break;
|
|
1554
|
-
} else if (child instanceof ShadowRoot) {
|
|
1555
|
-
this._shadowRoot = child;
|
|
1556
|
-
break;
|
|
1557
|
-
}
|
|
1558
|
-
child = child.parentNode;
|
|
1559
|
-
}
|
|
1560
|
-
}
|
|
1561
|
-
|
|
1562
|
-
// wisywig attributes
|
|
1563
|
-
const attr = frameOptions.get('editableFrameAttributes');
|
|
1564
|
-
for (const k in attr) {
|
|
1565
|
-
e.get('wysiwyg').setAttribute(k, attr[k]);
|
|
1566
|
-
}
|
|
1567
|
-
|
|
1568
|
-
// init, validate
|
|
1569
|
-
if (frameOptions.get('iframe')) {
|
|
1570
|
-
e.set('_ww', e.get('wysiwygFrame').contentWindow);
|
|
1571
|
-
e.set('_wd', e.get('wysiwygFrame').contentDocument);
|
|
1572
|
-
e.set('wysiwyg', e.get('_wd').body);
|
|
1573
|
-
// e.get('wysiwyg').className += ' ' + options.get('_editableClass');
|
|
1574
|
-
if (frameOptions.get('_defaultStyles').editor) e.get('wysiwyg').style.cssText = frameOptions.get('_defaultStyles').editor;
|
|
1575
|
-
if (frameOptions.get('height') === 'auto') e.set('_iframeAuto', e.get('_wd').body);
|
|
1576
|
-
} else {
|
|
1577
|
-
e.set('_ww', _w);
|
|
1578
|
-
e.set('_wd', this._d);
|
|
1579
|
-
}
|
|
1580
|
-
},
|
|
1581
|
-
|
|
1582
|
-
/**
|
|
1583
|
-
* @private
|
|
1584
|
-
* @description Registers and initializes editor classes.
|
|
1585
|
-
*/
|
|
1586
|
-
__registerClass() {
|
|
1587
|
-
// use events
|
|
1588
|
-
this.events = { ...Events, ...this.options.get('events') };
|
|
1589
|
-
this.triggerEvent = async (eventName, eventData) => {
|
|
1590
|
-
// [iframe] wysiwyg is disabled, the event is not called.
|
|
1591
|
-
if (eventData?.frameContext?.get('wysiwyg').getAttribute('contenteditable') === 'false') return false;
|
|
1592
|
-
const eventHandler = this.events[eventName];
|
|
1593
|
-
if (typeof eventHandler === 'function') {
|
|
1594
|
-
return await eventHandler({ editor: this, ...eventData });
|
|
1595
|
-
}
|
|
1596
|
-
return env.NO_EVENT;
|
|
1597
|
-
};
|
|
1598
|
-
|
|
1599
|
-
// history function
|
|
1600
|
-
this.history = History(this);
|
|
1601
|
-
|
|
1602
|
-
// eventManager
|
|
1603
|
-
this.eventManager = new EventManager(this);
|
|
1604
|
-
|
|
1605
|
-
// util classes
|
|
1606
|
-
this.offset = new Offset(this);
|
|
1607
|
-
this.shortcuts = new Shortcuts(this);
|
|
1608
|
-
// main classes
|
|
1609
|
-
this.toolbar = new Toolbar(this, { keyName: 'toolbar', balloon: this.isBalloon, balloonAlways: this.isBalloonAlways, inline: this.isInline, res: this._responsiveButtons });
|
|
1610
|
-
if (this.options.has('_subMode')) {
|
|
1611
|
-
this.subToolbar = new Toolbar(this, {
|
|
1612
|
-
keyName: 'toolbar.sub',
|
|
1613
|
-
balloon: this.isSubBalloon,
|
|
1614
|
-
balloonAlways: this.isSubBalloonAlways,
|
|
1615
|
-
inline: false,
|
|
1616
|
-
res: this._responsiveButtons_sub
|
|
1617
|
-
});
|
|
1618
|
-
}
|
|
1619
|
-
this.selection = new Selection_(this);
|
|
1620
|
-
this.html = new HTML(this);
|
|
1621
|
-
this.nodeTransform = new NodeTransform(this);
|
|
1622
|
-
this.component = new Component(this);
|
|
1623
|
-
this.format = new Format(this);
|
|
1624
|
-
this.menu = new Menu(this);
|
|
1625
|
-
this.char = new Char(this);
|
|
1626
|
-
this.ui = new UI(this);
|
|
1627
|
-
this.viewer = new Viewer(this);
|
|
1628
|
-
|
|
1629
|
-
// register classes to the eventManager
|
|
1630
|
-
ClassInjector.call(this.eventManager, this);
|
|
1631
|
-
// register main classes
|
|
1632
|
-
ClassInjector.call(this.char, this);
|
|
1633
|
-
ClassInjector.call(this.component, this);
|
|
1634
|
-
ClassInjector.call(this.format, this);
|
|
1635
|
-
ClassInjector.call(this.html, this);
|
|
1636
|
-
ClassInjector.call(this.menu, this);
|
|
1637
|
-
ClassInjector.call(this.nodeTransform, this);
|
|
1638
|
-
ClassInjector.call(this.offset, this);
|
|
1639
|
-
ClassInjector.call(this.selection, this);
|
|
1640
|
-
ClassInjector.call(this.shortcuts, this);
|
|
1641
|
-
ClassInjector.call(this.toolbar, this);
|
|
1642
|
-
ClassInjector.call(this.ui, this);
|
|
1643
|
-
ClassInjector.call(this.viewer, this);
|
|
1644
|
-
if (this.options.has('_subMode')) ClassInjector.call(this.subToolbar, this);
|
|
1645
|
-
|
|
1646
|
-
// delete self reference
|
|
1647
|
-
delete this.eventManager['eventManager'];
|
|
1648
|
-
delete this.char['char'];
|
|
1649
|
-
delete this.component['component'];
|
|
1650
|
-
delete this.format['format'];
|
|
1651
|
-
delete this.html['html'];
|
|
1652
|
-
delete this.menu['menu'];
|
|
1653
|
-
delete this.nodeTransform['nodeTransform'];
|
|
1654
|
-
delete this.offset['offset'];
|
|
1655
|
-
delete this.selection['selection'];
|
|
1656
|
-
delete this.shortcuts['shortcuts'];
|
|
1657
|
-
delete this.toolbar['toolbar'];
|
|
1658
|
-
delete this.ui['ui'];
|
|
1659
|
-
delete this.viewer['viewer'];
|
|
1660
|
-
if (this.subToolbar) delete this.subToolbar['subToolbar'];
|
|
1661
|
-
|
|
1662
|
-
this._responsiveButtons = this._responsiveButtons_sub = null;
|
|
1663
|
-
},
|
|
248
|
+
}
|
|
1664
249
|
|
|
1665
250
|
/**
|
|
1666
|
-
* @private
|
|
1667
251
|
* @description Creates the editor instance and initializes components.
|
|
1668
|
-
* @param {
|
|
252
|
+
* @param {SunEditor.InitOptions} originOptions - The initial editor options.
|
|
1669
253
|
* @returns {Promise<void>}
|
|
1670
254
|
*/
|
|
1671
|
-
async
|
|
1672
|
-
// set modes
|
|
1673
|
-
this.isInline = /inline/i.test(this.options.get('mode'));
|
|
1674
|
-
this.isBalloon = /balloon/i.test(this.options.get('mode'));
|
|
1675
|
-
this.isBalloonAlways = /balloon-always/i.test(this.options.get('mode'));
|
|
1676
|
-
this.isClassic = /classic/i.test(this.options.get('mode'));
|
|
1677
|
-
// set subToolbar modes
|
|
1678
|
-
this.isSubBalloon = /balloon/i.test(this.options.get('_subMode'));
|
|
1679
|
-
this.isSubBalloonAlways = /balloon-always/i.test(this.options.get('_subMode'));
|
|
1680
|
-
|
|
1681
|
-
// register class
|
|
1682
|
-
this.__registerClass();
|
|
1683
|
-
|
|
255
|
+
async #Create(originOptions) {
|
|
1684
256
|
// common events
|
|
1685
|
-
this.
|
|
257
|
+
this.#kernel._eventOrchestrator._addCommonEvents();
|
|
1686
258
|
|
|
1687
259
|
// init
|
|
1688
260
|
const iframePromises = [];
|
|
1689
|
-
this.
|
|
261
|
+
this.$.contextProvider.applyToRoots((e) => {
|
|
1690
262
|
const o = e.get('originElement');
|
|
1691
263
|
const t = e.get('topArea');
|
|
1692
264
|
o.style.display = 'none';
|
|
@@ -1695,8 +267,8 @@ Editor.prototype = {
|
|
|
1695
267
|
|
|
1696
268
|
if (e.get('options').get('iframe')) {
|
|
1697
269
|
const iframeLoaded = new Promise((resolve) => {
|
|
1698
|
-
this
|
|
1699
|
-
this
|
|
270
|
+
this.$.eventManager.addEvent(e.get('wysiwygFrame'), 'load', ({ target }) => {
|
|
271
|
+
this.#setIframeDocument(/** @type{HTMLIFrameElement} */ (target), this.$.optionProvider.options, e.get('options'));
|
|
1700
272
|
resolve();
|
|
1701
273
|
});
|
|
1702
274
|
});
|
|
@@ -1704,16 +276,16 @@ Editor.prototype = {
|
|
|
1704
276
|
}
|
|
1705
277
|
});
|
|
1706
278
|
|
|
1707
|
-
this.
|
|
279
|
+
this.$.contextProvider.applyToRoots((e) => {
|
|
1708
280
|
e.get('wrapper').appendChild(e.get('wysiwygFrame'));
|
|
1709
281
|
|
|
1710
282
|
// document type
|
|
1711
283
|
if (e.get('documentTypeInner')) {
|
|
1712
|
-
if (this
|
|
284
|
+
if (this.$.options.get('_rtl')) e.get('wrapper').appendChild(e.get('documentTypeInner'));
|
|
1713
285
|
else e.get('wrapper').insertBefore(e.get('documentTypeInner'), e.get('wysiwygFrame'));
|
|
1714
286
|
}
|
|
1715
287
|
if (e.get('documentTypePage')) {
|
|
1716
|
-
if (this
|
|
288
|
+
if (this.$.options.get('_rtl')) e.get('wrapper').insertBefore(e.get('documentTypePage'), e.get('wysiwygFrame'));
|
|
1717
289
|
else e.get('wrapper').appendChild(e.get('documentTypePage'));
|
|
1718
290
|
// page mirror
|
|
1719
291
|
e.get('wrapper').appendChild(e.get('documentTypePageMirror'));
|
|
@@ -1724,50 +296,7 @@ Editor.prototype = {
|
|
|
1724
296
|
await Promise.all(iframePromises);
|
|
1725
297
|
}
|
|
1726
298
|
|
|
1727
|
-
this
|
|
1728
|
-
},
|
|
1729
|
-
|
|
1730
|
-
Constructor: Editor
|
|
1731
|
-
};
|
|
1732
|
-
|
|
1733
|
-
function RestoreFrameOptions(key, option, frameRoots, rootDiff, newRootKeys, newRoots) {
|
|
1734
|
-
const nro = option[key];
|
|
1735
|
-
const newKeys = Object.keys(nro);
|
|
1736
|
-
CheckResetKeys(newKeys, null, key + '.');
|
|
1737
|
-
if (newKeys.length === 0) return false;
|
|
1738
|
-
|
|
1739
|
-
const rootKey = key || null;
|
|
1740
|
-
rootDiff.set(rootKey, new Map());
|
|
1741
|
-
|
|
1742
|
-
const o = frameRoots.get(rootKey).get('options').get('_origin');
|
|
1743
|
-
const no = {};
|
|
1744
|
-
const hasOwn = Object.prototype.hasOwnProperty;
|
|
1745
|
-
for (const rk in nro) {
|
|
1746
|
-
if (!hasOwn.call(OPTION_FRAME_FIXED_FLAG, rk)) continue;
|
|
1747
|
-
const roV = nro[rk];
|
|
1748
|
-
if (!newKeys.includes(rk) || o[rk] === roV) continue;
|
|
1749
|
-
rootDiff.get(rootKey).set(GetResetDiffKey(rk), true);
|
|
1750
|
-
no[rk] = roV;
|
|
1751
|
-
}
|
|
1752
|
-
|
|
1753
|
-
const newO = { ...o, ...no };
|
|
1754
|
-
newRootKeys.set(rootKey, new Map(Object.entries(newO)));
|
|
1755
|
-
newRoots.push({ key: rootKey, options: newO });
|
|
1756
|
-
}
|
|
1757
|
-
|
|
1758
|
-
function GetResetDiffKey(key) {
|
|
1759
|
-
if (/^statusbar|^charCounter/.test(key)) return 'statusbar-changed';
|
|
1760
|
-
return key;
|
|
1761
|
-
}
|
|
1762
|
-
|
|
1763
|
-
function CheckResetKeys(keys, plugins, root) {
|
|
1764
|
-
for (let i = 0, len = keys.length, k; i < len; i++) {
|
|
1765
|
-
k = keys[i];
|
|
1766
|
-
if (OPTION_FIXED_FLAG[k] === 'fixed' || OPTION_FRAME_FIXED_FLAG[k] === 'fixed' || (plugins && plugins[k])) {
|
|
1767
|
-
console.warn(`[SUNEDITOR.warn.resetOptions] The "[${root + k}]" option cannot be changed after the editor is created.`);
|
|
1768
|
-
keys.splice(i--, 1);
|
|
1769
|
-
len--;
|
|
1770
|
-
}
|
|
299
|
+
this.#editorInit(originOptions);
|
|
1771
300
|
}
|
|
1772
301
|
}
|
|
1773
302
|
|