suneditor 3.0.0-beta.3 → 3.0.0-beta.30

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.
Files changed (241) hide show
  1. package/CONTRIBUTING.md +8 -8
  2. package/README.md +44 -49
  3. package/dist/suneditor.min.css +1 -1
  4. package/dist/suneditor.min.js +1 -1
  5. package/package.json +95 -53
  6. package/src/assets/design/color.css +2 -2
  7. package/src/assets/design/size.css +2 -0
  8. package/src/assets/icons/defaultIcons.js +16 -1
  9. package/src/assets/suneditor-contents.css +9 -8
  10. package/src/assets/suneditor.css +29 -26
  11. package/src/core/{section → base}/actives.js +20 -12
  12. package/src/core/base/history.js +4 -4
  13. package/src/core/class/char.js +10 -10
  14. package/src/core/class/component.js +146 -57
  15. package/src/core/class/format.js +94 -2458
  16. package/src/core/class/html.js +187 -129
  17. package/src/core/class/inline.js +1853 -0
  18. package/src/core/class/listFormat.js +582 -0
  19. package/src/core/class/menu.js +14 -3
  20. package/src/core/class/nodeTransform.js +9 -14
  21. package/src/core/class/offset.js +162 -197
  22. package/src/core/class/selection.js +137 -34
  23. package/src/core/class/toolbar.js +73 -52
  24. package/src/core/class/ui.js +11 -11
  25. package/src/core/class/viewer.js +56 -55
  26. package/src/core/config/context.js +122 -0
  27. package/src/core/config/frameContext.js +204 -0
  28. package/src/core/config/options.js +639 -0
  29. package/src/core/editor.js +181 -108
  30. package/src/core/event/actions/index.js +229 -0
  31. package/src/core/event/effects/common.registry.js +60 -0
  32. package/src/core/event/effects/keydown.registry.js +551 -0
  33. package/src/core/event/effects/ruleHelpers.js +145 -0
  34. package/src/core/{base → event}/eventManager.js +119 -201
  35. package/src/core/event/executor.js +21 -0
  36. package/src/core/{base/eventHandlers → event/handlers}/handler_toolbar.js +4 -4
  37. package/src/core/{base/eventHandlers → event/handlers}/handler_ww_dragDrop.js +2 -2
  38. package/src/core/event/handlers/handler_ww_input.js +77 -0
  39. package/src/core/event/handlers/handler_ww_key.js +228 -0
  40. package/src/core/{base/eventHandlers → event/handlers}/handler_ww_mouse.js +3 -3
  41. package/src/core/event/ports.js +211 -0
  42. package/src/core/event/reducers/keydown.reducer.js +89 -0
  43. package/src/core/event/rules/keydown.rule.arrow.js +54 -0
  44. package/src/core/event/rules/keydown.rule.backspace.js +202 -0
  45. package/src/core/event/rules/keydown.rule.delete.js +126 -0
  46. package/src/core/event/rules/keydown.rule.enter.js +144 -0
  47. package/src/core/event/rules/keydown.rule.tab.js +29 -0
  48. package/src/core/section/constructor.js +79 -388
  49. package/src/core/section/documentType.js +47 -26
  50. package/src/core/util/instanceCheck.js +59 -0
  51. package/src/editorInjector/_classes.js +4 -0
  52. package/src/editorInjector/_core.js +17 -7
  53. package/src/editorInjector/index.js +10 -2
  54. package/src/events.js +6 -0
  55. package/src/helper/clipboard.js +24 -10
  56. package/src/helper/converter.js +17 -12
  57. package/src/helper/dom/domCheck.js +22 -3
  58. package/src/helper/dom/domQuery.js +91 -45
  59. package/src/helper/dom/domUtils.js +93 -19
  60. package/src/helper/dom/index.js +4 -0
  61. package/src/helper/env.js +11 -7
  62. package/src/helper/keyCodeMap.js +4 -3
  63. package/src/langs/ckb.js +1 -1
  64. package/src/langs/cs.js +1 -1
  65. package/src/langs/da.js +1 -1
  66. package/src/langs/de.js +1 -1
  67. package/src/langs/en.js +1 -1
  68. package/src/langs/es.js +1 -1
  69. package/src/langs/fa.js +1 -1
  70. package/src/langs/fr.js +1 -1
  71. package/src/langs/he.js +1 -1
  72. package/src/langs/hu.js +1 -1
  73. package/src/langs/it.js +1 -1
  74. package/src/langs/ja.js +1 -1
  75. package/src/langs/km.js +1 -1
  76. package/src/langs/ko.js +1 -1
  77. package/src/langs/lv.js +1 -1
  78. package/src/langs/nl.js +1 -1
  79. package/src/langs/pl.js +1 -1
  80. package/src/langs/pt_br.js +10 -10
  81. package/src/langs/ro.js +1 -1
  82. package/src/langs/ru.js +1 -1
  83. package/src/langs/se.js +1 -1
  84. package/src/langs/tr.js +1 -1
  85. package/src/langs/uk.js +1 -1
  86. package/src/langs/ur.js +1 -1
  87. package/src/langs/zh_cn.js +1 -1
  88. package/src/modules/ApiManager.js +25 -18
  89. package/src/modules/Browser.js +52 -61
  90. package/src/modules/ColorPicker.js +37 -38
  91. package/src/modules/Controller.js +85 -79
  92. package/src/modules/Figure.js +275 -187
  93. package/src/modules/FileManager.js +86 -92
  94. package/src/modules/HueSlider.js +67 -35
  95. package/src/modules/Modal.js +84 -77
  96. package/src/modules/ModalAnchorEditor.js +62 -79
  97. package/src/modules/SelectMenu.js +89 -86
  98. package/src/plugins/browser/audioGallery.js +9 -5
  99. package/src/plugins/browser/fileBrowser.js +10 -6
  100. package/src/plugins/browser/fileGallery.js +9 -5
  101. package/src/plugins/browser/imageGallery.js +9 -5
  102. package/src/plugins/browser/videoGallery.js +11 -6
  103. package/src/plugins/command/blockquote.js +1 -0
  104. package/src/plugins/command/exportPDF.js +11 -8
  105. package/src/plugins/command/fileUpload.js +41 -29
  106. package/src/plugins/command/list_bulleted.js +2 -1
  107. package/src/plugins/command/list_numbered.js +2 -1
  108. package/src/plugins/dropdown/align.js +8 -2
  109. package/src/plugins/dropdown/backgroundColor.js +19 -11
  110. package/src/plugins/dropdown/font.js +15 -9
  111. package/src/plugins/dropdown/fontColor.js +19 -11
  112. package/src/plugins/dropdown/formatBlock.js +7 -2
  113. package/src/plugins/dropdown/hr.js +7 -3
  114. package/src/plugins/dropdown/layout.js +6 -2
  115. package/src/plugins/dropdown/lineHeight.js +8 -3
  116. package/src/plugins/dropdown/list.js +2 -1
  117. package/src/plugins/dropdown/paragraphStyle.js +15 -11
  118. package/src/plugins/dropdown/{table.js → table/index.js} +514 -362
  119. package/src/plugins/dropdown/template.js +6 -2
  120. package/src/plugins/dropdown/textStyle.js +7 -3
  121. package/src/plugins/field/mention.js +33 -27
  122. package/src/plugins/input/fontSize.js +44 -37
  123. package/src/plugins/input/pageNavigator.js +3 -2
  124. package/src/plugins/modal/audio.js +90 -85
  125. package/src/plugins/modal/drawing.js +58 -66
  126. package/src/plugins/modal/embed.js +193 -180
  127. package/src/plugins/modal/image.js +441 -439
  128. package/src/plugins/modal/link.js +31 -8
  129. package/src/plugins/modal/math.js +23 -22
  130. package/src/plugins/modal/video.js +233 -230
  131. package/src/plugins/popup/anchor.js +24 -18
  132. package/src/suneditor.js +69 -24
  133. package/src/typedef.js +42 -19
  134. package/types/assets/icons/defaultIcons.d.ts +8 -0
  135. package/types/core/class/char.d.ts +1 -1
  136. package/types/core/class/component.d.ts +29 -7
  137. package/types/core/class/format.d.ts +4 -354
  138. package/types/core/class/html.d.ts +13 -4
  139. package/types/core/class/inline.d.ts +263 -0
  140. package/types/core/class/listFormat.d.ts +135 -0
  141. package/types/core/class/menu.d.ts +10 -2
  142. package/types/core/class/offset.d.ts +24 -26
  143. package/types/core/class/selection.d.ts +2 -0
  144. package/types/core/class/toolbar.d.ts +24 -11
  145. package/types/core/class/ui.d.ts +1 -1
  146. package/types/core/class/viewer.d.ts +1 -1
  147. package/types/core/config/context.d.ts +157 -0
  148. package/types/core/config/frameContext.d.ts +367 -0
  149. package/types/core/config/options.d.ts +1119 -0
  150. package/types/core/editor.d.ts +101 -66
  151. package/types/core/event/actions/index.d.ts +47 -0
  152. package/types/core/event/effects/common.registry.d.ts +50 -0
  153. package/types/core/event/effects/keydown.registry.d.ts +73 -0
  154. package/types/core/event/effects/ruleHelpers.d.ts +31 -0
  155. package/types/core/{base → event}/eventManager.d.ts +15 -46
  156. package/types/core/event/executor.d.ts +6 -0
  157. package/types/core/event/handlers/handler_ww_input.d.ts +41 -0
  158. package/types/core/{base/eventHandlers/handler_ww_key_input.d.ts → event/handlers/handler_ww_key.d.ts} +4 -6
  159. package/types/core/event/ports.d.ts +255 -0
  160. package/types/core/event/reducers/keydown.reducer.d.ts +75 -0
  161. package/types/core/event/rules/keydown.rule.arrow.d.ts +8 -0
  162. package/types/core/event/rules/keydown.rule.backspace.d.ts +9 -0
  163. package/types/core/event/rules/keydown.rule.delete.d.ts +9 -0
  164. package/types/core/event/rules/keydown.rule.enter.d.ts +9 -0
  165. package/types/core/event/rules/keydown.rule.tab.d.ts +9 -0
  166. package/types/core/section/constructor.d.ts +101 -631
  167. package/types/core/section/documentType.d.ts +14 -4
  168. package/types/core/util/instanceCheck.d.ts +50 -0
  169. package/types/editorInjector/_classes.d.ts +4 -0
  170. package/types/editorInjector/_core.d.ts +17 -7
  171. package/types/editorInjector/index.d.ts +10 -2
  172. package/types/events.d.ts +1 -0
  173. package/types/helper/clipboard.d.ts +2 -2
  174. package/types/helper/converter.d.ts +6 -9
  175. package/types/helper/dom/domCheck.d.ts +7 -0
  176. package/types/helper/dom/domQuery.d.ts +19 -8
  177. package/types/helper/dom/domUtils.d.ts +24 -2
  178. package/types/helper/dom/index.d.ts +86 -1
  179. package/types/helper/env.d.ts +6 -1
  180. package/types/helper/index.d.ts +7 -1
  181. package/types/helper/keyCodeMap.d.ts +3 -3
  182. package/types/index.d.ts +23 -117
  183. package/types/langs/index.d.ts +2 -2
  184. package/types/modules/ApiManager.d.ts +1 -8
  185. package/types/modules/Browser.d.ts +4 -62
  186. package/types/modules/ColorPicker.d.ts +4 -21
  187. package/types/modules/Controller.d.ts +8 -64
  188. package/types/modules/Figure.d.ts +54 -50
  189. package/types/modules/FileManager.d.ts +1 -13
  190. package/types/modules/HueSlider.d.ts +13 -3
  191. package/types/modules/Modal.d.ts +0 -43
  192. package/types/modules/ModalAnchorEditor.d.ts +0 -73
  193. package/types/modules/SelectMenu.d.ts +0 -85
  194. package/types/modules/index.d.ts +3 -3
  195. package/types/plugins/browser/audioGallery.d.ts +29 -18
  196. package/types/plugins/browser/fileBrowser.d.ts +38 -27
  197. package/types/plugins/browser/fileGallery.d.ts +29 -18
  198. package/types/plugins/browser/imageGallery.d.ts +24 -16
  199. package/types/plugins/browser/videoGallery.d.ts +29 -18
  200. package/types/plugins/command/blockquote.d.ts +1 -0
  201. package/types/plugins/command/exportPDF.d.ts +18 -18
  202. package/types/plugins/command/fileUpload.d.ts +65 -45
  203. package/types/plugins/command/list_bulleted.d.ts +1 -0
  204. package/types/plugins/command/list_numbered.d.ts +1 -0
  205. package/types/plugins/dropdown/align.d.ts +13 -8
  206. package/types/plugins/dropdown/backgroundColor.d.ts +30 -19
  207. package/types/plugins/dropdown/font.d.ts +13 -12
  208. package/types/plugins/dropdown/fontColor.d.ts +30 -19
  209. package/types/plugins/dropdown/formatBlock.d.ts +13 -8
  210. package/types/plugins/dropdown/hr.d.ts +15 -11
  211. package/types/plugins/dropdown/layout.d.ts +15 -11
  212. package/types/plugins/dropdown/lineHeight.d.ts +16 -11
  213. package/types/plugins/dropdown/list.d.ts +1 -0
  214. package/types/plugins/dropdown/paragraphStyle.d.ts +31 -27
  215. package/types/plugins/dropdown/table/index.d.ts +582 -0
  216. package/types/plugins/dropdown/table.d.ts +41 -86
  217. package/types/plugins/dropdown/template.d.ts +15 -11
  218. package/types/plugins/dropdown/textStyle.d.ts +19 -11
  219. package/types/plugins/field/mention.d.ts +58 -56
  220. package/types/plugins/index.d.ts +38 -38
  221. package/types/plugins/input/fontSize.d.ts +46 -50
  222. package/types/plugins/modal/audio.d.ts +26 -56
  223. package/types/plugins/modal/drawing.d.ts +0 -85
  224. package/types/plugins/modal/embed.d.ts +15 -79
  225. package/types/plugins/modal/image.d.ts +24 -136
  226. package/types/plugins/modal/link.d.ts +34 -15
  227. package/types/plugins/modal/math.d.ts +0 -16
  228. package/types/plugins/modal/video.d.ts +17 -86
  229. package/types/plugins/popup/anchor.d.ts +1 -8
  230. package/types/suneditor.d.ts +70 -19
  231. package/types/typedef.d.ts +60 -46
  232. package/src/core/base/eventHandlers/handler_ww_key_input.js +0 -1200
  233. package/src/core/section/context.js +0 -102
  234. package/types/core/section/context.d.ts +0 -45
  235. package/types/langs/_Lang.d.ts +0 -194
  236. /package/src/core/{base/eventHandlers → event/handlers}/handler_ww_clipboard.js +0 -0
  237. /package/types/core/{section → base}/actives.d.ts +0 -0
  238. /package/types/core/{base/eventHandlers → event/handlers}/handler_toolbar.d.ts +0 -0
  239. /package/types/core/{base/eventHandlers → event/handlers}/handler_ww_clipboard.d.ts +0 -0
  240. /package/types/core/{base/eventHandlers → event/handlers}/handler_ww_dragDrop.d.ts +0 -0
  241. /package/types/core/{base/eventHandlers → event/handlers}/handler_ww_mouse.d.ts +0 -0
@@ -0,0 +1,89 @@
1
+ import { env, dom, keyCodeMap } from '../../../helper';
2
+
3
+ import { reduceBackspaceDown } from '../rules/keydown.rule.backspace';
4
+ import { reduceDeleteDown } from '../rules/keydown.rule.delete';
5
+ import { reduceEnterDown } from '../rules/keydown.rule.enter';
6
+ import { reduceTabDown } from '../rules/keydown.rule.tab';
7
+ import { reduceArrowDown } from '../rules/keydown.rule.arrow';
8
+ import { A } from '../actions';
9
+
10
+ const { isOSX_IOS } = env;
11
+
12
+ /**
13
+ * @typedef {Object} KeydownReducerCtx - Keydown Reducer Context object
14
+ * @property {KeyboardEvent} ctx.e - The keyboard event
15
+ * @property {__se__FrameContext} ctx.fc - Frame context object
16
+ * @property {__se__EditorStatus} ctx.status - Editor status object
17
+ * @property {__se__BaseOptions} ctx.options - Options object
18
+ * @property {__se__FrameOptions} ctx.frameOptions - Frame options object
19
+ * @property {Range} ctx.range - Current selection range
20
+ * @property {HTMLElement|Text} ctx.selectionNode - Current selection node
21
+ * @property {HTMLElement} ctx.formatEl - Current format element
22
+ * @property {string} ctx.keyCode - Key code
23
+ * @property {boolean} ctx.ctrl - Whether the ctrl key is pressed
24
+ * @property {boolean} ctx.alt - Whether the alt key is pressed
25
+ * @property {boolean} ctx.shift - Whether the shift key is pressed
26
+ */
27
+
28
+ /**
29
+ * @description Keydown event reducer
30
+ * @param {__se__EventPorts} ports - Ports for interacting with editor
31
+ * @param {KeydownReducerCtx} ctx - Context object
32
+ * @returns {Promise<__se__EventActions>} Action list
33
+ */
34
+ export async function reduceKeydown(ports, ctx) {
35
+ const actions = [];
36
+
37
+ switch (ctx.keyCode) {
38
+ case 'Backspace' /** backspace key */: {
39
+ if (reduceBackspaceDown(actions, ports, ctx) === false) {
40
+ return actions;
41
+ }
42
+ break;
43
+ }
44
+ case 'Delete' /** delete key */: {
45
+ if (reduceDeleteDown(actions, ports, ctx) === false) {
46
+ return actions;
47
+ }
48
+ break;
49
+ }
50
+ case 'Tab' /** tab key */: {
51
+ if (reduceTabDown(actions, ports, ctx) === false) {
52
+ return actions;
53
+ }
54
+ break;
55
+ }
56
+ case 'Enter' /** enter key */: {
57
+ if (reduceEnterDown(actions, ports, ctx) === false) {
58
+ return actions;
59
+ }
60
+ break;
61
+ }
62
+ }
63
+
64
+ // ZWS, nbsp, documentType
65
+ const { fc, keyCode, shift, alt, ctrl, range } = ctx;
66
+
67
+ if (shift && (isOSX_IOS ? alt : ctrl) && keyCodeMap.isSpace(keyCode)) {
68
+ actions.push(A.preventStop());
69
+ actions.push(A.keydownInputInsertNbsp());
70
+ return actions;
71
+ }
72
+
73
+ const selectRange = !range.collapsed || range.startContainer !== range.endContainer;
74
+ if (!ctrl && !alt && !selectRange && !keyCodeMap.isNonTextKey(keyCode) && dom.check.isBreak(range.commonAncestorContainer)) {
75
+ actions.push(A.keydownInputInsertZWS());
76
+ return actions;
77
+ }
78
+
79
+ // document type
80
+ if (fc.has('documentType_use_header') && selectRange && !ctrl && !alt && !shift && !keyCodeMap.isDirectionKey(keyCode)) {
81
+ actions.push(A.documentTypeRefreshHeader());
82
+ return actions;
83
+ }
84
+
85
+ // Arrow key - select component action
86
+ reduceArrowDown(actions, ports, ctx);
87
+
88
+ return actions;
89
+ }
@@ -0,0 +1,54 @@
1
+ import { dom } from '../../../helper';
2
+ import { A } from '../actions';
3
+
4
+ /**
5
+ * @this {void}
6
+ * @description Arrow key down rule
7
+ * @param {__se__EventActions} actions - Action list
8
+ * @param {__se__EventPorts} ports - Ports for interacting with editor
9
+ * @param {__se__EventKeydownCtx} ctx - Context object
10
+ */
11
+ export function reduceArrowDown(actions, ports, ctx) {
12
+ const { component } = ports;
13
+ const { formatEl, range, selectionNode, keyCode } = ctx;
14
+
15
+ // next component
16
+ let cmponentInfo = null;
17
+ switch (keyCode) {
18
+ case 'ArrowUp' /** up key */:
19
+ if (component.is(formatEl.previousElementSibling)) {
20
+ cmponentInfo = component.get(formatEl.previousElementSibling);
21
+ }
22
+ break;
23
+ case 'ArrowLeft' /** left key */:
24
+ if (dom.check.isEdgePoint(selectionNode, range.startOffset, 'front')) {
25
+ const prevEl = selectionNode.previousElementSibling || dom.query.getPreviousDeepestNode(selectionNode);
26
+ if (prevEl) {
27
+ if (component.is(prevEl)) cmponentInfo = component.get(prevEl);
28
+ } else if (component.is(formatEl.previousElementSibling)) {
29
+ cmponentInfo = component.get(formatEl.previousElementSibling);
30
+ }
31
+ }
32
+ break;
33
+ case 'ArrowDown' /** down key */:
34
+ if (component.is(formatEl.nextElementSibling)) {
35
+ cmponentInfo = component.get(formatEl.nextElementSibling);
36
+ }
37
+ break;
38
+ case 'ArrowRight' /** right key */:
39
+ if (dom.check.isEdgePoint(selectionNode, range.endOffset, 'end')) {
40
+ const nextEl = selectionNode.nextElementSibling || dom.query.getNextDeepestNode(selectionNode);
41
+ if (nextEl) {
42
+ if (component.is(nextEl)) cmponentInfo = component.get(nextEl);
43
+ } else if (component.is(formatEl.nextElementSibling)) {
44
+ cmponentInfo = component.get(formatEl.nextElementSibling);
45
+ }
46
+ }
47
+ break;
48
+ }
49
+
50
+ if (cmponentInfo && !cmponentInfo.options?.isInputComponent) {
51
+ actions.push(A.prevent());
52
+ actions.push(A.selectComponentFallback(cmponentInfo));
53
+ }
54
+ }
@@ -0,0 +1,202 @@
1
+ import { dom } from '../../../helper';
2
+ import { cleanRemovedTags, hardDelete, isUneditableNode, setDefaultLine } from '../effects/ruleHelpers';
3
+ import { A } from '../actions';
4
+
5
+ /**
6
+ * @this {void}
7
+ * @description Backspace key down rule
8
+ * @param {__se__EventActions} actions - Action list
9
+ * @param {__se__EventPorts} ports - Ports for interacting with editor
10
+ * @param {__se__EventKeydownCtx} ctx - Context object
11
+ * @returns {boolean} Return false to stop the processing
12
+ */
13
+ export function reduceBackspaceDown(actions, ports, ctx) {
14
+ const { format, component } = ports;
15
+ const { fc, options, range, selectionNode } = ctx;
16
+ let { formatEl } = ctx;
17
+
18
+ const selectRange = !range.collapsed || range.startContainer !== range.endContainer;
19
+
20
+ actions.push(A.componentDeselect());
21
+ actions.push(A.cacheStyleNode());
22
+
23
+ if (selectRange && hardDelete(ports)) {
24
+ actions.push(A.preventStop());
25
+ return true;
26
+ }
27
+
28
+ if (!format.isNormalLine(formatEl) && !format.isBrLine(formatEl) && !fc.get('wysiwyg').firstElementChild && !component.is(selectionNode) && setDefaultLine(ports, options.get('defaultLine')) !== null) {
29
+ actions.push(A.preventStop());
30
+ return false;
31
+ }
32
+
33
+ // line delete
34
+ if (
35
+ format.isLine(formatEl) &&
36
+ selectRange &&
37
+ dom.check.isEdgePoint(range.startContainer, range.startOffset, 'front') &&
38
+ (!range.startContainer.previousSibling || dom.check.isZeroWidth(range.startContainer.previousSibling)) &&
39
+ format.getLine(range.startContainer) !== format.getLine(range.endContainer) &&
40
+ (format.isLine(formatEl.previousElementSibling) || dom.check.isListCell(formatEl))
41
+ ) {
42
+ actions.push(A.preventStop());
43
+ actions.push(A.delFormatRemoveAndMove(range.startContainer, formatEl));
44
+ actions.push(A.historyPush(true));
45
+ return false;
46
+ }
47
+
48
+ // closure, default
49
+ if (
50
+ !selectRange &&
51
+ !formatEl.previousElementSibling &&
52
+ range.startOffset === 0 &&
53
+ !selectionNode.previousSibling &&
54
+ !dom.check.isListCell(formatEl) &&
55
+ format.isLine(formatEl) &&
56
+ (!format.isBrLine(formatEl) || format.isClosureBrLine(formatEl))
57
+ ) {
58
+ // closure range
59
+ if (format.isClosureBlock(formatEl.parentNode)) {
60
+ actions.push(A.preventStop());
61
+ return false;
62
+ }
63
+
64
+ // maintain default format
65
+ if (dom.check.isWysiwygFrame(formatEl.parentNode) && formatEl.childNodes.length <= 1 && (!formatEl.firstChild || dom.check.isZeroWidth(formatEl.textContent))) {
66
+ actions.push(A.preventStop());
67
+ actions.push(A.backspaceFormatMaintain(formatEl));
68
+ }
69
+
70
+ actions.push(A.editorNativeFocus());
71
+ return false;
72
+ }
73
+
74
+ // clean remove tag
75
+ const startCon = range.startContainer;
76
+ if (formatEl && !formatEl.previousElementSibling && range.startOffset === 0 && startCon.nodeType === 3 && dom.check.isZeroWidth(startCon)) {
77
+ if (cleanRemovedTags(ports, startCon, formatEl) === true) return true;
78
+ }
79
+
80
+ // line component
81
+ if (!selectRange && formatEl && (range.startOffset === 0 || selectionNode === formatEl)) {
82
+ const sel =
83
+ selectionNode === formatEl
84
+ ? isUneditableNode(ports, range, true)
85
+ : dom.check.isElement(selectionNode.previousSibling)
86
+ ? selectionNode.previousSibling
87
+ : dom.check.isEdgePoint(range.startContainer, range.startOffset)
88
+ ? dom.query.getPreviousDeepestNode(range.startContainer)
89
+ : null;
90
+ if (component.is(sel)) {
91
+ const fileComponentInfo = component.get(sel);
92
+ if (fileComponentInfo) {
93
+ actions.push(A.preventStop());
94
+ actions.push(A.backspaceComponentSelect(selectionNode, range, fileComponentInfo));
95
+ return true;
96
+ }
97
+ }
98
+ }
99
+
100
+ // tag[contenteditable='false']
101
+ if (isUneditableNode(ports, range, true)) {
102
+ actions.push(A.preventStop());
103
+ return true;
104
+ }
105
+
106
+ // format attributes
107
+ if (!selectRange && format.isEdgeLine(range.startContainer, range.startOffset, 'front')) {
108
+ if (format.isLine(formatEl.previousElementSibling)) {
109
+ actions.push(A.cacheFormatAttrsTemp(formatEl.previousElementSibling.attributes));
110
+ }
111
+ }
112
+
113
+ // nested list
114
+ formatEl = format.getLine(range.startContainer, null);
115
+ const rangeEl = format.getBlock(formatEl, null);
116
+ const commonCon = range.commonAncestorContainer;
117
+ if (rangeEl && formatEl && !dom.check.isTableCell(rangeEl) && !/^FIGCAPTION$/i.test(rangeEl.nodeName)) {
118
+ if (
119
+ dom.check.isListCell(formatEl) &&
120
+ dom.check.isList(rangeEl) &&
121
+ (dom.check.isListCell(rangeEl.parentElement) || formatEl.previousElementSibling) &&
122
+ (selectionNode === formatEl || (selectionNode.nodeType === 3 && (!selectionNode.previousSibling || dom.check.isList(selectionNode.previousSibling)))) &&
123
+ (format.getLine(range.startContainer, null) !== format.getLine(range.endContainer, null) ? rangeEl.contains(range.startContainer) : range.startOffset === 0 && range.collapsed)
124
+ ) {
125
+ if (range.startContainer !== range.endContainer) {
126
+ actions.push(A.prevent());
127
+ actions.push(A.backspaceListRemoveNested(range));
128
+ actions.push(A.historyPush(true));
129
+ } else {
130
+ let prev = formatEl.previousElementSibling || rangeEl.parentElement;
131
+ if (dom.check.isListCell(prev)) {
132
+ actions.push(A.prevent());
133
+
134
+ let prevLast = prev;
135
+ if (!prev.contains(formatEl) && dom.check.isListCell(prevLast) && dom.check.isList(prevLast.lastElementChild)) {
136
+ prevLast = /** @type {HTMLLIElement} */ (prevLast.lastElementChild.lastElementChild);
137
+ while (dom.check.isListCell(prevLast) && dom.check.isList(prevLast.lastElementChild)) {
138
+ prevLast = /** @type {HTMLLIElement} */ (prevLast.lastElementChild && prevLast.lastElementChild.lastElementChild);
139
+ }
140
+ prev = prevLast;
141
+ }
142
+
143
+ actions.push(A.backspaceListMergePrev(prev, formatEl, rangeEl));
144
+ actions.push(A.historyPush(true));
145
+ }
146
+ }
147
+
148
+ return true;
149
+ }
150
+
151
+ // detach range
152
+ if (!selectRange && range.startOffset === 0) {
153
+ let detach = true;
154
+ let comm = commonCon;
155
+ while (comm && comm !== rangeEl && !dom.check.isWysiwygFrame(comm)) {
156
+ if (comm.previousSibling) {
157
+ if (comm.previousSibling.nodeType === 1 || !dom.check.isZeroWidth(comm.previousSibling.textContent.trim())) {
158
+ detach = false;
159
+ break;
160
+ }
161
+ }
162
+ comm = comm.parentNode;
163
+ }
164
+
165
+ if (detach && rangeEl.parentNode) {
166
+ actions.push(A.prevent());
167
+ actions.push(A.formatRemoveBlock(rangeEl, dom.check.isListCell(formatEl) ? [formatEl] : null, null, false, false));
168
+ actions.push(A.historyPush(true));
169
+ return true;
170
+ }
171
+ }
172
+ }
173
+
174
+ // component
175
+ if (!selectRange && formatEl && (range.startOffset === 0 || (selectionNode === formatEl ? formatEl.childNodes[range.startOffset] : false))) {
176
+ const isList = dom.check.isListCell(formatEl);
177
+ const sel = selectionNode === formatEl ? formatEl.childNodes[range.startOffset] : selectionNode;
178
+ const prev = (isList ? sel : formatEl).previousSibling;
179
+ // select file component
180
+ const ignoreZWS = isList || ((commonCon.nodeType === 3 || dom.check.isBreak(commonCon)) && !commonCon.previousSibling && range.startOffset === 0);
181
+ if (sel && (isList || !sel.previousSibling) && ((commonCon && component.is(commonCon.previousSibling)) || (ignoreZWS && component.is(prev)))) {
182
+ const fileComponentInfo = component.get(prev);
183
+ if (fileComponentInfo) {
184
+ actions.push(A.preventStop());
185
+ actions.push(A.backspaceComponentRemove(isList, sel, formatEl, fileComponentInfo));
186
+ } else if (component.is(prev)) {
187
+ actions.push(A.preventStop());
188
+ actions.push(A.domUtilsRemoveItem(prev));
189
+ }
190
+ return true;
191
+ }
192
+
193
+ // delete nonEditable
194
+ if (sel && dom.check.isNonEditable(sel.previousSibling)) {
195
+ actions.push(A.preventStop());
196
+ actions.push(A.domUtilsRemoveItem(sel.previousSibling));
197
+ return true;
198
+ }
199
+ }
200
+
201
+ return true;
202
+ }
@@ -0,0 +1,126 @@
1
+ import { dom } from '../../../helper';
2
+ import { hardDelete, isUneditableNode } from '../effects/ruleHelpers';
3
+ import { A } from '../actions';
4
+
5
+ /**
6
+ * @this {void}
7
+ * @description Delete key down rule
8
+ * @param {__se__EventActions} actions - Action list
9
+ * @param {__se__EventPorts} ports - Ports for interacting with editor
10
+ * @param {__se__EventKeydownCtx} ctx - Context object
11
+ * @returns {boolean} Return false to stop the processing
12
+ */
13
+ export function reduceDeleteDown(actions, ports, ctx) {
14
+ const { format, component } = ports;
15
+ const { range, selectionNode } = ctx;
16
+ let { formatEl } = ctx;
17
+
18
+ const selectRange = !range.collapsed || range.startContainer !== range.endContainer;
19
+
20
+ actions.push(A.componentDeselect());
21
+ actions.push(A.cacheStyleNode());
22
+
23
+ if (selectRange && hardDelete(ports)) {
24
+ actions.push(A.preventStop());
25
+ return true;
26
+ }
27
+
28
+ if (!selectRange && format.isEdgeLine(range.endContainer, range.endOffset, 'end') && !formatEl.nextSibling) {
29
+ actions.push(A.preventStop());
30
+ return false;
31
+ }
32
+
33
+ // line delete
34
+ if (
35
+ format.isLine(formatEl) &&
36
+ selectRange &&
37
+ dom.check.isEdgePoint(range.endContainer, range.endOffset, 'end') &&
38
+ (!range.endContainer.nextSibling || dom.check.isZeroWidth(range.endContainer.nextSibling)) &&
39
+ format.getLine(range.startContainer) !== format.getLine(range.endContainer) &&
40
+ (format.isLine(formatEl.nextElementSibling) || dom.check.isListCell(formatEl))
41
+ ) {
42
+ actions.push(A.preventStop());
43
+ actions.push(A.delFormatRemoveAndMove(range.endContainer, formatEl));
44
+ actions.push(A.historyPush(true));
45
+ return false;
46
+ }
47
+
48
+ // line component
49
+ if (!selectRange && formatEl && (range.endOffset === range.endContainer.textContent.length || selectionNode === formatEl)) {
50
+ const sel =
51
+ selectionNode === formatEl
52
+ ? isUneditableNode(ports, range, false)
53
+ : dom.check.isElement(selectionNode.nextSibling)
54
+ ? selectionNode.nextSibling
55
+ : dom.check.isEdgePoint(range.endContainer, range.endOffset)
56
+ ? dom.query.getNextDeepestNode(range.endContainer, null)
57
+ : null;
58
+ if (component.is(sel)) {
59
+ const fileComponentInfo = component.get(sel);
60
+ if (fileComponentInfo) {
61
+ actions.push(A.preventStop());
62
+ actions.push(A.deleteComponentSelect(formatEl, fileComponentInfo));
63
+ return true;
64
+ }
65
+ }
66
+ }
67
+
68
+ // tag[contenteditable='false']
69
+ if (isUneditableNode(ports, range, false)) {
70
+ actions.push(A.preventStop());
71
+ return true;
72
+ }
73
+
74
+ // component
75
+ if (
76
+ (format.isLine(selectionNode) || selectionNode.nextSibling === null || (dom.check.isZeroWidth(selectionNode.nextSibling) && selectionNode.nextSibling.nextSibling === null)) &&
77
+ range.startOffset === selectionNode.textContent.length
78
+ ) {
79
+ const nextEl = formatEl.nextElementSibling;
80
+ if (!nextEl) return true;
81
+
82
+ if (component.is(nextEl)) {
83
+ actions.push(A.prevent());
84
+ actions.push(A.deleteComponentSelectNext(formatEl, nextEl));
85
+ return true;
86
+ }
87
+ }
88
+
89
+ if (!selectRange && (dom.check.isEdgePoint(range.endContainer, range.endOffset) || (selectionNode === formatEl ? formatEl.childNodes[range.startOffset] : false))) {
90
+ const sel = selectionNode === formatEl ? formatEl.childNodes[range.startOffset] || selectionNode : selectionNode;
91
+ // delete nonEditable
92
+ if (sel && dom.check.isNonEditable(sel.nextSibling)) {
93
+ actions.push(A.preventStop());
94
+ actions.push(A.domUtilsRemoveItem(sel.nextSibling));
95
+ return true;
96
+ } else if (component.is(sel)) {
97
+ actions.push(A.preventStop());
98
+ actions.push(A.domUtilsRemoveItem(sel));
99
+ return true;
100
+ }
101
+ }
102
+
103
+ // format attributes
104
+ if (!selectRange && format.isEdgeLine(range.endContainer, range.endOffset, 'end')) {
105
+ if (format.isLine(formatEl.nextElementSibling)) {
106
+ actions.push(A.cacheFormatAttrsTemp(formatEl.attributes));
107
+ }
108
+ }
109
+
110
+ // nested list
111
+ formatEl = format.getLine(range.startContainer, null);
112
+ const rangeEl = format.getBlock(formatEl, null);
113
+ if (
114
+ dom.check.isListCell(formatEl) &&
115
+ dom.check.isList(rangeEl) &&
116
+ (selectionNode === formatEl ||
117
+ (selectionNode.nodeType === 3 &&
118
+ (!selectionNode.nextSibling || dom.check.isList(selectionNode.nextSibling)) &&
119
+ (format.getLine(range.startContainer, null) !== format.getLine(range.endContainer, null) ? rangeEl.contains(range.endContainer) : range.endOffset === selectionNode.textContent.length && range.collapsed)))
120
+ ) {
121
+ actions.push(A.deleteListRemoveNested(range, formatEl, rangeEl));
122
+ return true;
123
+ }
124
+
125
+ return true;
126
+ }
@@ -0,0 +1,144 @@
1
+ import { dom } from '../../../helper';
2
+ import { A } from '../actions';
3
+
4
+ /**
5
+ * @this {void}
6
+ * @description Enter key down rule
7
+ * @param {__se__EventActions} actions - Action list
8
+ * @param {__se__EventPorts} ports - Ports for interacting with editor
9
+ * @param {__se__EventKeydownCtx} ctx - Context object
10
+ * @returns {boolean} Return false to stop the processing
11
+ */
12
+ export function reduceEnterDown(actions, ports, ctx) {
13
+ const { format, char, selection } = ports;
14
+ const { frameOptions, range, formatEl, selectionNode, shift, e } = ctx;
15
+ const selectRange = !range.collapsed || range.startContainer !== range.endContainer;
16
+
17
+ actions.push(A.componentDeselect());
18
+
19
+ const brBlock = format.getBrLine(selectionNode, null);
20
+ const rangeEl = format.getBlock(formatEl, null);
21
+
22
+ if (frameOptions.get('charCounter_type') === 'byte-html') {
23
+ let enterHTML = '';
24
+ if ((!shift && brBlock) || shift) {
25
+ enterHTML = '<br>';
26
+ } else {
27
+ enterHTML = '<' + formatEl.nodeName + '><br></' + formatEl.nodeName + '>';
28
+ }
29
+
30
+ if (!char.check(enterHTML)) {
31
+ actions.push(A.prevent());
32
+ return false;
33
+ }
34
+ }
35
+
36
+ if (!shift) {
37
+ const formatEndEdge = !range.endContainer.nextSibling && format.isEdgeLine(range.endContainer, range.endOffset, 'end');
38
+ const formatStartEdge = !range.startContainer.previousSibling && format.isEdgeLine(range.startContainer, range.startOffset, 'front');
39
+
40
+ // add default format line
41
+ if (formatEndEdge && (/^H[1-6]$/i.test(formatEl.nodeName) || /^HR$/i.test(formatEl.nodeName))) {
42
+ ports.enterPrevent(e);
43
+ actions.push(A.enterLineAddDefault(formatEl));
44
+ actions.push(A.enterScrollTo(range));
45
+ return true;
46
+ } else if (rangeEl && formatEl && !dom.check.isTableCell(rangeEl) && !/^FIGCAPTION$/i.test(rangeEl.nodeName)) {
47
+ // add default List line
48
+ const rangeEnt = selection.getRange();
49
+ if (dom.check.isEdgePoint(rangeEnt.endContainer, rangeEnt.endOffset) && dom.check.isList(selectionNode.nextSibling)) {
50
+ ports.enterPrevent(e);
51
+ actions.push(A.enterListAddItem(formatEl, selectionNode));
52
+ actions.push(A.enterScrollTo(range));
53
+ return true;
54
+ }
55
+
56
+ if (
57
+ (rangeEnt.commonAncestorContainer.nodeType === 3 ? !(/** @type {HTMLElement} */ (rangeEnt.commonAncestorContainer).nextElementSibling) : true) &&
58
+ dom.check.isZeroWidth(formatEl.innerText.trim()) &&
59
+ !dom.check.isListCell(formatEl.nextElementSibling)
60
+ ) {
61
+ ports.enterPrevent(e);
62
+ actions.push(A.enterFormatExitEmpty(formatEl, rangeEl));
63
+ return true;
64
+ }
65
+ }
66
+
67
+ // br line | closure block exception
68
+ if (brBlock || (rangeEl === formatEl && format.isClosureBlock(rangeEl) && format.isLine(formatEl))) {
69
+ ports.enterPrevent(e);
70
+
71
+ const selectionFormat = selectionNode === brBlock;
72
+ const wSelection = selection.get();
73
+ const children = selectionNode.childNodes,
74
+ offset = wSelection.focusOffset,
75
+ prev = selectionNode.previousElementSibling,
76
+ next = selectionNode.nextSibling;
77
+
78
+ if (
79
+ !format.isClosureBrLine(brBlock) &&
80
+ children &&
81
+ ((selectionFormat &&
82
+ range.collapsed &&
83
+ children.length - 1 <= offset + 1 &&
84
+ dom.check.isBreak(children[offset]) &&
85
+ (!children[offset + 1] || ((!children[offset + 2] || dom.check.isZeroWidth(children[offset + 2].textContent)) && children[offset + 1].nodeType === 3 && dom.check.isZeroWidth(children[offset + 1].textContent))) &&
86
+ offset > 0 &&
87
+ dom.check.isBreak(children[offset - 1])) ||
88
+ (!selectionFormat &&
89
+ dom.check.isZeroWidth(selectionNode.textContent) &&
90
+ dom.check.isBreak(prev) &&
91
+ (dom.check.isBreak(prev.previousSibling) || !dom.check.isZeroWidth(prev.previousSibling?.textContent)) &&
92
+ (!next || (!dom.check.isBreak(next) && dom.check.isZeroWidth(next.textContent)))))
93
+ ) {
94
+ actions.push(A.enterFormatCleanBrAndZWS(selectionNode, selectionFormat, brBlock, children, offset));
95
+ actions.push(A.enterScrollTo(range));
96
+ return true;
97
+ }
98
+
99
+ if (selectionFormat) {
100
+ actions.push(A.enterFormatInsertBrHtml(brBlock, range, wSelection, offset));
101
+ } else {
102
+ actions.push(A.enterFormatInsertBrNode(wSelection));
103
+ }
104
+
105
+ actions.push(A.enterScrollTo(range));
106
+ return true;
107
+ }
108
+
109
+ // set format attrs - edge
110
+ if (range.collapsed && (formatStartEdge || formatEndEdge)) {
111
+ ports.enterPrevent(e);
112
+ actions.push(A.enterFormatBreakAtEdge(formatEl, selectionNode, formatStartEdge, formatEndEdge));
113
+ actions.push(A.enterScrollTo(range));
114
+ return true;
115
+ }
116
+
117
+ if (formatEl) {
118
+ actions.push(A.prevent());
119
+
120
+ /** @type {HTMLElement} */
121
+ if (selectRange) {
122
+ actions.push(A.enterFormatBreakWithSelection(formatEl, range, formatStartEdge, formatEndEdge));
123
+ } else {
124
+ actions.push(A.enterFormatBreakAtCursor(formatEl, range));
125
+ }
126
+
127
+ actions.push(A.enterScrollTo(range));
128
+ return true;
129
+ }
130
+ }
131
+
132
+ if (selectRange) {
133
+ actions.push(A.enterScrollTo(range));
134
+ return true;
135
+ }
136
+
137
+ if (rangeEl && dom.query.getParentElement(rangeEl, 'FIGCAPTION') && dom.query.getParentElement(rangeEl, dom.check.isList)) {
138
+ ports.enterPrevent(e);
139
+ actions.push(A.enterFigcaptionExitInList(formatEl));
140
+ actions.push(A.enterScrollTo(range));
141
+ }
142
+
143
+ return true;
144
+ }
@@ -0,0 +1,29 @@
1
+ import { dom } from '../../../helper';
2
+ import { A } from '../actions';
3
+
4
+ /**
5
+ * @this {void}
6
+ * @description Tab key down rule
7
+ * @param {__se__EventActions} actions - Action list
8
+ * @param {__se__EventPorts} _ports - Ports for interacting with editor
9
+ * @param {__se__EventKeydownCtx} ctx - Context object
10
+ * @returns {boolean} Return false to stop the processing
11
+ */
12
+ export function reduceTabDown(actions, _ports, ctx) {
13
+ const { options, selectionNode, range, formatEl, ctrl, alt, shift } = ctx;
14
+
15
+ if (options.get('tabDisable')) {
16
+ return true;
17
+ }
18
+
19
+ actions.push(A.prevent());
20
+
21
+ if (ctrl || alt || dom.check.isWysiwygFrame(selectionNode)) {
22
+ return true;
23
+ }
24
+
25
+ actions.push(A.tabFormatIndent(range, formatEl, shift));
26
+ actions.push(A.historyPush(false));
27
+
28
+ return true;
29
+ }