jodit 4.18.7 → 4.18.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/es2015/jodit.css +1 -1
- package/es2015/jodit.fat.min.js +9 -9
- package/es2015/jodit.js +215 -47
- package/es2015/jodit.min.js +7 -7
- package/es2015/plugins/debug/debug.css +1 -1
- package/es2015/plugins/debug/debug.js +1 -1
- package/es2015/plugins/debug/debug.min.js +1 -1
- package/es2015/plugins/speech-recognize/speech-recognize.css +1 -1
- package/es2015/plugins/speech-recognize/speech-recognize.js +1 -1
- package/es2015/plugins/speech-recognize/speech-recognize.min.js +1 -1
- package/es2018/jodit.fat.min.js +9 -9
- package/es2018/jodit.min.js +7 -7
- package/es2018/plugins/debug/debug.min.js +1 -1
- package/es2018/plugins/speech-recognize/speech-recognize.min.js +1 -1
- package/es2021/jodit.css +1 -1
- package/es2021/jodit.fat.min.js +10 -10
- package/es2021/jodit.js +215 -47
- package/es2021/jodit.min.js +7 -7
- package/es2021/plugins/debug/debug.css +1 -1
- package/es2021/plugins/debug/debug.js +1 -1
- package/es2021/plugins/debug/debug.min.js +1 -1
- package/es2021/plugins/speech-recognize/speech-recognize.css +1 -1
- package/es2021/plugins/speech-recognize/speech-recognize.js +1 -1
- package/es2021/plugins/speech-recognize/speech-recognize.min.js +1 -1
- package/es2021.en/jodit.css +1 -1
- package/es2021.en/jodit.fat.min.js +10 -10
- package/es2021.en/jodit.js +189 -21
- package/es2021.en/jodit.min.js +7 -7
- package/es2021.en/plugins/debug/debug.css +1 -1
- package/es2021.en/plugins/debug/debug.js +1 -1
- package/es2021.en/plugins/debug/debug.min.js +1 -1
- package/es2021.en/plugins/speech-recognize/speech-recognize.css +1 -1
- package/es2021.en/plugins/speech-recognize/speech-recognize.js +1 -1
- package/es2021.en/plugins/speech-recognize/speech-recognize.min.js +1 -1
- package/es5/jodit.css +2 -2
- package/es5/jodit.fat.min.js +2 -2
- package/es5/jodit.js +223 -47
- package/es5/jodit.min.css +2 -2
- package/es5/jodit.min.js +2 -2
- package/es5/plugins/debug/debug.css +1 -1
- package/es5/plugins/debug/debug.js +1 -1
- package/es5/plugins/debug/debug.min.js +1 -1
- package/es5/plugins/speech-recognize/speech-recognize.css +1 -1
- package/es5/plugins/speech-recognize/speech-recognize.js +1 -1
- package/es5/plugins/speech-recognize/speech-recognize.min.js +1 -1
- package/es5/polyfills.fat.min.js +1 -1
- package/es5/polyfills.js +1 -1
- package/es5/polyfills.min.js +1 -1
- package/esm/config.d.ts +2 -2
- package/esm/core/constants.js +1 -1
- package/esm/core/ui/button/tooltip/tooltip.js +7 -0
- package/esm/langs/ar.d.ts +1 -0
- package/esm/langs/ar.js +2 -1
- package/esm/langs/az.d.ts +1 -0
- package/esm/langs/az.js +2 -1
- package/esm/langs/cs_cz.d.ts +1 -0
- package/esm/langs/cs_cz.js +2 -1
- package/esm/langs/de.d.ts +1 -0
- package/esm/langs/de.js +2 -1
- package/esm/langs/es.d.ts +1 -0
- package/esm/langs/es.js +2 -1
- package/esm/langs/fa.d.ts +1 -0
- package/esm/langs/fa.js +2 -1
- package/esm/langs/fi.d.ts +1 -0
- package/esm/langs/fi.js +2 -1
- package/esm/langs/fr.d.ts +1 -0
- package/esm/langs/fr.js +2 -1
- package/esm/langs/he.d.ts +1 -0
- package/esm/langs/he.js +2 -1
- package/esm/langs/hu.d.ts +1 -0
- package/esm/langs/hu.js +2 -1
- package/esm/langs/id.d.ts +1 -0
- package/esm/langs/id.js +2 -1
- package/esm/langs/it.d.ts +1 -0
- package/esm/langs/it.js +2 -1
- package/esm/langs/ja.d.ts +1 -0
- package/esm/langs/ja.js +2 -1
- package/esm/langs/ko.d.ts +1 -0
- package/esm/langs/ko.js +2 -1
- package/esm/langs/mn.d.ts +1 -0
- package/esm/langs/mn.js +2 -1
- package/esm/langs/nl.d.ts +1 -0
- package/esm/langs/nl.js +2 -1
- package/esm/langs/no.d.ts +1 -0
- package/esm/langs/no.js +2 -1
- package/esm/langs/pl.d.ts +1 -0
- package/esm/langs/pl.js +2 -1
- package/esm/langs/pt_br.d.ts +1 -0
- package/esm/langs/pt_br.js +2 -1
- package/esm/langs/ru.d.ts +1 -0
- package/esm/langs/ru.js +2 -1
- package/esm/langs/sk.d.ts +1 -0
- package/esm/langs/sk.js +2 -1
- package/esm/langs/sv.d.ts +1 -0
- package/esm/langs/sv.js +2 -1
- package/esm/langs/tr.d.ts +1 -0
- package/esm/langs/tr.js +2 -1
- package/esm/langs/ua.d.ts +1 -0
- package/esm/langs/ua.js +2 -1
- package/esm/langs/zh_cn.d.ts +1 -0
- package/esm/langs/zh_cn.js +2 -1
- package/esm/langs/zh_tw.d.ts +1 -0
- package/esm/langs/zh_tw.js +2 -1
- package/esm/modules/dialog/dialog.js +19 -3
- package/esm/plugins/ai-assistant/ui/ui-ai-assistant.js +11 -2
- package/esm/plugins/backspace/cases/check-join-neighbors.js +81 -0
- package/esm/plugins/backspace/cases/check-remove-char.js +6 -5
- package/esm/plugins/backspace/cases/check-unwrap-list-item.d.ts +26 -0
- package/esm/plugins/backspace/cases/check-unwrap-list-item.js +56 -0
- package/esm/plugins/backspace/cases/index.js +2 -0
- package/esm/plugins/backspace/config.d.ts +2 -2
- package/esm/plugins/bold/config.js +2 -2
- package/esm/plugins/enter/enter.js +1 -1
- package/esm/plugins/enter/helpers/check-br.js +7 -2
- package/package.json +1 -1
- package/types/config.d.ts +2 -2
- package/types/langs/ar.d.ts +1 -0
- package/types/langs/az.d.ts +1 -0
- package/types/langs/cs_cz.d.ts +1 -0
- package/types/langs/de.d.ts +1 -0
- package/types/langs/es.d.ts +1 -0
- package/types/langs/fa.d.ts +1 -0
- package/types/langs/fi.d.ts +1 -0
- package/types/langs/fr.d.ts +1 -0
- package/types/langs/he.d.ts +1 -0
- package/types/langs/hu.d.ts +1 -0
- package/types/langs/id.d.ts +1 -0
- package/types/langs/it.d.ts +1 -0
- package/types/langs/ja.d.ts +1 -0
- package/types/langs/ko.d.ts +1 -0
- package/types/langs/mn.d.ts +1 -0
- package/types/langs/nl.d.ts +1 -0
- package/types/langs/no.d.ts +1 -0
- package/types/langs/pl.d.ts +1 -0
- package/types/langs/pt_br.d.ts +1 -0
- package/types/langs/ru.d.ts +1 -0
- package/types/langs/sk.d.ts +1 -0
- package/types/langs/sv.d.ts +1 -0
- package/types/langs/tr.d.ts +1 -0
- package/types/langs/ua.d.ts +1 -0
- package/types/langs/zh_cn.d.ts +1 -0
- package/types/langs/zh_tw.d.ts +1 -0
- package/types/plugins/backspace/cases/check-unwrap-list-item.d.ts +26 -0
- package/types/plugins/backspace/config.d.ts +2 -2
|
@@ -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: [],
|
|
@@ -47,6 +51,7 @@ Config.prototype.dialog = {
|
|
|
47
51
|
Config.prototype.controls.dialog = {
|
|
48
52
|
close: {
|
|
49
53
|
icon: 'cancel',
|
|
54
|
+
tooltip: 'Close',
|
|
50
55
|
exec: dialog => {
|
|
51
56
|
dialog.close();
|
|
52
57
|
}
|
|
@@ -126,6 +131,11 @@ let Dialog = Dialog_1 = class Dialog extends ViewWithToolbar {
|
|
|
126
131
|
this.startY = e.clientY;
|
|
127
132
|
this.startPoint.x = css(this.dialog, 'left');
|
|
128
133
|
this.startPoint.y = css(this.dialog, 'top');
|
|
134
|
+
// Rounded up: at the right edge a fraction of a pixel less room would
|
|
135
|
+
// wrap the header of a panel that has no width of its own
|
|
136
|
+
const { width, height } = this.dialog.getBoundingClientRect();
|
|
137
|
+
this.startPoint.w = Math.ceil(width);
|
|
138
|
+
this.startPoint.h = Math.ceil(height);
|
|
129
139
|
this.setMaxZIndex();
|
|
130
140
|
if (e.cancelable) {
|
|
131
141
|
e.preventDefault();
|
|
@@ -142,7 +152,13 @@ let Dialog = Dialog_1 = class Dialog extends ViewWithToolbar {
|
|
|
142
152
|
}
|
|
143
153
|
__onMouseMove(e) {
|
|
144
154
|
if (this.draggable && this.o.draggable) {
|
|
145
|
-
|
|
155
|
+
const { documentElement } = this.od;
|
|
156
|
+
// Keep the whole panel in the window at the size it had when the
|
|
157
|
+
// drag began. A panel with no width of its own would otherwise
|
|
158
|
+
// shrink as it neared the right edge, and then leave the window
|
|
159
|
+
this.setPosition(clampToWindow(this.startPoint.x + e.clientX - this.startX, (documentElement.clientWidth || this.ow.innerWidth) -
|
|
160
|
+
this.startPoint.w), clampToWindow(this.startPoint.y + e.clientY - this.startY, (documentElement.clientHeight || this.ow.innerHeight) -
|
|
161
|
+
this.startPoint.h));
|
|
146
162
|
if (this.e) {
|
|
147
163
|
/**
|
|
148
164
|
* Fired when dialog box is moved
|
|
@@ -291,8 +307,8 @@ let Dialog = Dialog_1 = class Dialog extends ViewWithToolbar {
|
|
|
291
307
|
}
|
|
292
308
|
// strings on purpose: `css()` would truncate fractional pixels
|
|
293
309
|
css(this.dialog, {
|
|
294
|
-
left: (x
|
|
295
|
-
top: (y
|
|
310
|
+
left: (x !== null && x !== void 0 ? x : left) + 'px',
|
|
311
|
+
top: (y !== null && y !== void 0 ? y : top) + 'px'
|
|
296
312
|
});
|
|
297
313
|
return this;
|
|
298
314
|
}
|
|
@@ -40,8 +40,17 @@ let UiAiAssistant = class UiAiAssistant extends UIElement {
|
|
|
40
40
|
this.__toggleSubmitButton(true);
|
|
41
41
|
}
|
|
42
42
|
};
|
|
43
|
-
this.__submitButton = Button(jodit,
|
|
44
|
-
|
|
43
|
+
this.__submitButton = Button(jodit, {
|
|
44
|
+
icon: { name: 'ai-assistant' },
|
|
45
|
+
name: 'ai-assistant',
|
|
46
|
+
tooltip: 'Submit'
|
|
47
|
+
}).onAction(onSubmit);
|
|
48
|
+
this.__tryAgainButton = Button(jodit, {
|
|
49
|
+
icon: { name: 'update' },
|
|
50
|
+
name: 'update',
|
|
51
|
+
tooltip: 'Try Again',
|
|
52
|
+
variant: 'initial'
|
|
53
|
+
}).onAction(onSubmit);
|
|
45
54
|
this.promptInput = new UITextArea(jodit, {
|
|
46
55
|
name: 'prompt',
|
|
47
56
|
required: true,
|
|
@@ -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
|
|
88
|
-
// neighbor can be the text of the parent/previous item
|
|
89
|
-
//
|
|
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,
|
|
92
|
-
Dom.closest(nextSibling,
|
|
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`, `
|
|
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', {
|
|
@@ -6,11 +6,11 @@
|
|
|
6
6
|
import { Config } from "../../config.js";
|
|
7
7
|
Config.prototype.controls.subscript = {
|
|
8
8
|
tags: ['sub'],
|
|
9
|
-
tooltip: '
|
|
9
|
+
tooltip: 'Subscript'
|
|
10
10
|
};
|
|
11
11
|
Config.prototype.controls.superscript = {
|
|
12
12
|
tags: ['sup'],
|
|
13
|
-
tooltip: '
|
|
13
|
+
tooltip: 'Superscript'
|
|
14
14
|
};
|
|
15
15
|
Config.prototype.controls.bold = {
|
|
16
16
|
tagRegExp: /^(strong|b)$/i,
|
|
@@ -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
|
|
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
|
-
|
|
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
|
|
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
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`, `
|
|
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', {
|
package/types/langs/ar.d.ts
CHANGED
package/types/langs/az.d.ts
CHANGED
package/types/langs/cs_cz.d.ts
CHANGED
package/types/langs/de.d.ts
CHANGED
package/types/langs/es.d.ts
CHANGED
package/types/langs/fa.d.ts
CHANGED
package/types/langs/fi.d.ts
CHANGED
package/types/langs/fr.d.ts
CHANGED
package/types/langs/he.d.ts
CHANGED
package/types/langs/hu.d.ts
CHANGED
package/types/langs/id.d.ts
CHANGED
package/types/langs/it.d.ts
CHANGED
package/types/langs/ja.d.ts
CHANGED
package/types/langs/ko.d.ts
CHANGED
package/types/langs/mn.d.ts
CHANGED
package/types/langs/nl.d.ts
CHANGED
package/types/langs/no.d.ts
CHANGED
package/types/langs/pl.d.ts
CHANGED
package/types/langs/pt_br.d.ts
CHANGED
package/types/langs/ru.d.ts
CHANGED
package/types/langs/sk.d.ts
CHANGED
package/types/langs/sv.d.ts
CHANGED
package/types/langs/tr.d.ts
CHANGED
package/types/langs/ua.d.ts
CHANGED
package/types/langs/zh_cn.d.ts
CHANGED
package/types/langs/zh_tw.d.ts
CHANGED
|
@@ -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`, `
|
|
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', {
|