jodit 4.18.4 → 4.18.7

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 (209) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/es2015/jodit.css +13 -34
  3. package/es2015/jodit.fat.min.css +1 -1
  4. package/es2015/jodit.fat.min.js +12 -12
  5. package/es2015/jodit.js +1130 -225
  6. package/es2015/jodit.min.css +1 -1
  7. package/es2015/jodit.min.js +12 -12
  8. package/es2015/plugins/debug/debug.css +1 -1
  9. package/es2015/plugins/debug/debug.js +1 -1
  10. package/es2015/plugins/debug/debug.min.js +1 -1
  11. package/es2015/plugins/speech-recognize/speech-recognize.css +1 -1
  12. package/es2015/plugins/speech-recognize/speech-recognize.js +1 -1
  13. package/es2015/plugins/speech-recognize/speech-recognize.min.js +1 -1
  14. package/es2018/jodit.fat.min.css +1 -1
  15. package/es2018/jodit.fat.min.js +12 -12
  16. package/es2018/jodit.min.css +1 -1
  17. package/es2018/jodit.min.js +12 -12
  18. package/es2018/plugins/debug/debug.min.js +1 -1
  19. package/es2018/plugins/speech-recognize/speech-recognize.min.js +1 -1
  20. package/es2021/jodit.css +13 -34
  21. package/es2021/jodit.fat.min.css +1 -1
  22. package/es2021/jodit.fat.min.js +16 -16
  23. package/es2021/jodit.js +1121 -223
  24. package/es2021/jodit.min.css +1 -1
  25. package/es2021/jodit.min.js +16 -16
  26. package/es2021/plugins/debug/debug.css +1 -1
  27. package/es2021/plugins/debug/debug.js +1 -1
  28. package/es2021/plugins/debug/debug.min.js +1 -1
  29. package/es2021/plugins/speech-recognize/speech-recognize.css +1 -1
  30. package/es2021/plugins/speech-recognize/speech-recognize.js +1 -1
  31. package/es2021/plugins/speech-recognize/speech-recognize.min.js +1 -1
  32. package/es2021.en/jodit.css +13 -34
  33. package/es2021.en/jodit.fat.min.css +1 -1
  34. package/es2021.en/jodit.fat.min.js +16 -16
  35. package/es2021.en/jodit.js +1095 -197
  36. package/es2021.en/jodit.min.css +1 -1
  37. package/es2021.en/jodit.min.js +16 -16
  38. package/es2021.en/plugins/debug/debug.css +1 -1
  39. package/es2021.en/plugins/debug/debug.js +1 -1
  40. package/es2021.en/plugins/debug/debug.min.js +1 -1
  41. package/es2021.en/plugins/speech-recognize/speech-recognize.css +1 -1
  42. package/es2021.en/plugins/speech-recognize/speech-recognize.js +1 -1
  43. package/es2021.en/plugins/speech-recognize/speech-recognize.min.js +1 -1
  44. package/es5/jodit.css +14 -41
  45. package/es5/jodit.fat.min.css +1 -1
  46. package/es5/jodit.fat.min.js +2 -2
  47. package/es5/jodit.js +1260 -273
  48. package/es5/jodit.min.css +3 -3
  49. package/es5/jodit.min.js +2 -2
  50. package/es5/plugins/debug/debug.css +1 -1
  51. package/es5/plugins/debug/debug.js +1 -1
  52. package/es5/plugins/debug/debug.min.js +1 -1
  53. package/es5/plugins/speech-recognize/speech-recognize.css +1 -1
  54. package/es5/plugins/speech-recognize/speech-recognize.js +1 -1
  55. package/es5/plugins/speech-recognize/speech-recognize.min.js +1 -1
  56. package/es5/polyfills.fat.min.js +1 -1
  57. package/es5/polyfills.js +1 -1
  58. package/es5/polyfills.min.js +1 -1
  59. package/esm/config.d.ts +5 -0
  60. package/esm/core/constants.js +1 -1
  61. package/esm/core/decorators/component/component.js +12 -0
  62. package/esm/core/helpers/html/apply-styles.js +3 -0
  63. package/esm/core/helpers/html/clean-from-word.js +3 -0
  64. package/esm/core/helpers/html/strip-tags.js +24 -6
  65. package/esm/core/helpers/html/word-lists.d.ts +29 -0
  66. package/esm/core/helpers/html/word-lists.js +158 -0
  67. package/esm/core/selection/helpers/index.d.ts +1 -0
  68. package/esm/core/selection/helpers/index.js +1 -0
  69. package/esm/core/selection/helpers/is-moved.d.ts +15 -0
  70. package/esm/core/selection/helpers/is-moved.js +22 -0
  71. package/esm/core/selection/style/api/list/toggle-ordered-list.js +40 -3
  72. package/esm/core/selection/style/transactions.js +5 -2
  73. package/esm/core/ui/popup/popup.js +14 -9
  74. package/esm/jodit.js +5 -1
  75. package/esm/langs/ar.d.ts +3 -0
  76. package/esm/langs/ar.js +4 -1
  77. package/esm/langs/az.d.ts +3 -0
  78. package/esm/langs/az.js +4 -1
  79. package/esm/langs/cs_cz.d.ts +3 -0
  80. package/esm/langs/cs_cz.js +4 -1
  81. package/esm/langs/de.d.ts +3 -0
  82. package/esm/langs/de.js +4 -1
  83. package/esm/langs/es.d.ts +3 -0
  84. package/esm/langs/es.js +4 -1
  85. package/esm/langs/fa.d.ts +3 -0
  86. package/esm/langs/fa.js +4 -1
  87. package/esm/langs/fi.d.ts +3 -0
  88. package/esm/langs/fi.js +4 -1
  89. package/esm/langs/fr.d.ts +3 -0
  90. package/esm/langs/fr.js +4 -1
  91. package/esm/langs/he.d.ts +3 -0
  92. package/esm/langs/he.js +4 -1
  93. package/esm/langs/hu.d.ts +3 -0
  94. package/esm/langs/hu.js +4 -1
  95. package/esm/langs/id.d.ts +3 -0
  96. package/esm/langs/id.js +4 -1
  97. package/esm/langs/it.d.ts +3 -0
  98. package/esm/langs/it.js +4 -1
  99. package/esm/langs/ja.d.ts +3 -0
  100. package/esm/langs/ja.js +4 -1
  101. package/esm/langs/ko.d.ts +3 -0
  102. package/esm/langs/ko.js +4 -1
  103. package/esm/langs/mn.d.ts +3 -0
  104. package/esm/langs/mn.js +4 -1
  105. package/esm/langs/nl.d.ts +3 -0
  106. package/esm/langs/nl.js +4 -1
  107. package/esm/langs/no.d.ts +3 -0
  108. package/esm/langs/no.js +4 -1
  109. package/esm/langs/pl.d.ts +3 -0
  110. package/esm/langs/pl.js +4 -1
  111. package/esm/langs/pt_br.d.ts +3 -0
  112. package/esm/langs/pt_br.js +4 -1
  113. package/esm/langs/ru.d.ts +3 -0
  114. package/esm/langs/ru.js +4 -1
  115. package/esm/langs/sk.d.ts +3 -0
  116. package/esm/langs/sk.js +4 -1
  117. package/esm/langs/sv.d.ts +3 -0
  118. package/esm/langs/sv.js +4 -1
  119. package/esm/langs/tr.d.ts +3 -0
  120. package/esm/langs/tr.js +4 -1
  121. package/esm/langs/ua.d.ts +3 -0
  122. package/esm/langs/ua.js +4 -1
  123. package/esm/langs/zh_cn.d.ts +3 -0
  124. package/esm/langs/zh_cn.js +4 -1
  125. package/esm/langs/zh_tw.d.ts +3 -0
  126. package/esm/langs/zh_tw.js +4 -1
  127. package/esm/modules/dialog/dialog.d.ts +7 -0
  128. package/esm/modules/dialog/dialog.js +24 -6
  129. package/esm/modules/file-browser/ui/files/files.js +17 -2
  130. package/esm/modules/file-browser/ui/tree/tree.js +17 -2
  131. package/esm/modules/table/table.d.ts +6 -0
  132. package/esm/modules/table/table.js +18 -26
  133. package/esm/plugins/backspace/cases/check-join-neighbors.js +90 -3
  134. package/esm/plugins/backspace/cases/check-remove-char.d.ts +2 -1
  135. package/esm/plugins/backspace/cases/check-remove-char.js +25 -4
  136. package/esm/plugins/backspace/config.d.ts +2 -0
  137. package/esm/plugins/backspace/config.js +6 -3
  138. package/esm/plugins/clean-html/clean-html.d.ts +8 -0
  139. package/esm/plugins/clean-html/clean-html.js +21 -1
  140. package/esm/plugins/clean-html/helpers/index.d.ts +1 -0
  141. package/esm/plugins/clean-html/helpers/index.js +1 -0
  142. package/esm/plugins/clean-html/helpers/remove-placeholder-br.d.ts +16 -0
  143. package/esm/plugins/clean-html/helpers/remove-placeholder-br.js +51 -0
  144. package/esm/plugins/delete/delete.d.ts +11 -1
  145. package/esm/plugins/delete/delete.js +92 -16
  146. package/esm/plugins/focus/focus.js +12 -1
  147. package/esm/plugins/iframe/config.d.ts +3 -0
  148. package/esm/plugins/iframe/config.js +0 -27
  149. package/esm/plugins/iframe/iframe.js +8 -1
  150. package/esm/plugins/image-processor/image-processor.js +6 -1
  151. package/esm/plugins/image-properties/image-properties.d.ts +5 -0
  152. package/esm/plugins/image-properties/image-properties.js +30 -5
  153. package/esm/plugins/inline-popup/inline-popup.d.ts +19 -0
  154. package/esm/plugins/inline-popup/inline-popup.js +70 -1
  155. package/esm/plugins/mobile/mobile.js +7 -4
  156. package/esm/plugins/ordered-list/config.js +13 -2
  157. package/esm/plugins/ordered-list/start-dialog.d.ts +19 -0
  158. package/esm/plugins/ordered-list/start-dialog.js +58 -0
  159. package/esm/plugins/placeholder/placeholder.js +7 -1
  160. package/esm/plugins/resizer/resizer.d.ts +10 -0
  161. package/esm/plugins/resizer/resizer.js +76 -2
  162. package/esm/plugins/select-cells/select-cells.d.ts +23 -0
  163. package/esm/plugins/select-cells/select-cells.js +75 -1
  164. package/esm/plugins/table-keyboard-navigation/table-keyboard-navigation.js +3 -2
  165. package/package.json +1 -1
  166. package/types/config.d.ts +5 -0
  167. package/types/core/helpers/html/word-lists.d.ts +29 -0
  168. package/types/core/selection/helpers/index.d.ts +1 -0
  169. package/types/core/selection/helpers/is-moved.d.ts +15 -0
  170. package/types/langs/ar.d.ts +3 -0
  171. package/types/langs/az.d.ts +3 -0
  172. package/types/langs/cs_cz.d.ts +3 -0
  173. package/types/langs/de.d.ts +3 -0
  174. package/types/langs/es.d.ts +3 -0
  175. package/types/langs/fa.d.ts +3 -0
  176. package/types/langs/fi.d.ts +3 -0
  177. package/types/langs/fr.d.ts +3 -0
  178. package/types/langs/he.d.ts +3 -0
  179. package/types/langs/hu.d.ts +3 -0
  180. package/types/langs/id.d.ts +3 -0
  181. package/types/langs/it.d.ts +3 -0
  182. package/types/langs/ja.d.ts +3 -0
  183. package/types/langs/ko.d.ts +3 -0
  184. package/types/langs/mn.d.ts +3 -0
  185. package/types/langs/nl.d.ts +3 -0
  186. package/types/langs/no.d.ts +3 -0
  187. package/types/langs/pl.d.ts +3 -0
  188. package/types/langs/pt_br.d.ts +3 -0
  189. package/types/langs/ru.d.ts +3 -0
  190. package/types/langs/sk.d.ts +3 -0
  191. package/types/langs/sv.d.ts +3 -0
  192. package/types/langs/tr.d.ts +3 -0
  193. package/types/langs/ua.d.ts +3 -0
  194. package/types/langs/zh_cn.d.ts +3 -0
  195. package/types/langs/zh_tw.d.ts +3 -0
  196. package/types/modules/dialog/dialog.d.ts +7 -0
  197. package/types/modules/table/table.d.ts +6 -0
  198. package/types/plugins/backspace/cases/check-remove-char.d.ts +2 -1
  199. package/types/plugins/backspace/config.d.ts +2 -0
  200. package/types/plugins/clean-html/clean-html.d.ts +8 -0
  201. package/types/plugins/clean-html/helpers/index.d.ts +1 -0
  202. package/types/plugins/clean-html/helpers/remove-placeholder-br.d.ts +16 -0
  203. package/types/plugins/delete/delete.d.ts +11 -1
  204. package/types/plugins/iframe/config.d.ts +3 -0
  205. package/types/plugins/image-properties/image-properties.d.ts +5 -0
  206. package/types/plugins/inline-popup/inline-popup.d.ts +19 -0
  207. package/types/plugins/ordered-list/start-dialog.d.ts +19 -0
  208. package/types/plugins/resizer/resizer.d.ts +10 -0
  209. package/types/plugins/select-cells/select-cells.d.ts +23 -0
@@ -33,6 +33,10 @@ export function isEditorEmpty(root) {
33
33
  return true;
34
34
  }
35
35
  const first = root.firstChild;
36
+ // Firefox pads an empty editable body with a bare <br>
37
+ if (Dom.isTag(first, 'br') && !Dom.next(first, Boolean, root)) {
38
+ return true;
39
+ }
36
40
  if (INSEPARABLE_TAGS.has((_a = first.nodeName) === null || _a === void 0 ? void 0 : _a.toLowerCase()) ||
37
41
  /^(TABLE)$/i.test(first.nodeName)) {
38
42
  return false;
@@ -69,7 +73,7 @@ export class placeholder extends Plugin {
69
73
  .on('changePlace.placeholder', this.addNativeListeners)
70
74
  .on('change.placeholder focus.placeholder keyup.placeholder mouseup.placeholder keydown.placeholder ' +
71
75
  'mousedown.placeholder afterSetMode.placeholder changePlace.placeholder ' +
72
- 'internalChange.placeholder afterCommand.placeholder', this.toggle)
76
+ 'internalChange.placeholder afterCommand.placeholder resize.placeholder', this.toggle)
73
77
  .on(window, 'load', this.toggle);
74
78
  this.addNativeListeners();
75
79
  this.toggle();
@@ -115,12 +119,14 @@ export class placeholder extends Plugin {
115
119
  marginTop = parseInt(style2.getPropertyValue('margin-top'), 10);
116
120
  marginLeft = parseInt(style2.getPropertyValue('margin-left'), 10);
117
121
  css(this.placeholderElm, {
122
+ fontFamily: style2.getPropertyValue('font-family'),
118
123
  fontSize: parseInt(style2.getPropertyValue('font-size'), 10),
119
124
  lineHeight: style2.getPropertyValue('line-height')
120
125
  });
121
126
  }
122
127
  else {
123
128
  css(this.placeholderElm, {
129
+ fontFamily: style.getPropertyValue('font-family'),
124
130
  fontSize: parseInt(style.getPropertyValue('font-size'), 10),
125
131
  lineHeight: style.getPropertyValue('line-height')
126
132
  });
@@ -46,6 +46,16 @@ export declare class resizer extends Plugin {
46
46
  private pointerX;
47
47
  private pointerY;
48
48
  private onResize;
49
+ private __keyDownRange;
50
+ private __keyDownTable;
51
+ private onEditorKeyDown;
52
+ private __caretTable;
53
+ /**
54
+ * Hide the frame once a key has moved the caret off its element, and
55
+ * frame a table the caret has moved into, as clicks do
56
+ */
57
+ protected onEditorKeyUp(): void;
58
+ private __followCaret;
49
59
  private isAltMode;
50
60
  private onKeyDown;
51
61
  private onKeyUp;
@@ -17,10 +17,13 @@ import * as consts from "../../core/constants.js";
17
17
  import { IS_ES_NEXT, IS_IE, KEY_ALT } from "../../core/constants.js";
18
18
  import { autobind, watch } from "../../core/decorators/index.js";
19
19
  import { Dom } from "../../core/dom/dom.js";
20
- import { eventEmitter, pluginSystem } from "../../core/global.js";
20
+ import { eventEmitter, getContainer, pluginSystem } from "../../core/global.js";
21
21
  import { $$, attr, css, dataBind, getWrappedMedia, innerWidth, markOwner, offset } from "../../core/helpers/index.js";
22
22
  import { cssInline } from "../../core/helpers/utils/css.js";
23
23
  import { Plugin } from "../../core/plugin/plugin.js";
24
+ import { isMoved } from "../../core/selection/helpers/index.js";
25
+ import { UIElement } from "../../core/ui/index.js";
26
+ import { Popup } from "../../core/ui/popup/index.js";
24
27
  import "./config.js";
25
28
  const keyBInd = '__jodit-resizer_binded';
26
29
  /**
@@ -45,6 +48,17 @@ function heightFollowsWidth(element) {
45
48
  !attr(element, 'height') &&
46
49
  !cssInline(element, 'height'));
47
50
  }
51
+ const IFRAME_WRAPPER = '[data-jodit_iframe_wrapper]';
52
+ /**
53
+ * A click on an embed lands on its wrapper, so it selects the embed, until the
54
+ * wrapper is active. While the editor is locked, as during resizing, the
55
+ * wrapper takes the mouse again.
56
+ */
57
+ const EMBED_WRAPPER_STYLE = `${IFRAME_WRAPPER}{position:relative;display:block;user-select:none}` +
58
+ `${IFRAME_WRAPPER} iframe{position:relative}` +
59
+ `${IFRAME_WRAPPER}::after{position:absolute;z-index:1;display:block;background:transparent;content:'';cursor:pointer;inset:0}` +
60
+ `${IFRAME_WRAPPER}[data-jodit-wrapper_active=true] iframe{z-index:2}` +
61
+ `.jodit_lock ${IFRAME_WRAPPER}[data-jodit-wrapper_active=true] iframe{z-index:1}`;
48
62
  /**
49
63
  * The module creates a supporting frame for resizing of the elements img and table
50
64
  */
@@ -72,6 +86,8 @@ export class resizer extends Plugin {
72
86
  this.sizeViewer = this.rect.getElementsByTagName('span')[0];
73
87
  this.pointerX = 0;
74
88
  this.pointerY = 0;
89
+ this.__keyDownRange = null;
90
+ this.__keyDownTable = null;
75
91
  this.isAltMode = false;
76
92
  this.onClickElement = (element) => {
77
93
  if (this.isResizeMode) {
@@ -123,6 +139,9 @@ export class resizer extends Plugin {
123
139
  }
124
140
  /** @override */
125
141
  afterInit(editor) {
142
+ // It goes in the editing document, so iframe mode has it whatever `iframeStyle` holds
143
+ getContainer(editor, 'resizer', 'style', true).textContent =
144
+ EMBED_WRAPPER_STYLE;
126
145
  $$('div', this.rect).forEach((resizeHandle) => {
127
146
  editor.e.on(resizeHandle, 'mousedown.resizer touchstart.resizer', this.onStartResizing.bind(this, resizeHandle));
128
147
  });
@@ -134,6 +153,9 @@ export class resizer extends Plugin {
134
153
  }
135
154
  })
136
155
  .on('afterInit changePlace', this.addEventListeners.bind(this))
156
+ // Handlers without a namespace run first, ahead of those that
157
+ // move the caret, as table-keyboard-navigation's do
158
+ .on('keydown', this.onEditorKeyDown, { top: true })
137
159
  .on('afterGetValueFromEditor.resizer', (data) => {
138
160
  const rgx = /<jodit[^>]+data-jodit_iframe_wrapper[^>]+>(.*?<iframe[^>]*>.*?<\/iframe>.*?)<\/jodit>/gi;
139
161
  if (rgx.test(data.value)) {
@@ -308,6 +330,43 @@ export class resizer extends Plugin {
308
330
  e.stopImmediatePropagation();
309
331
  }
310
332
  }
333
+ onEditorKeyDown(event) {
334
+ // A key held down moves the caret on every repeat, with one keyup
335
+ if (event === null || event === void 0 ? void 0 : event.repeat) {
336
+ this.__followCaret();
337
+ }
338
+ this.__keyDownRange = this.j.s.range.cloneRange();
339
+ this.__keyDownTable = this.__caretTable();
340
+ }
341
+ __caretTable() {
342
+ return Dom.closest(this.j.s.range.startContainer, 'table', this.j.editor);
343
+ }
344
+ /**
345
+ * Hide the frame once a key has moved the caret off its element, and
346
+ * frame a table the caret has moved into, as clicks do
347
+ */
348
+ onEditorKeyUp() {
349
+ this.__followCaret();
350
+ }
351
+ __followCaret() {
352
+ const before = this.__keyDownRange;
353
+ this.__keyDownRange = null;
354
+ if (!isMoved(this.j, before)) {
355
+ return;
356
+ }
357
+ if (this.isShown &&
358
+ this.element &&
359
+ !this.j.s.range.intersectsNode(this.element)) {
360
+ this.hide();
361
+ }
362
+ const table = this.__caretTable();
363
+ if (table &&
364
+ table !== this.__keyDownTable &&
365
+ this.j.o.allowResizeTags.has('table')) {
366
+ this.__bind(table);
367
+ this.onClickElement(table);
368
+ }
369
+ }
311
370
  onKeyDown(e) {
312
371
  this.isAltMode = e.key === KEY_ALT;
313
372
  if (!this.isAltMode && this.isResizeMode) {
@@ -329,6 +388,12 @@ export class resizer extends Plugin {
329
388
  return;
330
389
  }
331
390
  if (!this.isResizeMode) {
391
+ // A click in the element's popup, or in a list it opens, works on
392
+ // the element, so it keeps its frame
393
+ if ((e === null || e === void 0 ? void 0 : e.target) &&
394
+ UIElement.closestElement(e.target, Popup)) {
395
+ return;
396
+ }
332
397
  return this.hide();
333
398
  }
334
399
  e.stopImmediatePropagation();
@@ -512,7 +577,10 @@ export class resizer extends Plugin {
512
577
  this.hide();
513
578
  Dom.safeRemove(this.layer);
514
579
  eventEmitter.off('hideHelpers', this.hide);
515
- jodit.e.off(this.j.ow, '.resizer').off('.resizer');
580
+ jodit.e
581
+ .off(this.j.ow, '.resizer')
582
+ .off('.resizer')
583
+ .off('keydown', this.onEditorKeyDown);
516
584
  }
517
585
  }
518
586
  __decorate([
@@ -530,6 +598,12 @@ __decorate([
530
598
  __decorate([
531
599
  autobind
532
600
  ], resizer.prototype, "onResize", null);
601
+ __decorate([
602
+ autobind
603
+ ], resizer.prototype, "onEditorKeyDown", null);
604
+ __decorate([
605
+ watch(':keyup')
606
+ ], resizer.prototype, "onEditorKeyUp", null);
533
607
  __decorate([
534
608
  autobind
535
609
  ], resizer.prototype, "onKeyDown", null);
@@ -18,6 +18,29 @@ export declare class selectCells extends Plugin {
18
18
  */
19
19
  private get __tableModule();
20
20
  protected afterInit(jodit: IJodit): void;
21
+ /**
22
+ * The cell with the caret, and the selection, when a key went down
23
+ */
24
+ private __keyDownCell;
25
+ private __keyDownRange;
26
+ private __onKeyDown;
27
+ /**
28
+ * A link's popup replaces the cell's while the caret is in the link
29
+ */
30
+ private __keyDownInLink;
31
+ private __isInLink;
32
+ /**
33
+ * Where the selection starts rather than `s.current()`, which finds the
34
+ * first cell when the caret is just before the table
35
+ */
36
+ private __caretCell;
37
+ /**
38
+ * A key that moves the caret into a cell, from another cell or from
39
+ * outside the table, marks that cell and opens its popup, as a click on
40
+ * it does. One that moves the caret out of the table unmarks the cells
41
+ */
42
+ protected onKeyUp(): void;
43
+ private __followCaret;
21
44
  /**
22
45
  * First selected cell
23
46
  */
@@ -19,6 +19,7 @@ import { Dom } from "../../core/dom/dom.js";
19
19
  import { pluginSystem } from "../../core/global.js";
20
20
  import { $$, alignElement, position, toArray } from "../../core/helpers/index.js";
21
21
  import { Plugin } from "../../core/plugin/index.js";
22
+ import { isMoved } from "../../core/selection/helpers/index.js";
22
23
  import { Table } from "../../modules/table/table.js";
23
24
  import "./config.js";
24
25
  const key = 'table_processor_observer';
@@ -26,6 +27,15 @@ const MOUSE_MOVE_LABEL = 'onMoveTableSelectCell';
26
27
  export class selectCells extends Plugin {
27
28
  constructor() {
28
29
  super(...arguments);
30
+ /**
31
+ * The cell with the caret, and the selection, when a key went down
32
+ */
33
+ this.__keyDownCell = null;
34
+ this.__keyDownRange = null;
35
+ /**
36
+ * A link's popup replaces the cell's while the caret is in the link
37
+ */
38
+ this.__keyDownInLink = false;
29
39
  /**
30
40
  * First selected cell
31
41
  */
@@ -46,6 +56,9 @@ export class selectCells extends Plugin {
46
56
  return;
47
57
  }
48
58
  jodit.e
59
+ // Handlers without a namespace run first, ahead of those that
60
+ // move the caret, as table-keyboard-navigation's do
61
+ .on('keydown', this.__onKeyDown, { top: true })
49
62
  .on('keydown.select-cells', (event) => {
50
63
  if (event.key === KEY_TAB) {
51
64
  this.unselectCells();
@@ -76,6 +89,61 @@ export class selectCells extends Plugin {
76
89
  }
77
90
  });
78
91
  }
92
+ __onKeyDown(event) {
93
+ // A key held down moves the caret on every repeat, with one keyup
94
+ if (event === null || event === void 0 ? void 0 : event.repeat) {
95
+ this.__followCaret();
96
+ }
97
+ this.__keyDownCell = this.__caretCell();
98
+ this.__keyDownRange = this.j.s.range.cloneRange();
99
+ this.__keyDownInLink = this.__isInLink();
100
+ }
101
+ __isInLink() {
102
+ return Boolean(Dom.closest(this.j.s.range.startContainer, 'a', this.j.editor));
103
+ }
104
+ /**
105
+ * Where the selection starts rather than `s.current()`, which finds the
106
+ * first cell when the caret is just before the table
107
+ */
108
+ __caretCell() {
109
+ return Dom.closest(this.j.s.range.startContainer, Dom.isCell, this.j.editor);
110
+ }
111
+ /**
112
+ * A key that moves the caret into a cell, from another cell or from
113
+ * outside the table, marks that cell and opens its popup, as a click on
114
+ * it does. One that moves the caret out of the table unmarks the cells
115
+ */
116
+ onKeyUp() {
117
+ this.__followCaret();
118
+ }
119
+ __followCaret() {
120
+ const before = this.__keyDownRange;
121
+ this.__keyDownRange = null;
122
+ if (this.j.o.readonly || !isMoved(this.j, before)) {
123
+ return;
124
+ }
125
+ const cell = this.__caretCell();
126
+ const hasLeftLink = this.__keyDownInLink && !this.__isInLink();
127
+ if (cell === this.__keyDownCell && !(cell && hasLeftLink)) {
128
+ return;
129
+ }
130
+ const hadMarked = this.__tableModule.getAllSelectedCells().length > 0;
131
+ this.unselectCells();
132
+ if (!cell) {
133
+ if (hadMarked) {
134
+ this.j.e.fire('hidePopup', 'cells');
135
+ }
136
+ return;
137
+ }
138
+ const table = Dom.closest(cell, 'table', this.j.editor);
139
+ if (!table) {
140
+ return;
141
+ }
142
+ // As after a click, the first change to the cell keeps the mark
143
+ this.__selectedCell = cell;
144
+ this.__tableModule.addSelection(cell);
145
+ this.j.e.fire('showPopup', table, () => position(cell, this.j), 'cells');
146
+ }
79
147
  /**
80
148
  * Mouse click inside the table
81
149
  */
@@ -418,10 +486,16 @@ export class selectCells extends Plugin {
418
486
  /** @override */
419
487
  beforeDestruct(jodit) {
420
488
  this.__onRemoveSelection();
421
- jodit.e.off('.select-cells');
489
+ jodit.e.off('.select-cells').off('keydown', this.__onKeyDown);
422
490
  }
423
491
  }
424
492
  selectCells.requires = ['select'];
493
+ __decorate([
494
+ autobind
495
+ ], selectCells.prototype, "__onKeyDown", null);
496
+ __decorate([
497
+ watch(':keyup')
498
+ ], selectCells.prototype, "onKeyUp", null);
425
499
  __decorate([
426
500
  autobind
427
501
  ], selectCells.prototype, "onStartSelection", null);
@@ -36,7 +36,9 @@ export function tableKeyboardNavigation(editor) {
36
36
  case consts.KEY_TAB:
37
37
  case consts.KEY_LEFT: {
38
38
  next = getNextCell();
39
- if (!next) {
39
+ // Left in the first cell leaves the table, as Up in the
40
+ // top row does
41
+ if (!next && key === consts.KEY_TAB) {
40
42
  tableModule.appendRow(table, !isPrev
41
43
  ? false
42
44
  : Dom.first(table, node => Dom.isTag(node, 'tr')), !isPrev);
@@ -65,7 +67,6 @@ export function tableKeyboardNavigation(editor) {
65
67
  if (!next) {
66
68
  return;
67
69
  }
68
- editor.e.fire('hidePopup hideResizer');
69
70
  if (!next.firstChild) {
70
71
  const first = editor.createInside.element('br');
71
72
  Dom.append(next, first);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jodit",
3
- "version": "4.18.4",
3
+ "version": "4.18.7",
4
4
  "description": "Jodit is an awesome and useful wysiwyg editor with filebrowser",
5
5
  "main": "esm/index.js",
6
6
  "types": "types/index.d.ts",
package/types/config.d.ts CHANGED
@@ -1034,6 +1034,8 @@ interface Config {
1034
1034
  interface Config {
1035
1035
  /**
1036
1036
  * Keyboard hotkey mappings for delete and backspace operations (character, word, sentence).
1037
+ * On macOS the defaults leave out Cmd+Backspace, Ctrl+Backspace, Ctrl+Option+Backspace
1038
+ * and Cmd+Option+Backspace, so the browser applies the system's own bindings to them.
1037
1039
  */
1038
1040
  delete: {
1039
1041
  hotkeys: {
@@ -1404,6 +1406,9 @@ interface Config {
1404
1406
  iframeDoctype: string;
1405
1407
  /**
1406
1408
  * Custom style to be used inside the iframe to display content.
1409
+ * It goes in after `iframeCSSLinks`. The rules Jodit's own plugins need
1410
+ * in the editing document are added apart from it, so a value of your
1411
+ * own doesn't have to repeat them.
1407
1412
  *
1408
1413
  * ```javascript
1409
1414
  * Jodit.make('#editor', {
@@ -0,0 +1,29 @@
1
+ /*!
2
+ * Jodit Editor (https://xdsoft.net/jodit/)
3
+ * Released under MIT see LICENSE.txt in the project root for license information.
4
+ * Copyright (c) 2013-2026 Valerii Chupurnov. All rights reserved. https://xdsoft.net
5
+ */
6
+ /**
7
+ * A Word list paragraph, read before its `mso-list` style is lost
8
+ */
9
+ export interface WordListItem {
10
+ paragraph: HTMLElement;
11
+ list: string;
12
+ level: number;
13
+ tag: 'ul' | 'ol';
14
+ listStyleType: string | null;
15
+ start: number;
16
+ }
17
+ /**
18
+ * Finds Word's list paragraphs (`<p style="mso-list:l0 level1 lfo1">`), reads
19
+ * their list, level and type from the `mso-list:Ignore` marker, and removes the
20
+ * marker. Call it before anything strips the `mso-list` styles, then pass the
21
+ * result to {@link wrapWordListItems}
22
+ */
23
+ export declare function readWordListItems(root: HTMLElement): WordListItem[];
24
+ /**
25
+ * Turns the paragraphs found by {@link readWordListItems} into `<ul>`/`<ol>`
26
+ * lists, nesting them by level. Each paragraph becomes an `<li>` without Word's
27
+ * hanging indent
28
+ */
29
+ export declare function wrapWordListItems(items: WordListItem[]): void;
@@ -4,6 +4,7 @@
4
4
  * Copyright (c) 2013-2026 Valerii Chupurnov. All rights reserved. https://xdsoft.net
5
5
  */
6
6
  export * from "./composed-ranges";
7
+ export * from "./is-moved";
7
8
  export * from "./move-node-inside-start";
8
9
  export * from "./move-the-node-along-the-edge-outward";
9
10
  /**
@@ -0,0 +1,15 @@
1
+ /*!
2
+ * Jodit Editor (https://xdsoft.net/jodit/)
3
+ * Released under MIT see LICENSE.txt in the project root for license information.
4
+ * Copyright (c) 2013-2026 Valerii Chupurnov. All rights reserved. https://xdsoft.net
5
+ */
6
+ /**
7
+ * @module selection
8
+ */
9
+ import type { IJodit, Nullable } from "../../../types/index";
10
+ /**
11
+ * Whether the selection, `before` as it was when a key went down, has since
12
+ * moved to somewhere else in the editor
13
+ * @private
14
+ */
15
+ export declare function isMoved(jodit: IJodit, before: Nullable<Range>): boolean;
@@ -220,5 +220,8 @@ declare const _exports: {
220
220
  Loop: string;
221
221
  Muted: string;
222
222
  Controls: string;
223
+ 'Start at...': string;
224
+ 'Start numbering at': string;
225
+ 'Number for the first item': string;
223
226
  };
224
227
  export = _exports;
@@ -226,5 +226,8 @@ declare const _exports: {
226
226
  Loop: string;
227
227
  Muted: string;
228
228
  Controls: string;
229
+ 'Start at...': string;
230
+ 'Start numbering at': string;
231
+ 'Number for the first item': string;
229
232
  };
230
233
  export = _exports;
@@ -218,5 +218,8 @@ declare const _exports: {
218
218
  Loop: string;
219
219
  Muted: string;
220
220
  Controls: string;
221
+ 'Start at...': string;
222
+ 'Start numbering at': string;
223
+ 'Number for the first item': string;
221
224
  };
222
225
  export = _exports;
@@ -222,5 +222,8 @@ declare const _exports: {
222
222
  Loop: string;
223
223
  Muted: string;
224
224
  Controls: string;
225
+ 'Start at...': string;
226
+ 'Start numbering at': string;
227
+ 'Number for the first item': string;
225
228
  };
226
229
  export = _exports;
@@ -222,5 +222,8 @@ declare const _exports: {
222
222
  Loop: string;
223
223
  Muted: string;
224
224
  Controls: string;
225
+ 'Start at...': string;
226
+ 'Start numbering at': string;
227
+ 'Number for the first item': string;
225
228
  };
226
229
  export = _exports;
@@ -217,5 +217,8 @@ declare const _exports: {
217
217
  Loop: string;
218
218
  Muted: string;
219
219
  Controls: string;
220
+ 'Start at...': string;
221
+ 'Start numbering at': string;
222
+ 'Number for the first item': string;
220
223
  };
221
224
  export = _exports;
@@ -223,5 +223,8 @@ declare const _exports: {
223
223
  Loop: string;
224
224
  Muted: string;
225
225
  Controls: string;
226
+ 'Start at...': string;
227
+ 'Start numbering at': string;
228
+ 'Number for the first item': string;
226
229
  };
227
230
  export = _exports;
@@ -217,5 +217,8 @@ declare const _exports: {
217
217
  Loop: string;
218
218
  Muted: string;
219
219
  Controls: string;
220
+ 'Start at...': string;
221
+ 'Start numbering at': string;
222
+ 'Number for the first item': string;
220
223
  };
221
224
  export = _exports;
@@ -217,5 +217,8 @@ declare const _exports: {
217
217
  Loop: string;
218
218
  Muted: string;
219
219
  Controls: string;
220
+ 'Start at...': string;
221
+ 'Start numbering at': string;
222
+ 'Number for the first item': string;
220
223
  };
221
224
  export = _exports;
@@ -219,5 +219,8 @@ declare const _exports: {
219
219
  Loop: string;
220
220
  Muted: string;
221
221
  Controls: string;
222
+ 'Start at...': string;
223
+ 'Start numbering at': string;
224
+ 'Number for the first item': string;
222
225
  };
223
226
  export = _exports;
@@ -218,5 +218,8 @@ declare const _exports: {
218
218
  Loop: string;
219
219
  Muted: string;
220
220
  Controls: string;
221
+ 'Start at...': string;
222
+ 'Start numbering at': string;
223
+ 'Number for the first item': string;
221
224
  };
222
225
  export = _exports;
@@ -222,5 +222,8 @@ declare const _exports: {
222
222
  Loop: string;
223
223
  Muted: string;
224
224
  Controls: string;
225
+ 'Start at...': string;
226
+ 'Start numbering at': string;
227
+ 'Number for the first item': string;
225
228
  };
226
229
  export = _exports;
@@ -222,5 +222,8 @@ declare const _exports: {
222
222
  Loop: string;
223
223
  Muted: string;
224
224
  Controls: string;
225
+ 'Start at...': string;
226
+ 'Start numbering at': string;
227
+ 'Number for the first item': string;
225
228
  };
226
229
  export = _exports;
@@ -216,5 +216,8 @@ declare const _exports: {
216
216
  Loop: string;
217
217
  Muted: string;
218
218
  Controls: string;
219
+ 'Start at...': string;
220
+ 'Start numbering at': string;
221
+ 'Number for the first item': string;
219
222
  };
220
223
  export = _exports;
@@ -217,5 +217,8 @@ declare const _exports: {
217
217
  Loop: string;
218
218
  Muted: string;
219
219
  Controls: string;
220
+ 'Start at...': string;
221
+ 'Start numbering at': string;
222
+ 'Number for the first item': string;
220
223
  };
221
224
  export = _exports;
@@ -218,5 +218,8 @@ declare const _exports: {
218
218
  Loop: string;
219
219
  Muted: string;
220
220
  Controls: string;
221
+ 'Start at...': string;
222
+ 'Start numbering at': string;
223
+ 'Number for the first item': string;
221
224
  };
222
225
  export = _exports;
@@ -226,5 +226,8 @@ declare const _exports: {
226
226
  Loop: string;
227
227
  Muted: string;
228
228
  Controls: string;
229
+ 'Start at...': string;
230
+ 'Start numbering at': string;
231
+ 'Number for the first item': string;
229
232
  };
230
233
  export = _exports;
@@ -217,5 +217,8 @@ declare const _exports: {
217
217
  Loop: string;
218
218
  Muted: string;
219
219
  Controls: string;
220
+ 'Start at...': string;
221
+ 'Start numbering at': string;
222
+ 'Number for the first item': string;
220
223
  };
221
224
  export = _exports;
@@ -222,5 +222,8 @@ declare const _exports: {
222
222
  Loop: string;
223
223
  Muted: string;
224
224
  Controls: string;
225
+ 'Start at...': string;
226
+ 'Start numbering at': string;
227
+ 'Number for the first item': string;
225
228
  };
226
229
  export = _exports;
@@ -216,5 +216,8 @@ declare const _exports: {
216
216
  Loop: string;
217
217
  Muted: string;
218
218
  Controls: string;
219
+ 'Start at...': string;
220
+ 'Start numbering at': string;
221
+ 'Number for the first item': string;
219
222
  };
220
223
  export = _exports;
@@ -224,5 +224,8 @@ declare const _exports: {
224
224
  Loop: string;
225
225
  Muted: string;
226
226
  Controls: string;
227
+ 'Start at...': string;
228
+ 'Start numbering at': string;
229
+ 'Number for the first item': string;
227
230
  };
228
231
  export = _exports;
@@ -225,5 +225,8 @@ declare const _exports: {
225
225
  Loop: string;
226
226
  Muted: string;
227
227
  Controls: string;
228
+ 'Start at...': string;
229
+ 'Start numbering at': string;
230
+ 'Number for the first item': string;
228
231
  };
229
232
  export = _exports;