suneditor 3.0.0-beta.3 → 3.0.0-beta.30
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/CONTRIBUTING.md +8 -8
- package/README.md +44 -49
- package/dist/suneditor.min.css +1 -1
- package/dist/suneditor.min.js +1 -1
- package/package.json +95 -53
- package/src/assets/design/color.css +2 -2
- package/src/assets/design/size.css +2 -0
- package/src/assets/icons/defaultIcons.js +16 -1
- package/src/assets/suneditor-contents.css +9 -8
- package/src/assets/suneditor.css +29 -26
- package/src/core/{section → base}/actives.js +20 -12
- package/src/core/base/history.js +4 -4
- package/src/core/class/char.js +10 -10
- package/src/core/class/component.js +146 -57
- package/src/core/class/format.js +94 -2458
- package/src/core/class/html.js +187 -129
- package/src/core/class/inline.js +1853 -0
- package/src/core/class/listFormat.js +582 -0
- package/src/core/class/menu.js +14 -3
- package/src/core/class/nodeTransform.js +9 -14
- package/src/core/class/offset.js +162 -197
- package/src/core/class/selection.js +137 -34
- package/src/core/class/toolbar.js +73 -52
- package/src/core/class/ui.js +11 -11
- package/src/core/class/viewer.js +56 -55
- package/src/core/config/context.js +122 -0
- package/src/core/config/frameContext.js +204 -0
- package/src/core/config/options.js +639 -0
- package/src/core/editor.js +181 -108
- package/src/core/event/actions/index.js +229 -0
- package/src/core/event/effects/common.registry.js +60 -0
- package/src/core/event/effects/keydown.registry.js +551 -0
- package/src/core/event/effects/ruleHelpers.js +145 -0
- package/src/core/{base → event}/eventManager.js +119 -201
- package/src/core/event/executor.js +21 -0
- package/src/core/{base/eventHandlers → event/handlers}/handler_toolbar.js +4 -4
- package/src/core/{base/eventHandlers → event/handlers}/handler_ww_dragDrop.js +2 -2
- package/src/core/event/handlers/handler_ww_input.js +77 -0
- package/src/core/event/handlers/handler_ww_key.js +228 -0
- package/src/core/{base/eventHandlers → event/handlers}/handler_ww_mouse.js +3 -3
- package/src/core/event/ports.js +211 -0
- package/src/core/event/reducers/keydown.reducer.js +89 -0
- package/src/core/event/rules/keydown.rule.arrow.js +54 -0
- package/src/core/event/rules/keydown.rule.backspace.js +202 -0
- package/src/core/event/rules/keydown.rule.delete.js +126 -0
- package/src/core/event/rules/keydown.rule.enter.js +144 -0
- package/src/core/event/rules/keydown.rule.tab.js +29 -0
- package/src/core/section/constructor.js +79 -388
- package/src/core/section/documentType.js +47 -26
- package/src/core/util/instanceCheck.js +59 -0
- package/src/editorInjector/_classes.js +4 -0
- package/src/editorInjector/_core.js +17 -7
- package/src/editorInjector/index.js +10 -2
- package/src/events.js +6 -0
- package/src/helper/clipboard.js +24 -10
- package/src/helper/converter.js +17 -12
- package/src/helper/dom/domCheck.js +22 -3
- package/src/helper/dom/domQuery.js +91 -45
- package/src/helper/dom/domUtils.js +93 -19
- package/src/helper/dom/index.js +4 -0
- package/src/helper/env.js +11 -7
- package/src/helper/keyCodeMap.js +4 -3
- package/src/langs/ckb.js +1 -1
- package/src/langs/cs.js +1 -1
- package/src/langs/da.js +1 -1
- package/src/langs/de.js +1 -1
- package/src/langs/en.js +1 -1
- package/src/langs/es.js +1 -1
- package/src/langs/fa.js +1 -1
- package/src/langs/fr.js +1 -1
- package/src/langs/he.js +1 -1
- package/src/langs/hu.js +1 -1
- package/src/langs/it.js +1 -1
- package/src/langs/ja.js +1 -1
- package/src/langs/km.js +1 -1
- package/src/langs/ko.js +1 -1
- package/src/langs/lv.js +1 -1
- package/src/langs/nl.js +1 -1
- package/src/langs/pl.js +1 -1
- package/src/langs/pt_br.js +10 -10
- package/src/langs/ro.js +1 -1
- package/src/langs/ru.js +1 -1
- package/src/langs/se.js +1 -1
- package/src/langs/tr.js +1 -1
- package/src/langs/uk.js +1 -1
- package/src/langs/ur.js +1 -1
- package/src/langs/zh_cn.js +1 -1
- package/src/modules/ApiManager.js +25 -18
- package/src/modules/Browser.js +52 -61
- package/src/modules/ColorPicker.js +37 -38
- package/src/modules/Controller.js +85 -79
- package/src/modules/Figure.js +275 -187
- package/src/modules/FileManager.js +86 -92
- package/src/modules/HueSlider.js +67 -35
- package/src/modules/Modal.js +84 -77
- package/src/modules/ModalAnchorEditor.js +62 -79
- package/src/modules/SelectMenu.js +89 -86
- package/src/plugins/browser/audioGallery.js +9 -5
- package/src/plugins/browser/fileBrowser.js +10 -6
- package/src/plugins/browser/fileGallery.js +9 -5
- package/src/plugins/browser/imageGallery.js +9 -5
- package/src/plugins/browser/videoGallery.js +11 -6
- package/src/plugins/command/blockquote.js +1 -0
- package/src/plugins/command/exportPDF.js +11 -8
- package/src/plugins/command/fileUpload.js +41 -29
- package/src/plugins/command/list_bulleted.js +2 -1
- package/src/plugins/command/list_numbered.js +2 -1
- package/src/plugins/dropdown/align.js +8 -2
- package/src/plugins/dropdown/backgroundColor.js +19 -11
- package/src/plugins/dropdown/font.js +15 -9
- package/src/plugins/dropdown/fontColor.js +19 -11
- package/src/plugins/dropdown/formatBlock.js +7 -2
- package/src/plugins/dropdown/hr.js +7 -3
- package/src/plugins/dropdown/layout.js +6 -2
- package/src/plugins/dropdown/lineHeight.js +8 -3
- package/src/plugins/dropdown/list.js +2 -1
- package/src/plugins/dropdown/paragraphStyle.js +15 -11
- package/src/plugins/dropdown/{table.js → table/index.js} +514 -362
- package/src/plugins/dropdown/template.js +6 -2
- package/src/plugins/dropdown/textStyle.js +7 -3
- package/src/plugins/field/mention.js +33 -27
- package/src/plugins/input/fontSize.js +44 -37
- package/src/plugins/input/pageNavigator.js +3 -2
- package/src/plugins/modal/audio.js +90 -85
- package/src/plugins/modal/drawing.js +58 -66
- package/src/plugins/modal/embed.js +193 -180
- package/src/plugins/modal/image.js +441 -439
- package/src/plugins/modal/link.js +31 -8
- package/src/plugins/modal/math.js +23 -22
- package/src/plugins/modal/video.js +233 -230
- package/src/plugins/popup/anchor.js +24 -18
- package/src/suneditor.js +69 -24
- package/src/typedef.js +42 -19
- package/types/assets/icons/defaultIcons.d.ts +8 -0
- package/types/core/class/char.d.ts +1 -1
- package/types/core/class/component.d.ts +29 -7
- package/types/core/class/format.d.ts +4 -354
- package/types/core/class/html.d.ts +13 -4
- package/types/core/class/inline.d.ts +263 -0
- package/types/core/class/listFormat.d.ts +135 -0
- package/types/core/class/menu.d.ts +10 -2
- package/types/core/class/offset.d.ts +24 -26
- package/types/core/class/selection.d.ts +2 -0
- package/types/core/class/toolbar.d.ts +24 -11
- package/types/core/class/ui.d.ts +1 -1
- package/types/core/class/viewer.d.ts +1 -1
- package/types/core/config/context.d.ts +157 -0
- package/types/core/config/frameContext.d.ts +367 -0
- package/types/core/config/options.d.ts +1119 -0
- package/types/core/editor.d.ts +101 -66
- package/types/core/event/actions/index.d.ts +47 -0
- package/types/core/event/effects/common.registry.d.ts +50 -0
- package/types/core/event/effects/keydown.registry.d.ts +73 -0
- package/types/core/event/effects/ruleHelpers.d.ts +31 -0
- package/types/core/{base → event}/eventManager.d.ts +15 -46
- package/types/core/event/executor.d.ts +6 -0
- package/types/core/event/handlers/handler_ww_input.d.ts +41 -0
- package/types/core/{base/eventHandlers/handler_ww_key_input.d.ts → event/handlers/handler_ww_key.d.ts} +4 -6
- package/types/core/event/ports.d.ts +255 -0
- package/types/core/event/reducers/keydown.reducer.d.ts +75 -0
- package/types/core/event/rules/keydown.rule.arrow.d.ts +8 -0
- package/types/core/event/rules/keydown.rule.backspace.d.ts +9 -0
- package/types/core/event/rules/keydown.rule.delete.d.ts +9 -0
- package/types/core/event/rules/keydown.rule.enter.d.ts +9 -0
- package/types/core/event/rules/keydown.rule.tab.d.ts +9 -0
- package/types/core/section/constructor.d.ts +101 -631
- package/types/core/section/documentType.d.ts +14 -4
- package/types/core/util/instanceCheck.d.ts +50 -0
- package/types/editorInjector/_classes.d.ts +4 -0
- package/types/editorInjector/_core.d.ts +17 -7
- package/types/editorInjector/index.d.ts +10 -2
- package/types/events.d.ts +1 -0
- package/types/helper/clipboard.d.ts +2 -2
- package/types/helper/converter.d.ts +6 -9
- package/types/helper/dom/domCheck.d.ts +7 -0
- package/types/helper/dom/domQuery.d.ts +19 -8
- package/types/helper/dom/domUtils.d.ts +24 -2
- package/types/helper/dom/index.d.ts +86 -1
- package/types/helper/env.d.ts +6 -1
- package/types/helper/index.d.ts +7 -1
- package/types/helper/keyCodeMap.d.ts +3 -3
- package/types/index.d.ts +23 -117
- package/types/langs/index.d.ts +2 -2
- package/types/modules/ApiManager.d.ts +1 -8
- package/types/modules/Browser.d.ts +4 -62
- package/types/modules/ColorPicker.d.ts +4 -21
- package/types/modules/Controller.d.ts +8 -64
- package/types/modules/Figure.d.ts +54 -50
- package/types/modules/FileManager.d.ts +1 -13
- package/types/modules/HueSlider.d.ts +13 -3
- package/types/modules/Modal.d.ts +0 -43
- package/types/modules/ModalAnchorEditor.d.ts +0 -73
- package/types/modules/SelectMenu.d.ts +0 -85
- package/types/modules/index.d.ts +3 -3
- package/types/plugins/browser/audioGallery.d.ts +29 -18
- package/types/plugins/browser/fileBrowser.d.ts +38 -27
- package/types/plugins/browser/fileGallery.d.ts +29 -18
- package/types/plugins/browser/imageGallery.d.ts +24 -16
- package/types/plugins/browser/videoGallery.d.ts +29 -18
- package/types/plugins/command/blockquote.d.ts +1 -0
- package/types/plugins/command/exportPDF.d.ts +18 -18
- package/types/plugins/command/fileUpload.d.ts +65 -45
- package/types/plugins/command/list_bulleted.d.ts +1 -0
- package/types/plugins/command/list_numbered.d.ts +1 -0
- package/types/plugins/dropdown/align.d.ts +13 -8
- package/types/plugins/dropdown/backgroundColor.d.ts +30 -19
- package/types/plugins/dropdown/font.d.ts +13 -12
- package/types/plugins/dropdown/fontColor.d.ts +30 -19
- package/types/plugins/dropdown/formatBlock.d.ts +13 -8
- package/types/plugins/dropdown/hr.d.ts +15 -11
- package/types/plugins/dropdown/layout.d.ts +15 -11
- package/types/plugins/dropdown/lineHeight.d.ts +16 -11
- package/types/plugins/dropdown/list.d.ts +1 -0
- package/types/plugins/dropdown/paragraphStyle.d.ts +31 -27
- package/types/plugins/dropdown/table/index.d.ts +582 -0
- package/types/plugins/dropdown/table.d.ts +41 -86
- package/types/plugins/dropdown/template.d.ts +15 -11
- package/types/plugins/dropdown/textStyle.d.ts +19 -11
- package/types/plugins/field/mention.d.ts +58 -56
- package/types/plugins/index.d.ts +38 -38
- package/types/plugins/input/fontSize.d.ts +46 -50
- package/types/plugins/modal/audio.d.ts +26 -56
- package/types/plugins/modal/drawing.d.ts +0 -85
- package/types/plugins/modal/embed.d.ts +15 -79
- package/types/plugins/modal/image.d.ts +24 -136
- package/types/plugins/modal/link.d.ts +34 -15
- package/types/plugins/modal/math.d.ts +0 -16
- package/types/plugins/modal/video.d.ts +17 -86
- package/types/plugins/popup/anchor.d.ts +1 -8
- package/types/suneditor.d.ts +70 -19
- package/types/typedef.d.ts +60 -46
- package/src/core/base/eventHandlers/handler_ww_key_input.js +0 -1200
- package/src/core/section/context.js +0 -102
- package/types/core/section/context.d.ts +0 -45
- package/types/langs/_Lang.d.ts +0 -194
- /package/src/core/{base/eventHandlers → event/handlers}/handler_ww_clipboard.js +0 -0
- /package/types/core/{section → base}/actives.d.ts +0 -0
- /package/types/core/{base/eventHandlers → event/handlers}/handler_toolbar.d.ts +0 -0
- /package/types/core/{base/eventHandlers → event/handlers}/handler_ww_clipboard.d.ts +0 -0
- /package/types/core/{base/eventHandlers → event/handlers}/handler_ww_dragDrop.d.ts +0 -0
- /package/types/core/{base/eventHandlers → event/handlers}/handler_ww_mouse.d.ts +0 -0
package/src/core/class/format.js
CHANGED
|
@@ -3,32 +3,22 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import CoreInjector from '../../editorInjector/_core';
|
|
6
|
-
import { dom, unicode, numbers
|
|
6
|
+
import { dom, unicode, numbers } from '../../helper';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* @typedef {Omit<Format & Partial<__se__EditorInjector>, 'format'>} FormatThis
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
/**
|
|
13
|
-
* @typedef {Object} NodeStyleContainerType
|
|
14
|
-
* @property {?Node=} ancestor
|
|
15
|
-
* @property {?number=} offset
|
|
16
|
-
* @property {?Node=} container
|
|
17
|
-
* @property {?Node=} endContainer
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
12
|
/**
|
|
21
13
|
* @constructor
|
|
22
14
|
* @this {FormatThis}
|
|
23
|
-
* @description Classes related to editor formats such as line
|
|
15
|
+
* @description Classes related to editor formats such as "line" and "block".
|
|
24
16
|
* @param {__se__EditorCore} editor - The root editor instance
|
|
25
17
|
*/
|
|
26
18
|
function Format(editor) {
|
|
27
19
|
CoreInjector.call(this, editor);
|
|
28
20
|
|
|
29
21
|
// members
|
|
30
|
-
this._listCamel = this.options.get('__listCommonStyle');
|
|
31
|
-
this._listKebab = converter.camelToKebabCase(this.options.get('__listCommonStyle'));
|
|
32
22
|
this._formatLineCheck = this.options.get('formatLine').reg;
|
|
33
23
|
this._formatBrLineCheck = this.options.get('formatBrLine').reg;
|
|
34
24
|
this._formatBlockCheck = this.options.get('formatBlock').reg;
|
|
@@ -78,8 +68,8 @@ Format.prototype = {
|
|
|
78
68
|
this.history.push(false);
|
|
79
69
|
|
|
80
70
|
// document type
|
|
81
|
-
if (this.
|
|
82
|
-
this.
|
|
71
|
+
if (this.frameContext.has('documentType_use_header')) {
|
|
72
|
+
this.frameContext.get('documentType').reHeader();
|
|
83
73
|
}
|
|
84
74
|
},
|
|
85
75
|
|
|
@@ -92,16 +82,24 @@ Format.prototype = {
|
|
|
92
82
|
*/
|
|
93
83
|
getLine(node, validation) {
|
|
94
84
|
if (!node) return null;
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
return true;
|
|
98
|
-
};
|
|
99
|
-
}
|
|
85
|
+
|
|
86
|
+
validation ||= () => true;
|
|
100
87
|
|
|
101
88
|
while (node) {
|
|
102
89
|
if (dom.check.isWysiwygFrame(node)) return null;
|
|
103
|
-
|
|
104
|
-
if (this.
|
|
90
|
+
|
|
91
|
+
if (this.isBlock(node)) {
|
|
92
|
+
if (this.isLine(node.firstElementChild)) {
|
|
93
|
+
return /** @type {HTMLElement} */ (node.firstElementChild);
|
|
94
|
+
}
|
|
95
|
+
if (this.isLine(node)) {
|
|
96
|
+
return /** @type {HTMLElement} */ (node);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (this.isLine(node) && validation(node)) {
|
|
101
|
+
return /** @type {HTMLElement} */ (node);
|
|
102
|
+
}
|
|
105
103
|
|
|
106
104
|
node = node.parentNode;
|
|
107
105
|
}
|
|
@@ -187,11 +185,8 @@ Format.prototype = {
|
|
|
187
185
|
*/
|
|
188
186
|
getBrLine(element, validation) {
|
|
189
187
|
if (!element) return null;
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
return true;
|
|
193
|
-
};
|
|
194
|
-
}
|
|
188
|
+
|
|
189
|
+
validation ||= () => true;
|
|
195
190
|
|
|
196
191
|
while (element) {
|
|
197
192
|
if (dom.check.isWysiwygFrame(element)) return null;
|
|
@@ -220,7 +215,7 @@ Format.prototype = {
|
|
|
220
215
|
if (!this.isBrLine(element) && this.isBrLine(currentFormatEl || element.parentNode) && !this.component.is(element)) {
|
|
221
216
|
oFormat = dom.utils.createElement('BR');
|
|
222
217
|
} else {
|
|
223
|
-
const oFormatName = lineNode ? (typeof lineNode === 'string' ? lineNode : lineNode.nodeName) : this.
|
|
218
|
+
const oFormatName = lineNode ? (typeof lineNode === 'string' ? lineNode : lineNode.nodeName) : this.isNormalLine(currentFormatEl) ? currentFormatEl.nodeName : this.options.get('defaultLine');
|
|
224
219
|
oFormat = dom.utils.createElement(oFormatName, null, '<br>');
|
|
225
220
|
if ((lineNode && typeof lineNode !== 'string') || (!lineNode && this.isLine(currentFormatEl))) {
|
|
226
221
|
dom.utils.copyTagAttributes(oFormat, /** @type {Node} */ (lineNode || currentFormatEl), ['id']);
|
|
@@ -242,11 +237,8 @@ Format.prototype = {
|
|
|
242
237
|
*/
|
|
243
238
|
getBlock(element, validation) {
|
|
244
239
|
if (!element) return null;
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
return true;
|
|
248
|
-
};
|
|
249
|
-
}
|
|
240
|
+
|
|
241
|
+
validation ||= () => true;
|
|
250
242
|
|
|
251
243
|
while (element) {
|
|
252
244
|
if (dom.check.isWysiwygFrame(element)) return null;
|
|
@@ -296,7 +288,7 @@ Format.prototype = {
|
|
|
296
288
|
}
|
|
297
289
|
}
|
|
298
290
|
|
|
299
|
-
const last = rangeLines
|
|
291
|
+
const last = rangeLines.at(-1);
|
|
300
292
|
let standTag, beforeTag, pElement;
|
|
301
293
|
|
|
302
294
|
if (this.isBlock(last) || this.isLine(last)) {
|
|
@@ -385,7 +377,7 @@ Format.prototype = {
|
|
|
385
377
|
}
|
|
386
378
|
|
|
387
379
|
if (!nested) block.appendChild(listParent);
|
|
388
|
-
if (nextList) edge.removeArray
|
|
380
|
+
if (nextList) edge.removeArray.at(-1).appendChild(nextList);
|
|
389
381
|
listParent = null;
|
|
390
382
|
nested = false;
|
|
391
383
|
}
|
|
@@ -454,7 +446,7 @@ Format.prototype = {
|
|
|
454
446
|
let so = range.startOffset;
|
|
455
447
|
let eo = range.endOffset;
|
|
456
448
|
|
|
457
|
-
let children = dom.query.getListChildNodes(blockElement,
|
|
449
|
+
let children = dom.query.getListChildNodes(blockElement, null, 1);
|
|
458
450
|
let parent = blockElement.parentNode;
|
|
459
451
|
let firstNode = null;
|
|
460
452
|
let lastNode = null;
|
|
@@ -467,7 +459,7 @@ Format.prototype = {
|
|
|
467
459
|
let moveComplete = false;
|
|
468
460
|
|
|
469
461
|
const appendNode = (parentEl, insNode, sibling, originNode) => {
|
|
470
|
-
if (dom.check.isZeroWidth(insNode)) {
|
|
462
|
+
if (insNode.childNodes.length === 1 && dom.check.isZeroWidth(insNode)) {
|
|
471
463
|
insNode.innerHTML = unicode.zeroWidthSpace;
|
|
472
464
|
so = eo = 1;
|
|
473
465
|
}
|
|
@@ -486,12 +478,12 @@ Format.prototype = {
|
|
|
486
478
|
c = insChildren[0];
|
|
487
479
|
if (this._notTextNode(c) && !dom.check.isBreak(c) && !dom.check.isListCell(format)) {
|
|
488
480
|
if (format.childNodes.length > 0) {
|
|
489
|
-
|
|
481
|
+
first ||= format;
|
|
490
482
|
parentEl.insertBefore(format, sibling);
|
|
491
483
|
format = insNode.cloneNode(false);
|
|
492
484
|
}
|
|
493
485
|
parentEl.insertBefore(c, sibling);
|
|
494
|
-
|
|
486
|
+
first ||= c;
|
|
495
487
|
} else {
|
|
496
488
|
format.appendChild(c);
|
|
497
489
|
}
|
|
@@ -508,7 +500,7 @@ Format.prototype = {
|
|
|
508
500
|
parentEl.parentNode.insertBefore(format, parentEl.nextElementSibling);
|
|
509
501
|
} else {
|
|
510
502
|
const originNext = originNode.nextElementSibling;
|
|
511
|
-
const detachRange = this.
|
|
503
|
+
const detachRange = this.listFormat.removeNested(originNode, false);
|
|
512
504
|
if (blockElement !== detachRange || originNext !== originNode.nextElementSibling) {
|
|
513
505
|
const fChildren = format.childNodes;
|
|
514
506
|
while (fChildren[0]) {
|
|
@@ -523,7 +515,7 @@ Format.prototype = {
|
|
|
523
515
|
parentEl.insertBefore(format, sibling);
|
|
524
516
|
}
|
|
525
517
|
|
|
526
|
-
|
|
518
|
+
first ||= format;
|
|
527
519
|
}
|
|
528
520
|
|
|
529
521
|
return first;
|
|
@@ -545,7 +537,7 @@ Format.prototype = {
|
|
|
545
537
|
|
|
546
538
|
if (selectedFormats) lineIndex = selectedFormats.indexOf(insNode);
|
|
547
539
|
if (selectedFormats && lineIndex === -1) {
|
|
548
|
-
|
|
540
|
+
rangeEl ||= /** @type {HTMLElement} */ (blockElement.cloneNode(false));
|
|
549
541
|
rangeEl.appendChild(insNode);
|
|
550
542
|
} else {
|
|
551
543
|
if (selectedFormats) next = selectedFormats[lineIndex + 1];
|
|
@@ -557,7 +549,7 @@ Format.prototype = {
|
|
|
557
549
|
if (!newList && dom.check.isListCell(insNode)) {
|
|
558
550
|
if (next && dom.query.getNodeDepth(insNode) !== dom.query.getNodeDepth(next) && (dom.check.isListCell(parent) || dom.utils.arrayFind(insNode.children, dom.check.isList))) {
|
|
559
551
|
const insNext = insNode.nextElementSibling;
|
|
560
|
-
const detachRange = this.
|
|
552
|
+
const detachRange = this.listFormat.removeNested(insNode, false);
|
|
561
553
|
if (blockElement !== detachRange || insNext !== insNode.nextElementSibling) {
|
|
562
554
|
blockElement = detachRange;
|
|
563
555
|
reset = true;
|
|
@@ -568,10 +560,10 @@ Format.prototype = {
|
|
|
568
560
|
shouldDelete
|
|
569
561
|
? inner.nodeName
|
|
570
562
|
: dom.check.isList(blockElement.parentNode) || dom.check.isListCell(blockElement.parentNode)
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
563
|
+
? 'LI'
|
|
564
|
+
: dom.check.isTableCell(blockElement.parentNode)
|
|
565
|
+
? 'DIV'
|
|
566
|
+
: this.options.get('defaultLine')
|
|
575
567
|
);
|
|
576
568
|
const isCell = dom.check.isListCell(insNode);
|
|
577
569
|
const innerChildren = inner.childNodes;
|
|
@@ -601,9 +593,7 @@ Format.prototype = {
|
|
|
601
593
|
if (!reset) {
|
|
602
594
|
if (selectedFormats) {
|
|
603
595
|
lastNode = insNode;
|
|
604
|
-
|
|
605
|
-
firstNode = insNode;
|
|
606
|
-
}
|
|
596
|
+
firstNode ||= insNode;
|
|
607
597
|
} else if (!firstNode) {
|
|
608
598
|
firstNode = lastNode = insNode;
|
|
609
599
|
}
|
|
@@ -615,7 +605,7 @@ Format.prototype = {
|
|
|
615
605
|
|
|
616
606
|
if (reset) {
|
|
617
607
|
reset = moveComplete = false;
|
|
618
|
-
children = dom.query.getListChildNodes(blockElement,
|
|
608
|
+
children = dom.query.getListChildNodes(blockElement, null, 1);
|
|
619
609
|
rangeEl = /** @type {HTMLElement} */ (blockElement.cloneNode(false));
|
|
620
610
|
parent = blockElement.parentNode;
|
|
621
611
|
i = -1;
|
|
@@ -633,7 +623,7 @@ Format.prototype = {
|
|
|
633
623
|
}
|
|
634
624
|
|
|
635
625
|
if (newBlockElement) firstNode = newBlockElement.previousSibling;
|
|
636
|
-
else
|
|
626
|
+
else firstNode ||= blockElement.previousSibling;
|
|
637
627
|
rangeRight = blockElement.nextSibling !== rangeEl ? blockElement.nextSibling : rangeEl ? rangeEl.nextSibling : null;
|
|
638
628
|
|
|
639
629
|
if (/** @type {HTMLElement} */ (blockElement).children.length === 0 || blockElement.textContent.length === 0) {
|
|
@@ -643,6 +633,8 @@ Format.prototype = {
|
|
|
643
633
|
}
|
|
644
634
|
|
|
645
635
|
let edge = null;
|
|
636
|
+
this.editor.effectNode = null;
|
|
637
|
+
|
|
646
638
|
if (shouldDelete) {
|
|
647
639
|
edge = {
|
|
648
640
|
cc: rangeParent,
|
|
@@ -653,20 +645,23 @@ Format.prototype = {
|
|
|
653
645
|
removeArray: removeArray
|
|
654
646
|
};
|
|
655
647
|
} else {
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
const childEdge = dom.query.getEdgeChildNodes(firstNode, lastNode
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
648
|
+
firstNode ||= lastNode;
|
|
649
|
+
lastNode ||= firstNode;
|
|
650
|
+
const childEdge = dom.query.getEdgeChildNodes(firstNode, lastNode?.parentNode ? firstNode : lastNode);
|
|
651
|
+
if (!childEdge) {
|
|
652
|
+
this.editor.focus();
|
|
653
|
+
} else {
|
|
654
|
+
edge = {
|
|
655
|
+
cc: (childEdge.sc || childEdge.ec).parentNode,
|
|
656
|
+
sc: childEdge.sc,
|
|
657
|
+
so: so,
|
|
658
|
+
ec: childEdge.ec,
|
|
659
|
+
eo: eo,
|
|
660
|
+
removeArray: null
|
|
661
|
+
};
|
|
662
|
+
}
|
|
667
663
|
}
|
|
668
664
|
|
|
669
|
-
this.editor.effectNode = null;
|
|
670
665
|
if (skipHistory) return edge;
|
|
671
666
|
|
|
672
667
|
if (!shouldDelete && edge) {
|
|
@@ -680,273 +675,6 @@ Format.prototype = {
|
|
|
680
675
|
this.history.push(false);
|
|
681
676
|
},
|
|
682
677
|
|
|
683
|
-
/**
|
|
684
|
-
* @this {FormatThis}
|
|
685
|
-
* @description Append all selected "line" element to the list and insert.
|
|
686
|
-
* @param {string} type List type. (ol | ul):[listStyleType]
|
|
687
|
-
* @param {Array<Node>} selectedCells "line" elements or list cells.
|
|
688
|
-
* @param {boolean} nested If true, indenting existing list cells.
|
|
689
|
-
*/
|
|
690
|
-
applyList(type, selectedCells, nested) {
|
|
691
|
-
const listTag = (type.split(':')[0] || 'ol').toUpperCase();
|
|
692
|
-
const listStyle = type.split(':')[1] || '';
|
|
693
|
-
|
|
694
|
-
let range = this.selection.getRange();
|
|
695
|
-
let selectedFormats = /** @type {Array<HTMLElement>} */ (!selectedCells ? this.getLinesAndComponents(false) : selectedCells);
|
|
696
|
-
|
|
697
|
-
if (selectedFormats.length === 0) {
|
|
698
|
-
if (selectedCells) return;
|
|
699
|
-
range = this.selection.getRangeAndAddLine(range, null);
|
|
700
|
-
selectedFormats = this.getLinesAndComponents(false);
|
|
701
|
-
if (selectedFormats.length === 0) return;
|
|
702
|
-
}
|
|
703
|
-
|
|
704
|
-
dom.query.sortNodeByDepth(selectedFormats, true);
|
|
705
|
-
|
|
706
|
-
// merge
|
|
707
|
-
const firstSel = selectedFormats[0];
|
|
708
|
-
const lastSel = selectedFormats[selectedFormats.length - 1];
|
|
709
|
-
let topEl = (dom.check.isListCell(firstSel) || this.component.is(firstSel)) && !firstSel.previousElementSibling ? firstSel.parentElement.previousElementSibling : firstSel.previousElementSibling;
|
|
710
|
-
let bottomEl = (dom.check.isListCell(lastSel) || this.component.is(lastSel)) && !lastSel.nextElementSibling ? lastSel.parentElement.nextElementSibling : lastSel.nextElementSibling;
|
|
711
|
-
|
|
712
|
-
const isCollapsed = range.collapsed;
|
|
713
|
-
const originRange = {
|
|
714
|
-
sc: range.startContainer,
|
|
715
|
-
so: range.startContainer === range.endContainer && dom.check.isZeroWidth(range.startContainer) && range.startOffset === 0 && range.endOffset === 1 ? range.endOffset : range.startOffset,
|
|
716
|
-
ec: range.endContainer,
|
|
717
|
-
eo: range.endOffset
|
|
718
|
-
};
|
|
719
|
-
let afterRange = null;
|
|
720
|
-
let isRemove = true;
|
|
721
|
-
|
|
722
|
-
for (let i = 0, len = selectedFormats.length; i < len; i++) {
|
|
723
|
-
if (!dom.check.isList(this.getBlock(selectedFormats[i], (current) => this.getBlock(current) && current !== selectedFormats[i]))) {
|
|
724
|
-
isRemove = false;
|
|
725
|
-
break;
|
|
726
|
-
}
|
|
727
|
-
}
|
|
728
|
-
|
|
729
|
-
if (isRemove && (!topEl || firstSel.tagName !== topEl.tagName || listTag !== topEl.tagName.toUpperCase()) && (!bottomEl || lastSel.tagName !== bottomEl.tagName || listTag !== bottomEl.tagName.toUpperCase())) {
|
|
730
|
-
if (nested) {
|
|
731
|
-
for (let i = 0, len = selectedFormats.length; i < len; i++) {
|
|
732
|
-
for (let j = i - 1; j >= 0; j--) {
|
|
733
|
-
if (selectedFormats[j].contains(selectedFormats[i])) {
|
|
734
|
-
selectedFormats.splice(i, 1);
|
|
735
|
-
i--;
|
|
736
|
-
len--;
|
|
737
|
-
break;
|
|
738
|
-
}
|
|
739
|
-
}
|
|
740
|
-
}
|
|
741
|
-
}
|
|
742
|
-
|
|
743
|
-
const currentFormat = this.getBlock(firstSel);
|
|
744
|
-
const cancel = currentFormat?.tagName === listTag;
|
|
745
|
-
let rangeArr, tempList;
|
|
746
|
-
const passComponent = (current) => {
|
|
747
|
-
return !this.component.is(current);
|
|
748
|
-
};
|
|
749
|
-
|
|
750
|
-
if (!cancel) {
|
|
751
|
-
tempList = dom.utils.createElement(listTag, { style: 'list-style-type: ' + listStyle });
|
|
752
|
-
}
|
|
753
|
-
|
|
754
|
-
for (let i = 0, len = selectedFormats.length, r, o; i < len; i++) {
|
|
755
|
-
o = this.getBlock(selectedFormats[i], passComponent);
|
|
756
|
-
if (!o || !dom.check.isList(o)) continue;
|
|
757
|
-
|
|
758
|
-
if (!r) {
|
|
759
|
-
r = o;
|
|
760
|
-
rangeArr = {
|
|
761
|
-
r: r,
|
|
762
|
-
f: [dom.query.getParentElement(selectedFormats[i], 'LI')]
|
|
763
|
-
};
|
|
764
|
-
} else {
|
|
765
|
-
if (r !== o) {
|
|
766
|
-
if (nested && dom.check.isListCell(o.parentNode)) {
|
|
767
|
-
this._detachNested(rangeArr.f);
|
|
768
|
-
} else {
|
|
769
|
-
afterRange = this.removeBlock(rangeArr.f[0].parentElement, { selectedFormats: rangeArr.f, newBlockElement: tempList, shouldDelete: false, skipHistory: true });
|
|
770
|
-
}
|
|
771
|
-
|
|
772
|
-
o = selectedFormats[i].parentNode;
|
|
773
|
-
if (!cancel) {
|
|
774
|
-
tempList = dom.utils.createElement(listTag, { style: 'list-style-type: ' + listStyle });
|
|
775
|
-
}
|
|
776
|
-
|
|
777
|
-
r = o;
|
|
778
|
-
rangeArr = {
|
|
779
|
-
r: r,
|
|
780
|
-
f: [dom.query.getParentElement(selectedFormats[i], 'LI')]
|
|
781
|
-
};
|
|
782
|
-
} else {
|
|
783
|
-
rangeArr.f.push(dom.query.getParentElement(selectedFormats[i], 'LI'));
|
|
784
|
-
}
|
|
785
|
-
}
|
|
786
|
-
|
|
787
|
-
if (i === len - 1) {
|
|
788
|
-
if (nested && dom.check.isListCell(o.parentNode)) {
|
|
789
|
-
this._detachNested(rangeArr.f);
|
|
790
|
-
} else {
|
|
791
|
-
afterRange = this.removeBlock(rangeArr.f[0].parentElement, { selectedFormats: rangeArr.f, newBlockElement: tempList, shouldDelete: false, skipHistory: true });
|
|
792
|
-
}
|
|
793
|
-
}
|
|
794
|
-
}
|
|
795
|
-
} else {
|
|
796
|
-
const topElParent = topEl ? topEl.parentNode : topEl;
|
|
797
|
-
const bottomElParent = bottomEl ? bottomEl.parentNode : bottomEl;
|
|
798
|
-
topEl = /** @type {HTMLElement} */ (topElParent && !dom.check.isWysiwygFrame(topElParent) && topElParent.nodeName === listTag ? topElParent : topEl);
|
|
799
|
-
bottomEl = /** @type {HTMLElement} */ (bottomElParent && !dom.check.isWysiwygFrame(bottomElParent) && bottomElParent.nodeName === listTag ? bottomElParent : bottomEl);
|
|
800
|
-
|
|
801
|
-
const mergeTop = topEl?.tagName === listTag;
|
|
802
|
-
const mergeBottom = bottomEl?.tagName === listTag;
|
|
803
|
-
|
|
804
|
-
let list = mergeTop ? topEl : dom.utils.createElement(listTag, { style: 'list-style-type: ' + listStyle });
|
|
805
|
-
let firstList = null;
|
|
806
|
-
let topNumber = null;
|
|
807
|
-
// let lastList = null;
|
|
808
|
-
// let bottomNumber = null;
|
|
809
|
-
|
|
810
|
-
const passComponent = (current) => {
|
|
811
|
-
return !this.component.is(current) && !dom.check.isList(current);
|
|
812
|
-
};
|
|
813
|
-
|
|
814
|
-
for (let i = 0, len = selectedFormats.length, newCell, fTag, isCell, next, originParent, nextParent, parentTag, siblingTag, rangeTag; i < len; i++) {
|
|
815
|
-
fTag = selectedFormats[i];
|
|
816
|
-
if (fTag.childNodes.length === 0 && !this._isIgnoreNodeChange(fTag)) {
|
|
817
|
-
dom.utils.removeItem(fTag);
|
|
818
|
-
continue;
|
|
819
|
-
}
|
|
820
|
-
next = selectedFormats[i + 1];
|
|
821
|
-
originParent = fTag.parentNode;
|
|
822
|
-
nextParent = next ? next.parentNode : null;
|
|
823
|
-
isCell = dom.check.isListCell(fTag);
|
|
824
|
-
rangeTag = this.isBlock(originParent) ? originParent : null;
|
|
825
|
-
parentTag = isCell && !dom.check.isWysiwygFrame(originParent) ? originParent.parentNode : originParent;
|
|
826
|
-
siblingTag = isCell && !dom.check.isWysiwygFrame(originParent) ? (!next || dom.check.isListCell(parentTag) ? originParent : originParent.nextSibling) : fTag.nextSibling;
|
|
827
|
-
|
|
828
|
-
newCell = dom.utils.createElement('LI');
|
|
829
|
-
dom.utils.copyFormatAttributes(newCell, fTag);
|
|
830
|
-
if (this.component.is(fTag)) {
|
|
831
|
-
const isHR = /^HR$/i.test(fTag.nodeName);
|
|
832
|
-
if (!isHR) newCell.innerHTML = '<br>';
|
|
833
|
-
newCell.innerHTML += fTag.outerHTML;
|
|
834
|
-
if (isHR) newCell.innerHTML += '<br>';
|
|
835
|
-
} else {
|
|
836
|
-
const fChildren = fTag.childNodes;
|
|
837
|
-
while (fChildren[0]) {
|
|
838
|
-
newCell.appendChild(fChildren[0]);
|
|
839
|
-
}
|
|
840
|
-
}
|
|
841
|
-
list.appendChild(newCell);
|
|
842
|
-
|
|
843
|
-
// if (!next) lastList = list;
|
|
844
|
-
if (!next || parentTag !== nextParent || this.isBlock(siblingTag)) {
|
|
845
|
-
if (!firstList) firstList = list;
|
|
846
|
-
if ((!mergeTop || !next || parentTag !== nextParent) && !(next && dom.check.isList(nextParent) && nextParent === originParent)) {
|
|
847
|
-
if (list.parentNode !== parentTag) parentTag.insertBefore(list, siblingTag);
|
|
848
|
-
}
|
|
849
|
-
}
|
|
850
|
-
|
|
851
|
-
dom.utils.removeItem(fTag);
|
|
852
|
-
if (mergeTop && topNumber === null) topNumber = list.children.length - 1;
|
|
853
|
-
if (
|
|
854
|
-
next &&
|
|
855
|
-
(this.getBlock(nextParent, passComponent) !== this.getBlock(originParent, passComponent) ||
|
|
856
|
-
(dom.check.isList(nextParent) && dom.check.isList(originParent) && dom.query.getNodeDepth(nextParent) !== dom.query.getNodeDepth(originParent)))
|
|
857
|
-
) {
|
|
858
|
-
list = dom.utils.createElement(listTag, { style: 'list-style-type: ' + listStyle });
|
|
859
|
-
}
|
|
860
|
-
|
|
861
|
-
if (rangeTag?.children.length === 0) dom.utils.removeItem(rangeTag);
|
|
862
|
-
}
|
|
863
|
-
|
|
864
|
-
if (topNumber) {
|
|
865
|
-
firstList = firstList.children[topNumber];
|
|
866
|
-
}
|
|
867
|
-
|
|
868
|
-
if (mergeBottom) {
|
|
869
|
-
// bottomNumber = list.children.length - 1;
|
|
870
|
-
list.innerHTML += bottomEl.innerHTML;
|
|
871
|
-
// lastList = list.children[bottomNumber] || lastList;
|
|
872
|
-
dom.utils.removeItem(bottomEl);
|
|
873
|
-
}
|
|
874
|
-
}
|
|
875
|
-
|
|
876
|
-
this.editor.effectNode = null;
|
|
877
|
-
return !isRemove || !isCollapsed ? originRange : afterRange || originRange;
|
|
878
|
-
},
|
|
879
|
-
|
|
880
|
-
/**
|
|
881
|
-
* @this {FormatThis}
|
|
882
|
-
* @description "selectedCells" array are detached from the list element.
|
|
883
|
-
* - The return value is applied when the first and last lines of "selectedFormats" are "LI" respectively.
|
|
884
|
-
* @param {Array<Node>} selectedCells Array of ["line", li] elements(LI, P...) to remove.
|
|
885
|
-
* @param {boolean} shouldDelete If true, It does not just remove the list, it deletes the content.
|
|
886
|
-
* @returns {{sc: Node, ec: Node}} Node information after deletion
|
|
887
|
-
* - sc: Start container node
|
|
888
|
-
* - ec: End container node
|
|
889
|
-
*/
|
|
890
|
-
removeList(selectedCells, shouldDelete) {
|
|
891
|
-
let rangeArr = {};
|
|
892
|
-
let listFirst = false;
|
|
893
|
-
let listLast = false;
|
|
894
|
-
let first = null;
|
|
895
|
-
let last = null;
|
|
896
|
-
const passComponent = (current) => {
|
|
897
|
-
return !this.component.is(current);
|
|
898
|
-
};
|
|
899
|
-
|
|
900
|
-
for (let i = 0, len = selectedCells.length, r, o, lastIndex, isList; i < len; i++) {
|
|
901
|
-
lastIndex = i === len - 1;
|
|
902
|
-
o = this.getBlock(selectedCells[i], passComponent);
|
|
903
|
-
isList = dom.check.isList(o);
|
|
904
|
-
if (!r && isList) {
|
|
905
|
-
r = o;
|
|
906
|
-
rangeArr = {
|
|
907
|
-
r: r,
|
|
908
|
-
f: [dom.query.getParentElement(selectedCells[i], 'LI')]
|
|
909
|
-
};
|
|
910
|
-
if (i === 0) listFirst = true;
|
|
911
|
-
} else if (r && isList) {
|
|
912
|
-
if (r !== o) {
|
|
913
|
-
const edge = this.removeBlock(rangeArr.f[0].parentNode, { selectedFormats: rangeArr.f, newBlockElement: null, shouldDelete, skipHistory: true });
|
|
914
|
-
o = selectedCells[i].parentNode;
|
|
915
|
-
if (listFirst) {
|
|
916
|
-
first = edge.sc;
|
|
917
|
-
listFirst = false;
|
|
918
|
-
}
|
|
919
|
-
if (lastIndex) last = edge.ec;
|
|
920
|
-
|
|
921
|
-
if (isList) {
|
|
922
|
-
r = o;
|
|
923
|
-
rangeArr = {
|
|
924
|
-
r: r,
|
|
925
|
-
f: [dom.query.getParentElement(selectedCells[i], 'LI')]
|
|
926
|
-
};
|
|
927
|
-
if (lastIndex) listLast = true;
|
|
928
|
-
} else {
|
|
929
|
-
r = null;
|
|
930
|
-
}
|
|
931
|
-
} else {
|
|
932
|
-
rangeArr.f.push(dom.query.getParentElement(selectedCells[i], 'LI'));
|
|
933
|
-
if (lastIndex) listLast = true;
|
|
934
|
-
}
|
|
935
|
-
}
|
|
936
|
-
|
|
937
|
-
if (lastIndex && dom.check.isList(r)) {
|
|
938
|
-
const edge = this.removeBlock(rangeArr.f[0].parentNode, { selectedFormats: rangeArr.f, newBlockElement: null, shouldDelete, skipHistory: true });
|
|
939
|
-
if (listLast || len === 1) last = edge.ec;
|
|
940
|
-
if (listFirst) first = edge.sc || last;
|
|
941
|
-
}
|
|
942
|
-
}
|
|
943
|
-
|
|
944
|
-
return {
|
|
945
|
-
sc: first,
|
|
946
|
-
ec: last
|
|
947
|
-
};
|
|
948
|
-
},
|
|
949
|
-
|
|
950
678
|
/**
|
|
951
679
|
* @this {FormatThis}
|
|
952
680
|
* @description Indent more the selected lines.
|
|
@@ -964,7 +692,7 @@ Format.prototype = {
|
|
|
964
692
|
|
|
965
693
|
// list cells
|
|
966
694
|
if (cells.length > 0) {
|
|
967
|
-
this.
|
|
695
|
+
this.listFormat.applyNested(cells, false);
|
|
968
696
|
}
|
|
969
697
|
|
|
970
698
|
this.editor.effectNode = null;
|
|
@@ -989,7 +717,7 @@ Format.prototype = {
|
|
|
989
717
|
|
|
990
718
|
// list cells
|
|
991
719
|
if (cells.length > 0) {
|
|
992
|
-
this.
|
|
720
|
+
this.listFormat.applyNested(cells, true);
|
|
993
721
|
}
|
|
994
722
|
|
|
995
723
|
this.editor.effectNode = null;
|
|
@@ -997,378 +725,6 @@ Format.prototype = {
|
|
|
997
725
|
this.history.push(false);
|
|
998
726
|
},
|
|
999
727
|
|
|
1000
|
-
/**
|
|
1001
|
-
* @this {FormatThis}
|
|
1002
|
-
* @description Adds, updates, or deletes style nodes from selected text (a, span, strong, etc.).
|
|
1003
|
-
* @param {?Node} styleNode The element to be added to the selection. If null, only existing nodes are modified or removed.
|
|
1004
|
-
* @param {Object} [options] Options
|
|
1005
|
-
* @param {Array<string>} [options.stylesToModify=null] Array of style or class names to check and modify.
|
|
1006
|
-
* (e.g., ['font-size'], ['.className'], ['font-family', 'color', '.className'])
|
|
1007
|
-
* @param {Array<string>} [options.nodesToRemove=null] Array of node names to remove.
|
|
1008
|
-
* If empty array or null when styleNode is null, all formats are removed.
|
|
1009
|
-
* (e.g., ['span'], ['strong', 'em'])
|
|
1010
|
-
* @param {boolean} [options.strictRemove=false] If true, only removes nodes from nodesToRemove if all styles and classes are removed.
|
|
1011
|
-
* @returns {HTMLElement} The element that was added to or modified in the selection.
|
|
1012
|
-
*
|
|
1013
|
-
* @details
|
|
1014
|
-
* 1. If styleNode is provided, a node with the same tags and attributes is added to the selected text.
|
|
1015
|
-
* 2. If the same tag already exists, only its attributes are updated.
|
|
1016
|
-
* 3. If styleNode is null, existing nodes are updated or removed without adding new ones.
|
|
1017
|
-
* 4. Styles matching those in stylesToModify are removed. (Use CSS attribute names, e.g., "background-color")
|
|
1018
|
-
* 5. Classes matching those in stylesToModify (prefixed with ".") are removed.
|
|
1019
|
-
* 6. stylesToModify is used to avoid duplicate property values from styleNode.
|
|
1020
|
-
* 7. Nodes with all styles and classes removed are deleted if they match styleNode, are in nodesToRemove, or if styleNode is null.
|
|
1021
|
-
* 8. Tags matching names in nodesToRemove are deleted regardless of their style and class.
|
|
1022
|
-
* 9. If strictRemove is true, nodes in nodesToRemove are only removed if all their styles and classes are removed.
|
|
1023
|
-
* 10. The function won't modify nodes if the parent has the same class and style values.
|
|
1024
|
-
* - However, if nodesToRemove has values, it will work and separate text nodes even if there's no node to replace.
|
|
1025
|
-
*/
|
|
1026
|
-
applyInlineElement(styleNode, { stylesToModify, nodesToRemove, strictRemove } = {}) {
|
|
1027
|
-
if (dom.query.getParentElement(this.selection.getNode(), dom.check.isNonEditable)) return;
|
|
1028
|
-
|
|
1029
|
-
this.selection._resetRangeToTextNode();
|
|
1030
|
-
let range = this.selection.getRangeAndAddLine(this.selection.getRange(), null);
|
|
1031
|
-
stylesToModify = stylesToModify?.length > 0 ? stylesToModify : null;
|
|
1032
|
-
nodesToRemove = nodesToRemove?.length > 0 ? nodesToRemove : null;
|
|
1033
|
-
|
|
1034
|
-
const isRemoveNode = !styleNode;
|
|
1035
|
-
const isRemoveFormat = isRemoveNode && !nodesToRemove && !stylesToModify;
|
|
1036
|
-
let startCon = range.startContainer;
|
|
1037
|
-
let startOff = range.startOffset;
|
|
1038
|
-
let endCon = range.endContainer;
|
|
1039
|
-
let endOff = range.endOffset;
|
|
1040
|
-
|
|
1041
|
-
if ((isRemoveFormat && range.collapsed && this.isLine(startCon.parentNode) && this.isLine(endCon.parentNode)) || (startCon === endCon && startCon.nodeType === 1 && dom.check.isNonEditable(startCon))) {
|
|
1042
|
-
const format = startCon.parentNode;
|
|
1043
|
-
if (
|
|
1044
|
-
!dom.check.isListCell(format) ||
|
|
1045
|
-
!converter.getValues(format.style).some((k) => {
|
|
1046
|
-
return this._listKebab.includes(k);
|
|
1047
|
-
})
|
|
1048
|
-
)
|
|
1049
|
-
return;
|
|
1050
|
-
return;
|
|
1051
|
-
}
|
|
1052
|
-
|
|
1053
|
-
if (range.collapsed && !isRemoveFormat) {
|
|
1054
|
-
if (startCon.nodeType === 1 && !dom.check.isBreak(startCon) && !this.component.is(startCon)) {
|
|
1055
|
-
let afterNode = null;
|
|
1056
|
-
const focusNode = startCon.childNodes[startOff];
|
|
1057
|
-
|
|
1058
|
-
if (focusNode) {
|
|
1059
|
-
if (!focusNode.nextSibling) {
|
|
1060
|
-
afterNode = null;
|
|
1061
|
-
} else {
|
|
1062
|
-
afterNode = dom.check.isBreak(focusNode) ? focusNode : focusNode.nextSibling;
|
|
1063
|
-
}
|
|
1064
|
-
}
|
|
1065
|
-
|
|
1066
|
-
const zeroWidth = dom.utils.createTextNode(unicode.zeroWidthSpace);
|
|
1067
|
-
startCon.insertBefore(zeroWidth, afterNode);
|
|
1068
|
-
this.selection.setRange(zeroWidth, 1, zeroWidth, 1);
|
|
1069
|
-
|
|
1070
|
-
range = this.selection.getRange();
|
|
1071
|
-
startCon = range.startContainer;
|
|
1072
|
-
startOff = range.startOffset;
|
|
1073
|
-
endCon = range.endContainer;
|
|
1074
|
-
endOff = range.endOffset;
|
|
1075
|
-
}
|
|
1076
|
-
}
|
|
1077
|
-
|
|
1078
|
-
if (this.isLine(startCon)) {
|
|
1079
|
-
startCon = startCon.childNodes[startOff] || startCon.firstChild;
|
|
1080
|
-
startOff = 0;
|
|
1081
|
-
}
|
|
1082
|
-
if (this.isLine(endCon)) {
|
|
1083
|
-
endCon = endCon.childNodes[endOff] || endCon.lastChild;
|
|
1084
|
-
endOff = endCon.textContent.length;
|
|
1085
|
-
}
|
|
1086
|
-
|
|
1087
|
-
if (isRemoveNode) {
|
|
1088
|
-
styleNode = dom.utils.createElement('DIV');
|
|
1089
|
-
}
|
|
1090
|
-
|
|
1091
|
-
const wRegExp = RegExp;
|
|
1092
|
-
const newNodeName = styleNode.nodeName;
|
|
1093
|
-
|
|
1094
|
-
/* checked same style property */
|
|
1095
|
-
if (!isRemoveFormat && startCon === endCon && !nodesToRemove && styleNode) {
|
|
1096
|
-
let sNode = startCon;
|
|
1097
|
-
let checkCnt = 0;
|
|
1098
|
-
const checkAttrs = [];
|
|
1099
|
-
|
|
1100
|
-
const checkStyles = /** @type {HTMLElement} */ (styleNode).style;
|
|
1101
|
-
for (let i = 0, len = checkStyles.length; i < len; i++) {
|
|
1102
|
-
checkAttrs.push(checkStyles[i]);
|
|
1103
|
-
}
|
|
1104
|
-
|
|
1105
|
-
const checkClassName = /** @type {HTMLElement} */ (styleNode).className;
|
|
1106
|
-
const ckeckClasses = /** @type {HTMLElement} */ (styleNode).classList;
|
|
1107
|
-
for (let i = 0, len = ckeckClasses.length; i < len; i++) {
|
|
1108
|
-
checkAttrs.push('.' + ckeckClasses[i]);
|
|
1109
|
-
}
|
|
1110
|
-
|
|
1111
|
-
if (checkAttrs.length > 0) {
|
|
1112
|
-
while (!this.isLine(sNode) && !dom.check.isWysiwygFrame(sNode)) {
|
|
1113
|
-
for (let i = 0; i < checkAttrs.length; i++) {
|
|
1114
|
-
if (sNode.nodeType === 1) {
|
|
1115
|
-
const s = checkAttrs[i];
|
|
1116
|
-
const classReg = /^\./.test(s) ? new wRegExp('\\s*' + s.replace(/^\./, '') + '(\\s+|$)', 'ig') : false;
|
|
1117
|
-
const sNodeStyle = /** @type {HTMLElement} */ (sNode).style;
|
|
1118
|
-
const sNodeClassName = /** @type {HTMLElement} */ (sNode).className;
|
|
1119
|
-
|
|
1120
|
-
const styleCheck = isRemoveNode ? !!sNodeStyle[s] : !!sNodeStyle[s] && !!checkStyles[s] && sNodeStyle[s] === checkStyles[s];
|
|
1121
|
-
const classCheck = classReg === false ? false : isRemoveNode ? !!sNodeClassName.match(classReg) : !!sNodeClassName.match(classReg) && !!checkClassName.match(classReg);
|
|
1122
|
-
if (styleCheck || classCheck) {
|
|
1123
|
-
checkCnt++;
|
|
1124
|
-
}
|
|
1125
|
-
}
|
|
1126
|
-
}
|
|
1127
|
-
sNode = sNode.parentNode;
|
|
1128
|
-
}
|
|
1129
|
-
|
|
1130
|
-
if (checkCnt >= checkAttrs.length) return;
|
|
1131
|
-
}
|
|
1132
|
-
}
|
|
1133
|
-
|
|
1134
|
-
let newNode;
|
|
1135
|
-
/** @type {NodeStyleContainerType} */
|
|
1136
|
-
let start = {};
|
|
1137
|
-
/** @type {NodeStyleContainerType} */
|
|
1138
|
-
let end = {};
|
|
1139
|
-
|
|
1140
|
-
/** @type {string|RegExp} */
|
|
1141
|
-
let styleRegExp;
|
|
1142
|
-
/** @type {string|RegExp} */
|
|
1143
|
-
let classRegExp;
|
|
1144
|
-
/** @type {string|RegExp} */
|
|
1145
|
-
let removeNodeRegExp;
|
|
1146
|
-
|
|
1147
|
-
if (stylesToModify) {
|
|
1148
|
-
for (let i = 0, len = stylesToModify.length, s; i < len; i++) {
|
|
1149
|
-
s = stylesToModify[i];
|
|
1150
|
-
if (/^\./.test(s)) {
|
|
1151
|
-
classRegExp += (classRegExp ? '|' : '\\s*(?:') + s.replace(/^\./, '');
|
|
1152
|
-
} else {
|
|
1153
|
-
styleRegExp += (styleRegExp ? '|' : '(?:;|^|\\s)(?:') + s;
|
|
1154
|
-
}
|
|
1155
|
-
}
|
|
1156
|
-
|
|
1157
|
-
if (styleRegExp) {
|
|
1158
|
-
styleRegExp += ')\\s*:[^;]*\\s*(?:;|$)';
|
|
1159
|
-
styleRegExp = new wRegExp(styleRegExp, 'ig');
|
|
1160
|
-
}
|
|
1161
|
-
|
|
1162
|
-
if (classRegExp) {
|
|
1163
|
-
classRegExp += ')(?=\\s+|$)';
|
|
1164
|
-
classRegExp = new wRegExp(classRegExp, 'ig');
|
|
1165
|
-
}
|
|
1166
|
-
}
|
|
1167
|
-
|
|
1168
|
-
if (nodesToRemove) {
|
|
1169
|
-
removeNodeRegExp = '^(?:' + nodesToRemove[0];
|
|
1170
|
-
for (let i = 1; i < nodesToRemove.length; i++) {
|
|
1171
|
-
removeNodeRegExp += '|' + nodesToRemove[i];
|
|
1172
|
-
}
|
|
1173
|
-
removeNodeRegExp += ')$';
|
|
1174
|
-
removeNodeRegExp = new wRegExp(removeNodeRegExp, 'i');
|
|
1175
|
-
}
|
|
1176
|
-
|
|
1177
|
-
/** validation check function*/
|
|
1178
|
-
const _removeCheck = {
|
|
1179
|
-
v: false
|
|
1180
|
-
};
|
|
1181
|
-
const validation = function (checkNode) {
|
|
1182
|
-
const vNode = checkNode.cloneNode(false);
|
|
1183
|
-
|
|
1184
|
-
// all path
|
|
1185
|
-
if (vNode.nodeType === 3 || dom.check.isBreak(vNode)) return vNode;
|
|
1186
|
-
// all remove
|
|
1187
|
-
if (isRemoveFormat) return null;
|
|
1188
|
-
|
|
1189
|
-
// remove node check
|
|
1190
|
-
const tagRemove = (!removeNodeRegExp && isRemoveNode) || /** @type {RegExp} */ (removeNodeRegExp)?.test(vNode.nodeName);
|
|
1191
|
-
|
|
1192
|
-
// tag remove
|
|
1193
|
-
if (tagRemove && !strictRemove) {
|
|
1194
|
-
_removeCheck.v = true;
|
|
1195
|
-
return null;
|
|
1196
|
-
}
|
|
1197
|
-
|
|
1198
|
-
// style regexp
|
|
1199
|
-
const originStyle = vNode.style.cssText;
|
|
1200
|
-
let style = '';
|
|
1201
|
-
if (styleRegExp && originStyle.length > 0) {
|
|
1202
|
-
style = originStyle.replace(styleRegExp, '').trim();
|
|
1203
|
-
if (style !== originStyle) _removeCheck.v = true;
|
|
1204
|
-
}
|
|
1205
|
-
|
|
1206
|
-
// class check
|
|
1207
|
-
const originClasses = vNode.className;
|
|
1208
|
-
let classes = '';
|
|
1209
|
-
if (classRegExp && originClasses.length > 0) {
|
|
1210
|
-
classes = originClasses.replace(classRegExp, '').trim();
|
|
1211
|
-
if (classes !== originClasses) _removeCheck.v = true;
|
|
1212
|
-
}
|
|
1213
|
-
|
|
1214
|
-
// remove only
|
|
1215
|
-
if (isRemoveNode) {
|
|
1216
|
-
if ((classRegExp || !originClasses) && (styleRegExp || !originStyle) && !style && !classes && tagRemove) {
|
|
1217
|
-
_removeCheck.v = true;
|
|
1218
|
-
return null;
|
|
1219
|
-
}
|
|
1220
|
-
}
|
|
1221
|
-
|
|
1222
|
-
// change
|
|
1223
|
-
if (style || classes || vNode.nodeName !== newNodeName || Boolean(styleRegExp) !== Boolean(originStyle) || Boolean(classRegExp) !== Boolean(originClasses)) {
|
|
1224
|
-
if (styleRegExp && originStyle.length > 0) vNode.style.cssText = style;
|
|
1225
|
-
if (!vNode.style.cssText) {
|
|
1226
|
-
vNode.removeAttribute('style');
|
|
1227
|
-
}
|
|
1228
|
-
|
|
1229
|
-
if (classRegExp && originClasses.length > 0) vNode.className = classes.trim();
|
|
1230
|
-
if (!vNode.className.trim()) {
|
|
1231
|
-
vNode.removeAttribute('class');
|
|
1232
|
-
}
|
|
1233
|
-
|
|
1234
|
-
if (!vNode.style.cssText && !vNode.className && (vNode.nodeName === newNodeName || tagRemove)) {
|
|
1235
|
-
_removeCheck.v = true;
|
|
1236
|
-
return null;
|
|
1237
|
-
}
|
|
1238
|
-
|
|
1239
|
-
return vNode;
|
|
1240
|
-
}
|
|
1241
|
-
|
|
1242
|
-
_removeCheck.v = true;
|
|
1243
|
-
return null;
|
|
1244
|
-
};
|
|
1245
|
-
|
|
1246
|
-
// get line nodes
|
|
1247
|
-
const lineNodes = this.getLines(null);
|
|
1248
|
-
range = this.selection.getRange();
|
|
1249
|
-
startCon = range.startContainer;
|
|
1250
|
-
startOff = range.startOffset;
|
|
1251
|
-
endCon = range.endContainer;
|
|
1252
|
-
endOff = range.endOffset;
|
|
1253
|
-
|
|
1254
|
-
if (!this.getLine(startCon, null)) {
|
|
1255
|
-
startCon = dom.query.getEdgeChild(
|
|
1256
|
-
lineNodes[0],
|
|
1257
|
-
function (current) {
|
|
1258
|
-
return current.nodeType === 3;
|
|
1259
|
-
},
|
|
1260
|
-
false
|
|
1261
|
-
);
|
|
1262
|
-
startOff = 0;
|
|
1263
|
-
}
|
|
1264
|
-
|
|
1265
|
-
if (!this.getLine(endCon, null)) {
|
|
1266
|
-
endCon = dom.query.getEdgeChild(
|
|
1267
|
-
lineNodes[lineNodes.length - 1],
|
|
1268
|
-
function (current) {
|
|
1269
|
-
return current.nodeType === 3;
|
|
1270
|
-
},
|
|
1271
|
-
false
|
|
1272
|
-
);
|
|
1273
|
-
endOff = endCon.textContent.length;
|
|
1274
|
-
}
|
|
1275
|
-
|
|
1276
|
-
const oneLine = this.getLine(startCon, null) === this.getLine(endCon, null);
|
|
1277
|
-
const endLength = lineNodes.length - (oneLine ? 0 : 1);
|
|
1278
|
-
|
|
1279
|
-
// node Changes
|
|
1280
|
-
newNode = styleNode.cloneNode(false);
|
|
1281
|
-
|
|
1282
|
-
const isRemoveAnchor =
|
|
1283
|
-
isRemoveFormat ||
|
|
1284
|
-
(isRemoveNode &&
|
|
1285
|
-
(function (inst, arr) {
|
|
1286
|
-
for (let n = 0, len = arr.length; n < len; n++) {
|
|
1287
|
-
if (inst._isNonSplitNode(arr[n])) return true;
|
|
1288
|
-
}
|
|
1289
|
-
return false;
|
|
1290
|
-
})(this, nodesToRemove));
|
|
1291
|
-
|
|
1292
|
-
const isSizeNode = isRemoveNode || this._sn_isSizeNode(newNode);
|
|
1293
|
-
const _getMaintainedNode = this._sn_getMaintainedNode.bind(this, isRemoveAnchor, isSizeNode);
|
|
1294
|
-
const _isMaintainedNode = this._sn_isMaintainedNode.bind(this, isRemoveAnchor, isSizeNode);
|
|
1295
|
-
|
|
1296
|
-
// one line
|
|
1297
|
-
if (oneLine) {
|
|
1298
|
-
if (this._sn_resetCommonListCell(lineNodes[0], stylesToModify)) range = this.selection.setRange(startCon, startOff, endCon, endOff);
|
|
1299
|
-
|
|
1300
|
-
const newRange = this._setNode_oneLine(lineNodes[0], newNode, validation, startCon, startOff, endCon, endOff, isRemoveFormat, isRemoveNode, range.collapsed, _removeCheck, _getMaintainedNode, _isMaintainedNode);
|
|
1301
|
-
start.container = newRange.startContainer;
|
|
1302
|
-
start.offset = newRange.startOffset;
|
|
1303
|
-
end.container = newRange.endContainer;
|
|
1304
|
-
end.offset = newRange.endOffset;
|
|
1305
|
-
|
|
1306
|
-
if (start.container === end.container && dom.check.isZeroWidth(start.container)) {
|
|
1307
|
-
start.offset = end.offset = 1;
|
|
1308
|
-
}
|
|
1309
|
-
this._sn_setCommonListStyle(newRange.ancestor, null);
|
|
1310
|
-
} else {
|
|
1311
|
-
// multi line
|
|
1312
|
-
let appliedCommonList = false;
|
|
1313
|
-
if (endLength > 0 && this._sn_resetCommonListCell(lineNodes[endLength], stylesToModify)) appliedCommonList = true;
|
|
1314
|
-
if (this._sn_resetCommonListCell(lineNodes[0], stylesToModify)) appliedCommonList = true;
|
|
1315
|
-
if (appliedCommonList) this.selection.setRange(startCon, startOff, endCon, endOff);
|
|
1316
|
-
|
|
1317
|
-
// end
|
|
1318
|
-
if (endLength > 0) {
|
|
1319
|
-
newNode = styleNode.cloneNode(false);
|
|
1320
|
-
end = this._setNode_endLine(lineNodes[endLength], newNode, validation, endCon, endOff, isRemoveFormat, isRemoveNode, _removeCheck, _getMaintainedNode, _isMaintainedNode);
|
|
1321
|
-
}
|
|
1322
|
-
|
|
1323
|
-
// mid
|
|
1324
|
-
for (let i = endLength - 1, newRange; i > 0; i--) {
|
|
1325
|
-
this._sn_resetCommonListCell(lineNodes[i], stylesToModify);
|
|
1326
|
-
newNode = styleNode.cloneNode(false);
|
|
1327
|
-
newRange = this._setNode_middleLine(lineNodes[i], newNode, validation, isRemoveFormat, isRemoveNode, _removeCheck, end.container);
|
|
1328
|
-
if (newRange.endContainer && newRange.ancestor.contains(newRange.endContainer)) {
|
|
1329
|
-
end.ancestor = null;
|
|
1330
|
-
end.container = newRange.endContainer;
|
|
1331
|
-
}
|
|
1332
|
-
this._sn_setCommonListStyle(newRange.ancestor, null);
|
|
1333
|
-
}
|
|
1334
|
-
|
|
1335
|
-
// start
|
|
1336
|
-
newNode = styleNode.cloneNode(false);
|
|
1337
|
-
start = this._setNode_startLine(lineNodes[0], newNode, validation, startCon, startOff, isRemoveFormat, isRemoveNode, _removeCheck, _getMaintainedNode, _isMaintainedNode, end.container);
|
|
1338
|
-
|
|
1339
|
-
if (start.endContainer) {
|
|
1340
|
-
end.ancestor = null;
|
|
1341
|
-
end.container = start.endContainer;
|
|
1342
|
-
}
|
|
1343
|
-
|
|
1344
|
-
if (endLength <= 0) {
|
|
1345
|
-
end = start;
|
|
1346
|
-
} else if (!end.container) {
|
|
1347
|
-
end.ancestor = null;
|
|
1348
|
-
end.container = start.container;
|
|
1349
|
-
end.offset = start.container.textContent.length;
|
|
1350
|
-
}
|
|
1351
|
-
|
|
1352
|
-
this._sn_setCommonListStyle(start.ancestor, null);
|
|
1353
|
-
this._sn_setCommonListStyle(end.ancestor || this.getLine(end.container), null);
|
|
1354
|
-
}
|
|
1355
|
-
|
|
1356
|
-
// set range
|
|
1357
|
-
this.ui._offCurrentController();
|
|
1358
|
-
this.selection.setRange(start.container, start.offset, end.container, end.offset);
|
|
1359
|
-
this.history.push(false);
|
|
1360
|
-
|
|
1361
|
-
return /** @type {HTMLElement} */ (newNode);
|
|
1362
|
-
},
|
|
1363
|
-
|
|
1364
|
-
/**
|
|
1365
|
-
* @this {FormatThis}
|
|
1366
|
-
* @description Remove format of the currently selected text.
|
|
1367
|
-
*/
|
|
1368
|
-
removeInlineElement() {
|
|
1369
|
-
this.applyInlineElement(null, { stylesToModify: null, nodesToRemove: null, strictRemove: null });
|
|
1370
|
-
},
|
|
1371
|
-
|
|
1372
728
|
/**
|
|
1373
729
|
* @this {FormatThis}
|
|
1374
730
|
* @description Check if the container and offset values are the edges of the "line"
|
|
@@ -1401,7 +757,7 @@ Format.prototype = {
|
|
|
1401
757
|
* @returns {element is HTMLElement}
|
|
1402
758
|
*/
|
|
1403
759
|
isTextStyleNode(element) {
|
|
1404
|
-
return typeof element === 'string' ? this._textStyleTagsCheck.test(element) : element
|
|
760
|
+
return typeof element === 'string' ? this._textStyleTagsCheck.test(element) : element?.nodeType === 1 && this._textStyleTagsCheck.test(element.nodeName);
|
|
1405
761
|
},
|
|
1406
762
|
|
|
1407
763
|
/**
|
|
@@ -1413,20 +769,19 @@ Format.prototype = {
|
|
|
1413
769
|
* @returns {element is HTMLElement}
|
|
1414
770
|
*/
|
|
1415
771
|
isLine(element) {
|
|
1416
|
-
if (this.isBlock(element)) return false;
|
|
1417
772
|
return typeof element === 'string'
|
|
1418
773
|
? this._formatLineCheck.test(element)
|
|
1419
|
-
: element
|
|
774
|
+
: element?.nodeType === 1 && (this._formatLineCheck.test(element.nodeName) || dom.utils.hasClass(element, '__se__format__line_.+|__se__format__br_line_.+')) && !this._nonFormat(element);
|
|
1420
775
|
},
|
|
1421
776
|
|
|
1422
777
|
/**
|
|
1423
778
|
* @this {FormatThis}
|
|
1424
|
-
* @description It is judged whether it is the only "line" element
|
|
779
|
+
* @description It is judged whether it is the only "line" element.
|
|
1425
780
|
* @param {Node|string} element The node to check
|
|
1426
781
|
* @returns {element is HTMLElement}
|
|
1427
782
|
*/
|
|
1428
|
-
|
|
1429
|
-
return this.isLine(element) && (this._brLineBreak || !this.isBrLine(element));
|
|
783
|
+
isNormalLine(element) {
|
|
784
|
+
return this.isLine(element) && (this._brLineBreak || !this.isBrLine(element)) && !this.isBlock(element);
|
|
1430
785
|
},
|
|
1431
786
|
|
|
1432
787
|
/**
|
|
@@ -1444,7 +799,7 @@ Format.prototype = {
|
|
|
1444
799
|
(this._brLineBreak && this.isLine(element)) ||
|
|
1445
800
|
(typeof element === 'string'
|
|
1446
801
|
? this._formatBrLineCheck.test(element)
|
|
1447
|
-
: element
|
|
802
|
+
: element?.nodeType === 1 && (this._formatBrLineCheck.test(element.nodeName) || dom.utils.hasClass(element, '__se__format__br_line_.+')) && !this._nonFormat(element))
|
|
1448
803
|
);
|
|
1449
804
|
},
|
|
1450
805
|
|
|
@@ -1459,7 +814,7 @@ Format.prototype = {
|
|
|
1459
814
|
isBlock(element) {
|
|
1460
815
|
return typeof element === 'string'
|
|
1461
816
|
? this._formatBlockCheck.test(element)
|
|
1462
|
-
: element
|
|
817
|
+
: element?.nodeType === 1 && (this._formatBlockCheck.test(element.nodeName) || dom.utils.hasClass(element, '__se__format__block_.+')) && !this._nonFormat(element);
|
|
1463
818
|
},
|
|
1464
819
|
|
|
1465
820
|
/**
|
|
@@ -1476,7 +831,7 @@ Format.prototype = {
|
|
|
1476
831
|
isClosureBlock(element) {
|
|
1477
832
|
return typeof element === 'string'
|
|
1478
833
|
? this._formatClosureBlockCheck.test(element)
|
|
1479
|
-
: element
|
|
834
|
+
: element?.nodeType === 1 && (this._formatClosureBlockCheck.test(element.nodeName) || dom.utils.hasClass(element, '__se__format__block_closure_.+')) && !this._nonFormat(element);
|
|
1480
835
|
},
|
|
1481
836
|
|
|
1482
837
|
/**
|
|
@@ -1493,7 +848,7 @@ Format.prototype = {
|
|
|
1493
848
|
isClosureBrLine(element) {
|
|
1494
849
|
return typeof element === 'string'
|
|
1495
850
|
? this._formatClosureBrLineCheck.test(element)
|
|
1496
|
-
: element
|
|
851
|
+
: element?.nodeType === 1 && (this._formatClosureBrLineCheck.test(element.nodeName) || dom.utils.hasClass(element, '__se__format__br_line__closure_.+')) && !this._nonFormat(element);
|
|
1497
852
|
},
|
|
1498
853
|
|
|
1499
854
|
/**
|
|
@@ -1507,10 +862,10 @@ Format.prototype = {
|
|
|
1507
862
|
let range = this.selection.getRange();
|
|
1508
863
|
|
|
1509
864
|
if (dom.check.isWysiwygFrame(range.startContainer)) {
|
|
1510
|
-
const children = this.
|
|
865
|
+
const children = this.frameContext.get('wysiwyg').children;
|
|
1511
866
|
if (children.length === 0) return [];
|
|
1512
867
|
|
|
1513
|
-
this.selection.setRange(children[0], 0, children
|
|
868
|
+
this.selection.setRange(children[0], 0, children.at(-1), children.at(-1).textContent.trim().length);
|
|
1514
869
|
range = this.selection.getRange();
|
|
1515
870
|
}
|
|
1516
871
|
|
|
@@ -1519,11 +874,10 @@ Format.prototype = {
|
|
|
1519
874
|
const commonCon = range.commonAncestorContainer;
|
|
1520
875
|
|
|
1521
876
|
// get line nodes
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
});
|
|
877
|
+
validation ||= this.isLine.bind(this);
|
|
878
|
+
const lineNodes = dom.query.getListChildren(commonCon, (current) => validation(current), null);
|
|
1525
879
|
|
|
1526
|
-
if (!dom.check.isWysiwygFrame(commonCon) && !this.isBlock(commonCon)) lineNodes.unshift(this.getLine(commonCon, null));
|
|
880
|
+
if (commonCon.nodeType === 3 || (!dom.check.isWysiwygFrame(commonCon) && !this.isBlock(commonCon))) lineNodes.unshift(this.getLine(commonCon, null));
|
|
1527
881
|
if (startCon === endCon || lineNodes.length === 1) return lineNodes;
|
|
1528
882
|
|
|
1529
883
|
const startLine = this.getLine(startCon, null);
|
|
@@ -1575,8 +929,8 @@ Format.prototype = {
|
|
|
1575
929
|
? this.getLines(null)
|
|
1576
930
|
: this.getLines((current) => {
|
|
1577
931
|
const component = dom.query.getParentElement(current, this.component.is.bind(this.component));
|
|
1578
|
-
return (this.isLine(current) && (!component || component === myComponent)) || (
|
|
1579
|
-
|
|
932
|
+
return (this.isLine(current) && (!component || component === myComponent)) || (dom.check.isComponentContainer(current) && !this.getLine(current));
|
|
933
|
+
});
|
|
1580
934
|
|
|
1581
935
|
if (removeDuplicate) {
|
|
1582
936
|
for (let i = 0, len = selectedLines.length; i < len; i++) {
|
|
@@ -1616,20 +970,6 @@ Format.prototype = {
|
|
|
1616
970
|
return dom.check.isExcludeFormat(element) || this.component.is(element) || dom.check.isWysiwygFrame(element);
|
|
1617
971
|
},
|
|
1618
972
|
|
|
1619
|
-
/**
|
|
1620
|
-
* @private
|
|
1621
|
-
* @this {FormatThis}
|
|
1622
|
-
* @description Nodes that must remain undetached when changing text nodes (A, Label, Code, Span:font-size)
|
|
1623
|
-
* @param {Node|string} element Element to check
|
|
1624
|
-
* @returns {boolean}
|
|
1625
|
-
*/
|
|
1626
|
-
_isNonSplitNode(element) {
|
|
1627
|
-
if (!element) return false;
|
|
1628
|
-
const checkRegExp = /^(a|label|code|summary)$/i;
|
|
1629
|
-
if (typeof element === 'string') return checkRegExp.test(element);
|
|
1630
|
-
return element.nodeType === 1 && checkRegExp.test(element.nodeName);
|
|
1631
|
-
},
|
|
1632
|
-
|
|
1633
973
|
/**
|
|
1634
974
|
* @private
|
|
1635
975
|
* @this {FormatThis}
|
|
@@ -1644,17 +984,6 @@ Format.prototype = {
|
|
|
1644
984
|
return element.nodeType === 1 && (this.component.is(element) || checkRegExp.test(element.nodeName));
|
|
1645
985
|
},
|
|
1646
986
|
|
|
1647
|
-
/**
|
|
1648
|
-
* @private
|
|
1649
|
-
* @this {FormatThis}
|
|
1650
|
-
* @description Nodes that need to be added without modification when changing text nodes
|
|
1651
|
-
* @param {Node} element Element to check
|
|
1652
|
-
* @returns {boolean}
|
|
1653
|
-
*/
|
|
1654
|
-
_isIgnoreNodeChange(element) {
|
|
1655
|
-
return element && element.nodeType === 1 && (dom.check.isNonEditable(element) || !this.isTextStyleNode(element) || this.component.is(element));
|
|
1656
|
-
},
|
|
1657
|
-
|
|
1658
987
|
/**
|
|
1659
988
|
* @private
|
|
1660
989
|
* @this {FormatThis}
|
|
@@ -1675,12 +1004,12 @@ Format.prototype = {
|
|
|
1675
1004
|
const endOffset = range.endOffset;
|
|
1676
1005
|
|
|
1677
1006
|
let first = /** @type {Node} */ (selectedFormsts[0]);
|
|
1678
|
-
let last = /** @type {Node} */ (selectedFormsts
|
|
1007
|
+
let last = /** @type {Node} */ (selectedFormsts.at(-1));
|
|
1679
1008
|
const firstPath = dom.query.getNodePath(range.startContainer, first, null);
|
|
1680
1009
|
const lastPath = dom.query.getNodePath(range.endContainer, last, null);
|
|
1681
1010
|
|
|
1682
1011
|
// remove selected list
|
|
1683
|
-
const rlist = this.
|
|
1012
|
+
const rlist = this.listFormat.remove(selectedFormsts, false);
|
|
1684
1013
|
if (rlist.sc) first = rlist.sc;
|
|
1685
1014
|
if (rlist.ec) last = rlist.ec;
|
|
1686
1015
|
|
|
@@ -1701,1700 +1030,25 @@ Format.prototype = {
|
|
|
1701
1030
|
/**
|
|
1702
1031
|
* @private
|
|
1703
1032
|
* @this {FormatThis}
|
|
1704
|
-
* @description
|
|
1705
|
-
*
|
|
1706
|
-
* @param {Element} originList The original list element where the nested list is inserted.
|
|
1707
|
-
* @param {Element} innerList The nested list element.
|
|
1708
|
-
* @param {Element} prev The previous sibling element.
|
|
1709
|
-
* @param {Element} next The next sibling element.
|
|
1710
|
-
* @param {{s: Array<number> | null, e: Array<number> | null, sl: Node | null, el: Node | null}} nodePath Object storing the start and end node paths.
|
|
1711
|
-
* - s : Start node path.
|
|
1712
|
-
* - e : End node path.
|
|
1713
|
-
* - sl : Start node's parent element.
|
|
1714
|
-
* - el : End node's parent element.
|
|
1715
|
-
* @returns {Node} The attached inner list.
|
|
1033
|
+
* @description Reset the line break format.
|
|
1034
|
+
* @param {"line"|"br"} breakFormat options.get('defaultLineBreakFormat')
|
|
1716
1035
|
*/
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
if (innerList.tagName === prev?.tagName) {
|
|
1721
|
-
const children = innerList.children;
|
|
1722
|
-
while (children[0]) {
|
|
1723
|
-
prev.appendChild(children[0]);
|
|
1724
|
-
}
|
|
1036
|
+
__resetBrLineBreak(breakFormat) {
|
|
1037
|
+
this._brLineBreak = breakFormat === 'br';
|
|
1038
|
+
},
|
|
1725
1039
|
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
}
|
|
1040
|
+
constructor: Format
|
|
1041
|
+
};
|
|
1729
1042
|
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
}
|
|
1740
|
-
|
|
1741
|
-
if (!insertPrev) {
|
|
1742
|
-
if (dom.check.isListCell(prev)) {
|
|
1743
|
-
originList = prev;
|
|
1744
|
-
next = null;
|
|
1745
|
-
}
|
|
1746
|
-
|
|
1747
|
-
originList.insertBefore(innerList, next);
|
|
1748
|
-
|
|
1749
|
-
if (!nodePath.s) {
|
|
1750
|
-
nodePath.s = dom.query.getNodePath(innerList.firstElementChild.firstChild, originList, null);
|
|
1751
|
-
nodePath.sl = originList;
|
|
1752
|
-
}
|
|
1753
|
-
|
|
1754
|
-
const slPath = originList.contains(nodePath.sl) ? dom.query.getNodePath(nodePath.sl, originList) : null;
|
|
1755
|
-
nodePath.e = dom.query.getNodePath(innerList.lastElementChild.firstChild, originList, null);
|
|
1756
|
-
nodePath.el = originList;
|
|
1757
|
-
|
|
1758
|
-
this.nodeTransform.mergeSameTags(originList, [nodePath.s, nodePath.e, slPath], false);
|
|
1759
|
-
this.nodeTransform.mergeNestedTags(originList);
|
|
1760
|
-
if (slPath) nodePath.sl = dom.query.getNodeFromPath(slPath, originList);
|
|
1761
|
-
}
|
|
1762
|
-
|
|
1763
|
-
return innerList;
|
|
1764
|
-
},
|
|
1765
|
-
|
|
1766
|
-
/**
|
|
1767
|
-
* @private
|
|
1768
|
-
* @this {FormatThis}
|
|
1769
|
-
* @description Detaches a nested list structure by extracting list items from their parent list.
|
|
1770
|
-
* - Ensures proper restructuring of the list elements.
|
|
1771
|
-
* @param {Array<HTMLElement>} cells The list items to be detached.
|
|
1772
|
-
* @returns {{cc: Node, sc: Node, ec: Node}} An object containing reference nodes for repositioning.
|
|
1773
|
-
* - cc : The parent node of the first list item.
|
|
1774
|
-
* - sc : The first list item.
|
|
1775
|
-
* - ec : The last list item.
|
|
1776
|
-
*/
|
|
1777
|
-
_detachNested(cells) {
|
|
1778
|
-
const first = cells[0];
|
|
1779
|
-
const last = cells[cells.length - 1];
|
|
1780
|
-
const next = last.nextElementSibling;
|
|
1781
|
-
const originList = first.parentElement;
|
|
1782
|
-
const sibling = originList.parentElement.nextElementSibling;
|
|
1783
|
-
const parentNode = originList.parentElement.parentElement;
|
|
1784
|
-
|
|
1785
|
-
for (let c = 0, cLen = cells.length; c < cLen; c++) {
|
|
1786
|
-
parentNode.insertBefore(cells[c], sibling);
|
|
1787
|
-
}
|
|
1788
|
-
|
|
1789
|
-
if (next && originList.children.length > 0) {
|
|
1790
|
-
const newList = originList.cloneNode(false);
|
|
1791
|
-
const children = originList.childNodes;
|
|
1792
|
-
const index = dom.query.getPositionIndex(next);
|
|
1793
|
-
while (children[index]) {
|
|
1794
|
-
newList.appendChild(children[index]);
|
|
1795
|
-
}
|
|
1796
|
-
last.appendChild(newList);
|
|
1797
|
-
}
|
|
1798
|
-
|
|
1799
|
-
if (originList.children.length === 0) dom.utils.removeItem(originList);
|
|
1800
|
-
this.nodeTransform.mergeSameTags(parentNode);
|
|
1801
|
-
|
|
1802
|
-
const edge = dom.query.getEdgeChildNodes(first, last);
|
|
1803
|
-
|
|
1804
|
-
return {
|
|
1805
|
-
cc: first.parentNode,
|
|
1806
|
-
sc: edge.sc,
|
|
1807
|
-
ec: edge.ec
|
|
1808
|
-
};
|
|
1809
|
-
},
|
|
1810
|
-
|
|
1811
|
-
/**
|
|
1812
|
-
* @private
|
|
1813
|
-
* @this {FormatThis}
|
|
1814
|
-
* @description Nest list cells or cancel nested cells.
|
|
1815
|
-
* @param selectedCells List cells.
|
|
1816
|
-
* @param nested Nested or cancel nested.
|
|
1817
|
-
*/
|
|
1818
|
-
_applyNestedList(selectedCells, nested) {
|
|
1819
|
-
selectedCells = !selectedCells
|
|
1820
|
-
? this.getLines().filter(function (el) {
|
|
1821
|
-
return dom.check.isListCell(el);
|
|
1822
|
-
})
|
|
1823
|
-
: selectedCells;
|
|
1824
|
-
const cellsLen = selectedCells.length;
|
|
1825
|
-
if (cellsLen === 0 || (!nested && !dom.check.isListCell(selectedCells[0].previousElementSibling) && !dom.check.isListCell(selectedCells[cellsLen - 1].nextElementSibling))) {
|
|
1826
|
-
return {
|
|
1827
|
-
sc: selectedCells[0],
|
|
1828
|
-
so: 0,
|
|
1829
|
-
ec: selectedCells[cellsLen - 1],
|
|
1830
|
-
eo: 1
|
|
1831
|
-
};
|
|
1832
|
-
}
|
|
1833
|
-
|
|
1834
|
-
let originList = selectedCells[0].parentNode;
|
|
1835
|
-
let lastCell = selectedCells[cellsLen - 1];
|
|
1836
|
-
let range = null;
|
|
1837
|
-
|
|
1838
|
-
if (nested) {
|
|
1839
|
-
if (originList !== lastCell.parentNode && dom.check.isList(lastCell.parentNode.parentNode) && lastCell.nextElementSibling) {
|
|
1840
|
-
lastCell = lastCell.nextElementSibling;
|
|
1841
|
-
while (lastCell) {
|
|
1842
|
-
selectedCells.push(lastCell);
|
|
1843
|
-
lastCell = lastCell.nextElementSibling;
|
|
1844
|
-
}
|
|
1845
|
-
}
|
|
1846
|
-
range = this.applyList(originList.nodeName + ':' + originList.style.listStyleType, selectedCells, true);
|
|
1847
|
-
} else {
|
|
1848
|
-
let innerList = dom.utils.createElement(originList.nodeName);
|
|
1849
|
-
let prev = selectedCells[0].previousElementSibling;
|
|
1850
|
-
let next = lastCell.nextElementSibling;
|
|
1851
|
-
const nodePath = {
|
|
1852
|
-
s: null,
|
|
1853
|
-
e: null,
|
|
1854
|
-
sl: originList,
|
|
1855
|
-
el: originList
|
|
1856
|
-
};
|
|
1857
|
-
|
|
1858
|
-
for (let i = 0, len = cellsLen, c; i < len; i++) {
|
|
1859
|
-
c = selectedCells[i];
|
|
1860
|
-
if (c.parentNode !== originList) {
|
|
1861
|
-
this._attachNested(originList, innerList, prev, next, nodePath);
|
|
1862
|
-
originList = c.parentNode;
|
|
1863
|
-
innerList = dom.utils.createElement(originList.nodeName);
|
|
1864
|
-
}
|
|
1865
|
-
|
|
1866
|
-
prev = c.previousElementSibling;
|
|
1867
|
-
next = c.nextElementSibling;
|
|
1868
|
-
innerList.appendChild(c);
|
|
1869
|
-
}
|
|
1870
|
-
|
|
1871
|
-
this._attachNested(originList, innerList, prev, next, nodePath);
|
|
1872
|
-
|
|
1873
|
-
const sc = dom.query.getNodeFromPath(nodePath.s, nodePath.sl);
|
|
1874
|
-
const ec = dom.query.getNodeFromPath(nodePath.e, nodePath.el);
|
|
1875
|
-
range = {
|
|
1876
|
-
sc: sc,
|
|
1877
|
-
so: 0,
|
|
1878
|
-
ec: ec,
|
|
1879
|
-
eo: ec.textContent.length
|
|
1880
|
-
};
|
|
1881
|
-
}
|
|
1882
|
-
|
|
1883
|
-
return range;
|
|
1884
|
-
},
|
|
1885
|
-
|
|
1886
|
-
/**
|
|
1887
|
-
* @private
|
|
1888
|
-
* @this {FormatThis}
|
|
1889
|
-
* @description Detach Nested all nested lists under the "baseNode".
|
|
1890
|
-
* - Returns a list with nested removed.
|
|
1891
|
-
* @param {HTMLElement} baseNode Element on which to base.
|
|
1892
|
-
* @param {boolean} all If true, it also detach all nested lists of a returned list.
|
|
1893
|
-
* @returns {Node} Result element
|
|
1894
|
-
*/
|
|
1895
|
-
_removeNestedList(baseNode, all) {
|
|
1896
|
-
const rNode = DeleteNestedList(baseNode);
|
|
1897
|
-
let rangeElement, cNodes;
|
|
1898
|
-
|
|
1899
|
-
if (rNode) {
|
|
1900
|
-
rangeElement = rNode.cloneNode(false);
|
|
1901
|
-
cNodes = rNode.childNodes;
|
|
1902
|
-
const index = dom.query.getPositionIndex(baseNode);
|
|
1903
|
-
while (cNodes[index]) {
|
|
1904
|
-
rangeElement.appendChild(cNodes[index]);
|
|
1905
|
-
}
|
|
1906
|
-
} else {
|
|
1907
|
-
rangeElement = baseNode;
|
|
1908
|
-
}
|
|
1909
|
-
|
|
1910
|
-
let rChildren;
|
|
1911
|
-
if (!all) {
|
|
1912
|
-
const depth = dom.query.getNodeDepth(baseNode) + 2;
|
|
1913
|
-
rChildren = dom.query.getListChildren(baseNode, (current) => {
|
|
1914
|
-
return dom.check.isListCell(current) && !current.previousElementSibling && dom.query.getNodeDepth(current) === depth;
|
|
1915
|
-
});
|
|
1916
|
-
} else {
|
|
1917
|
-
rChildren = dom.query.getListChildren(rangeElement, (current) => {
|
|
1918
|
-
return dom.check.isListCell(current) && !current.previousElementSibling;
|
|
1919
|
-
});
|
|
1920
|
-
}
|
|
1921
|
-
|
|
1922
|
-
for (let i = 0, len = rChildren.length; i < len; i++) {
|
|
1923
|
-
DeleteNestedList(rChildren[i]);
|
|
1924
|
-
}
|
|
1925
|
-
|
|
1926
|
-
if (rNode) {
|
|
1927
|
-
rNode.parentNode.insertBefore(rangeElement, rNode.nextSibling);
|
|
1928
|
-
if (cNodes?.length === 0) dom.utils.removeItem(rNode);
|
|
1929
|
-
}
|
|
1930
|
-
|
|
1931
|
-
return rangeElement === baseNode ? rangeElement.parentNode : rangeElement;
|
|
1932
|
-
},
|
|
1933
|
-
|
|
1934
|
-
/**
|
|
1935
|
-
* @private
|
|
1936
|
-
* @this {FormatThis}
|
|
1937
|
-
* @description wraps text nodes of line selected text.
|
|
1938
|
-
* @param {Node} element The node of the line that contains the selected text node.
|
|
1939
|
-
* @param {Node} newInnerNode The dom that will wrap the selected text area
|
|
1940
|
-
* @param {(current: Node) => Node|null} validation Check if the node should be stripped.
|
|
1941
|
-
* @param {Node} startCon The startContainer property of the selection object.
|
|
1942
|
-
* @param {number} startOff The startOffset property of the selection object.
|
|
1943
|
-
* @param {Node} endCon The endContainer property of the selection object.
|
|
1944
|
-
* @param {number} endOff The endOffset property of the selection object.
|
|
1945
|
-
* @param {boolean} isRemoveFormat Is the remove all formats command?
|
|
1946
|
-
* @param {boolean} isRemoveNode "newInnerNode" is remove node?
|
|
1947
|
-
* @param {boolean} collapsed range.collapsed
|
|
1948
|
-
* @returns {{ancestor: *, startContainer: *, startOffset: *, endContainer: *, endOffset: *}}
|
|
1949
|
-
*/
|
|
1950
|
-
_setNode_oneLine(element, newInnerNode, validation, startCon, startOff, endCon, endOff, isRemoveFormat, isRemoveNode, collapsed, _removeCheck, _getMaintainedNode, _isMaintainedNode) {
|
|
1951
|
-
// not add tag
|
|
1952
|
-
let parentCon = startCon.parentNode;
|
|
1953
|
-
while (!parentCon.nextSibling && !parentCon.previousSibling && !this.isLine(parentCon.parentNode) && !dom.check.isWysiwygFrame(parentCon.parentNode)) {
|
|
1954
|
-
if (parentCon.nodeName === newInnerNode.nodeName) break;
|
|
1955
|
-
parentCon = parentCon.parentNode;
|
|
1956
|
-
}
|
|
1957
|
-
|
|
1958
|
-
if (!isRemoveNode && parentCon === endCon.parentNode && parentCon.nodeName === newInnerNode.nodeName) {
|
|
1959
|
-
if (dom.check.isZeroWidth(startCon.textContent.slice(0, startOff)) && dom.check.isZeroWidth(endCon.textContent.slice(endOff))) {
|
|
1960
|
-
const children = parentCon.childNodes;
|
|
1961
|
-
let sameTag = false;
|
|
1962
|
-
|
|
1963
|
-
for (let i = 0, len = children.length, c, s, e, z; i < len; i++) {
|
|
1964
|
-
c = children[i];
|
|
1965
|
-
z = !dom.check.isZeroWidth(c);
|
|
1966
|
-
if (c === startCon) {
|
|
1967
|
-
s = true;
|
|
1968
|
-
continue;
|
|
1969
|
-
}
|
|
1970
|
-
if (c === endCon) {
|
|
1971
|
-
e = true;
|
|
1972
|
-
continue;
|
|
1973
|
-
}
|
|
1974
|
-
if ((!s && z) || (s && e && z)) {
|
|
1975
|
-
sameTag = false;
|
|
1976
|
-
break;
|
|
1977
|
-
}
|
|
1978
|
-
}
|
|
1979
|
-
|
|
1980
|
-
if (sameTag) {
|
|
1981
|
-
dom.utils.copyTagAttributes(parentCon, newInnerNode);
|
|
1982
|
-
|
|
1983
|
-
return {
|
|
1984
|
-
ancestor: element,
|
|
1985
|
-
startContainer: startCon,
|
|
1986
|
-
startOffset: startOff,
|
|
1987
|
-
endContainer: endCon,
|
|
1988
|
-
endOffset: endOff
|
|
1989
|
-
};
|
|
1990
|
-
}
|
|
1991
|
-
}
|
|
1992
|
-
}
|
|
1993
|
-
|
|
1994
|
-
// add tag
|
|
1995
|
-
_removeCheck.v = false;
|
|
1996
|
-
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
1997
|
-
const inst = this;
|
|
1998
|
-
const el = element;
|
|
1999
|
-
const nNodeArray = [newInnerNode];
|
|
2000
|
-
const pNode = element.cloneNode(false);
|
|
2001
|
-
const isSameNode = startCon === endCon;
|
|
2002
|
-
let startContainer = startCon;
|
|
2003
|
-
let startOffset = startOff;
|
|
2004
|
-
let endContainer = endCon;
|
|
2005
|
-
let endOffset = endOff;
|
|
2006
|
-
let startPass = false;
|
|
2007
|
-
let endPass = false;
|
|
2008
|
-
let pCurrent, newNode, appendNode, cssText, anchorNode;
|
|
2009
|
-
|
|
2010
|
-
const wRegExp = RegExp;
|
|
2011
|
-
function checkCss(vNode) {
|
|
2012
|
-
const regExp = new wRegExp('(?:;|^|\\s)(?:' + cssText + 'null)\\s*:[^;]*\\s*(?:;|$)', 'ig');
|
|
2013
|
-
let style = false;
|
|
2014
|
-
|
|
2015
|
-
if (regExp && vNode.style.cssText.length > 0) {
|
|
2016
|
-
style = regExp.test(vNode.style.cssText);
|
|
2017
|
-
}
|
|
2018
|
-
|
|
2019
|
-
return !style;
|
|
2020
|
-
}
|
|
2021
|
-
|
|
2022
|
-
(function recursionFunc(current, ancestor) {
|
|
2023
|
-
const childNodes = current.childNodes;
|
|
2024
|
-
|
|
2025
|
-
for (let i = 0, len = childNodes.length, vNode; i < len; i++) {
|
|
2026
|
-
const child = childNodes[i];
|
|
2027
|
-
if (!child) continue;
|
|
2028
|
-
let coverNode = ancestor;
|
|
2029
|
-
let cloneNode;
|
|
2030
|
-
|
|
2031
|
-
// startContainer
|
|
2032
|
-
if (!startPass && child === startContainer) {
|
|
2033
|
-
let line = pNode;
|
|
2034
|
-
anchorNode = _getMaintainedNode(child);
|
|
2035
|
-
|
|
2036
|
-
let _prevText = '';
|
|
2037
|
-
let _nextText = '';
|
|
2038
|
-
if (startContainer.nodeType === 3) {
|
|
2039
|
-
const sText = /** @type {Text} */ (startContainer);
|
|
2040
|
-
_prevText = sText.substringData(0, startOffset);
|
|
2041
|
-
_nextText = sText.substringData(startOffset, isSameNode ? (endOffset >= startOffset ? endOffset - startOffset : sText.data.length - startOffset) : sText.data.length - startOffset);
|
|
2042
|
-
}
|
|
2043
|
-
|
|
2044
|
-
const prevNode = dom.utils.createTextNode(_prevText);
|
|
2045
|
-
const textNode = dom.utils.createTextNode(_nextText);
|
|
2046
|
-
|
|
2047
|
-
if (anchorNode) {
|
|
2048
|
-
const a = _getMaintainedNode(ancestor);
|
|
2049
|
-
if (a.parentNode !== line) {
|
|
2050
|
-
let m = a;
|
|
2051
|
-
let p = null;
|
|
2052
|
-
while (m.parentNode !== line) {
|
|
2053
|
-
ancestor = p = m.parentNode.cloneNode(false);
|
|
2054
|
-
while (m.childNodes[0]) {
|
|
2055
|
-
p.appendChild(m.childNodes[0]);
|
|
2056
|
-
}
|
|
2057
|
-
m.appendChild(p);
|
|
2058
|
-
m = m.parentNode;
|
|
2059
|
-
}
|
|
2060
|
-
m.parentNode.appendChild(a);
|
|
2061
|
-
}
|
|
2062
|
-
anchorNode = anchorNode.cloneNode(false);
|
|
2063
|
-
}
|
|
2064
|
-
|
|
2065
|
-
if (!dom.check.isZeroWidth(prevNode)) {
|
|
2066
|
-
ancestor.appendChild(prevNode);
|
|
2067
|
-
}
|
|
2068
|
-
|
|
2069
|
-
const prevAnchorNode = _getMaintainedNode(ancestor);
|
|
2070
|
-
if (prevAnchorNode) anchorNode = prevAnchorNode;
|
|
2071
|
-
if (anchorNode) line = anchorNode;
|
|
2072
|
-
|
|
2073
|
-
newNode = /** @type {HTMLElement} */ (child);
|
|
2074
|
-
pCurrent = [];
|
|
2075
|
-
cssText = '';
|
|
2076
|
-
while (newNode !== line && newNode !== el && newNode !== null) {
|
|
2077
|
-
vNode = _isMaintainedNode(newNode) ? null : validation(newNode);
|
|
2078
|
-
if (vNode && newNode.nodeType === 1 && checkCss(newNode)) {
|
|
2079
|
-
pCurrent.push(vNode);
|
|
2080
|
-
cssText += newNode.style.cssText.substring(0, newNode.style.cssText.indexOf(':')) + '|';
|
|
2081
|
-
}
|
|
2082
|
-
newNode = newNode.parentElement;
|
|
2083
|
-
}
|
|
2084
|
-
|
|
2085
|
-
const childNode = pCurrent.pop() || textNode;
|
|
2086
|
-
appendNode = newNode = childNode;
|
|
2087
|
-
while (pCurrent.length > 0) {
|
|
2088
|
-
newNode = pCurrent.pop();
|
|
2089
|
-
appendNode.appendChild(newNode);
|
|
2090
|
-
appendNode = newNode;
|
|
2091
|
-
}
|
|
2092
|
-
|
|
2093
|
-
newInnerNode.appendChild(childNode);
|
|
2094
|
-
line.appendChild(newInnerNode);
|
|
2095
|
-
|
|
2096
|
-
if (anchorNode && !_getMaintainedNode(endContainer)) {
|
|
2097
|
-
newInnerNode = newInnerNode.cloneNode(false);
|
|
2098
|
-
pNode.appendChild(newInnerNode);
|
|
2099
|
-
nNodeArray.push(newInnerNode);
|
|
2100
|
-
}
|
|
2101
|
-
|
|
2102
|
-
startContainer = textNode;
|
|
2103
|
-
startOffset = 0;
|
|
2104
|
-
startPass = true;
|
|
2105
|
-
|
|
2106
|
-
if (newNode !== textNode) newNode.appendChild(startContainer);
|
|
2107
|
-
if (!isSameNode) continue;
|
|
2108
|
-
}
|
|
2109
|
-
|
|
2110
|
-
// endContainer
|
|
2111
|
-
if (!endPass && child === endContainer) {
|
|
2112
|
-
anchorNode = _getMaintainedNode(child);
|
|
2113
|
-
|
|
2114
|
-
let _prevText = '';
|
|
2115
|
-
let _nextText = '';
|
|
2116
|
-
if (endContainer.nodeType === 3) {
|
|
2117
|
-
const eText = /** @type {Text} */ (endContainer);
|
|
2118
|
-
_prevText = eText.substringData(endOffset, eText.length - endOffset);
|
|
2119
|
-
_nextText = isSameNode ? '' : eText.substringData(0, endOffset);
|
|
2120
|
-
}
|
|
2121
|
-
|
|
2122
|
-
const afterNode = dom.utils.createTextNode(_prevText);
|
|
2123
|
-
const textNode = dom.utils.createTextNode(_nextText);
|
|
2124
|
-
|
|
2125
|
-
if (anchorNode) {
|
|
2126
|
-
anchorNode = anchorNode.cloneNode(false);
|
|
2127
|
-
} else if (_isMaintainedNode(newInnerNode.parentNode) && !anchorNode) {
|
|
2128
|
-
newInnerNode = newInnerNode.cloneNode(false);
|
|
2129
|
-
pNode.appendChild(newInnerNode);
|
|
2130
|
-
nNodeArray.push(newInnerNode);
|
|
2131
|
-
}
|
|
2132
|
-
|
|
2133
|
-
if (!dom.check.isZeroWidth(afterNode)) {
|
|
2134
|
-
newNode = /** @type {HTMLElement} */ (child);
|
|
2135
|
-
cssText = '';
|
|
2136
|
-
pCurrent = [];
|
|
2137
|
-
const anchors = [];
|
|
2138
|
-
while (newNode !== pNode && newNode !== el && newNode !== null) {
|
|
2139
|
-
if (newNode.nodeType === 1 && checkCss(newNode)) {
|
|
2140
|
-
if (_isMaintainedNode(newNode)) anchors.push(newNode.cloneNode(false));
|
|
2141
|
-
else pCurrent.push(newNode.cloneNode(false));
|
|
2142
|
-
cssText += newNode.style.cssText.substring(0, newNode.style.cssText.indexOf(':')) + '|';
|
|
2143
|
-
}
|
|
2144
|
-
newNode = newNode.parentElement;
|
|
2145
|
-
}
|
|
2146
|
-
pCurrent = pCurrent.concat(anchors);
|
|
2147
|
-
|
|
2148
|
-
cloneNode = appendNode = newNode = pCurrent.pop() || afterNode;
|
|
2149
|
-
while (pCurrent.length > 0) {
|
|
2150
|
-
newNode = pCurrent.pop();
|
|
2151
|
-
appendNode.appendChild(newNode);
|
|
2152
|
-
appendNode = newNode;
|
|
2153
|
-
}
|
|
2154
|
-
|
|
2155
|
-
pNode.appendChild(cloneNode);
|
|
2156
|
-
newNode.textContent = afterNode.data;
|
|
2157
|
-
}
|
|
2158
|
-
|
|
2159
|
-
if (anchorNode && cloneNode) {
|
|
2160
|
-
const afterAnchorNode = _getMaintainedNode(cloneNode);
|
|
2161
|
-
if (afterAnchorNode) {
|
|
2162
|
-
anchorNode = afterAnchorNode;
|
|
2163
|
-
}
|
|
2164
|
-
}
|
|
2165
|
-
|
|
2166
|
-
newNode = /** @type {HTMLElement} */ (child);
|
|
2167
|
-
pCurrent = [];
|
|
2168
|
-
cssText = '';
|
|
2169
|
-
while (newNode !== pNode && newNode !== el && newNode !== null) {
|
|
2170
|
-
vNode = _isMaintainedNode(newNode) ? null : validation(newNode);
|
|
2171
|
-
if (vNode && newNode.nodeType === 1 && checkCss(newNode)) {
|
|
2172
|
-
pCurrent.push(vNode);
|
|
2173
|
-
cssText += newNode.style.cssText.substring(0, newNode.style.cssText.indexOf(':')) + '|';
|
|
2174
|
-
}
|
|
2175
|
-
newNode = newNode.parentElement;
|
|
2176
|
-
}
|
|
2177
|
-
|
|
2178
|
-
const childNode = pCurrent.pop() || textNode;
|
|
2179
|
-
appendNode = newNode = childNode;
|
|
2180
|
-
while (pCurrent.length > 0) {
|
|
2181
|
-
newNode = pCurrent.pop();
|
|
2182
|
-
appendNode.appendChild(newNode);
|
|
2183
|
-
appendNode = newNode;
|
|
2184
|
-
}
|
|
2185
|
-
|
|
2186
|
-
if (anchorNode) {
|
|
2187
|
-
newInnerNode = newInnerNode.cloneNode(false);
|
|
2188
|
-
newInnerNode.appendChild(childNode);
|
|
2189
|
-
anchorNode.insertBefore(newInnerNode, anchorNode.firstChild);
|
|
2190
|
-
pNode.appendChild(anchorNode);
|
|
2191
|
-
nNodeArray.push(newInnerNode);
|
|
2192
|
-
anchorNode = null;
|
|
2193
|
-
} else {
|
|
2194
|
-
newInnerNode.appendChild(childNode);
|
|
2195
|
-
}
|
|
2196
|
-
|
|
2197
|
-
endContainer = textNode;
|
|
2198
|
-
endOffset = textNode.data.length;
|
|
2199
|
-
endPass = true;
|
|
2200
|
-
|
|
2201
|
-
if (!isRemoveFormat && collapsed) {
|
|
2202
|
-
newInnerNode = textNode;
|
|
2203
|
-
textNode.textContent = unicode.zeroWidthSpace;
|
|
2204
|
-
}
|
|
2205
|
-
|
|
2206
|
-
if (newNode !== textNode) newNode.appendChild(endContainer);
|
|
2207
|
-
continue;
|
|
2208
|
-
}
|
|
2209
|
-
|
|
2210
|
-
// other
|
|
2211
|
-
if (startPass) {
|
|
2212
|
-
if (child.nodeType === 1 && !dom.check.isBreak(child)) {
|
|
2213
|
-
if (inst._isIgnoreNodeChange(child)) {
|
|
2214
|
-
pNode.appendChild(child.cloneNode(true));
|
|
2215
|
-
if (!collapsed) {
|
|
2216
|
-
newInnerNode = newInnerNode.cloneNode(false);
|
|
2217
|
-
pNode.appendChild(newInnerNode);
|
|
2218
|
-
nNodeArray.push(newInnerNode);
|
|
2219
|
-
}
|
|
2220
|
-
} else {
|
|
2221
|
-
recursionFunc(child, child);
|
|
2222
|
-
}
|
|
2223
|
-
continue;
|
|
2224
|
-
}
|
|
2225
|
-
|
|
2226
|
-
newNode = /** @type {HTMLElement} */ (child);
|
|
2227
|
-
pCurrent = [];
|
|
2228
|
-
cssText = '';
|
|
2229
|
-
const anchors = [];
|
|
2230
|
-
while (newNode.parentNode !== null && newNode !== el && newNode !== newInnerNode) {
|
|
2231
|
-
vNode = endPass ? newNode.cloneNode(false) : validation(newNode);
|
|
2232
|
-
if (newNode.nodeType === 1 && !dom.check.isBreak(child) && vNode && checkCss(newNode)) {
|
|
2233
|
-
if (_isMaintainedNode(newNode)) {
|
|
2234
|
-
if (!anchorNode) anchors.push(vNode);
|
|
2235
|
-
} else {
|
|
2236
|
-
pCurrent.push(vNode);
|
|
2237
|
-
}
|
|
2238
|
-
cssText += newNode.style.cssText.substring(0, newNode.style.cssText.indexOf(':')) + '|';
|
|
2239
|
-
}
|
|
2240
|
-
newNode = newNode.parentElement;
|
|
2241
|
-
}
|
|
2242
|
-
pCurrent = pCurrent.concat(anchors);
|
|
2243
|
-
|
|
2244
|
-
const childNode = pCurrent.pop() || child;
|
|
2245
|
-
appendNode = newNode = childNode;
|
|
2246
|
-
while (pCurrent.length > 0) {
|
|
2247
|
-
newNode = pCurrent.pop();
|
|
2248
|
-
appendNode.appendChild(newNode);
|
|
2249
|
-
appendNode = newNode;
|
|
2250
|
-
}
|
|
2251
|
-
|
|
2252
|
-
if (_isMaintainedNode(newInnerNode.parentNode) && !_isMaintainedNode(childNode) && !dom.check.isZeroWidth(newInnerNode)) {
|
|
2253
|
-
newInnerNode = newInnerNode.cloneNode(false);
|
|
2254
|
-
pNode.appendChild(newInnerNode);
|
|
2255
|
-
nNodeArray.push(newInnerNode);
|
|
2256
|
-
}
|
|
2257
|
-
|
|
2258
|
-
if (!endPass && !anchorNode && _isMaintainedNode(childNode)) {
|
|
2259
|
-
newInnerNode = newInnerNode.cloneNode(false);
|
|
2260
|
-
const aChildren = childNode.childNodes;
|
|
2261
|
-
for (let a = 0, aLen = aChildren.length; a < aLen; a++) {
|
|
2262
|
-
newInnerNode.appendChild(aChildren[a]);
|
|
2263
|
-
}
|
|
2264
|
-
childNode.appendChild(newInnerNode);
|
|
2265
|
-
pNode.appendChild(childNode);
|
|
2266
|
-
nNodeArray.push(newInnerNode);
|
|
2267
|
-
if (/** @type {HTMLElement} */ (newInnerNode).children.length > 0) ancestor = newNode;
|
|
2268
|
-
else ancestor = newInnerNode;
|
|
2269
|
-
} else if (childNode === child) {
|
|
2270
|
-
if (!endPass) ancestor = newInnerNode;
|
|
2271
|
-
else ancestor = pNode;
|
|
2272
|
-
} else if (endPass) {
|
|
2273
|
-
pNode.appendChild(childNode);
|
|
2274
|
-
ancestor = newNode;
|
|
2275
|
-
} else {
|
|
2276
|
-
newInnerNode.appendChild(childNode);
|
|
2277
|
-
ancestor = newNode;
|
|
2278
|
-
}
|
|
2279
|
-
|
|
2280
|
-
if (anchorNode && child.nodeType === 3) {
|
|
2281
|
-
if (_getMaintainedNode(child)) {
|
|
2282
|
-
const ancestorAnchorNode = dom.query.getParentElement(ancestor, (c) => {
|
|
2283
|
-
return inst._isNonSplitNode(c.parentNode) || c.parentNode === pNode;
|
|
2284
|
-
});
|
|
2285
|
-
anchorNode.appendChild(ancestorAnchorNode);
|
|
2286
|
-
newInnerNode = ancestorAnchorNode.cloneNode(false);
|
|
2287
|
-
nNodeArray.push(newInnerNode);
|
|
2288
|
-
pNode.appendChild(newInnerNode);
|
|
2289
|
-
} else {
|
|
2290
|
-
anchorNode = null;
|
|
2291
|
-
}
|
|
2292
|
-
}
|
|
2293
|
-
}
|
|
2294
|
-
|
|
2295
|
-
cloneNode = child.cloneNode(false);
|
|
2296
|
-
ancestor.appendChild(cloneNode);
|
|
2297
|
-
if (child.nodeType === 1 && !dom.check.isBreak(child)) coverNode = cloneNode;
|
|
2298
|
-
|
|
2299
|
-
recursionFunc(child, coverNode);
|
|
2300
|
-
}
|
|
2301
|
-
})(element, pNode);
|
|
2302
|
-
|
|
2303
|
-
// not remove tag
|
|
2304
|
-
if (isRemoveNode && !isRemoveFormat && !_removeCheck.v) {
|
|
2305
|
-
return {
|
|
2306
|
-
ancestor: element,
|
|
2307
|
-
startContainer: startCon,
|
|
2308
|
-
startOffset: startOff,
|
|
2309
|
-
endContainer: endCon,
|
|
2310
|
-
endOffset: endOff
|
|
2311
|
-
};
|
|
2312
|
-
}
|
|
2313
|
-
|
|
2314
|
-
isRemoveFormat = isRemoveFormat && isRemoveNode;
|
|
2315
|
-
|
|
2316
|
-
if (isRemoveFormat) {
|
|
2317
|
-
for (let i = 0; i < nNodeArray.length; i++) {
|
|
2318
|
-
const removeNode = nNodeArray[i];
|
|
2319
|
-
let textNode, textNode_s, textNode_e;
|
|
2320
|
-
|
|
2321
|
-
if (collapsed) {
|
|
2322
|
-
textNode = dom.utils.createTextNode(unicode.zeroWidthSpace);
|
|
2323
|
-
pNode.replaceChild(textNode, removeNode);
|
|
2324
|
-
} else {
|
|
2325
|
-
const rChildren = removeNode.childNodes;
|
|
2326
|
-
textNode_s = rChildren[0];
|
|
2327
|
-
while (rChildren[0]) {
|
|
2328
|
-
textNode_e = rChildren[0];
|
|
2329
|
-
pNode.insertBefore(textNode_e, removeNode);
|
|
2330
|
-
}
|
|
2331
|
-
dom.utils.removeItem(removeNode);
|
|
2332
|
-
}
|
|
2333
|
-
|
|
2334
|
-
if (i === 0) {
|
|
2335
|
-
if (collapsed) {
|
|
2336
|
-
startContainer = endContainer = textNode;
|
|
2337
|
-
} else {
|
|
2338
|
-
startContainer = textNode_s;
|
|
2339
|
-
endContainer = textNode_e;
|
|
2340
|
-
}
|
|
2341
|
-
}
|
|
2342
|
-
}
|
|
2343
|
-
} else {
|
|
2344
|
-
if (isRemoveNode) {
|
|
2345
|
-
for (let i = 0; i < nNodeArray.length; i++) {
|
|
2346
|
-
SN_StripRemoveNode(nNodeArray[i]);
|
|
2347
|
-
}
|
|
2348
|
-
}
|
|
2349
|
-
|
|
2350
|
-
if (collapsed) {
|
|
2351
|
-
startContainer = endContainer = newInnerNode;
|
|
2352
|
-
}
|
|
2353
|
-
}
|
|
2354
|
-
|
|
2355
|
-
this.nodeTransform.removeEmptyNode(pNode, newInnerNode, false);
|
|
2356
|
-
|
|
2357
|
-
if (collapsed) {
|
|
2358
|
-
startOffset = startContainer.textContent.length;
|
|
2359
|
-
endOffset = endContainer.textContent.length;
|
|
2360
|
-
}
|
|
2361
|
-
|
|
2362
|
-
// endContainer reset
|
|
2363
|
-
const endConReset = isRemoveFormat || endContainer.textContent.length === 0;
|
|
2364
|
-
|
|
2365
|
-
if (!dom.check.isBreak(endContainer) && endContainer.textContent.length === 0) {
|
|
2366
|
-
dom.utils.removeItem(endContainer);
|
|
2367
|
-
endContainer = startContainer;
|
|
2368
|
-
}
|
|
2369
|
-
endOffset = endConReset ? endContainer.textContent.length : endOffset;
|
|
2370
|
-
|
|
2371
|
-
// node change
|
|
2372
|
-
const newStartOffset = {
|
|
2373
|
-
s: 0,
|
|
2374
|
-
e: 0
|
|
2375
|
-
};
|
|
2376
|
-
const startPath = dom.query.getNodePath(startContainer, pNode, newStartOffset);
|
|
2377
|
-
|
|
2378
|
-
const mergeEndCon = !endContainer.parentNode;
|
|
2379
|
-
if (mergeEndCon) endContainer = startContainer;
|
|
2380
|
-
const newEndOffset = {
|
|
2381
|
-
s: 0,
|
|
2382
|
-
e: 0
|
|
2383
|
-
};
|
|
2384
|
-
const endPath = dom.query.getNodePath(endContainer, pNode, !mergeEndCon && !endConReset ? newEndOffset : null);
|
|
2385
|
-
|
|
2386
|
-
startOffset += newStartOffset.s;
|
|
2387
|
-
endOffset = collapsed ? startOffset : mergeEndCon ? startContainer.textContent.length : endConReset ? endOffset + newStartOffset.s : endOffset + newEndOffset.s;
|
|
2388
|
-
|
|
2389
|
-
// tag merge
|
|
2390
|
-
const newOffsets = this.nodeTransform.mergeSameTags(pNode, [startPath, endPath], true);
|
|
2391
|
-
|
|
2392
|
-
element.parentNode.replaceChild(pNode, element);
|
|
2393
|
-
|
|
2394
|
-
startContainer = dom.query.getNodeFromPath(startPath, pNode);
|
|
2395
|
-
endContainer = dom.query.getNodeFromPath(endPath, pNode);
|
|
2396
|
-
|
|
2397
|
-
return {
|
|
2398
|
-
ancestor: pNode,
|
|
2399
|
-
startContainer: startContainer,
|
|
2400
|
-
startOffset: startOffset + newOffsets[0],
|
|
2401
|
-
endContainer: endContainer,
|
|
2402
|
-
endOffset: endOffset + newOffsets[1]
|
|
2403
|
-
};
|
|
2404
|
-
},
|
|
2405
|
-
|
|
2406
|
-
/**
|
|
2407
|
-
* @private
|
|
2408
|
-
* @this {FormatThis}
|
|
2409
|
-
* @description wraps first line selected text.
|
|
2410
|
-
* @param {Node} element The node of the line that contains the selected text node.
|
|
2411
|
-
* @param {Node} newInnerNode The dom that will wrap the selected text area
|
|
2412
|
-
* @param {(current: Node) => Node|null} validation Check if the node should be stripped.
|
|
2413
|
-
* @param {Node} startCon The startContainer property of the selection object.
|
|
2414
|
-
* @param {number} startOff The startOffset property of the selection object.
|
|
2415
|
-
* @param {boolean} isRemoveFormat Is the remove all formats command?
|
|
2416
|
-
* @param {boolean} isRemoveNode "newInnerNode" is remove node?
|
|
2417
|
-
* @returns {NodeStyleContainerType} { ancestor, container, offset, endContainer }
|
|
2418
|
-
*/
|
|
2419
|
-
_setNode_startLine(element, newInnerNode, validation, startCon, startOff, isRemoveFormat, isRemoveNode, _removeCheck, _getMaintainedNode, _isMaintainedNode, _endContainer) {
|
|
2420
|
-
// not add tag
|
|
2421
|
-
let parentCon = startCon.parentNode;
|
|
2422
|
-
while (!parentCon.nextSibling && !parentCon.previousSibling && !this.isLine(parentCon.parentNode) && !dom.check.isWysiwygFrame(parentCon.parentNode)) {
|
|
2423
|
-
if (parentCon.nodeName === newInnerNode.nodeName) break;
|
|
2424
|
-
parentCon = parentCon.parentNode;
|
|
2425
|
-
}
|
|
2426
|
-
|
|
2427
|
-
if (!isRemoveNode && parentCon.nodeName === newInnerNode.nodeName && !this.isLine(parentCon) && !parentCon.nextSibling && dom.check.isZeroWidth(startCon.textContent.slice(0, startOff))) {
|
|
2428
|
-
let sameTag = false;
|
|
2429
|
-
let s = startCon.previousSibling;
|
|
2430
|
-
while (s) {
|
|
2431
|
-
if (!dom.check.isZeroWidth(s)) {
|
|
2432
|
-
sameTag = false;
|
|
2433
|
-
break;
|
|
2434
|
-
}
|
|
2435
|
-
s = s.previousSibling;
|
|
2436
|
-
}
|
|
2437
|
-
|
|
2438
|
-
if (sameTag) {
|
|
2439
|
-
dom.utils.copyTagAttributes(parentCon, newInnerNode);
|
|
2440
|
-
|
|
2441
|
-
return {
|
|
2442
|
-
ancestor: element,
|
|
2443
|
-
container: startCon,
|
|
2444
|
-
offset: startOff
|
|
2445
|
-
};
|
|
2446
|
-
}
|
|
2447
|
-
}
|
|
2448
|
-
|
|
2449
|
-
// add tag
|
|
2450
|
-
_removeCheck.v = false;
|
|
2451
|
-
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
2452
|
-
const inst = this;
|
|
2453
|
-
const el = element;
|
|
2454
|
-
const nNodeArray = [newInnerNode];
|
|
2455
|
-
const pNode = element.cloneNode(false);
|
|
2456
|
-
|
|
2457
|
-
let container = startCon;
|
|
2458
|
-
let offset = startOff;
|
|
2459
|
-
let passNode = false;
|
|
2460
|
-
let pCurrent, newNode, appendNode, anchorNode;
|
|
2461
|
-
|
|
2462
|
-
(function recursionFunc(current, ancestor) {
|
|
2463
|
-
const childNodes = current.childNodes;
|
|
2464
|
-
|
|
2465
|
-
for (let i = 0, len = childNodes.length, vNode, cloneChild; i < len; i++) {
|
|
2466
|
-
const child = /** @type {HTMLElement} */ (childNodes[i]);
|
|
2467
|
-
if (!child) continue;
|
|
2468
|
-
let coverNode = ancestor;
|
|
2469
|
-
|
|
2470
|
-
if (passNode && !dom.check.isBreak(child)) {
|
|
2471
|
-
if (child.nodeType === 1) {
|
|
2472
|
-
if (inst._isIgnoreNodeChange(child)) {
|
|
2473
|
-
newInnerNode = newInnerNode.cloneNode(false);
|
|
2474
|
-
cloneChild = child.cloneNode(true);
|
|
2475
|
-
pNode.appendChild(cloneChild);
|
|
2476
|
-
pNode.appendChild(newInnerNode);
|
|
2477
|
-
nNodeArray.push(newInnerNode);
|
|
2478
|
-
|
|
2479
|
-
// end container
|
|
2480
|
-
if (_endContainer && child.contains(_endContainer)) {
|
|
2481
|
-
const endPath = dom.query.getNodePath(_endContainer, child);
|
|
2482
|
-
_endContainer = dom.query.getNodeFromPath(endPath, cloneChild);
|
|
2483
|
-
}
|
|
2484
|
-
} else {
|
|
2485
|
-
recursionFunc(child, child);
|
|
2486
|
-
}
|
|
2487
|
-
continue;
|
|
2488
|
-
}
|
|
2489
|
-
|
|
2490
|
-
newNode = child;
|
|
2491
|
-
pCurrent = [];
|
|
2492
|
-
const anchors = [];
|
|
2493
|
-
while (newNode.parentNode !== null && newNode !== el && newNode !== newInnerNode) {
|
|
2494
|
-
vNode = validation(newNode);
|
|
2495
|
-
if (newNode.nodeType === 1 && vNode) {
|
|
2496
|
-
if (_isMaintainedNode(newNode)) {
|
|
2497
|
-
if (!anchorNode) anchors.push(vNode);
|
|
2498
|
-
} else {
|
|
2499
|
-
pCurrent.push(vNode);
|
|
2500
|
-
}
|
|
2501
|
-
}
|
|
2502
|
-
newNode = newNode.parentNode;
|
|
2503
|
-
}
|
|
2504
|
-
pCurrent = pCurrent.concat(anchors);
|
|
2505
|
-
|
|
2506
|
-
const isTopNode = pCurrent.length > 0;
|
|
2507
|
-
const childNode = pCurrent.pop() || child;
|
|
2508
|
-
appendNode = newNode = childNode;
|
|
2509
|
-
while (pCurrent.length > 0) {
|
|
2510
|
-
newNode = pCurrent.pop();
|
|
2511
|
-
appendNode.appendChild(newNode);
|
|
2512
|
-
appendNode = newNode;
|
|
2513
|
-
}
|
|
2514
|
-
|
|
2515
|
-
if (_isMaintainedNode(newInnerNode.parentNode) && !_isMaintainedNode(childNode)) {
|
|
2516
|
-
newInnerNode = newInnerNode.cloneNode(false);
|
|
2517
|
-
pNode.appendChild(newInnerNode);
|
|
2518
|
-
nNodeArray.push(newInnerNode);
|
|
2519
|
-
}
|
|
2520
|
-
|
|
2521
|
-
if (!anchorNode && _isMaintainedNode(childNode)) {
|
|
2522
|
-
newInnerNode = newInnerNode.cloneNode(false);
|
|
2523
|
-
const aChildren = childNode.childNodes;
|
|
2524
|
-
for (let a = 0, aLen = aChildren.length; a < aLen; a++) {
|
|
2525
|
-
newInnerNode.appendChild(aChildren[a]);
|
|
2526
|
-
}
|
|
2527
|
-
childNode.appendChild(newInnerNode);
|
|
2528
|
-
pNode.appendChild(childNode);
|
|
2529
|
-
ancestor = !_isMaintainedNode(newNode) ? newNode : newInnerNode;
|
|
2530
|
-
nNodeArray.push(newInnerNode);
|
|
2531
|
-
} else if (isTopNode) {
|
|
2532
|
-
newInnerNode.appendChild(childNode);
|
|
2533
|
-
ancestor = newNode;
|
|
2534
|
-
} else {
|
|
2535
|
-
ancestor = newInnerNode;
|
|
2536
|
-
}
|
|
2537
|
-
|
|
2538
|
-
if (anchorNode && child.nodeType === 3) {
|
|
2539
|
-
if (_getMaintainedNode(child)) {
|
|
2540
|
-
const ancestorAnchorNode = dom.query.getParentElement(ancestor, (c) => {
|
|
2541
|
-
return inst._isNonSplitNode(c.parentNode) || c.parentNode === pNode;
|
|
2542
|
-
});
|
|
2543
|
-
anchorNode.appendChild(ancestorAnchorNode);
|
|
2544
|
-
newInnerNode = ancestorAnchorNode.cloneNode(false);
|
|
2545
|
-
nNodeArray.push(newInnerNode);
|
|
2546
|
-
pNode.appendChild(newInnerNode);
|
|
2547
|
-
} else {
|
|
2548
|
-
anchorNode = null;
|
|
2549
|
-
}
|
|
2550
|
-
}
|
|
2551
|
-
}
|
|
2552
|
-
|
|
2553
|
-
// startContainer
|
|
2554
|
-
if (!passNode && child === container) {
|
|
2555
|
-
let line = pNode;
|
|
2556
|
-
anchorNode = _getMaintainedNode(child);
|
|
2557
|
-
|
|
2558
|
-
let _prevText = '';
|
|
2559
|
-
let _nextText = '';
|
|
2560
|
-
if (container.nodeType === 3) {
|
|
2561
|
-
const cText = /** @type {Text} */ (container);
|
|
2562
|
-
_prevText = cText.substringData(0, offset);
|
|
2563
|
-
_nextText = cText.substringData(offset, cText.length - offset);
|
|
2564
|
-
}
|
|
2565
|
-
|
|
2566
|
-
const prevNode = dom.utils.createTextNode(_prevText);
|
|
2567
|
-
const textNode = dom.utils.createTextNode(_nextText);
|
|
2568
|
-
|
|
2569
|
-
if (anchorNode) {
|
|
2570
|
-
const a = _getMaintainedNode(ancestor);
|
|
2571
|
-
if (a && a.parentNode !== line) {
|
|
2572
|
-
let m = a;
|
|
2573
|
-
let p = null;
|
|
2574
|
-
while (m.parentNode !== line) {
|
|
2575
|
-
ancestor = p = m.parentNode.cloneNode(false);
|
|
2576
|
-
while (m.childNodes[0]) {
|
|
2577
|
-
p.appendChild(m.childNodes[0]);
|
|
2578
|
-
}
|
|
2579
|
-
m.appendChild(p);
|
|
2580
|
-
m = m.parentNode;
|
|
2581
|
-
}
|
|
2582
|
-
m.parentNode.appendChild(a);
|
|
2583
|
-
}
|
|
2584
|
-
anchorNode = anchorNode.cloneNode(false);
|
|
2585
|
-
}
|
|
2586
|
-
|
|
2587
|
-
if (!dom.check.isZeroWidth(prevNode)) {
|
|
2588
|
-
ancestor.appendChild(prevNode);
|
|
2589
|
-
}
|
|
2590
|
-
|
|
2591
|
-
const prevAnchorNode = _getMaintainedNode(ancestor);
|
|
2592
|
-
if (prevAnchorNode) anchorNode = prevAnchorNode;
|
|
2593
|
-
if (anchorNode) line = anchorNode;
|
|
2594
|
-
|
|
2595
|
-
newNode = ancestor;
|
|
2596
|
-
pCurrent = [];
|
|
2597
|
-
while (newNode !== line && newNode !== null) {
|
|
2598
|
-
vNode = validation(newNode);
|
|
2599
|
-
if (newNode.nodeType === 1 && vNode) {
|
|
2600
|
-
pCurrent.push(vNode);
|
|
2601
|
-
}
|
|
2602
|
-
newNode = newNode.parentNode;
|
|
2603
|
-
}
|
|
2604
|
-
|
|
2605
|
-
const childNode = pCurrent.pop() || ancestor;
|
|
2606
|
-
appendNode = newNode = childNode;
|
|
2607
|
-
while (pCurrent.length > 0) {
|
|
2608
|
-
newNode = pCurrent.pop();
|
|
2609
|
-
appendNode.appendChild(newNode);
|
|
2610
|
-
appendNode = newNode;
|
|
2611
|
-
}
|
|
2612
|
-
|
|
2613
|
-
if (childNode !== ancestor) {
|
|
2614
|
-
newInnerNode.appendChild(childNode);
|
|
2615
|
-
ancestor = newNode;
|
|
2616
|
-
} else {
|
|
2617
|
-
ancestor = newInnerNode;
|
|
2618
|
-
}
|
|
2619
|
-
|
|
2620
|
-
if (dom.check.isBreak(child)) newInnerNode.appendChild(child.cloneNode(false));
|
|
2621
|
-
line.appendChild(newInnerNode);
|
|
2622
|
-
|
|
2623
|
-
container = textNode;
|
|
2624
|
-
offset = 0;
|
|
2625
|
-
passNode = true;
|
|
2626
|
-
|
|
2627
|
-
ancestor.appendChild(container);
|
|
2628
|
-
continue;
|
|
2629
|
-
}
|
|
2630
|
-
|
|
2631
|
-
vNode = !passNode ? child.cloneNode(false) : validation(child);
|
|
2632
|
-
if (vNode) {
|
|
2633
|
-
ancestor.appendChild(vNode);
|
|
2634
|
-
if (child.nodeType === 1 && !dom.check.isBreak(child)) coverNode = vNode;
|
|
2635
|
-
}
|
|
2636
|
-
|
|
2637
|
-
recursionFunc(child, coverNode);
|
|
2638
|
-
}
|
|
2639
|
-
})(element, pNode);
|
|
2640
|
-
|
|
2641
|
-
// not remove tag
|
|
2642
|
-
if (isRemoveNode && !isRemoveFormat && !_removeCheck.v) {
|
|
2643
|
-
return {
|
|
2644
|
-
ancestor: element,
|
|
2645
|
-
container: startCon,
|
|
2646
|
-
offset: startOff,
|
|
2647
|
-
endContainer: _endContainer
|
|
2648
|
-
};
|
|
2649
|
-
}
|
|
2650
|
-
|
|
2651
|
-
isRemoveFormat = isRemoveFormat && isRemoveNode;
|
|
2652
|
-
|
|
2653
|
-
if (isRemoveFormat) {
|
|
2654
|
-
for (let i = 0; i < nNodeArray.length; i++) {
|
|
2655
|
-
const removeNode = nNodeArray[i];
|
|
2656
|
-
|
|
2657
|
-
const rChildren = removeNode.childNodes;
|
|
2658
|
-
const textNode = rChildren[0];
|
|
2659
|
-
while (rChildren[0]) {
|
|
2660
|
-
pNode.insertBefore(rChildren[0], removeNode);
|
|
2661
|
-
}
|
|
2662
|
-
dom.utils.removeItem(removeNode);
|
|
2663
|
-
|
|
2664
|
-
if (i === 0) container = textNode;
|
|
2665
|
-
}
|
|
2666
|
-
} else if (isRemoveNode) {
|
|
2667
|
-
newInnerNode = newInnerNode.firstChild;
|
|
2668
|
-
for (let i = 0; i < nNodeArray.length; i++) {
|
|
2669
|
-
SN_StripRemoveNode(nNodeArray[i]);
|
|
2670
|
-
}
|
|
2671
|
-
}
|
|
2672
|
-
|
|
2673
|
-
if (!isRemoveFormat && pNode.childNodes.length === 0) {
|
|
2674
|
-
if (element.childNodes) {
|
|
2675
|
-
container = element.childNodes[0];
|
|
2676
|
-
} else {
|
|
2677
|
-
container = dom.utils.createTextNode(unicode.zeroWidthSpace);
|
|
2678
|
-
element.appendChild(container);
|
|
2679
|
-
}
|
|
2680
|
-
} else {
|
|
2681
|
-
this.nodeTransform.removeEmptyNode(pNode, newInnerNode, false);
|
|
2682
|
-
|
|
2683
|
-
if (dom.check.isZeroWidth(pNode.textContent)) {
|
|
2684
|
-
container = pNode.firstChild;
|
|
2685
|
-
offset = 0;
|
|
2686
|
-
}
|
|
2687
|
-
|
|
2688
|
-
// node change
|
|
2689
|
-
const offsets = {
|
|
2690
|
-
s: 0,
|
|
2691
|
-
e: 0
|
|
2692
|
-
};
|
|
2693
|
-
const path = dom.query.getNodePath(container, pNode, offsets);
|
|
2694
|
-
offset += offsets.s;
|
|
2695
|
-
|
|
2696
|
-
// tag merge
|
|
2697
|
-
const newOffsets = this.nodeTransform.mergeSameTags(pNode, [path], true);
|
|
2698
|
-
|
|
2699
|
-
element.parentNode.replaceChild(pNode, element);
|
|
2700
|
-
|
|
2701
|
-
container = dom.query.getNodeFromPath(path, pNode);
|
|
2702
|
-
offset += newOffsets[0];
|
|
2703
|
-
}
|
|
2704
|
-
|
|
2705
|
-
return {
|
|
2706
|
-
ancestor: pNode,
|
|
2707
|
-
container: container,
|
|
2708
|
-
offset: offset,
|
|
2709
|
-
endContainer: _endContainer
|
|
2710
|
-
};
|
|
2711
|
-
},
|
|
2712
|
-
|
|
2713
|
-
/**
|
|
2714
|
-
* @private
|
|
2715
|
-
* @this {FormatThis}
|
|
2716
|
-
* @description wraps mid lines selected text.
|
|
2717
|
-
* @param {HTMLElement} element The node of the line that contains the selected text node.
|
|
2718
|
-
* @param {Node} newInnerNode The dom that will wrap the selected text area
|
|
2719
|
-
* @param {(current: Node) => Node|null} validation Check if the node should be stripped.
|
|
2720
|
-
* @param {boolean} isRemoveFormat Is the remove all formats command?
|
|
2721
|
-
* @param {boolean} isRemoveNode "newInnerNode" is remove node?
|
|
2722
|
-
* @param {Node} _endContainer Offset node of last line already modified (end.container)
|
|
2723
|
-
* @returns {NodeStyleContainerType} { ancestor, endContainer: "If end container is renewed, returned renewed node" }
|
|
2724
|
-
*/
|
|
2725
|
-
_setNode_middleLine(element, newInnerNode, validation, isRemoveFormat, isRemoveNode, _removeCheck, _endContainer) {
|
|
2726
|
-
// not add tag
|
|
2727
|
-
if (!isRemoveNode) {
|
|
2728
|
-
// end container path
|
|
2729
|
-
let endPath = null;
|
|
2730
|
-
if (_endContainer && element.contains(_endContainer)) endPath = dom.query.getNodePath(_endContainer, element);
|
|
2731
|
-
|
|
2732
|
-
const tempNode = element.cloneNode(true);
|
|
2733
|
-
const newNodeName = /** @type {HTMLElement} */ (newInnerNode).nodeName;
|
|
2734
|
-
const newCssText = /** @type {HTMLElement} */ (newInnerNode).style.cssText;
|
|
2735
|
-
const newClass = /** @type {HTMLElement} */ (newInnerNode).className;
|
|
2736
|
-
|
|
2737
|
-
let children = tempNode.childNodes;
|
|
2738
|
-
let i = 0,
|
|
2739
|
-
len = children.length;
|
|
2740
|
-
for (let child; i < len; i++) {
|
|
2741
|
-
child = /** @type {HTMLElement} */ (children[i]);
|
|
2742
|
-
if (child.nodeType === 3) break;
|
|
2743
|
-
if (child.nodeName === newNodeName) {
|
|
2744
|
-
child.style.cssText += newCssText;
|
|
2745
|
-
dom.utils.addClass(child, newClass);
|
|
2746
|
-
} else if (!dom.check.isBreak(child) && this._isIgnoreNodeChange(child)) {
|
|
2747
|
-
continue;
|
|
2748
|
-
} else if (len === 1) {
|
|
2749
|
-
children = child.childNodes;
|
|
2750
|
-
len = children.length;
|
|
2751
|
-
i = -1;
|
|
2752
|
-
continue;
|
|
2753
|
-
} else {
|
|
2754
|
-
break;
|
|
2755
|
-
}
|
|
2756
|
-
}
|
|
2757
|
-
|
|
2758
|
-
if (len > 0 && i === len) {
|
|
2759
|
-
element.innerHTML = /** @type {HTMLElement} */ (tempNode).innerHTML;
|
|
2760
|
-
return {
|
|
2761
|
-
ancestor: element,
|
|
2762
|
-
endContainer: endPath ? dom.query.getNodeFromPath(endPath, element) : null
|
|
2763
|
-
};
|
|
2764
|
-
}
|
|
2765
|
-
}
|
|
2766
|
-
|
|
2767
|
-
// add tag
|
|
2768
|
-
_removeCheck.v = false;
|
|
2769
|
-
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
2770
|
-
const inst = this;
|
|
2771
|
-
const pNode = element.cloneNode(false);
|
|
2772
|
-
const nNodeArray = [newInnerNode];
|
|
2773
|
-
let noneChange = true;
|
|
2774
|
-
|
|
2775
|
-
(function recursionFunc(current, ancestor) {
|
|
2776
|
-
const childNodes = current.childNodes;
|
|
2777
|
-
|
|
2778
|
-
for (let i = 0, len = childNodes.length, vNode, cloneChild; i < len; i++) {
|
|
2779
|
-
const child = /** @type {HTMLElement} */ (childNodes[i]);
|
|
2780
|
-
if (!child) continue;
|
|
2781
|
-
let coverNode = ancestor;
|
|
2782
|
-
|
|
2783
|
-
if (!dom.check.isBreak(child) && inst._isIgnoreNodeChange(child)) {
|
|
2784
|
-
if (newInnerNode.childNodes.length > 0) {
|
|
2785
|
-
pNode.appendChild(newInnerNode);
|
|
2786
|
-
newInnerNode = newInnerNode.cloneNode(false);
|
|
2787
|
-
}
|
|
2788
|
-
|
|
2789
|
-
cloneChild = child.cloneNode(true);
|
|
2790
|
-
pNode.appendChild(cloneChild);
|
|
2791
|
-
pNode.appendChild(newInnerNode);
|
|
2792
|
-
nNodeArray.push(newInnerNode);
|
|
2793
|
-
ancestor = newInnerNode;
|
|
2794
|
-
|
|
2795
|
-
// end container
|
|
2796
|
-
if (_endContainer && child.contains(_endContainer)) {
|
|
2797
|
-
const endPath = dom.query.getNodePath(_endContainer, child);
|
|
2798
|
-
_endContainer = dom.query.getNodeFromPath(endPath, cloneChild);
|
|
2799
|
-
}
|
|
2800
|
-
|
|
2801
|
-
continue;
|
|
2802
|
-
} else {
|
|
2803
|
-
vNode = validation(child);
|
|
2804
|
-
if (vNode) {
|
|
2805
|
-
noneChange = false;
|
|
2806
|
-
ancestor.appendChild(vNode);
|
|
2807
|
-
if (child.nodeType === 1) coverNode = vNode;
|
|
2808
|
-
}
|
|
2809
|
-
}
|
|
2810
|
-
|
|
2811
|
-
if (!dom.check.isBreak(child)) recursionFunc(child, coverNode);
|
|
2812
|
-
}
|
|
2813
|
-
})(element, newInnerNode);
|
|
2814
|
-
|
|
2815
|
-
// not remove tag
|
|
2816
|
-
if (noneChange || (isRemoveNode && !isRemoveFormat && !_removeCheck.v))
|
|
2817
|
-
return {
|
|
2818
|
-
ancestor: element,
|
|
2819
|
-
endContainer: _endContainer
|
|
2820
|
-
};
|
|
2821
|
-
|
|
2822
|
-
pNode.appendChild(newInnerNode);
|
|
2823
|
-
|
|
2824
|
-
if (isRemoveFormat && isRemoveNode) {
|
|
2825
|
-
for (let i = 0; i < nNodeArray.length; i++) {
|
|
2826
|
-
const removeNode = nNodeArray[i];
|
|
2827
|
-
|
|
2828
|
-
const rChildren = removeNode.childNodes;
|
|
2829
|
-
while (rChildren[0]) {
|
|
2830
|
-
pNode.insertBefore(rChildren[0], removeNode);
|
|
2831
|
-
}
|
|
2832
|
-
dom.utils.removeItem(removeNode);
|
|
2833
|
-
}
|
|
2834
|
-
} else if (isRemoveNode) {
|
|
2835
|
-
newInnerNode = newInnerNode.firstChild;
|
|
2836
|
-
for (let i = 0; i < nNodeArray.length; i++) {
|
|
2837
|
-
SN_StripRemoveNode(nNodeArray[i]);
|
|
2838
|
-
}
|
|
2839
|
-
}
|
|
2840
|
-
|
|
2841
|
-
this.nodeTransform.removeEmptyNode(pNode, newInnerNode, false);
|
|
2842
|
-
this.nodeTransform.mergeSameTags(pNode, null, true);
|
|
2843
|
-
|
|
2844
|
-
// node change
|
|
2845
|
-
element.parentNode.replaceChild(pNode, element);
|
|
2846
|
-
return {
|
|
2847
|
-
ancestor: pNode,
|
|
2848
|
-
endContainer: _endContainer
|
|
2849
|
-
};
|
|
2850
|
-
},
|
|
2851
|
-
|
|
2852
|
-
/**
|
|
2853
|
-
* @private
|
|
2854
|
-
* @this {FormatThis}
|
|
2855
|
-
* @description wraps last line selected text.
|
|
2856
|
-
* @param {Node} element The node of the line that contains the selected text node.
|
|
2857
|
-
* @param {Node} newInnerNode The dom that will wrap the selected text area
|
|
2858
|
-
* @param {(current: Node) => Node|null} validation Check if the node should be stripped.
|
|
2859
|
-
* @param {Node} endCon The endContainer property of the selection object.
|
|
2860
|
-
* @param {number} endOff The endOffset property of the selection object.
|
|
2861
|
-
* @param {boolean} isRemoveFormat Is the remove all formats command?
|
|
2862
|
-
* @param {boolean} isRemoveNode "newInnerNode" is remove node?
|
|
2863
|
-
* @returns {NodeStyleContainerType} { ancestor, container, offset }
|
|
2864
|
-
*/
|
|
2865
|
-
_setNode_endLine(element, newInnerNode, validation, endCon, endOff, isRemoveFormat, isRemoveNode, _removeCheck, _getMaintainedNode, _isMaintainedNode) {
|
|
2866
|
-
// not add tag
|
|
2867
|
-
let parentCon = endCon.parentNode;
|
|
2868
|
-
while (!parentCon.nextSibling && !parentCon.previousSibling && !this.isLine(parentCon.parentNode) && !dom.check.isWysiwygFrame(parentCon.parentNode)) {
|
|
2869
|
-
if (parentCon.nodeName === newInnerNode.nodeName) break;
|
|
2870
|
-
parentCon = parentCon.parentNode;
|
|
2871
|
-
}
|
|
2872
|
-
|
|
2873
|
-
if (!isRemoveNode && parentCon.nodeName === newInnerNode.nodeName && !this.isLine(parentCon) && !parentCon.previousSibling && dom.check.isZeroWidth(endCon.textContent.slice(endOff))) {
|
|
2874
|
-
let sameTag = false;
|
|
2875
|
-
let e = endCon.nextSibling;
|
|
2876
|
-
while (e) {
|
|
2877
|
-
if (!dom.check.isZeroWidth(e)) {
|
|
2878
|
-
sameTag = false;
|
|
2879
|
-
break;
|
|
2880
|
-
}
|
|
2881
|
-
e = e.nextSibling;
|
|
2882
|
-
}
|
|
2883
|
-
|
|
2884
|
-
if (sameTag) {
|
|
2885
|
-
dom.utils.copyTagAttributes(parentCon, newInnerNode);
|
|
2886
|
-
|
|
2887
|
-
return {
|
|
2888
|
-
ancestor: element,
|
|
2889
|
-
container: endCon,
|
|
2890
|
-
offset: endOff
|
|
2891
|
-
};
|
|
2892
|
-
}
|
|
2893
|
-
}
|
|
2894
|
-
|
|
2895
|
-
// add tag
|
|
2896
|
-
_removeCheck.v = false;
|
|
2897
|
-
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
2898
|
-
const inst = this;
|
|
2899
|
-
const el = element;
|
|
2900
|
-
const nNodeArray = [newInnerNode];
|
|
2901
|
-
const pNode = element.cloneNode(false);
|
|
2902
|
-
|
|
2903
|
-
let container = endCon;
|
|
2904
|
-
let offset = endOff;
|
|
2905
|
-
let passNode = false;
|
|
2906
|
-
let pCurrent, newNode, appendNode, anchorNode;
|
|
2907
|
-
|
|
2908
|
-
(function recursionFunc(current, ancestor) {
|
|
2909
|
-
const childNodes = current.childNodes;
|
|
2910
|
-
|
|
2911
|
-
for (let i = childNodes.length - 1, vNode; 0 <= i; i--) {
|
|
2912
|
-
const child = childNodes[i];
|
|
2913
|
-
if (!child) continue;
|
|
2914
|
-
let coverNode = ancestor;
|
|
2915
|
-
|
|
2916
|
-
if (passNode && !dom.check.isBreak(child)) {
|
|
2917
|
-
if (child.nodeType === 1) {
|
|
2918
|
-
if (inst._isIgnoreNodeChange(child)) {
|
|
2919
|
-
newInnerNode = newInnerNode.cloneNode(false);
|
|
2920
|
-
const cloneChild = child.cloneNode(true);
|
|
2921
|
-
pNode.insertBefore(cloneChild, ancestor);
|
|
2922
|
-
pNode.insertBefore(newInnerNode, cloneChild);
|
|
2923
|
-
nNodeArray.push(newInnerNode);
|
|
2924
|
-
} else {
|
|
2925
|
-
recursionFunc(child, child);
|
|
2926
|
-
}
|
|
2927
|
-
continue;
|
|
2928
|
-
}
|
|
2929
|
-
|
|
2930
|
-
newNode = child;
|
|
2931
|
-
pCurrent = [];
|
|
2932
|
-
const anchors = [];
|
|
2933
|
-
while (newNode.parentNode !== null && newNode !== el && newNode !== newInnerNode) {
|
|
2934
|
-
vNode = validation(newNode);
|
|
2935
|
-
if (vNode && newNode.nodeType === 1) {
|
|
2936
|
-
if (_isMaintainedNode(newNode)) {
|
|
2937
|
-
if (!anchorNode) anchors.push(vNode);
|
|
2938
|
-
} else {
|
|
2939
|
-
pCurrent.push(vNode);
|
|
2940
|
-
}
|
|
2941
|
-
}
|
|
2942
|
-
newNode = newNode.parentNode;
|
|
2943
|
-
}
|
|
2944
|
-
pCurrent = pCurrent.concat(anchors);
|
|
2945
|
-
|
|
2946
|
-
const isTopNode = pCurrent.length > 0;
|
|
2947
|
-
const childNode = pCurrent.pop() || child;
|
|
2948
|
-
appendNode = newNode = childNode;
|
|
2949
|
-
while (pCurrent.length > 0) {
|
|
2950
|
-
newNode = pCurrent.pop();
|
|
2951
|
-
appendNode.appendChild(newNode);
|
|
2952
|
-
appendNode = newNode;
|
|
2953
|
-
}
|
|
2954
|
-
|
|
2955
|
-
if (_isMaintainedNode(newInnerNode.parentNode) && !_isMaintainedNode(childNode)) {
|
|
2956
|
-
newInnerNode = newInnerNode.cloneNode(false);
|
|
2957
|
-
pNode.insertBefore(newInnerNode, pNode.firstChild);
|
|
2958
|
-
nNodeArray.push(newInnerNode);
|
|
2959
|
-
}
|
|
2960
|
-
|
|
2961
|
-
if (!anchorNode && _isMaintainedNode(childNode)) {
|
|
2962
|
-
newInnerNode = newInnerNode.cloneNode(false);
|
|
2963
|
-
const aChildren = childNode.childNodes;
|
|
2964
|
-
for (let a = 0, aLen = aChildren.length; a < aLen; a++) {
|
|
2965
|
-
newInnerNode.appendChild(aChildren[a]);
|
|
2966
|
-
}
|
|
2967
|
-
childNode.appendChild(newInnerNode);
|
|
2968
|
-
pNode.insertBefore(childNode, pNode.firstChild);
|
|
2969
|
-
nNodeArray.push(newInnerNode);
|
|
2970
|
-
if (/** @type {HTMLElement} */ (newInnerNode).children.length > 0) ancestor = newNode;
|
|
2971
|
-
else ancestor = newInnerNode;
|
|
2972
|
-
} else if (isTopNode) {
|
|
2973
|
-
newInnerNode.insertBefore(childNode, newInnerNode.firstChild);
|
|
2974
|
-
ancestor = newNode;
|
|
2975
|
-
} else {
|
|
2976
|
-
ancestor = newInnerNode;
|
|
2977
|
-
}
|
|
2978
|
-
|
|
2979
|
-
if (anchorNode && child.nodeType === 3) {
|
|
2980
|
-
if (_getMaintainedNode(child)) {
|
|
2981
|
-
const ancestorAnchorNode = dom.query.getParentElement(ancestor, (c) => {
|
|
2982
|
-
return inst._isNonSplitNode(c.parentNode) || c.parentNode === pNode;
|
|
2983
|
-
});
|
|
2984
|
-
anchorNode.appendChild(ancestorAnchorNode);
|
|
2985
|
-
newInnerNode = ancestorAnchorNode.cloneNode(false);
|
|
2986
|
-
nNodeArray.push(newInnerNode);
|
|
2987
|
-
pNode.insertBefore(newInnerNode, pNode.firstChild);
|
|
2988
|
-
} else {
|
|
2989
|
-
anchorNode = null;
|
|
2990
|
-
}
|
|
2991
|
-
}
|
|
2992
|
-
}
|
|
2993
|
-
|
|
2994
|
-
// endContainer
|
|
2995
|
-
if (!passNode && child === container) {
|
|
2996
|
-
anchorNode = _getMaintainedNode(child);
|
|
2997
|
-
|
|
2998
|
-
let _prevText = '';
|
|
2999
|
-
let _nextText = '';
|
|
3000
|
-
if (container.nodeType === 3) {
|
|
3001
|
-
const cText = /** @type {Text} */ (container);
|
|
3002
|
-
_prevText = cText.substringData(offset, cText.length - offset);
|
|
3003
|
-
_nextText = cText.substringData(0, offset);
|
|
3004
|
-
}
|
|
3005
|
-
|
|
3006
|
-
const afterNode = dom.utils.createTextNode(_prevText);
|
|
3007
|
-
const textNode = dom.utils.createTextNode(_nextText);
|
|
3008
|
-
|
|
3009
|
-
if (anchorNode) {
|
|
3010
|
-
anchorNode = anchorNode.cloneNode(false);
|
|
3011
|
-
const a = _getMaintainedNode(ancestor);
|
|
3012
|
-
if (a.parentNode !== pNode) {
|
|
3013
|
-
let m = a;
|
|
3014
|
-
let p = null;
|
|
3015
|
-
while (m.parentNode !== pNode) {
|
|
3016
|
-
ancestor = p = m.parentNode.cloneNode(false);
|
|
3017
|
-
while (m.childNodes[0]) {
|
|
3018
|
-
p.appendChild(m.childNodes[0]);
|
|
3019
|
-
}
|
|
3020
|
-
m.appendChild(p);
|
|
3021
|
-
m = m.parentNode;
|
|
3022
|
-
}
|
|
3023
|
-
m.parentNode.insertBefore(a, m.parentNode.firstChild);
|
|
3024
|
-
}
|
|
3025
|
-
anchorNode = anchorNode.cloneNode(false);
|
|
3026
|
-
} else if (_isMaintainedNode(newInnerNode.parentNode) && !anchorNode) {
|
|
3027
|
-
newInnerNode = newInnerNode.cloneNode(false);
|
|
3028
|
-
pNode.appendChild(newInnerNode);
|
|
3029
|
-
nNodeArray.push(newInnerNode);
|
|
3030
|
-
}
|
|
3031
|
-
|
|
3032
|
-
if (!dom.check.isZeroWidth(afterNode)) {
|
|
3033
|
-
ancestor.insertBefore(afterNode, ancestor.firstChild);
|
|
3034
|
-
}
|
|
3035
|
-
|
|
3036
|
-
newNode = ancestor;
|
|
3037
|
-
pCurrent = [];
|
|
3038
|
-
while (newNode !== pNode && newNode !== null) {
|
|
3039
|
-
vNode = _isMaintainedNode(newNode) ? null : validation(newNode);
|
|
3040
|
-
if (vNode && newNode.nodeType === 1) {
|
|
3041
|
-
pCurrent.push(vNode);
|
|
3042
|
-
}
|
|
3043
|
-
newNode = newNode.parentNode;
|
|
3044
|
-
}
|
|
3045
|
-
|
|
3046
|
-
const childNode = pCurrent.pop() || ancestor;
|
|
3047
|
-
appendNode = newNode = childNode;
|
|
3048
|
-
while (pCurrent.length > 0) {
|
|
3049
|
-
newNode = pCurrent.pop();
|
|
3050
|
-
appendNode.appendChild(newNode);
|
|
3051
|
-
appendNode = newNode;
|
|
3052
|
-
}
|
|
3053
|
-
|
|
3054
|
-
if (childNode !== ancestor) {
|
|
3055
|
-
newInnerNode.insertBefore(childNode, newInnerNode.firstChild);
|
|
3056
|
-
ancestor = newNode;
|
|
3057
|
-
} else {
|
|
3058
|
-
ancestor = newInnerNode;
|
|
3059
|
-
}
|
|
3060
|
-
|
|
3061
|
-
if (dom.check.isBreak(child)) newInnerNode.appendChild(child.cloneNode(false));
|
|
3062
|
-
|
|
3063
|
-
if (anchorNode) {
|
|
3064
|
-
anchorNode.insertBefore(newInnerNode, anchorNode.firstChild);
|
|
3065
|
-
pNode.insertBefore(anchorNode, pNode.firstChild);
|
|
3066
|
-
anchorNode = null;
|
|
3067
|
-
} else {
|
|
3068
|
-
pNode.insertBefore(newInnerNode, pNode.firstChild);
|
|
3069
|
-
}
|
|
3070
|
-
|
|
3071
|
-
container = textNode;
|
|
3072
|
-
offset = textNode.data.length;
|
|
3073
|
-
passNode = true;
|
|
3074
|
-
|
|
3075
|
-
ancestor.insertBefore(container, ancestor.firstChild);
|
|
3076
|
-
continue;
|
|
3077
|
-
}
|
|
3078
|
-
|
|
3079
|
-
vNode = !passNode ? child.cloneNode(false) : validation(child);
|
|
3080
|
-
if (vNode) {
|
|
3081
|
-
ancestor.insertBefore(vNode, ancestor.firstChild);
|
|
3082
|
-
if (child.nodeType === 1 && !dom.check.isBreak(child)) coverNode = vNode;
|
|
3083
|
-
}
|
|
3084
|
-
|
|
3085
|
-
recursionFunc(child, coverNode);
|
|
3086
|
-
}
|
|
3087
|
-
})(element, pNode);
|
|
3088
|
-
|
|
3089
|
-
// not remove tag
|
|
3090
|
-
if (isRemoveNode && !isRemoveFormat && !_removeCheck.v) {
|
|
3091
|
-
return {
|
|
3092
|
-
ancestor: element,
|
|
3093
|
-
container: endCon,
|
|
3094
|
-
offset: endOff
|
|
3095
|
-
};
|
|
3096
|
-
}
|
|
3097
|
-
|
|
3098
|
-
isRemoveFormat = isRemoveFormat && isRemoveNode;
|
|
3099
|
-
|
|
3100
|
-
if (isRemoveFormat) {
|
|
3101
|
-
for (let i = 0; i < nNodeArray.length; i++) {
|
|
3102
|
-
const removeNode = nNodeArray[i];
|
|
3103
|
-
|
|
3104
|
-
const rChildren = removeNode.childNodes;
|
|
3105
|
-
let textNode = null;
|
|
3106
|
-
while (rChildren[0]) {
|
|
3107
|
-
textNode = rChildren[0];
|
|
3108
|
-
pNode.insertBefore(textNode, removeNode);
|
|
3109
|
-
}
|
|
3110
|
-
dom.utils.removeItem(removeNode);
|
|
3111
|
-
|
|
3112
|
-
if (i === nNodeArray.length - 1) {
|
|
3113
|
-
container = textNode;
|
|
3114
|
-
offset = textNode.textContent.length;
|
|
3115
|
-
}
|
|
3116
|
-
}
|
|
3117
|
-
} else if (isRemoveNode) {
|
|
3118
|
-
newInnerNode = newInnerNode.firstChild;
|
|
3119
|
-
for (let i = 0; i < nNodeArray.length; i++) {
|
|
3120
|
-
SN_StripRemoveNode(nNodeArray[i]);
|
|
3121
|
-
}
|
|
3122
|
-
}
|
|
3123
|
-
|
|
3124
|
-
if (!isRemoveFormat && pNode.childNodes.length === 0) {
|
|
3125
|
-
if (element.childNodes) {
|
|
3126
|
-
container = element.childNodes[0];
|
|
3127
|
-
} else {
|
|
3128
|
-
container = dom.utils.createTextNode(unicode.zeroWidthSpace);
|
|
3129
|
-
element.appendChild(container);
|
|
3130
|
-
}
|
|
3131
|
-
} else {
|
|
3132
|
-
if (!isRemoveNode && newInnerNode.textContent.length === 0) {
|
|
3133
|
-
this.nodeTransform.removeEmptyNode(pNode, null, false);
|
|
3134
|
-
return {
|
|
3135
|
-
ancestor: null,
|
|
3136
|
-
container: null,
|
|
3137
|
-
offset: 0
|
|
3138
|
-
};
|
|
3139
|
-
}
|
|
3140
|
-
|
|
3141
|
-
this.nodeTransform.removeEmptyNode(pNode, newInnerNode, false);
|
|
3142
|
-
|
|
3143
|
-
if (dom.check.isZeroWidth(pNode.textContent)) {
|
|
3144
|
-
container = pNode.firstChild;
|
|
3145
|
-
offset = container.textContent.length;
|
|
3146
|
-
} else if (dom.check.isZeroWidth(container)) {
|
|
3147
|
-
container = newInnerNode;
|
|
3148
|
-
offset = 1;
|
|
3149
|
-
}
|
|
3150
|
-
|
|
3151
|
-
// node change
|
|
3152
|
-
const offsets = {
|
|
3153
|
-
s: 0,
|
|
3154
|
-
e: 0
|
|
3155
|
-
};
|
|
3156
|
-
const path = dom.query.getNodePath(container, pNode, offsets);
|
|
3157
|
-
offset += offsets.s;
|
|
3158
|
-
|
|
3159
|
-
// tag merge
|
|
3160
|
-
const newOffsets = this.nodeTransform.mergeSameTags(pNode, [path], true);
|
|
3161
|
-
|
|
3162
|
-
element.parentNode.replaceChild(pNode, element);
|
|
3163
|
-
|
|
3164
|
-
container = dom.query.getNodeFromPath(path, pNode);
|
|
3165
|
-
offset += newOffsets[0];
|
|
3166
|
-
}
|
|
3167
|
-
|
|
3168
|
-
return {
|
|
3169
|
-
ancestor: pNode,
|
|
3170
|
-
container: container,
|
|
3171
|
-
offset: container.nodeType === 1 && offset === 1 ? container.childNodes.length : offset
|
|
3172
|
-
};
|
|
3173
|
-
},
|
|
3174
|
-
|
|
3175
|
-
/**
|
|
3176
|
-
* @private
|
|
3177
|
-
* @this {FormatThis}
|
|
3178
|
-
* @description Node with font-size style
|
|
3179
|
-
* @param {Node} element Element to check
|
|
3180
|
-
* @returns {boolean}
|
|
3181
|
-
*/
|
|
3182
|
-
_sn_isSizeNode(element) {
|
|
3183
|
-
return element && typeof element !== 'string' && element.nodeType !== 3 && this.isTextStyleNode(element) && !!element.style.fontSize;
|
|
3184
|
-
},
|
|
3185
|
-
|
|
3186
|
-
/**
|
|
3187
|
-
* @private
|
|
3188
|
-
* @this {FormatThis}
|
|
3189
|
-
* @description Return the parent maintained tag. (bind and use a util object)
|
|
3190
|
-
* @param {boolean} _isRemove is remove anchor
|
|
3191
|
-
* @param {boolean} _isSizeNode is size span node
|
|
3192
|
-
* @param {Node} element Element
|
|
3193
|
-
* @returns {Node|null}
|
|
3194
|
-
*/
|
|
3195
|
-
_sn_getMaintainedNode(_isRemove, _isSizeNode, element) {
|
|
3196
|
-
if (!element || _isRemove) return null;
|
|
3197
|
-
return dom.query.getParentElement(element, this._isNonSplitNode.bind(this)) || (!_isSizeNode ? dom.query.getParentElement(element, this._sn_isSizeNode.bind(this)) : null);
|
|
3198
|
-
},
|
|
3199
|
-
|
|
3200
|
-
/**
|
|
3201
|
-
* @private
|
|
3202
|
-
* @this {FormatThis}
|
|
3203
|
-
* @description Check if element is a tag that should be persisted. (bind and use a util object)
|
|
3204
|
-
* @param {boolean} _isRemove is remove anchor
|
|
3205
|
-
* @param {boolean} _isSizeNode is size span node
|
|
3206
|
-
* @param {Node} element Element
|
|
3207
|
-
* @returns {boolean}
|
|
3208
|
-
*/
|
|
3209
|
-
_sn_isMaintainedNode(_isRemove, _isSizeNode, element) {
|
|
3210
|
-
if (!element || _isRemove || element.nodeType !== 1) return false;
|
|
3211
|
-
const anchor = this._isNonSplitNode(element);
|
|
3212
|
-
return dom.query.getParentElement(element, this._isNonSplitNode.bind(this)) ? anchor : anchor || (!_isSizeNode ? this._sn_isSizeNode(element) : false);
|
|
3213
|
-
},
|
|
3214
|
-
|
|
3215
|
-
/**
|
|
3216
|
-
* @private
|
|
3217
|
-
* @this {FormatThis}
|
|
3218
|
-
* @description If certain styles are applied to all child nodes of the list cell, the style of the list cell is also changed. (bold, color, size)
|
|
3219
|
-
* @param {Node} el List cell element. <li>
|
|
3220
|
-
* @param {?Node} child Variable for recursive call. ("null" on the first call)
|
|
3221
|
-
*/
|
|
3222
|
-
_sn_setCommonListStyle(el, child) {
|
|
3223
|
-
if (!dom.check.isListCell(el)) return;
|
|
3224
|
-
|
|
3225
|
-
const children = dom.utils.arrayFilter((child || el).childNodes, (current) => !dom.check.isBreak(current));
|
|
3226
|
-
child = children[0];
|
|
3227
|
-
|
|
3228
|
-
if (!dom.check.isElement(child) || children.length > 1) return;
|
|
3229
|
-
|
|
3230
|
-
// set cell style---
|
|
3231
|
-
const childStyle = child.style;
|
|
3232
|
-
const elStyle = el.style;
|
|
3233
|
-
const nodeName = child.nodeName.toLowerCase();
|
|
3234
|
-
let appliedEl = false;
|
|
3235
|
-
|
|
3236
|
-
// bold, italic
|
|
3237
|
-
if (this.options.get('_defaultStyleTagMap')[nodeName] === this.options.get('_defaultTagCommand').bold.toLowerCase()) elStyle.fontWeight = 'bold';
|
|
3238
|
-
if (this.options.get('_defaultStyleTagMap')[nodeName] === this.options.get('_defaultTagCommand').italic.toLowerCase()) elStyle.fontStyle = 'italic';
|
|
3239
|
-
|
|
3240
|
-
// styles
|
|
3241
|
-
const cKeys = converter.getValues(childStyle);
|
|
3242
|
-
if (cKeys.length > 0) {
|
|
3243
|
-
for (let i = 0, len = this._listCamel.length; i < len; i++) {
|
|
3244
|
-
if (cKeys.includes(this._listKebab[i])) {
|
|
3245
|
-
elStyle[this._listCamel[i]] = childStyle[this._listCamel[i]];
|
|
3246
|
-
childStyle.removeProperty(this._listKebab[i]);
|
|
3247
|
-
appliedEl = true;
|
|
3248
|
-
}
|
|
3249
|
-
}
|
|
3250
|
-
}
|
|
3251
|
-
|
|
3252
|
-
this._sn_setCommonListStyle(el, child);
|
|
3253
|
-
if (!appliedEl) return;
|
|
3254
|
-
|
|
3255
|
-
// common style
|
|
3256
|
-
if (!childStyle.length) {
|
|
3257
|
-
const ch = child.childNodes;
|
|
3258
|
-
const p = child.parentNode;
|
|
3259
|
-
const n = child.nextSibling;
|
|
3260
|
-
while (ch.length > 0) {
|
|
3261
|
-
p.insertBefore(ch[0], n);
|
|
3262
|
-
}
|
|
3263
|
-
dom.utils.removeItem(child);
|
|
3264
|
-
}
|
|
3265
|
-
},
|
|
3266
|
-
|
|
3267
|
-
/**
|
|
3268
|
-
* @private
|
|
3269
|
-
* @this {FormatThis}
|
|
3270
|
-
* @description Watch the applied text nodes and adjust the common styles of the list.
|
|
3271
|
-
* @param {Node} el "LI" element
|
|
3272
|
-
* @param {Array|null} styleArray Refer style array
|
|
3273
|
-
*/
|
|
3274
|
-
_sn_resetCommonListCell(el, styleArray) {
|
|
3275
|
-
if (!dom.check.isListCell(el)) return;
|
|
3276
|
-
if (!styleArray) styleArray = this._listKebab;
|
|
3277
|
-
|
|
3278
|
-
const children = dom.utils.arrayFilter(el.childNodes, (current) => !dom.check.isBreak(current));
|
|
3279
|
-
const elStyles = el.style;
|
|
3280
|
-
|
|
3281
|
-
const ec = [],
|
|
3282
|
-
ek = [],
|
|
3283
|
-
elKeys = converter.getValues(elStyles);
|
|
3284
|
-
for (let i = 0, len = this._listKebab.length; i < len; i++) {
|
|
3285
|
-
if (elKeys.includes(this._listKebab[i]) && styleArray.includes(this._listKebab[i])) {
|
|
3286
|
-
ec.push(this._listCamel[i]);
|
|
3287
|
-
ek.push(this._listKebab[i]);
|
|
3288
|
-
}
|
|
3289
|
-
}
|
|
3290
|
-
|
|
3291
|
-
if (!ec.length) return;
|
|
3292
|
-
|
|
3293
|
-
// reset cell style---
|
|
3294
|
-
const refer = dom.utils.createElement('SPAN');
|
|
3295
|
-
for (let i = 0, len = ec.length; i < len; i++) {
|
|
3296
|
-
refer.style[ec[i]] = elStyles[ek[i]];
|
|
3297
|
-
elStyles.removeProperty(ek[i]);
|
|
3298
|
-
}
|
|
3299
|
-
|
|
3300
|
-
let sel = refer.cloneNode(false);
|
|
3301
|
-
let r = null,
|
|
3302
|
-
appliedEl = false;
|
|
3303
|
-
for (let i = 0, len = children.length, c, s; i < len; i++) {
|
|
3304
|
-
c = /** @type {HTMLElement} */ (children[i]);
|
|
3305
|
-
if (this.options.get('_defaultStyleTagMap')[c.nodeName.toLowerCase()]) continue;
|
|
3306
|
-
|
|
3307
|
-
s = converter.getValues(c.style);
|
|
3308
|
-
if (
|
|
3309
|
-
s.length === 0 ||
|
|
3310
|
-
(ec.some(function (k) {
|
|
3311
|
-
return !s.includes(k);
|
|
3312
|
-
}) &&
|
|
3313
|
-
s.some(function (k) {
|
|
3314
|
-
ec.includes(k);
|
|
3315
|
-
}))
|
|
3316
|
-
) {
|
|
3317
|
-
r = c.nextSibling;
|
|
3318
|
-
sel.appendChild(c);
|
|
3319
|
-
} else if (sel.childNodes.length > 0) {
|
|
3320
|
-
el.insertBefore(sel, r);
|
|
3321
|
-
sel = refer.cloneNode(false);
|
|
3322
|
-
r = null;
|
|
3323
|
-
appliedEl = true;
|
|
3324
|
-
}
|
|
3325
|
-
}
|
|
3326
|
-
|
|
3327
|
-
if (sel.childNodes.length > 0) {
|
|
3328
|
-
el.insertBefore(sel, r);
|
|
3329
|
-
appliedEl = true;
|
|
3330
|
-
}
|
|
3331
|
-
if (!elStyles.length) {
|
|
3332
|
-
el.removeAttribute('style');
|
|
3333
|
-
}
|
|
3334
|
-
|
|
3335
|
-
return appliedEl;
|
|
3336
|
-
},
|
|
3337
|
-
|
|
3338
|
-
/**
|
|
3339
|
-
* @private
|
|
3340
|
-
* @this {FormatThis}
|
|
3341
|
-
* @description Reset the line break format.
|
|
3342
|
-
* @param {"line"|"br"} breakFormat options.get('defaultLineBreakFormat')
|
|
3343
|
-
*/
|
|
3344
|
-
__resetBrLineBreak(breakFormat) {
|
|
3345
|
-
this._brLineBreak = breakFormat === 'br';
|
|
3346
|
-
},
|
|
3347
|
-
|
|
3348
|
-
constructor: Format
|
|
3349
|
-
};
|
|
3350
|
-
|
|
3351
|
-
/**
|
|
3352
|
-
* @private
|
|
3353
|
-
* @param {Node} baseNode Node
|
|
3354
|
-
*/
|
|
3355
|
-
function DeleteNestedList(baseNode) {
|
|
3356
|
-
const baseParent = baseNode.parentNode;
|
|
3357
|
-
let parent = baseParent.parentNode;
|
|
3358
|
-
let siblingNode = /** @type {*} */ (baseParent);
|
|
3359
|
-
let liSibling, liParent, child, index, c;
|
|
3360
|
-
|
|
3361
|
-
while (dom.check.isListCell(parent)) {
|
|
3362
|
-
index = dom.query.getPositionIndex(baseNode);
|
|
3363
|
-
liSibling = parent.nextElementSibling;
|
|
3364
|
-
liParent = parent.parentNode;
|
|
3365
|
-
child = siblingNode;
|
|
3366
|
-
|
|
3367
|
-
while (child) {
|
|
3368
|
-
siblingNode = siblingNode.nextSibling;
|
|
3369
|
-
if (dom.check.isList(child)) {
|
|
3370
|
-
c = child.childNodes;
|
|
3371
|
-
while (c[index]) {
|
|
3372
|
-
liParent.insertBefore(c[index], liSibling);
|
|
3373
|
-
}
|
|
3374
|
-
if (c.length === 0) dom.utils.removeItem(child);
|
|
3375
|
-
} else {
|
|
3376
|
-
liParent.appendChild(child);
|
|
3377
|
-
}
|
|
3378
|
-
child = siblingNode;
|
|
3379
|
-
}
|
|
3380
|
-
|
|
3381
|
-
parent = liParent.parentNode;
|
|
3382
|
-
}
|
|
3383
|
-
|
|
3384
|
-
if (baseParent.children.length === 0) dom.utils.removeItem(baseParent);
|
|
3385
|
-
|
|
3386
|
-
return liParent;
|
|
3387
|
-
}
|
|
3388
|
-
|
|
3389
|
-
/**
|
|
3390
|
-
* @private
|
|
3391
|
-
* @param {Array<HTMLElement>} lines - Line elements
|
|
3392
|
-
* @param {number} size - Margin size
|
|
3393
|
-
* @param {string} dir - Direction
|
|
3394
|
-
* @returns
|
|
3395
|
-
*/
|
|
3396
|
-
function SetLineMargin(lines, size, dir) {
|
|
3397
|
-
const cells = [];
|
|
1043
|
+
/**
|
|
1044
|
+
* @private
|
|
1045
|
+
* @param {Array<HTMLElement>} lines - Line elements
|
|
1046
|
+
* @param {number} size - Margin size
|
|
1047
|
+
* @param {string} dir - Direction
|
|
1048
|
+
* @returns
|
|
1049
|
+
*/
|
|
1050
|
+
function SetLineMargin(lines, size, dir) {
|
|
1051
|
+
const cells = [];
|
|
3398
1052
|
|
|
3399
1053
|
for (let i = 0, len = lines.length, f, margin; i < len; i++) {
|
|
3400
1054
|
f = lines[i];
|
|
@@ -3412,22 +1066,4 @@ function SetLineMargin(lines, size, dir) {
|
|
|
3412
1066
|
return cells;
|
|
3413
1067
|
}
|
|
3414
1068
|
|
|
3415
|
-
/**
|
|
3416
|
-
* @private
|
|
3417
|
-
* @description Strip remove node
|
|
3418
|
-
* @param {Node} removeNode The remove node
|
|
3419
|
-
* @private
|
|
3420
|
-
*/
|
|
3421
|
-
function SN_StripRemoveNode(removeNode) {
|
|
3422
|
-
const element = removeNode.parentNode;
|
|
3423
|
-
if (!removeNode || removeNode.nodeType === 3 || !element) return;
|
|
3424
|
-
|
|
3425
|
-
const children = removeNode.childNodes;
|
|
3426
|
-
while (children[0]) {
|
|
3427
|
-
element.insertBefore(children[0], removeNode);
|
|
3428
|
-
}
|
|
3429
|
-
|
|
3430
|
-
element.removeChild(removeNode);
|
|
3431
|
-
}
|
|
3432
|
-
|
|
3433
1069
|
export default Format;
|