jodit 4.12.34 → 4.12.36
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 +28 -0
- package/es2015/jodit.css +1 -1
- package/es2015/jodit.fat.min.js +2 -2
- package/es2015/jodit.js +106 -50
- package/es2015/jodit.min.js +2 -2
- 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 +2 -2
- package/es2018/jodit.min.js +2 -2
- 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 +3 -3
- package/es2021/jodit.js +105 -48
- package/es2021/jodit.min.js +3 -3
- 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 +3 -3
- package/es2021.en/jodit.js +105 -48
- package/es2021.en/jodit.min.js +3 -3
- 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 +255 -196
- 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/core/constants.js +1 -1
- package/esm/core/dom/dom.d.ts +35 -12
- package/esm/core/dom/dom.js +42 -20
- package/esm/core/dom/lazy-walker.d.ts +18 -1
- package/esm/core/dom/lazy-walker.js +23 -3
- package/esm/core/request/ajax.js +1 -1
- package/esm/core/selection/helpers/index.d.ts +3 -1
- package/esm/core/selection/helpers/index.js +3 -1
- package/esm/core/selection/selection.d.ts +14 -0
- package/esm/core/selection/selection.js +19 -8
- package/esm/core/selection/style/api/is-same-attributes.d.ts +4 -2
- package/esm/core/selection/style/api/is-same-attributes.js +3 -4
- package/esm/core/selection/style/api/is-suit-element.d.ts +2 -1
- package/esm/core/selection/style/api/is-suit-element.js +2 -1
- package/esm/core/selection/style/api/list/toggle-ordered-list.js +7 -0
- package/esm/core/selection/style/api/toggle-attributes.js +3 -1
- package/esm/core/selection/style/commit-style.d.ts +1 -1
- package/esm/core/selection/style/commit-style.js +2 -2
- package/package.json +1 -1
- package/types/core/dom/dom.d.ts +35 -12
- package/types/core/dom/lazy-walker.d.ts +18 -1
- package/types/core/selection/helpers/index.d.ts +3 -1
- package/types/core/selection/selection.d.ts +14 -0
- package/types/core/selection/style/api/is-same-attributes.d.ts +4 -2
- package/types/core/selection/style/api/is-suit-element.d.ts +2 -1
- package/types/core/selection/style/commit-style.d.ts +1 -1
package/es5/polyfills.fat.min.js
CHANGED
package/es5/polyfills.js
CHANGED
package/es5/polyfills.min.js
CHANGED
package/esm/core/constants.js
CHANGED
|
@@ -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.12.
|
|
6
|
+
export const APP_VERSION = "4.12.36";
|
|
7
7
|
// prettier-ignore
|
|
8
8
|
export const ES = "es2020";
|
|
9
9
|
export const IS_ES_MODERN = true;
|
package/esm/core/dom/dom.d.ts
CHANGED
|
@@ -34,7 +34,11 @@ export declare class Dom {
|
|
|
34
34
|
*/
|
|
35
35
|
static unwrap(node: Node): void;
|
|
36
36
|
/**
|
|
37
|
-
* Call
|
|
37
|
+
* Call callback for all nodes between `start` and `end` in document order
|
|
38
|
+
* (`start` and `end` are not included). Iteration stops when the callback returns `true`.
|
|
39
|
+
*
|
|
40
|
+
* `end` must be positioned after `start` in the document (e.g. selection markers),
|
|
41
|
+
* otherwise iteration will stop only at the end of the tree.
|
|
38
42
|
*/
|
|
39
43
|
static between(start: Node, end: Node, callback: (node: Node) => void | boolean): void;
|
|
40
44
|
/**
|
|
@@ -46,14 +50,18 @@ export declare class Dom {
|
|
|
46
50
|
* @param notMoveContent - false - Move content from elm to newTagName
|
|
47
51
|
* @example
|
|
48
52
|
* ```javascript
|
|
49
|
-
* Jodit.modules.Dom.replace(
|
|
50
|
-
*
|
|
53
|
+
* Jodit.modules.Dom.replace(
|
|
54
|
+
* parent.editor.getElementsByTagName('span')[0],
|
|
55
|
+
* 'p',
|
|
56
|
+
* parent.createInside
|
|
57
|
+
* );
|
|
58
|
+
* // Replace the first <span> element to the <p>
|
|
51
59
|
* ```
|
|
52
60
|
*/
|
|
53
|
-
static replace<T extends HTMLElement>(elm: Node, newTagName: HTMLTagNames): T;
|
|
54
61
|
static replace<T extends HTMLElement>(elm: Node, newTagName: HTMLTagNames, create: ICreate, withAttributes?: boolean, notMoveContent?: boolean): T;
|
|
55
|
-
static replace<T extends Node>(elm: Node,
|
|
56
|
-
static replace<T extends Node>(elm: Node,
|
|
62
|
+
static replace<T extends Node>(elm: Node, newElement: T, create?: ICreate, withAttributes?: boolean, notMoveContent?: boolean): T;
|
|
63
|
+
static replace<T extends Node>(elm: Node, html: string, create: ICreate, withAttributes?: boolean, notMoveContent?: boolean): T;
|
|
64
|
+
static replace<T extends Node>(elm: Node, newTagNameOrElement: HTMLTagNames | T, create: ICreate, withAttributes?: boolean, notMoveContent?: boolean): T;
|
|
57
65
|
/**
|
|
58
66
|
* Checks whether the Node text and blank (in this case it may contain invisible auxiliary characters ,
|
|
59
67
|
* it is also empty )
|
|
@@ -80,9 +88,9 @@ export declare class Dom {
|
|
|
80
88
|
*/
|
|
81
89
|
static isCell(elm: unknown): elm is HTMLTableCellElement;
|
|
82
90
|
/**
|
|
83
|
-
* Check if element is a list
|
|
91
|
+
* Check if element is a list element UL or OL
|
|
84
92
|
*/
|
|
85
|
-
static isList(elm: Nullable<Node>): elm is HTMLOListElement;
|
|
93
|
+
static isList(elm: Nullable<Node>): elm is HTMLUListElement | HTMLOListElement;
|
|
86
94
|
/**
|
|
87
95
|
* Check if element is a part of list element LI
|
|
88
96
|
*/
|
|
@@ -103,7 +111,7 @@ export declare class Dom {
|
|
|
103
111
|
/**
|
|
104
112
|
* Check if element is comment node
|
|
105
113
|
*/
|
|
106
|
-
static isComment(node: Node): node is Comment;
|
|
114
|
+
static isComment(node: Nullable<Node> | false): node is Comment;
|
|
107
115
|
/**
|
|
108
116
|
* Check if element is element node
|
|
109
117
|
*/
|
|
@@ -147,7 +155,9 @@ export declare class Dom {
|
|
|
147
155
|
*/
|
|
148
156
|
static find<T extends Node = Node>(node: Node, condition: NodeCondition, root: HTMLElement, leftToRight?: boolean, withChild?: boolean): Nullable<T>;
|
|
149
157
|
/**
|
|
150
|
-
*
|
|
158
|
+
* Lazily iterate over all nodes what follow after `start` (in document order
|
|
159
|
+
* for `leftToRight = true`, in reverse order otherwise) inside `root`.
|
|
160
|
+
* Ancestors of `start` are not yielded.
|
|
151
161
|
*/
|
|
152
162
|
static nextGen(start: Node, root: HTMLElement, leftToRight?: boolean, withChild?: boolean): Generator<Node>;
|
|
153
163
|
/**
|
|
@@ -159,7 +169,7 @@ export declare class Dom {
|
|
|
159
169
|
* ```javascript
|
|
160
170
|
* Jodit.modules.Dom.each(editor.s.current(), function (node) {
|
|
161
171
|
* if (node.nodeType === Node.TEXT_NODE) {
|
|
162
|
-
* node.nodeValue = node.nodeValue.replace(Jodit.
|
|
172
|
+
* node.nodeValue = node.nodeValue.replace(Jodit.INVISIBLE_SPACE_REG_EXP(), '') // remove all of the text element codes invisible character
|
|
163
173
|
* }
|
|
164
174
|
* });
|
|
165
175
|
* ```
|
|
@@ -183,9 +193,16 @@ export declare class Dom {
|
|
|
183
193
|
* Returns the nearest non-empty neighbor
|
|
184
194
|
*/
|
|
185
195
|
static findNotEmptyNeighbor(node: Node, left: boolean, root: HTMLElement): Nullable<Node>;
|
|
196
|
+
/**
|
|
197
|
+
* Returns the previous (`left = true`) or next sibling of the node
|
|
198
|
+
*/
|
|
186
199
|
static sibling(node: Node, left?: boolean): Nullable<Node>;
|
|
187
200
|
/**
|
|
188
201
|
* It goes through all the elements in ascending order, and checks to see if they meet the predetermined condition
|
|
202
|
+
*
|
|
203
|
+
* The condition is checked for the `node` itself too. The `root` reached
|
|
204
|
+
* while ascending is checked only when `checkRoot = true`
|
|
205
|
+
* (but if `node === root` it is checked in any case).
|
|
189
206
|
*/
|
|
190
207
|
static up<T extends HTMLElement>(node: Nullable<Node>, condition: NodeCondition, root?: Node, checkRoot?: boolean): Nullable<T>;
|
|
191
208
|
/**
|
|
@@ -232,6 +249,12 @@ export declare class Dom {
|
|
|
232
249
|
* Safe remove element from DOM
|
|
233
250
|
*/
|
|
234
251
|
static safeRemove(...nodes: unknown[]): void;
|
|
252
|
+
/**
|
|
253
|
+
* Insert a node into the range and collapse the range to the start of
|
|
254
|
+
* the inserted content. Unlike the native `Range.insertNode` it does not
|
|
255
|
+
* split inseparable elements (BR, HR, IMG etc.) and removes empty text
|
|
256
|
+
* nodes produced by the split of a text container.
|
|
257
|
+
*/
|
|
235
258
|
static safeInsertNode(range: Range, node: Node): void;
|
|
236
259
|
/**
|
|
237
260
|
* Hide element
|
|
@@ -259,7 +282,7 @@ export declare class Dom {
|
|
|
259
282
|
*/
|
|
260
283
|
static isMarker(elm: Nullable<Node>): elm is HTMLElement;
|
|
261
284
|
/**
|
|
262
|
-
*
|
|
285
|
+
* Unwrap temporary elements inside a HTML string (keeps their content)
|
|
263
286
|
*/
|
|
264
287
|
static replaceTemporaryFromString(value: string): string;
|
|
265
288
|
/**
|
package/esm/core/dom/dom.js
CHANGED
|
@@ -19,6 +19,7 @@ import { css } from "../helpers/utils/css.js";
|
|
|
19
19
|
import { dataBind } from "../helpers/utils/data-bind.js";
|
|
20
20
|
import { error } from "../helpers/utils/error/index.js";
|
|
21
21
|
import { call } from "../helpers/utils/utils.js";
|
|
22
|
+
const TEMP_ELEMENT_REG_EXP = new RegExp(`<([a-z]+)[^>]+${TEMP_ATTR}[^>]*>(.+?)</\\1>`, 'gi');
|
|
22
23
|
/**
|
|
23
24
|
* Module for working with DOM
|
|
24
25
|
*/
|
|
@@ -129,7 +130,11 @@ export class Dom {
|
|
|
129
130
|
}
|
|
130
131
|
}
|
|
131
132
|
/**
|
|
132
|
-
* Call
|
|
133
|
+
* Call callback for all nodes between `start` and `end` in document order
|
|
134
|
+
* (`start` and `end` are not included). Iteration stops when the callback returns `true`.
|
|
135
|
+
*
|
|
136
|
+
* `end` must be positioned after `start` in the document (e.g. selection markers),
|
|
137
|
+
* otherwise iteration will stop only at the end of the tree.
|
|
133
138
|
*/
|
|
134
139
|
static between(start, end, callback) {
|
|
135
140
|
let next = start;
|
|
@@ -141,6 +146,10 @@ export class Dom {
|
|
|
141
146
|
if (!step) {
|
|
142
147
|
while (next && !next.nextSibling) {
|
|
143
148
|
next = next.parentNode;
|
|
149
|
+
// `end` was reached while ascending - all nodes between were visited
|
|
150
|
+
if (next === end) {
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
144
153
|
}
|
|
145
154
|
step = next === null || next === void 0 ? void 0 : next.nextSibling;
|
|
146
155
|
}
|
|
@@ -240,7 +249,7 @@ export class Dom {
|
|
|
240
249
|
return (Dom.isNode(elm) && (elm.nodeName === 'TD' || elm.nodeName === 'TH'));
|
|
241
250
|
}
|
|
242
251
|
/**
|
|
243
|
-
* Check if element is a list
|
|
252
|
+
* Check if element is a list element UL or OL
|
|
244
253
|
*/
|
|
245
254
|
static isList(elm) {
|
|
246
255
|
return Dom.isTag(elm, LIST_TAGS);
|
|
@@ -294,12 +303,13 @@ export class Dom {
|
|
|
294
303
|
* Check if element is document fragment
|
|
295
304
|
*/
|
|
296
305
|
static isFragment(node) {
|
|
297
|
-
var _a;
|
|
298
306
|
if (!Dom.isNode(node)) {
|
|
299
307
|
return false;
|
|
300
308
|
}
|
|
301
|
-
|
|
302
|
-
|
|
309
|
+
// no `defaultView` requirement — fragments of an inert document
|
|
310
|
+
// (`template.content`, `DOMParser`, `implementation.createHTMLDocument`)
|
|
311
|
+
// are still fragments
|
|
312
|
+
return node.nodeType === Node.DOCUMENT_FRAGMENT_NODE;
|
|
303
313
|
}
|
|
304
314
|
/**
|
|
305
315
|
* Check if element is HTMLElement node
|
|
@@ -424,7 +434,9 @@ export class Dom {
|
|
|
424
434
|
return null;
|
|
425
435
|
}
|
|
426
436
|
/**
|
|
427
|
-
*
|
|
437
|
+
* Lazily iterate over all nodes what follow after `start` (in document order
|
|
438
|
+
* for `leftToRight = true`, in reverse order otherwise) inside `root`.
|
|
439
|
+
* Ancestors of `start` are not yielded.
|
|
428
440
|
*/
|
|
429
441
|
static *nextGen(start, root, leftToRight = true, withChild = true) {
|
|
430
442
|
const stack = [];
|
|
@@ -434,9 +446,10 @@ export class Dom {
|
|
|
434
446
|
? currentNode.nextSibling
|
|
435
447
|
: currentNode.previousSibling;
|
|
436
448
|
while (next) {
|
|
437
|
-
stack.
|
|
449
|
+
stack.push(next);
|
|
438
450
|
next = leftToRight ? next.nextSibling : next.previousSibling;
|
|
439
451
|
}
|
|
452
|
+
stack.reverse();
|
|
440
453
|
yield* this.runInStack(start, stack, leftToRight, withChild);
|
|
441
454
|
currentNode = currentNode.parentNode;
|
|
442
455
|
} while (currentNode && currentNode !== root);
|
|
@@ -451,7 +464,7 @@ export class Dom {
|
|
|
451
464
|
* ```javascript
|
|
452
465
|
* Jodit.modules.Dom.each(editor.s.current(), function (node) {
|
|
453
466
|
* if (node.nodeType === Node.TEXT_NODE) {
|
|
454
|
-
* node.nodeValue = node.nodeValue.replace(Jodit.
|
|
467
|
+
* node.nodeValue = node.nodeValue.replace(Jodit.INVISIBLE_SPACE_REG_EXP(), '') // remove all of the text element codes invisible character
|
|
455
468
|
* }
|
|
456
469
|
* });
|
|
457
470
|
* ```
|
|
@@ -539,11 +552,18 @@ export class Dom {
|
|
|
539
552
|
(!(Dom.isText(n) || Dom.isComment(n)) ||
|
|
540
553
|
trim((n === null || n === void 0 ? void 0 : n.nodeValue) || '').length)), root);
|
|
541
554
|
}
|
|
555
|
+
/**
|
|
556
|
+
* Returns the previous (`left = true`) or next sibling of the node
|
|
557
|
+
*/
|
|
542
558
|
static sibling(node, left) {
|
|
543
559
|
return left ? node.previousSibling : node.nextSibling;
|
|
544
560
|
}
|
|
545
561
|
/**
|
|
546
562
|
* It goes through all the elements in ascending order, and checks to see if they meet the predetermined condition
|
|
563
|
+
*
|
|
564
|
+
* The condition is checked for the `node` itself too. The `root` reached
|
|
565
|
+
* while ascending is checked only when `checkRoot = true`
|
|
566
|
+
* (but if `node === root` it is checked in any case).
|
|
547
567
|
*/
|
|
548
568
|
static up(node, condition, root, checkRoot = false) {
|
|
549
569
|
let start = node;
|
|
@@ -689,6 +709,12 @@ export class Dom {
|
|
|
689
709
|
node.parentNode &&
|
|
690
710
|
node.parentNode.removeChild(node));
|
|
691
711
|
}
|
|
712
|
+
/**
|
|
713
|
+
* Insert a node into the range and collapse the range to the start of
|
|
714
|
+
* the inserted content. Unlike the native `Range.insertNode` it does not
|
|
715
|
+
* split inseparable elements (BR, HR, IMG etc.) and removes empty text
|
|
716
|
+
* nodes produced by the split of a text container.
|
|
717
|
+
*/
|
|
692
718
|
static safeInsertNode(range, node) {
|
|
693
719
|
range.collapsed || range.deleteContents();
|
|
694
720
|
const child = Dom.isFragment(node) ? node.lastChild : node;
|
|
@@ -730,22 +756,18 @@ export class Dom {
|
|
|
730
756
|
}
|
|
731
757
|
}
|
|
732
758
|
static isTag(node, tagNames) {
|
|
759
|
+
if (Array.isArray(tagNames)) {
|
|
760
|
+
throw new TypeError('Dom.isTag does not support array');
|
|
761
|
+
}
|
|
733
762
|
if (!this.isElement(node)) {
|
|
734
763
|
return false;
|
|
735
764
|
}
|
|
736
765
|
const nameL = node.tagName.toLowerCase();
|
|
737
|
-
const nameU = node.tagName.toUpperCase();
|
|
738
766
|
if (tagNames instanceof Set) {
|
|
739
|
-
return tagNames.has(nameL) ||
|
|
740
|
-
|
|
741
|
-
if (Array.isArray(tagNames)) {
|
|
742
|
-
throw new TypeError('Dom.isTag does not support array');
|
|
743
|
-
}
|
|
744
|
-
const tags = tagNames;
|
|
745
|
-
if (nameL === tags || nameU === tags) {
|
|
746
|
-
return true;
|
|
767
|
+
return (tagNames.has(nameL) ||
|
|
768
|
+
tagNames.has(node.tagName.toUpperCase()));
|
|
747
769
|
}
|
|
748
|
-
return
|
|
770
|
+
return (nameL === tagNames || node.tagName.toUpperCase() === tagNames);
|
|
749
771
|
}
|
|
750
772
|
/**
|
|
751
773
|
* Marks an item as temporary
|
|
@@ -773,10 +795,10 @@ export class Dom {
|
|
|
773
795
|
elm.hasAttribute('data-' + MARKER_CLASS));
|
|
774
796
|
}
|
|
775
797
|
/**
|
|
776
|
-
*
|
|
798
|
+
* Unwrap temporary elements inside a HTML string (keeps their content)
|
|
777
799
|
*/
|
|
778
800
|
static replaceTemporaryFromString(value) {
|
|
779
|
-
return value.replace(
|
|
801
|
+
return value.replace(TEMP_ELEMENT_REG_EXP, '$2');
|
|
780
802
|
}
|
|
781
803
|
/**
|
|
782
804
|
* Get temporary list
|
|
@@ -8,6 +8,16 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import type { IAsync, IDestructible } from "../../types/index";
|
|
10
10
|
import { Eventify } from "../event-emitter/eventify";
|
|
11
|
+
/**
|
|
12
|
+
* Walks the DOM tree in small chunks between browser tasks so that even huge
|
|
13
|
+
* documents do not block the main thread.
|
|
14
|
+
*
|
|
15
|
+
* Events:
|
|
16
|
+
* - `visit` - is called for every node; return `true` to mark the pass as
|
|
17
|
+
* "had effect" (it will be passed into the `end` event)
|
|
18
|
+
* - `break` - the pass was interrupted via [[LazyWalker.break]]
|
|
19
|
+
* - `end` - the pass is finished, receives `true` if some `visit` handler returned `true`
|
|
20
|
+
*/
|
|
11
21
|
export declare class LazyWalker extends Eventify<{
|
|
12
22
|
visit: (node: Node) => boolean;
|
|
13
23
|
break: (reason?: string) => void;
|
|
@@ -16,17 +26,24 @@ export declare class LazyWalker extends Eventify<{
|
|
|
16
26
|
private readonly async;
|
|
17
27
|
private readonly options;
|
|
18
28
|
private workNodes;
|
|
29
|
+
/**
|
|
30
|
+
* Starts a new pass over the `root` tree.
|
|
31
|
+
* If a previous pass is still running it will be stopped first.
|
|
32
|
+
*/
|
|
19
33
|
setWork(root: Node): this;
|
|
20
34
|
private hadAffect;
|
|
21
35
|
private isWorked;
|
|
22
36
|
private isFinished;
|
|
23
37
|
constructor(async: IAsync, options?: {
|
|
38
|
+
/** Visit only nodes with this `nodeType` (e.g. `Node.ELEMENT_NODE`) */
|
|
24
39
|
readonly whatToShow?: number;
|
|
40
|
+
/** Walk the tree from the last node to the first */
|
|
25
41
|
readonly reverse?: boolean;
|
|
42
|
+
/** How many nodes are processed per one chunk. Default: 50 */
|
|
26
43
|
readonly timeoutChunkSize?: number;
|
|
44
|
+
/** Delay between chunks in ms */
|
|
27
45
|
readonly timeout?: number;
|
|
28
46
|
});
|
|
29
|
-
private idleId;
|
|
30
47
|
private __schedulerController;
|
|
31
48
|
private _requestStarting;
|
|
32
49
|
break(reason?: string): void;
|
|
@@ -16,13 +16,32 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
16
16
|
import { autobind } from "../decorators/autobind/autobind.js";
|
|
17
17
|
import { Dom } from "./dom.js";
|
|
18
18
|
import { Eventify } from "../event-emitter/eventify.js";
|
|
19
|
+
/**
|
|
20
|
+
* Walks the DOM tree in small chunks between browser tasks so that even huge
|
|
21
|
+
* documents do not block the main thread.
|
|
22
|
+
*
|
|
23
|
+
* Events:
|
|
24
|
+
* - `visit` - is called for every node; return `true` to mark the pass as
|
|
25
|
+
* "had effect" (it will be passed into the `end` event)
|
|
26
|
+
* - `break` - the pass was interrupted via [[LazyWalker.break]]
|
|
27
|
+
* - `end` - the pass is finished, receives `true` if some `visit` handler returned `true`
|
|
28
|
+
*/
|
|
19
29
|
export class LazyWalker extends Eventify {
|
|
30
|
+
/**
|
|
31
|
+
* Starts a new pass over the `root` tree.
|
|
32
|
+
* If a previous pass is still running it will be stopped first.
|
|
33
|
+
*/
|
|
20
34
|
setWork(root) {
|
|
21
35
|
if (this.isWorked) {
|
|
22
36
|
this.break();
|
|
23
37
|
}
|
|
38
|
+
else {
|
|
39
|
+
// cancel a not yet started pass scheduled by the previous `setWork` call
|
|
40
|
+
this.stop();
|
|
41
|
+
}
|
|
24
42
|
this.workNodes = Dom.eachGen(root, !this.options.reverse);
|
|
25
43
|
this.isFinished = false;
|
|
44
|
+
this.hadAffect = false;
|
|
26
45
|
this._requestStarting();
|
|
27
46
|
return this;
|
|
28
47
|
}
|
|
@@ -34,7 +53,6 @@ export class LazyWalker extends Eventify {
|
|
|
34
53
|
this.hadAffect = false;
|
|
35
54
|
this.isWorked = false;
|
|
36
55
|
this.isFinished = false;
|
|
37
|
-
this.idleId = 0;
|
|
38
56
|
this.__schedulerController = null;
|
|
39
57
|
}
|
|
40
58
|
_requestStarting() {
|
|
@@ -60,10 +78,12 @@ export class LazyWalker extends Eventify {
|
|
|
60
78
|
}
|
|
61
79
|
}
|
|
62
80
|
stop() {
|
|
81
|
+
var _a;
|
|
63
82
|
this.isWorked = false;
|
|
64
83
|
this.isFinished = true;
|
|
65
84
|
this.workNodes = null;
|
|
66
|
-
this.
|
|
85
|
+
(_a = this.__schedulerController) === null || _a === void 0 ? void 0 : _a.abort();
|
|
86
|
+
this.__schedulerController = null;
|
|
67
87
|
}
|
|
68
88
|
destruct() {
|
|
69
89
|
super.destruct();
|
|
@@ -75,7 +95,7 @@ export class LazyWalker extends Eventify {
|
|
|
75
95
|
this.isWorked = true;
|
|
76
96
|
let count = 0;
|
|
77
97
|
const chunkSize = (_a = this.options.timeoutChunkSize) !== null && _a !== void 0 ? _a : 50;
|
|
78
|
-
while (!this.isFinished && count
|
|
98
|
+
while (!this.isFinished && count < chunkSize) {
|
|
79
99
|
const item = this.workNodes.next();
|
|
80
100
|
count += 1;
|
|
81
101
|
if (this.visitNode(item.value)) {
|
package/esm/core/request/ajax.js
CHANGED
|
@@ -243,7 +243,7 @@ export class Ajax {
|
|
|
243
243
|
if (method === 'get' && data && isPlainObject(data)) {
|
|
244
244
|
const qIndex = url.indexOf('?');
|
|
245
245
|
if (qIndex !== -1) {
|
|
246
|
-
const urlData = parseQuery(url);
|
|
246
|
+
const urlData = parseQuery(url.substring(qIndex));
|
|
247
247
|
url =
|
|
248
248
|
url.substring(0, qIndex) +
|
|
249
249
|
'?' +
|
|
@@ -6,7 +6,9 @@
|
|
|
6
6
|
export * from "./move-node-inside-start";
|
|
7
7
|
export * from "./move-the-node-along-the-edge-outward";
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
9
|
+
* Despite the name, returns `true` when the cursor is NOT at the checked edge
|
|
10
|
+
* of the text node: there is significant (non invisible-space) text between
|
|
11
|
+
* the offset and the start (`start = true`) or the end (`end = true`) of the string.
|
|
10
12
|
* @private
|
|
11
13
|
*/
|
|
12
14
|
export declare function cursorInTheEdgeOfString(container: Node, offset: number, start: boolean, end: boolean): boolean;
|
|
@@ -11,7 +11,9 @@ import { Dom } from "../../dom/dom.js";
|
|
|
11
11
|
export * from "./move-node-inside-start.js";
|
|
12
12
|
export * from "./move-the-node-along-the-edge-outward.js";
|
|
13
13
|
/**
|
|
14
|
-
*
|
|
14
|
+
* Despite the name, returns `true` when the cursor is NOT at the checked edge
|
|
15
|
+
* of the text node: there is significant (non invisible-space) text between
|
|
16
|
+
* the offset and the start (`start = true`) or the end (`end = true`) of the string.
|
|
15
17
|
* @private
|
|
16
18
|
*/
|
|
17
19
|
export function cursorInTheEdgeOfString(container, offset, start, end) {
|
|
@@ -90,6 +90,11 @@ export declare class Selection implements ISelect {
|
|
|
90
90
|
* Restores user selections using marker invisible elements in the DOM.
|
|
91
91
|
*/
|
|
92
92
|
restore(): void;
|
|
93
|
+
/**
|
|
94
|
+
* Inserts invisible fake nodes on the boundaries of the current selection
|
|
95
|
+
* and returns them. Unlike [[Select.save]] the selection stays valid while
|
|
96
|
+
* the DOM around it is being modified. Restore it later with [[Select.restoreFakes]].
|
|
97
|
+
*/
|
|
93
98
|
fakes(): [
|
|
94
99
|
] | [
|
|
95
100
|
Node
|
|
@@ -97,6 +102,10 @@ export declare class Selection implements ISelect {
|
|
|
97
102
|
Node,
|
|
98
103
|
Node
|
|
99
104
|
];
|
|
105
|
+
/**
|
|
106
|
+
* Restores the selection previously saved with [[Select.fakes]]
|
|
107
|
+
* and removes the fake nodes (disconnected fakes are ignored).
|
|
108
|
+
*/
|
|
100
109
|
restoreFakes(fakes: [
|
|
101
110
|
] | [
|
|
102
111
|
Node
|
|
@@ -244,5 +253,10 @@ export declare class Selection implements ISelect {
|
|
|
244
253
|
* Split selection on two parts: left and right
|
|
245
254
|
*/
|
|
246
255
|
splitSelection(currentBox: HTMLElement, edge?: Node): Nullable<Element>;
|
|
256
|
+
/**
|
|
257
|
+
* Expands the non-collapsed selection outward: boundaries positioned on the
|
|
258
|
+
* edge of their parents are moved out of them (e.g. `<p><b>|test|</b></p>`
|
|
259
|
+
* becomes `<p>|<b>test</b>|</p>`)
|
|
260
|
+
*/
|
|
247
261
|
expandSelection(): this;
|
|
248
262
|
}
|
|
@@ -178,7 +178,7 @@ export class Selection {
|
|
|
178
178
|
* Remove all markers
|
|
179
179
|
*/
|
|
180
180
|
removeMarkers() {
|
|
181
|
-
Dom.safeRemove
|
|
181
|
+
Dom.safeRemove(...this.markers);
|
|
182
182
|
}
|
|
183
183
|
/**
|
|
184
184
|
* Create marker element
|
|
@@ -244,6 +244,11 @@ export class Selection {
|
|
|
244
244
|
this.selectRange(range);
|
|
245
245
|
}
|
|
246
246
|
}
|
|
247
|
+
/**
|
|
248
|
+
* Inserts invisible fake nodes on the boundaries of the current selection
|
|
249
|
+
* and returns them. Unlike [[Select.save]] the selection stays valid while
|
|
250
|
+
* the DOM around it is being modified. Restore it later with [[Select.restoreFakes]].
|
|
251
|
+
*/
|
|
247
252
|
fakes() {
|
|
248
253
|
const sel = this.sel;
|
|
249
254
|
if (!sel || !sel.rangeCount) {
|
|
@@ -268,6 +273,10 @@ export class Selection {
|
|
|
268
273
|
this.selectRange(range);
|
|
269
274
|
return result;
|
|
270
275
|
}
|
|
276
|
+
/**
|
|
277
|
+
* Restores the selection previously saved with [[Select.fakes]]
|
|
278
|
+
* and removes the fake nodes (disconnected fakes are ignored).
|
|
279
|
+
*/
|
|
271
280
|
restoreFakes(fakes) {
|
|
272
281
|
var _a, _b, _c, _d;
|
|
273
282
|
const nodes = fakes.filter(n => n.isConnected);
|
|
@@ -523,7 +532,6 @@ export class Selection {
|
|
|
523
532
|
}
|
|
524
533
|
const node = this.j.createInside.div();
|
|
525
534
|
const fragment = this.j.createInside.fragment();
|
|
526
|
-
let lastChild;
|
|
527
535
|
if (!this.isFocused() && this.j.isEditorMode()) {
|
|
528
536
|
this.focus();
|
|
529
537
|
this.restore();
|
|
@@ -538,12 +546,10 @@ export class Selection {
|
|
|
538
546
|
this.j.e.fire('insertHTML', node.innerHTML) === false) {
|
|
539
547
|
return;
|
|
540
548
|
}
|
|
541
|
-
|
|
542
|
-
if (!lastChild) {
|
|
549
|
+
if (!node.lastChild) {
|
|
543
550
|
return;
|
|
544
551
|
}
|
|
545
552
|
while (node.firstChild) {
|
|
546
|
-
lastChild = node.firstChild;
|
|
547
553
|
fragment.appendChild(node.firstChild);
|
|
548
554
|
}
|
|
549
555
|
this.insertNode(fragment, insertCursorAfter, false);
|
|
@@ -678,7 +684,8 @@ export class Selection {
|
|
|
678
684
|
if (Dom.isEmptyTextNode(start)) {
|
|
679
685
|
nodes.push(start);
|
|
680
686
|
}
|
|
681
|
-
|
|
687
|
+
// `start` can be undefined for an empty root
|
|
688
|
+
if (start === null || start === void 0 ? void 0 : start.firstChild) {
|
|
682
689
|
nodes.push(start.firstChild);
|
|
683
690
|
}
|
|
684
691
|
}
|
|
@@ -694,8 +701,7 @@ export class Selection {
|
|
|
694
701
|
* @returns true - the cursor is at the end(start) block, null - cursor somewhere outside
|
|
695
702
|
*/
|
|
696
703
|
cursorInTheEdge(start, parentBlock, fake = null) {
|
|
697
|
-
|
|
698
|
-
const end = !start, range = (_a = this.sel) === null || _a === void 0 ? void 0 : _a.getRangeAt(0);
|
|
704
|
+
const end = !start, sel = this.sel, range = (sel === null || sel === void 0 ? void 0 : sel.rangeCount) ? sel.getRangeAt(0) : null;
|
|
699
705
|
fake !== null && fake !== void 0 ? fake : (fake = this.current(false));
|
|
700
706
|
if (!range || !fake || !Dom.isOrContains(parentBlock, fake, true)) {
|
|
701
707
|
return null;
|
|
@@ -1076,6 +1082,11 @@ export class Selection {
|
|
|
1076
1082
|
}
|
|
1077
1083
|
return currentBox.previousElementSibling;
|
|
1078
1084
|
}
|
|
1085
|
+
/**
|
|
1086
|
+
* Expands the non-collapsed selection outward: boundaries positioned on the
|
|
1087
|
+
* edge of their parents are moved out of them (e.g. `<p><b>|test|</b></p>`
|
|
1088
|
+
* becomes `<p>|<b>test</b>|</p>`)
|
|
1089
|
+
*/
|
|
1079
1090
|
expandSelection() {
|
|
1080
1091
|
if (this.isCollapsed()) {
|
|
1081
1092
|
return this;
|
|
@@ -5,8 +5,10 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import type { IDictionary } from "../../../../types/index";
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
8
|
+
* Checks that every attribute from `attrs` is present on the element with
|
|
9
|
+
* the same value (one-directional match: extra own attributes of the element
|
|
10
|
+
* are ignored, empty `attrs` matches any element)
|
|
9
11
|
* @private
|
|
10
12
|
*/
|
|
11
|
-
export declare function isSameAttributes(elm: HTMLElement, attrs?: IDictionary):
|
|
13
|
+
export declare function isSameAttributes(elm: HTMLElement, attrs?: IDictionary): boolean;
|
|
12
14
|
export declare function elementsEqualAttributes(elm1: HTMLElement, elm2: HTMLElement): boolean;
|