jodit 4.18.9 → 4.18.11
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 +21 -0
- package/es2015/jodit.css +1 -1
- package/es2015/jodit.fat.min.js +5 -5
- package/es2015/jodit.js +331 -71
- package/es2015/jodit.min.js +5 -5
- 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 +5 -5
- package/es2018/jodit.min.js +5 -5
- 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 +6 -6
- package/es2021/jodit.js +328 -71
- package/es2021/jodit.min.js +6 -6
- 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 +6 -6
- package/es2021.en/jodit.js +328 -71
- package/es2021.en/jodit.min.js +6 -6
- 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 +378 -72
- 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 +2 -2
- package/es5/polyfills.js +3 -3
- package/es5/polyfills.min.js +2 -2
- package/esm/core/async/async.js +2 -1
- package/esm/core/constants.js +1 -1
- package/esm/core/helpers/size/get-fixed-position-offset.d.ts +4 -2
- package/esm/core/helpers/size/get-fixed-position-offset.js +14 -2
- package/esm/plugins/add-new-line/add-new-line.d.ts +7 -0
- package/esm/plugins/add-new-line/add-new-line.js +45 -0
- package/esm/plugins/backspace/backspace.d.ts +7 -0
- package/esm/plugins/backspace/backspace.js +45 -2
- package/esm/plugins/backspace/cases/check-join-neighbors.js +161 -1
- package/esm/plugins/backspace/cases/check-remove-char.js +3 -1
- package/esm/plugins/backspace/cases/check-remove-content-not-editable.d.ts +4 -1
- package/esm/plugins/backspace/cases/check-remove-content-not-editable.js +39 -11
- package/esm/plugins/wrap-nodes/wrap-nodes.js +19 -2
- package/esm/types/async.d.ts +7 -0
- package/package.json +1 -1
- package/types/core/helpers/size/get-fixed-position-offset.d.ts +4 -2
- package/types/plugins/add-new-line/add-new-line.d.ts +7 -0
- package/types/plugins/backspace/backspace.d.ts +7 -0
- package/types/plugins/backspace/cases/check-remove-content-not-editable.d.ts +4 -1
- package/types/types/async.d.ts +7 -0
|
@@ -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
|
-
import { INSEPARABLE_TAGS, LIST_TAGS } from "../../../core/constants.js";
|
|
6
|
+
import { INSEPARABLE_TAGS, LIST_TAGS, NO_EMPTY_TAGS } from "../../../core/constants.js";
|
|
7
7
|
import { Dom } from "../../../core/dom/dom.js";
|
|
8
8
|
import { getMoveFilter } from "../helpers.js";
|
|
9
9
|
/**
|
|
@@ -11,6 +11,12 @@ import { getMoveFilter } from "../helpers.js";
|
|
|
11
11
|
* @private
|
|
12
12
|
*/
|
|
13
13
|
export function checkJoinNeighbors(jodit, fakeNode, backspace) {
|
|
14
|
+
return joinNeighbors(jodit, fakeNode, backspace, false);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* `moved` is set on the one re-entrant pass after `moveToNextLine`
|
|
18
|
+
*/
|
|
19
|
+
function joinNeighbors(jodit, fakeNode, backspace, moved) {
|
|
14
20
|
if (checkJoinBareText(jodit, fakeNode, backspace)) {
|
|
15
21
|
return true;
|
|
16
22
|
}
|
|
@@ -29,6 +35,9 @@ export function checkJoinNeighbors(jodit, fakeNode, backspace) {
|
|
|
29
35
|
return false;
|
|
30
36
|
}
|
|
31
37
|
const sibling = Dom.findNotEmptySibling(mainClosestBox, backspace);
|
|
38
|
+
if (moveInlinesInside(jodit, fakeNode, sibling)) {
|
|
39
|
+
return joinNeighbors(jodit, fakeNode, backspace, moved);
|
|
40
|
+
}
|
|
32
41
|
// A line break before the cursor is a single unit: remove it instead of
|
|
33
42
|
// merging the current element into the (void) `<br>`, which used to move
|
|
34
43
|
// the whole element's content into the `<br>` and delete it (#1282).
|
|
@@ -43,7 +52,22 @@ export function checkJoinNeighbors(jodit, fakeNode, backspace) {
|
|
|
43
52
|
jodit.s.setCursorBefore(fakeNode);
|
|
44
53
|
return true;
|
|
45
54
|
}
|
|
55
|
+
// A non-editable sibling is removed by remove-not-editable, never joined
|
|
56
|
+
if (Dom.isElement(sibling) &&
|
|
57
|
+
!Dom.isContentEditable(sibling, jodit.editor)) {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
46
60
|
const box = findCaretBox(fakeNode, mainClosestBox);
|
|
61
|
+
// One pass only: the line now sits beside the next one, so the
|
|
62
|
+
// cases below join them. The DOM has changed either way
|
|
63
|
+
if (!moved &&
|
|
64
|
+
sibling &&
|
|
65
|
+
moveToNextLine(jodit, fakeNode, box, sibling, backspace)) {
|
|
66
|
+
if (!joinNeighbors(jodit, fakeNode, backspace, true)) {
|
|
67
|
+
jodit.s.setCursorBefore(fakeNode);
|
|
68
|
+
}
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
47
71
|
if (sibling &&
|
|
48
72
|
(checkPullNextLine(jodit, fakeNode, box, sibling, backspace) ||
|
|
49
73
|
checkMoveListContent(jodit, box, sibling, backspace) ||
|
|
@@ -70,6 +94,66 @@ function findCaretBox(fakeNode, mainClosestBox) {
|
|
|
70
94
|
? block.parentElement
|
|
71
95
|
: block;
|
|
72
96
|
}
|
|
97
|
+
/**
|
|
98
|
+
* With an inline element round the caret's line or the one it joins moved
|
|
99
|
+
* inside its blocks, the cases join the lines as they join any two, and its
|
|
100
|
+
* styles stay with its text. One round both lines is left as it is.
|
|
101
|
+
*/
|
|
102
|
+
function moveInlinesInside(jodit, fakeNode, sibling) {
|
|
103
|
+
if (!sibling) {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
const around = Dom.furthest(fakeNode, node => Dom.isElement(node) &&
|
|
107
|
+
!Dom.isBlock(node) &&
|
|
108
|
+
!Dom.isOrContains(node, sibling), jodit.editor);
|
|
109
|
+
return (moveInlineInside(around, jodit.editor) ||
|
|
110
|
+
moveInlineInside(sibling, jodit.editor));
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Old content can have an inline element round blocks. This moves it inside
|
|
114
|
+
* them, and gives the text, images and line breaks beside them a copy of
|
|
115
|
+
* their own: `<span style="…"><p>one</p><br><p>two</p></span>` becomes
|
|
116
|
+
* `<p><span style="…">one</span></p><span style="…"><br></span><p><span style="…">two</span></p>`
|
|
117
|
+
*/
|
|
118
|
+
function moveInlineInside(node, root) {
|
|
119
|
+
if (!Dom.isElement(node) || Dom.isBlock(node)) {
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
// Embedded content, such as the `<iframe>` in a video's wrapper, counts
|
|
123
|
+
// as a block in `Dom.isBlock`, but stays with the text beside it
|
|
124
|
+
const isBlock = (child) => Dom.isBlock(child) && !Dom.isTag(child, NO_EMPTY_TAGS);
|
|
125
|
+
// The inner one first: `<span><strong><p>one</p></strong></span>`
|
|
126
|
+
Array.from(node.childNodes).forEach(child => moveInlineInside(child, root));
|
|
127
|
+
const children = Array.from(node.childNodes);
|
|
128
|
+
if (!children.some(isBlock)) {
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
let run = null;
|
|
132
|
+
for (const child of children) {
|
|
133
|
+
if (!isBlock(child)) {
|
|
134
|
+
// Blank text between blocks stays where it is
|
|
135
|
+
if (!run && !Dom.isEmptyTextNode(child)) {
|
|
136
|
+
run = node.cloneNode(false);
|
|
137
|
+
Dom.before(child, run);
|
|
138
|
+
}
|
|
139
|
+
run && Dom.append(run, child);
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
run = null;
|
|
143
|
+
// Nothing goes inside a rule or a non-editable block
|
|
144
|
+
if (Dom.isTag(child, INSEPARABLE_TAGS) ||
|
|
145
|
+
!Dom.isContentEditable(child, root)) {
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
const inner = node.cloneNode(false);
|
|
149
|
+
Dom.moveContent(child, inner);
|
|
150
|
+
Dom.append(child, inner);
|
|
151
|
+
// A list or a table: on down to its items or cells
|
|
152
|
+
moveInlineInside(inner, root);
|
|
153
|
+
}
|
|
154
|
+
Dom.unwrap(node);
|
|
155
|
+
return true;
|
|
156
|
+
}
|
|
73
157
|
/**
|
|
74
158
|
* The innermost block on the sibling's edge facing the caret, so the
|
|
75
159
|
* content is joined to text: `<div><p>one</p></div><p>|two</p>` gives
|
|
@@ -109,6 +193,82 @@ function resolveTableSibling(sibling, backspace) {
|
|
|
109
193
|
});
|
|
110
194
|
return cells.length ? cells[backspace ? cells.length - 1 : 0] : null;
|
|
111
195
|
}
|
|
196
|
+
/**
|
|
197
|
+
* On Delete, Word joins two lines where the next one is, inside or outside
|
|
198
|
+
* its box or quote, and the joined line keeps the caret line's kind, list item
|
|
199
|
+
* or paragraph. Two paragraphs already join that way. When either line is a
|
|
200
|
+
* list item, this moves the caret's line beside the next one, and the usual
|
|
201
|
+
* cases then join them: `<p>one|</p><div><ul><li>two</li></ul></div>` becomes
|
|
202
|
+
* `<div><p>one|</p><ul><li>two</li></ul></div>`
|
|
203
|
+
* @private
|
|
204
|
+
*/
|
|
205
|
+
function moveToNextLine(jodit, fakeNode, box, sibling, backspace) {
|
|
206
|
+
if (backspace ||
|
|
207
|
+
Dom.isTag(sibling, 'table') ||
|
|
208
|
+
Dom.isTag(sibling, INSEPARABLE_TAGS) ||
|
|
209
|
+
!Dom.isContentEditable(sibling, jodit.editor)) {
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
const line = Dom.up(fakeNode, Dom.isBlock, box, true);
|
|
213
|
+
const next = findEdgeBlock(sibling, false, jodit.editor);
|
|
214
|
+
if (!line ||
|
|
215
|
+
!next ||
|
|
216
|
+
!Dom.isContentEditable(next, jodit.editor) ||
|
|
217
|
+
!(Dom.isLeaf(line) || Dom.isLeaf(next)) ||
|
|
218
|
+
// A paragraph inside a list item is left as it is
|
|
219
|
+
Dom.isLeaf(line.parentElement) ||
|
|
220
|
+
Dom.isLeaf(next.parentElement) ||
|
|
221
|
+
boxOf(line) === boxOf(next)) {
|
|
222
|
+
return false;
|
|
223
|
+
}
|
|
224
|
+
const from = line.parentElement;
|
|
225
|
+
if (Dom.isLeaf(line) && Dom.isLeaf(next)) {
|
|
226
|
+
Dom.before(next, line);
|
|
227
|
+
}
|
|
228
|
+
else if (Dom.isLeaf(line)) {
|
|
229
|
+
// A list item keeps its bullet, in a list of its own
|
|
230
|
+
Dom.before(next, ownList(line));
|
|
231
|
+
}
|
|
232
|
+
else {
|
|
233
|
+
// A paragraph can't go inside a list, so it goes in front of it
|
|
234
|
+
Dom.before(next.parentElement, line);
|
|
235
|
+
}
|
|
236
|
+
let remove = from;
|
|
237
|
+
while (remove && remove !== jodit.editor && Dom.isEmpty(remove)) {
|
|
238
|
+
const parent = remove.parentElement;
|
|
239
|
+
Dom.safeRemove(remove);
|
|
240
|
+
remove = parent;
|
|
241
|
+
}
|
|
242
|
+
return true;
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* The box or quote a line is in, past its lists
|
|
246
|
+
*/
|
|
247
|
+
function boxOf(line) {
|
|
248
|
+
let box = line.parentElement;
|
|
249
|
+
while (Dom.isList(box) || Dom.isLeaf(box)) {
|
|
250
|
+
box = box.parentElement;
|
|
251
|
+
}
|
|
252
|
+
return box;
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Moves a list item into a list of its own, which carries on its numbering
|
|
256
|
+
*/
|
|
257
|
+
function ownList(item) {
|
|
258
|
+
const list = item.parentElement;
|
|
259
|
+
const own = list.cloneNode(false);
|
|
260
|
+
const index = Array.from(list.children).indexOf(item);
|
|
261
|
+
if (index) {
|
|
262
|
+
// Two lists cannot share one id
|
|
263
|
+
own.removeAttribute('id');
|
|
264
|
+
if (Dom.isTag(list, 'ol')) {
|
|
265
|
+
const start = parseInt(list.getAttribute('start') || '1', 10) || 1;
|
|
266
|
+
own.setAttribute('start', String(start + index));
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
Dom.append(own, item);
|
|
270
|
+
return own;
|
|
271
|
+
}
|
|
112
272
|
/**
|
|
113
273
|
* Delete at the edge of a list pulls the next line up to the caret, as the
|
|
114
274
|
* browsers do, instead of moving the caret's line into the next block:
|
|
@@ -37,7 +37,9 @@ export function checkRemoveChar(jodit, fakeNode, backspace, mode, stopBeforeSpac
|
|
|
37
37
|
while (Dom.isInlineBlock(sibling)) {
|
|
38
38
|
sibling = (backspace ? sibling === null || sibling === void 0 ? void 0 : sibling.lastChild : sibling === null || sibling === void 0 ? void 0 : sibling.firstChild);
|
|
39
39
|
}
|
|
40
|
-
|
|
40
|
+
// A block inside an inline element, such as the `<p>` in
|
|
41
|
+
// `<span><p>…</p></span>`, isn't a char: the join cases handle it
|
|
42
|
+
if (!sibling || Dom.isBlock(sibling)) {
|
|
41
43
|
break;
|
|
42
44
|
}
|
|
43
45
|
if ((_a = sibling.nodeValue) === null || _a === void 0 ? void 0 : _a.length) {
|
|
@@ -8,7 +8,10 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import type { IJodit } from "../../../types/index";
|
|
10
10
|
/**
|
|
11
|
-
* Checks if a non-editable element can be deleted
|
|
11
|
+
* Checks if a non-editable element can be deleted. A non-editable block goes
|
|
12
|
+
* whole, and the lines either side of it then join, as the spec's tests do:
|
|
13
|
+
* `<ul><li>one|</li></ul><div contenteditable="false">x</div><p>two</p>`
|
|
14
|
+
* gives `<ul><li>one|two</li></ul>`
|
|
12
15
|
* @private
|
|
13
16
|
*/
|
|
14
17
|
export declare function checkRemoveContentNotEditable(jodit: IJodit, fakeNode: Text, backspace: boolean): boolean;
|
|
@@ -6,24 +6,52 @@
|
|
|
6
6
|
import { Dom } from "../../../core/dom/index.js";
|
|
7
7
|
import { call } from "../../../core/helpers/index.js";
|
|
8
8
|
import { moveNodeInsideStart } from "../../../core/selection/helpers/index.js";
|
|
9
|
+
import { checkJoinNeighbors } from "./check-join-neighbors.js";
|
|
9
10
|
/**
|
|
10
|
-
* Checks if a non-editable element can be deleted
|
|
11
|
+
* Checks if a non-editable element can be deleted. A non-editable block goes
|
|
12
|
+
* whole, and the lines either side of it then join, as the spec's tests do:
|
|
13
|
+
* `<ul><li>one|</li></ul><div contenteditable="false">x</div><p>two</p>`
|
|
14
|
+
* gives `<ul><li>one|two</li></ul>`
|
|
11
15
|
* @private
|
|
12
16
|
*/
|
|
13
17
|
export function checkRemoveContentNotEditable(jodit, fakeNode, backspace) {
|
|
14
|
-
let
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
18
|
+
let node = fakeNode;
|
|
19
|
+
let neighbor = Dom.findSibling(node, backspace);
|
|
20
|
+
// Past the edges of the blocks the caret is at, but not into a table cell
|
|
21
|
+
while (!neighbor &&
|
|
22
|
+
node.parentElement &&
|
|
23
|
+
node.parentElement !== jodit.editor &&
|
|
24
|
+
!Dom.isCell(node.parentElement)) {
|
|
25
|
+
node = node.parentElement;
|
|
26
|
+
neighbor = Dom.findSibling(node, backspace);
|
|
27
|
+
// At the start of a list item, Backspace takes the bullet off first,
|
|
28
|
+
// unless the item before it is a non-editable one to remove
|
|
29
|
+
if (backspace &&
|
|
30
|
+
Dom.isLeaf(node) &&
|
|
31
|
+
!(Dom.isLeaf(neighbor) && isNotEditable(jodit, neighbor))) {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
19
34
|
}
|
|
20
|
-
if (
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
35
|
+
if (isNotEditable(jodit, neighbor)) {
|
|
36
|
+
if (Dom.isBlock(neighbor)) {
|
|
37
|
+
// Backspace after a removed list item leaves the items apart: the
|
|
38
|
+
// next press takes the bullet off, as for any later item
|
|
39
|
+
const joinLines = !(backspace && Dom.isLeaf(neighbor));
|
|
40
|
+
Dom.safeRemove(neighbor);
|
|
41
|
+
if (joinLines) {
|
|
42
|
+
checkJoinNeighbors(jodit, fakeNode, backspace);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
call(backspace ? Dom.before : Dom.after, neighbor, fakeNode);
|
|
47
|
+
Dom.safeRemove(neighbor);
|
|
48
|
+
moveNodeInsideStart(jodit, fakeNode, backspace);
|
|
49
|
+
}
|
|
25
50
|
call(backspace ? jodit.s.setCursorBefore : jodit.s.setCursorAfter, fakeNode);
|
|
26
51
|
return true;
|
|
27
52
|
}
|
|
28
53
|
return false;
|
|
29
54
|
}
|
|
55
|
+
function isNotEditable(jodit, node) {
|
|
56
|
+
return Dom.isElement(node) && !Dom.isContentEditable(node, jodit.editor);
|
|
57
|
+
}
|
|
@@ -13,6 +13,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
13
13
|
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
14
14
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
15
15
|
};
|
|
16
|
+
import { NO_EMPTY_TAGS } from "../../core/constants.js";
|
|
16
17
|
import { autobind } from "../../core/decorators/index.js";
|
|
17
18
|
import { Dom } from "../../core/dom/index.js";
|
|
18
19
|
import { pluginSystem } from "../../core/global.js";
|
|
@@ -45,7 +46,9 @@ class wrapNodes extends Plugin {
|
|
|
45
46
|
* Some element which needs to append in block
|
|
46
47
|
*/
|
|
47
48
|
this.isNotWrapped = (n) => Dom.isElement(n) &&
|
|
48
|
-
!(Dom.isBlock(n) ||
|
|
49
|
+
!(Dom.isBlock(n) ||
|
|
50
|
+
Dom.isTag(n, this.j.o.wrapNodes.exclude) ||
|
|
51
|
+
holdsBlock(n));
|
|
49
52
|
}
|
|
50
53
|
/** @override **/
|
|
51
54
|
afterInit(jodit) {
|
|
@@ -81,7 +84,9 @@ class wrapNodes extends Plugin {
|
|
|
81
84
|
isChanged = true;
|
|
82
85
|
const box = jodit.createInside.element(jodit.o.enter);
|
|
83
86
|
Dom.before(child, box);
|
|
84
|
-
|
|
87
|
+
// `exclude` keeps a <br> from starting a box, but one between loose lines stays with them
|
|
88
|
+
while (child &&
|
|
89
|
+
(this.isSuitable(child) || Dom.isTag(child, 'br'))) {
|
|
85
90
|
const next = child.nextSibling;
|
|
86
91
|
Dom.append(box, child);
|
|
87
92
|
child = next;
|
|
@@ -124,6 +129,18 @@ __decorate([
|
|
|
124
129
|
__decorate([
|
|
125
130
|
autobind
|
|
126
131
|
], wrapNodes.prototype, "preprocessInput", null);
|
|
132
|
+
/**
|
|
133
|
+
* A block can't go in a paragraph, so neither can an element that holds one,
|
|
134
|
+
* such as a `<span>` round a `<p>`. Embedded content such as an `<iframe>` can.
|
|
135
|
+
*/
|
|
136
|
+
function holdsBlock(elm) {
|
|
137
|
+
for (const node of Dom.eachGen(elm)) {
|
|
138
|
+
if (Dom.isBlock(node) && !Dom.isTag(node, NO_EMPTY_TAGS)) {
|
|
139
|
+
return true;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
127
144
|
function checkAloneListLeaf(child, jodit) {
|
|
128
145
|
let result = child;
|
|
129
146
|
let next = child;
|
package/esm/types/async.d.ts
CHANGED
|
@@ -20,6 +20,13 @@ interface RejectablePromise<T> extends Promise<T> {
|
|
|
20
20
|
}
|
|
21
21
|
export interface IAsync extends IDestructible {
|
|
22
22
|
delay(timeout: number | IAsyncParams): Promise<void>;
|
|
23
|
+
/**
|
|
24
|
+
* Calls `callback` after `timeout` milliseconds, unless the view is
|
|
25
|
+
* destroyed first. A timeout of 0, or none, calls it at once, before
|
|
26
|
+
* returning, where `window.setTimeout(callback, 0)` would wait for the
|
|
27
|
+
* current event to finish. To run after the browser has handled an event,
|
|
28
|
+
* such as moving the caret on a keydown, use a timeout of at least 1.
|
|
29
|
+
*/
|
|
23
30
|
setTimeout<T = any>(callback: (...args: T[]) => void, timeout: number | IAsyncParams, ...args: T[]): number;
|
|
24
31
|
updateTimeout(label: string, timeout: number): Nullable<number>;
|
|
25
32
|
clearTimeout(timer: number): void;
|
package/package.json
CHANGED
|
@@ -15,7 +15,9 @@ import type { IPoint } from "../../../types/index";
|
|
|
15
15
|
* ancestor's top-left corner. The returned offset should be subtracted from
|
|
16
16
|
* the desired viewport coordinates before applying them.
|
|
17
17
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
18
|
+
* Without such an ancestor the containing block is the layout viewport. Its
|
|
19
|
+
* offset is `{ x: 0, y: 0 }` in most browsers, but WebKit measures client
|
|
20
|
+
* rects from the visual viewport, so once the page is pinch-zoomed and panned
|
|
21
|
+
* the layout viewport starts above and to the left of the client origin.
|
|
20
22
|
*/
|
|
21
23
|
export declare function getFixedPositionOffset(elm: HTMLElement): IPoint;
|
|
@@ -30,6 +30,13 @@ export declare class addNewLine extends Plugin {
|
|
|
30
30
|
protected afterInit(editor: IJodit): void;
|
|
31
31
|
private __addEventListeners;
|
|
32
32
|
private __onClickLine;
|
|
33
|
+
/**
|
|
34
|
+
* A paragraph holding only an embed has no place for the caret, so the
|
|
35
|
+
* arrow keys can't get past one that ends the content, or before one that
|
|
36
|
+
* starts it. When an arrow key leaves the caret where it was and there is
|
|
37
|
+
* content beyond it, a new line goes there, as when the line is clicked.
|
|
38
|
+
*/
|
|
39
|
+
protected onArrowKey(e: KeyboardEvent): void;
|
|
33
40
|
protected onDblClickEditor(e: MouseEvent): void;
|
|
34
41
|
private __onMouseMove;
|
|
35
42
|
/** @override */
|
|
@@ -19,6 +19,13 @@ export declare class backspace extends Plugin {
|
|
|
19
19
|
* Listener BackSpace or Delete button
|
|
20
20
|
*/
|
|
21
21
|
private onDelete;
|
|
22
|
+
/**
|
|
23
|
+
* The browser types at the end of the text before the caret on its line,
|
|
24
|
+
* in that text's formatting, but not inside a link. Moving the caret there
|
|
25
|
+
* too makes a paste and the toolbar agree with what's typed:
|
|
26
|
+
* `<p>one</p><p><b>|two</b></p>` joins to `<p>one|<b>two</b></p>`
|
|
27
|
+
*/
|
|
28
|
+
private moveCaretToTextBefore;
|
|
22
29
|
/**
|
|
23
30
|
* Remove node and replace cursor position out of it
|
|
24
31
|
*/
|
|
@@ -8,7 +8,10 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import type { IJodit } from "../../../types/index";
|
|
10
10
|
/**
|
|
11
|
-
* Checks if a non-editable element can be deleted
|
|
11
|
+
* Checks if a non-editable element can be deleted. A non-editable block goes
|
|
12
|
+
* whole, and the lines either side of it then join, as the spec's tests do:
|
|
13
|
+
* `<ul><li>one|</li></ul><div contenteditable="false">x</div><p>two</p>`
|
|
14
|
+
* gives `<ul><li>one|two</li></ul>`
|
|
12
15
|
* @private
|
|
13
16
|
*/
|
|
14
17
|
export declare function checkRemoveContentNotEditable(jodit: IJodit, fakeNode: Text, backspace: boolean): boolean;
|
package/types/types/async.d.ts
CHANGED
|
@@ -20,6 +20,13 @@ interface RejectablePromise<T> extends Promise<T> {
|
|
|
20
20
|
}
|
|
21
21
|
export interface IAsync extends IDestructible {
|
|
22
22
|
delay(timeout: number | IAsyncParams): Promise<void>;
|
|
23
|
+
/**
|
|
24
|
+
* Calls `callback` after `timeout` milliseconds, unless the view is
|
|
25
|
+
* destroyed first. A timeout of 0, or none, calls it at once, before
|
|
26
|
+
* returning, where `window.setTimeout(callback, 0)` would wait for the
|
|
27
|
+
* current event to finish. To run after the browser has handled an event,
|
|
28
|
+
* such as moving the caret on a keydown, use a timeout of at least 1.
|
|
29
|
+
*/
|
|
23
30
|
setTimeout<T = any>(callback: (...args: T[]) => void, timeout: number | IAsyncParams, ...args: T[]): number;
|
|
24
31
|
updateTimeout(label: string, timeout: number): Nullable<number>;
|
|
25
32
|
clearTimeout(timer: number): void;
|