jodit 4.18.7 → 4.18.8

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 (64) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/es2015/jodit.css +1 -1
  3. package/es2015/jodit.fat.min.js +8 -8
  4. package/es2015/jodit.js +164 -16
  5. package/es2015/jodit.min.js +5 -5
  6. package/es2015/plugins/debug/debug.css +1 -1
  7. package/es2015/plugins/debug/debug.js +1 -1
  8. package/es2015/plugins/debug/debug.min.js +1 -1
  9. package/es2015/plugins/speech-recognize/speech-recognize.css +1 -1
  10. package/es2015/plugins/speech-recognize/speech-recognize.js +1 -1
  11. package/es2015/plugins/speech-recognize/speech-recognize.min.js +1 -1
  12. package/es2018/jodit.fat.min.js +8 -8
  13. package/es2018/jodit.min.js +5 -5
  14. package/es2018/plugins/debug/debug.min.js +1 -1
  15. package/es2018/plugins/speech-recognize/speech-recognize.min.js +1 -1
  16. package/es2021/jodit.css +1 -1
  17. package/es2021/jodit.fat.min.js +9 -9
  18. package/es2021/jodit.js +164 -16
  19. package/es2021/jodit.min.js +5 -5
  20. package/es2021/plugins/debug/debug.css +1 -1
  21. package/es2021/plugins/debug/debug.js +1 -1
  22. package/es2021/plugins/debug/debug.min.js +1 -1
  23. package/es2021/plugins/speech-recognize/speech-recognize.css +1 -1
  24. package/es2021/plugins/speech-recognize/speech-recognize.js +1 -1
  25. package/es2021/plugins/speech-recognize/speech-recognize.min.js +1 -1
  26. package/es2021.en/jodit.css +1 -1
  27. package/es2021.en/jodit.fat.min.js +9 -9
  28. package/es2021.en/jodit.js +164 -16
  29. package/es2021.en/jodit.min.js +5 -5
  30. package/es2021.en/plugins/debug/debug.css +1 -1
  31. package/es2021.en/plugins/debug/debug.js +1 -1
  32. package/es2021.en/plugins/debug/debug.min.js +1 -1
  33. package/es2021.en/plugins/speech-recognize/speech-recognize.css +1 -1
  34. package/es2021.en/plugins/speech-recognize/speech-recognize.js +1 -1
  35. package/es2021.en/plugins/speech-recognize/speech-recognize.min.js +1 -1
  36. package/es5/jodit.css +2 -2
  37. package/es5/jodit.fat.min.js +2 -2
  38. package/es5/jodit.js +172 -16
  39. package/es5/jodit.min.css +2 -2
  40. package/es5/jodit.min.js +2 -2
  41. package/es5/plugins/debug/debug.css +1 -1
  42. package/es5/plugins/debug/debug.js +1 -1
  43. package/es5/plugins/debug/debug.min.js +1 -1
  44. package/es5/plugins/speech-recognize/speech-recognize.css +1 -1
  45. package/es5/plugins/speech-recognize/speech-recognize.js +1 -1
  46. package/es5/plugins/speech-recognize/speech-recognize.min.js +1 -1
  47. package/es5/polyfills.fat.min.js +1 -1
  48. package/es5/polyfills.js +1 -1
  49. package/es5/polyfills.min.js +1 -1
  50. package/esm/config.d.ts +2 -2
  51. package/esm/core/constants.js +1 -1
  52. package/esm/modules/dialog/dialog.js +18 -3
  53. package/esm/plugins/backspace/cases/check-join-neighbors.js +81 -0
  54. package/esm/plugins/backspace/cases/check-remove-char.js +6 -5
  55. package/esm/plugins/backspace/cases/check-unwrap-list-item.d.ts +26 -0
  56. package/esm/plugins/backspace/cases/check-unwrap-list-item.js +56 -0
  57. package/esm/plugins/backspace/cases/index.js +2 -0
  58. package/esm/plugins/backspace/config.d.ts +2 -2
  59. package/esm/plugins/enter/enter.js +1 -1
  60. package/esm/plugins/enter/helpers/check-br.js +7 -2
  61. package/package.json +1 -1
  62. package/types/config.d.ts +2 -2
  63. package/types/plugins/backspace/cases/check-unwrap-list-item.d.ts +26 -0
  64. package/types/plugins/backspace/config.d.ts +2 -2
@@ -1,7 +1,7 @@
1
1
  /*!
2
2
  * jodit - Jodit is an awesome and useful wysiwyg editor with filebrowser
3
3
  * Author: Chupurnov <chupurnov@gmail.com> (https://xdsoft.net/jodit/)
4
- * Version: v4.18.7
4
+ * Version: v4.18.8
5
5
  * Url: https://xdsoft.net/jodit/
6
6
  * License(s): MIT
7
7
  */
@@ -1,7 +1,7 @@
1
1
  /*!
2
2
  * jodit - Jodit is an awesome and useful wysiwyg editor with filebrowser
3
3
  * Author: Chupurnov <chupurnov@gmail.com> (https://xdsoft.net/jodit/)
4
- * Version: v4.18.7
4
+ * Version: v4.18.8
5
5
  * Url: https://xdsoft.net/jodit/
6
6
  * License(s): MIT
7
7
  */
@@ -1,7 +1,7 @@
1
1
  /*!
2
2
  * jodit - Jodit is an awesome and useful wysiwyg editor with filebrowser
3
3
  * Author: Chupurnov <chupurnov@gmail.com> (https://xdsoft.net/jodit/)
4
- * Version: v4.18.7
4
+ * Version: v4.18.8
5
5
  * Url: https://xdsoft.net/jodit/
6
6
  * License(s): MIT
7
7
  */
@@ -1,7 +1,7 @@
1
1
  /*!
2
2
  * jodit - Jodit is an awesome and useful wysiwyg editor with filebrowser
3
3
  * Author: Chupurnov <chupurnov@gmail.com> (https://xdsoft.net/jodit/)
4
- * Version: v4.18.7
4
+ * Version: v4.18.8
5
5
  * Url: https://xdsoft.net/jodit/
6
6
  * License(s): MIT
7
7
  */
@@ -1,7 +1,7 @@
1
1
  /*!
2
2
  * jodit - Jodit is an awesome and useful wysiwyg editor with filebrowser
3
3
  * Author: Chupurnov <chupurnov@gmail.com> (https://xdsoft.net/jodit/)
4
- * Version: v4.18.7
4
+ * Version: v4.18.8
5
5
  * Url: https://xdsoft.net/jodit/
6
6
  * License(s): MIT
7
7
  */
@@ -1,7 +1,7 @@
1
1
  /*!
2
2
  * jodit - Jodit is an awesome and useful wysiwyg editor with filebrowser
3
3
  * Author: Chupurnov <chupurnov@gmail.com> (https://xdsoft.net/jodit/)
4
- * Version: v4.18.7
4
+ * Version: v4.18.8
5
5
  * Url: https://xdsoft.net/jodit/
6
6
  * License(s): MIT
7
7
  */
@@ -1,7 +1,7 @@
1
1
  /*!
2
2
  * jodit - Jodit is an awesome and useful wysiwyg editor with filebrowser
3
3
  * Author: Chupurnov <chupurnov@gmail.com> (https://xdsoft.net/jodit/)
4
- * Version: v4.18.7
4
+ * Version: v4.18.8
5
5
  * Url: https://xdsoft.net/jodit/
6
6
  * License(s): MIT
7
7
  */
package/es5/polyfills.js CHANGED
@@ -1,7 +1,7 @@
1
1
  /*!
2
2
  * jodit - Jodit is an awesome and useful wysiwyg editor with filebrowser
3
3
  * Author: Chupurnov <chupurnov@gmail.com> (https://xdsoft.net/jodit/)
4
- * Version: v4.18.7
4
+ * Version: v4.18.8
5
5
  * Url: https://xdsoft.net/jodit/
6
6
  * License(s): MIT
7
7
  */
@@ -1,7 +1,7 @@
1
1
  /*!
2
2
  * jodit - Jodit is an awesome and useful wysiwyg editor with filebrowser
3
3
  * Author: Chupurnov <chupurnov@gmail.com> (https://xdsoft.net/jodit/)
4
- * Version: v4.18.7
4
+ * Version: v4.18.8
5
5
  * Url: https://xdsoft.net/jodit/
6
6
  * License(s): MIT
7
7
  */
package/esm/config.d.ts CHANGED
@@ -1051,8 +1051,8 @@ interface Config {
1051
1051
  * key, so the plugin no longer applies that particular behavior.
1052
1052
  * Available keys: `remove-unbreakable`, `remove-not-editable`,
1053
1053
  * `remove-char`, `table-cell`, `remove-empty-parent`,
1054
- * `remove-empty-neighbor`, `join-two-lists`, `join-neighbors`,
1055
- * `unwrap-first-list-item`.
1054
+ * `remove-empty-neighbor`, `join-two-lists`, `unwrap-list-item`,
1055
+ * `join-neighbors`, `unwrap-first-list-item`.
1056
1056
  *
1057
1057
  * ```javascript
1058
1058
  * Jodit.make('#editor', {
@@ -3,7 +3,7 @@
3
3
  * Released under MIT see LICENSE.txt in the project root for license information.
4
4
  * Copyright (c) 2013-2026 Valerii Chupurnov. All rights reserved. https://xdsoft.net
5
5
  */
6
- export const APP_VERSION = "4.18.7";
6
+ export const APP_VERSION = "4.18.8";
7
7
  // prettier-ignore
8
8
  export const ES = "es2020";
9
9
  export const IS_ES_MODERN = true;
@@ -28,6 +28,10 @@ import { Icon } from "../../core/ui/index.js";
28
28
  import { View } from "../../core/view/view.js";
29
29
  import { ViewWithToolbar } from "../../core/view/view-with-toolbar.js";
30
30
  import { Config } from "../../config.js";
31
+ /**
32
+ * A position from 0 up to `max`, or 0 when the panel is larger than the window
33
+ */
34
+ const clampToWindow = (value, max) => Math.max(0, Math.min(value, max));
31
35
  Config.prototype.dialog = {
32
36
  namespace: '',
33
37
  extraButtons: [],
@@ -126,6 +130,11 @@ let Dialog = Dialog_1 = class Dialog extends ViewWithToolbar {
126
130
  this.startY = e.clientY;
127
131
  this.startPoint.x = css(this.dialog, 'left');
128
132
  this.startPoint.y = css(this.dialog, 'top');
133
+ // Rounded up: at the right edge a fraction of a pixel less room would
134
+ // wrap the header of a panel that has no width of its own
135
+ const { width, height } = this.dialog.getBoundingClientRect();
136
+ this.startPoint.w = Math.ceil(width);
137
+ this.startPoint.h = Math.ceil(height);
129
138
  this.setMaxZIndex();
130
139
  if (e.cancelable) {
131
140
  e.preventDefault();
@@ -142,7 +151,13 @@ let Dialog = Dialog_1 = class Dialog extends ViewWithToolbar {
142
151
  }
143
152
  __onMouseMove(e) {
144
153
  if (this.draggable && this.o.draggable) {
145
- this.setPosition(this.startPoint.x + e.clientX - this.startX, this.startPoint.y + e.clientY - this.startY);
154
+ const { documentElement } = this.od;
155
+ // Keep the whole panel in the window at the size it had when the
156
+ // drag began. A panel with no width of its own would otherwise
157
+ // shrink as it neared the right edge, and then leave the window
158
+ this.setPosition(clampToWindow(this.startPoint.x + e.clientX - this.startX, (documentElement.clientWidth || this.ow.innerWidth) -
159
+ this.startPoint.w), clampToWindow(this.startPoint.y + e.clientY - this.startY, (documentElement.clientHeight || this.ow.innerHeight) -
160
+ this.startPoint.h));
146
161
  if (this.e) {
147
162
  /**
148
163
  * Fired when dialog box is moved
@@ -291,8 +306,8 @@ let Dialog = Dialog_1 = class Dialog extends ViewWithToolbar {
291
306
  }
292
307
  // strings on purpose: `css()` would truncate fractional pixels
293
308
  css(this.dialog, {
294
- left: (x || left) + 'px',
295
- top: (y || top) + 'px'
309
+ left: (x !== null && x !== void 0 ? x : left) + 'px',
310
+ top: (y !== null && y !== void 0 ? y : top) + 'px'
296
311
  });
297
312
  return this;
298
313
  }
@@ -11,6 +11,9 @@ import { getMoveFilter } from "../helpers.js";
11
11
  * @private
12
12
  */
13
13
  export function checkJoinNeighbors(jodit, fakeNode, backspace) {
14
+ if (checkJoinBareText(jodit, fakeNode, backspace)) {
15
+ return true;
16
+ }
14
17
  let nextBox = fakeNode, mainClosestBox = nextBox;
15
18
  // Find the main big closest element
16
19
  while (nextBox &&
@@ -44,6 +47,7 @@ export function checkJoinNeighbors(jodit, fakeNode, backspace) {
44
47
  if (sibling &&
45
48
  (checkPullNextLine(jodit, fakeNode, box, sibling, backspace) ||
46
49
  checkMoveListContent(jodit, box, sibling, backspace) ||
50
+ checkJoinInlineSibling(jodit, box, sibling, backspace) ||
47
51
  moveContentAndRemoveEmpty(jodit, box, findEdgeBlock(resolveTableSibling(sibling, backspace), backspace, jodit.editor), backspace))) {
48
52
  jodit.s.setCursorBefore(fakeNode);
49
53
  return true;
@@ -143,6 +147,83 @@ function checkPullNextLine(jodit, fakeNode, box, sibling, backspace) {
143
147
  }
144
148
  return true;
145
149
  }
150
+ /**
151
+ * A block next to bare text in the same parent joins that text, as the
152
+ * browsers do: `<li>one<p>|two</p></li>` gives `<li>one|two</li>`, and
153
+ * `<li><p>one|</p>two</li>` gives `<li><p>one|two</p></li>`
154
+ * @private
155
+ */
156
+ function checkJoinInlineSibling(jodit, box, sibling, backspace) {
157
+ if (Dom.isBlock(sibling) ||
158
+ !Dom.isBlock(box) ||
159
+ Dom.isList(box) ||
160
+ // The caret's block is nested deeper than the text: `text<div><p>|x</p></div>`
161
+ box.parentNode !== sibling.parentNode ||
162
+ Array.from(box.childNodes).some(node => Dom.isBlock(node))) {
163
+ return false;
164
+ }
165
+ if (backspace) {
166
+ // Text after the block keeps its own line
167
+ const next = Dom.findNotEmptySibling(box, false);
168
+ if (next && !Dom.isBlock(next) && !Dom.isTag(next, 'br')) {
169
+ Dom.after(box, jodit.createInside.element('br'));
170
+ }
171
+ Dom.unwrap(box);
172
+ return true;
173
+ }
174
+ const filter = getMoveFilter(jodit);
175
+ for (let node = sibling; node && !Dom.isBlock(node);) {
176
+ const next = node.nextSibling;
177
+ if (Dom.isTag(node, 'br')) {
178
+ Dom.safeRemove(node);
179
+ break;
180
+ }
181
+ filter(node) ? Dom.append(box, node) : Dom.safeRemove(node);
182
+ node = next;
183
+ }
184
+ return true;
185
+ }
186
+ /**
187
+ * Bare text next to a block in the same parent, as the browsers join them:
188
+ * Backspace in `<div><p>a</p>|b</div>` gives `<div><p>a|b</p></div>`, Delete
189
+ * in `<div>a|<p>b</p>c</div>` gives `<div>a|b<br>c</div>`
190
+ */
191
+ function checkJoinBareText(jodit, fakeNode, backspace) {
192
+ const block = Dom.findNotEmptySibling(fakeNode, backspace);
193
+ if (!Dom.isElement(block) ||
194
+ !Dom.isBlock(block) ||
195
+ Dom.isList(block) ||
196
+ Dom.isTag(block, 'table') ||
197
+ Dom.isCell(block) ||
198
+ !Dom.isContentEditable(block, jodit.editor) ||
199
+ Array.from(block.childNodes).some(node => Dom.isBlock(node))) {
200
+ return false;
201
+ }
202
+ const filter = getMoveFilter(jodit);
203
+ if (backspace) {
204
+ // The caret's line goes to the end of the block before it
205
+ for (let node = fakeNode; node && !Dom.isBlock(node);) {
206
+ const next = node.nextSibling;
207
+ if (Dom.isTag(node, 'br')) {
208
+ Dom.safeRemove(node);
209
+ break;
210
+ }
211
+ filter(node) ? Dom.append(block, node) : Dom.safeRemove(node);
212
+ node = next;
213
+ }
214
+ }
215
+ else {
216
+ // The block's content joins the caret's line, and text after the
217
+ // block keeps its own line
218
+ const next = Dom.findNotEmptySibling(block, false);
219
+ if (next && !Dom.isBlock(next) && !Dom.isTag(next, 'br')) {
220
+ Dom.after(block, jodit.createInside.element('br'));
221
+ }
222
+ Dom.unwrap(block);
223
+ }
224
+ jodit.s.setCursorBefore(fakeNode);
225
+ return true;
226
+ }
146
227
  function checkMoveListContent(jodit, mainClosestBox, sibling, backspace) {
147
228
  // Process UL/LI/OL cases
148
229
  const siblingIsList = Dom.isTag(sibling, LIST_TAGS);
@@ -84,12 +84,13 @@ function getNextInlineSibling(sibling, backspace, root) {
84
84
  let nextSibling = Dom.sibling(sibling, backspace);
85
85
  if (!nextSibling && sibling.parentNode && sibling.parentNode !== root) {
86
86
  nextSibling = findMostNestedNeighbor(sibling, !backspace, root, true);
87
- // Do not cross a list-item boundary. At the start of a list item the
88
- // neighbor can be the text of the parent/previous item; deleting a char
89
- // there is wrong — the list cases must handle the outdent/merge (#1277).
87
+ // Do not cross a block boundary. At the start of a list item the
88
+ // neighbor can be the text of the parent/previous item (#1277), and at
89
+ // the start of a paragraph the text before it in the same parent
90
+ // (#1693); deleting a char there is wrong — the join cases handle them.
90
91
  if (nextSibling &&
91
- Dom.closest(sibling, 'li', root) !==
92
- Dom.closest(nextSibling, 'li', root)) {
92
+ Dom.closest(sibling, Dom.isBlock, root) !==
93
+ Dom.closest(nextSibling, Dom.isBlock, root)) {
93
94
  return null;
94
95
  }
95
96
  }
@@ -0,0 +1,26 @@
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 plugins/backspace
8
+ */
9
+ import type { IJodit } from "../../../types/index";
10
+ /**
11
+ * Backspace at the start of a later list item takes the bullet off, as Word
12
+ * does: the item becomes a paragraph where it was, and the list is split
13
+ * around it. A split `<ol>` carries its numbering on with `start`.
14
+ *
15
+ * @example
16
+ * ```html
17
+ * <ol><li>first</li><li>|second</li><li>third</li></ol>
18
+ * ```
19
+ * Result
20
+ * ```html
21
+ * <ol><li>first</li></ol><p>|second</p><ol start="2"><li>third</li></ol>
22
+ * ```
23
+ *
24
+ * @private
25
+ */
26
+ export declare function checkUnwrapListItem(jodit: IJodit, fakeNode: Node, backspace: boolean): boolean;
@@ -0,0 +1,56 @@
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
+ import { Dom } from "../../../core/dom/dom.js";
7
+ /**
8
+ * Backspace at the start of a later list item takes the bullet off, as Word
9
+ * does: the item becomes a paragraph where it was, and the list is split
10
+ * around it. A split `<ol>` carries its numbering on with `start`.
11
+ *
12
+ * @example
13
+ * ```html
14
+ * <ol><li>first</li><li>|second</li><li>third</li></ol>
15
+ * ```
16
+ * Result
17
+ * ```html
18
+ * <ol><li>first</li></ol><p>|second</p><ol start="2"><li>third</li></ol>
19
+ * ```
20
+ *
21
+ * @private
22
+ */
23
+ export function checkUnwrapListItem(jodit, fakeNode, backspace) {
24
+ if (!backspace) {
25
+ return false;
26
+ }
27
+ const li = Dom.closest(fakeNode, 'li', jodit.editor);
28
+ const list = li ? li.parentElement : null;
29
+ if (!li ||
30
+ !Dom.isList(list) ||
31
+ !li.previousElementSibling ||
32
+ Dom.isEmpty(li) ||
33
+ Array.from(li.childNodes).some(node => Dom.isBlock(node)) ||
34
+ !jodit.s.cursorInTheEdge(true, li)) {
35
+ return false;
36
+ }
37
+ const p = jodit.createInside.element(jodit.o.enterBlock);
38
+ Dom.after(list, p);
39
+ if (li.nextElementSibling) {
40
+ const rest = list.cloneNode(false);
41
+ // Two lists cannot share one id
42
+ rest.removeAttribute('id');
43
+ while (li.nextSibling) {
44
+ Dom.append(rest, li.nextSibling);
45
+ }
46
+ if (Dom.isTag(list, 'ol')) {
47
+ const start = parseInt(list.getAttribute('start') || '1', 10) || 1;
48
+ rest.setAttribute('start', String(start + list.children.length - 1));
49
+ }
50
+ Dom.after(p, rest);
51
+ }
52
+ Dom.moveContent(li, p);
53
+ Dom.safeRemove(li);
54
+ jodit.s.setCursorBefore(fakeNode);
55
+ return true;
56
+ }
@@ -12,6 +12,7 @@ import { checkRemoveEmptyParent } from "./check-remove-empty-parent.js";
12
12
  import { checkRemoveUnbreakableElement } from "./check-remove-unbreakable-element.js";
13
13
  import { checkTableCell } from "./check-table-cell.js";
14
14
  import { checkUnwrapFirstListItem } from "./check-unwrap-first-list-item.js";
15
+ import { checkUnwrapListItem } from "./check-unwrap-list-item.js";
15
16
  /**
16
17
  * Ordered delete/backspace cases with stable keys. The first one returning
17
18
  * `true` wins. The keys are stable across minified builds (function names are
@@ -26,6 +27,7 @@ export const casesMap = [
26
27
  ['remove-empty-parent', checkRemoveEmptyParent],
27
28
  ['remove-empty-neighbor', checkRemoveEmptyNeighbor],
28
29
  ['join-two-lists', checkJoinTwoLists],
30
+ ['unwrap-list-item', checkUnwrapListItem],
29
31
  ['join-neighbors', checkJoinNeighbors],
30
32
  ['unwrap-first-list-item', checkUnwrapFirstListItem]
31
33
  ];
@@ -24,8 +24,8 @@ declare module 'jodit/config' {
24
24
  * key, so the plugin no longer applies that particular behavior.
25
25
  * Available keys: `remove-unbreakable`, `remove-not-editable`,
26
26
  * `remove-char`, `table-cell`, `remove-empty-parent`,
27
- * `remove-empty-neighbor`, `join-two-lists`, `join-neighbors`,
28
- * `unwrap-first-list-item`.
27
+ * `remove-empty-neighbor`, `join-two-lists`, `unwrap-list-item`,
28
+ * `join-neighbors`, `unwrap-first-list-item`.
29
29
  *
30
30
  * ```javascript
31
31
  * Jodit.make('#editor', {
@@ -68,7 +68,7 @@ export class enter extends Plugin {
68
68
  moveCursorOutFromSpecialTags(jodit, fake, ['a']);
69
69
  let block = getBlockWrapper(fake, jodit);
70
70
  const isLi = Dom.isLeaf(block);
71
- // if use <br> defaultTag for break line or when was entered SHIFt key or in <td> or <th> or <blockquote>
71
+ // if use <br> defaultTag for break line or when was entered SHIFt key or in <td>, <th> or <blockquote> without an inner block
72
72
  if ((!isLi || (event === null || event === void 0 ? void 0 : event.shiftKey)) &&
73
73
  checkBR(fake, jodit, event === null || event === void 0 ? void 0 : event.shiftKey, block)) {
74
74
  return false;
@@ -11,7 +11,12 @@ import { scrollIntoViewIfNeeded } from "../../../core/helpers/utils/scroll-into-
11
11
  * @private
12
12
  */
13
13
  export function checkBR(fake, jodit, shiftKeyPressed, block) {
14
- const isMultiLineBlock = Boolean(Dom.closest(fake, ['pre', 'blockquote'], jodit.editor));
14
+ // Text in a <pre>, or bare text in a quote, gets a BR. A real block inside
15
+ // a quote (<p>, <h3>, ...) is split like anywhere else, as in a cell below.
16
+ const isMultiLineBlock = Boolean(Dom.closest(fake, 'pre', jodit.editor)) ||
17
+ (block
18
+ ? Dom.isTag(block, 'blockquote')
19
+ : Boolean(Dom.closest(fake, 'blockquote', jodit.editor)));
15
20
  // A cell itself can't be split into two cells, so bare cell content gets
16
21
  // a BR. But when the cell already holds a real block (<p>, <h3>, ...) that
17
22
  // block is split like anywhere else, otherwise every line of the cell
@@ -21,7 +26,7 @@ export function checkBR(fake, jodit, shiftKeyPressed, block) {
21
26
  ? Dom.isCell(block)
22
27
  : Boolean(Dom.closest(fake, ['td', 'th'], jodit.editor)));
23
28
  const isBRMode = jodit.o.enter.toLowerCase() === BR.toLowerCase();
24
- // if you use <br> defaultTag for break line or when was entered SHIFt key or in <td> or <th> or <blockquote>
29
+ // if you use <br> defaultTag for break line or when was entered SHIFt key or in <td>, <th> or <blockquote> without an inner block
25
30
  if (isBRMode ||
26
31
  isCell ||
27
32
  (shiftKeyPressed && !isMultiLineBlock) ||
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jodit",
3
- "version": "4.18.7",
3
+ "version": "4.18.8",
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
@@ -1051,8 +1051,8 @@ interface Config {
1051
1051
  * key, so the plugin no longer applies that particular behavior.
1052
1052
  * Available keys: `remove-unbreakable`, `remove-not-editable`,
1053
1053
  * `remove-char`, `table-cell`, `remove-empty-parent`,
1054
- * `remove-empty-neighbor`, `join-two-lists`, `join-neighbors`,
1055
- * `unwrap-first-list-item`.
1054
+ * `remove-empty-neighbor`, `join-two-lists`, `unwrap-list-item`,
1055
+ * `join-neighbors`, `unwrap-first-list-item`.
1056
1056
  *
1057
1057
  * ```javascript
1058
1058
  * Jodit.make('#editor', {
@@ -0,0 +1,26 @@
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 plugins/backspace
8
+ */
9
+ import type { IJodit } from "../../../types/index";
10
+ /**
11
+ * Backspace at the start of a later list item takes the bullet off, as Word
12
+ * does: the item becomes a paragraph where it was, and the list is split
13
+ * around it. A split `<ol>` carries its numbering on with `start`.
14
+ *
15
+ * @example
16
+ * ```html
17
+ * <ol><li>first</li><li>|second</li><li>third</li></ol>
18
+ * ```
19
+ * Result
20
+ * ```html
21
+ * <ol><li>first</li></ol><p>|second</p><ol start="2"><li>third</li></ol>
22
+ * ```
23
+ *
24
+ * @private
25
+ */
26
+ export declare function checkUnwrapListItem(jodit: IJodit, fakeNode: Node, backspace: boolean): boolean;
@@ -24,8 +24,8 @@ declare module 'jodit/config' {
24
24
  * key, so the plugin no longer applies that particular behavior.
25
25
  * Available keys: `remove-unbreakable`, `remove-not-editable`,
26
26
  * `remove-char`, `table-cell`, `remove-empty-parent`,
27
- * `remove-empty-neighbor`, `join-two-lists`, `join-neighbors`,
28
- * `unwrap-first-list-item`.
27
+ * `remove-empty-neighbor`, `join-two-lists`, `unwrap-list-item`,
28
+ * `join-neighbors`, `unwrap-first-list-item`.
29
29
  *
30
30
  * ```javascript
31
31
  * Jodit.make('#editor', {