suneditor 3.1.4 → 3.2.1
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/dist/suneditor-contents.min.css +1 -1
- package/dist/suneditor.min.css +28 -1
- package/dist/suneditor.min.js +1 -1
- package/package.json +2 -1
- package/src/assets/design/color.css +12 -0
- package/src/assets/design/size.css +9 -2
- package/src/assets/icons/defaultIcons.js +96 -47
- package/src/assets/suneditor-contents.css +3 -2
- package/src/assets/suneditor.css +481 -31
- package/src/core/config/contextProvider.js +2 -1
- package/src/core/config/eventManager.js +41 -2
- package/src/core/config/optionProvider.js +23 -2
- package/src/core/editor.js +32 -14
- package/src/core/event/actions/index.js +76 -9
- package/src/core/event/effects/common.registry.js +2 -1
- package/src/core/event/effects/keydown.registry.js +169 -33
- package/src/core/event/effects/ruleHelpers.js +20 -6
- package/src/core/event/eventOrchestrator.js +162 -30
- package/src/core/event/handlers/handler_toolbar.js +4 -2
- package/src/core/event/handlers/handler_ww_dragDrop.js +10 -0
- package/src/core/event/handlers/handler_ww_input.js +84 -2
- package/src/core/event/handlers/handler_ww_key.js +82 -21
- package/src/core/event/handlers/handler_ww_mouse.js +45 -8
- package/src/core/event/ports.js +27 -13
- package/src/core/event/reducers/keydown.reducer.js +33 -5
- package/src/core/event/rules/keydown.rule.arrow.js +12 -2
- package/src/core/event/rules/keydown.rule.backspace.js +110 -15
- package/src/core/event/rules/keydown.rule.delete.js +62 -7
- package/src/core/event/rules/keydown.rule.enter.js +62 -31
- package/src/core/event/support/defaultLineManager.js +9 -2
- package/src/core/event/support/selectionState.js +13 -3
- package/src/core/kernel/coreKernel.js +1 -0
- package/src/core/logic/dom/char.js +13 -3
- package/src/core/logic/dom/format.js +171 -39
- package/src/core/logic/dom/html.js +350 -72
- package/src/core/logic/dom/inline.js +229 -34
- package/src/core/logic/dom/listFormat.js +111 -20
- package/src/core/logic/dom/nodeTransform.js +36 -11
- package/src/core/logic/dom/offset.js +116 -31
- package/src/core/logic/dom/selection.js +147 -29
- package/src/core/logic/panel/blockHandle.js +785 -0
- package/src/core/logic/panel/blockResolver.js +278 -0
- package/src/core/logic/panel/finder.js +16 -6
- package/src/core/logic/panel/menu.js +119 -18
- package/src/core/logic/panel/toolbar.js +75 -19
- package/src/core/logic/panel/viewer.js +76 -20
- package/src/core/logic/shell/_commandExecutor.js +44 -9
- package/src/core/logic/shell/commandDispatcher.js +46 -4
- package/src/core/logic/shell/component.js +102 -25
- package/src/core/logic/shell/focusManager.js +13 -3
- package/src/core/logic/shell/history.js +21 -6
- package/src/core/logic/shell/pluginManager.js +21 -13
- package/src/core/logic/shell/shortcuts.js +9 -1
- package/src/core/logic/shell/ui.js +139 -37
- package/src/core/schema/frameContext.js +34 -3
- package/src/core/schema/options.js +46 -4
- package/src/core/section/constructor.js +537 -106
- package/src/core/section/documentType.js +35 -6
- package/src/helper/converter.js +24 -7
- package/src/helper/dom/domCheck.js +25 -5
- package/src/helper/dom/domQuery.js +2 -1
- package/src/helper/dom/domUtils.js +17 -4
- package/src/helper/env.js +11 -2
- package/src/helper/keyCodeMap.js +6 -2
- package/src/helper/markdown.js +24 -5
- package/src/helper/msOffice.js +9 -2
- package/src/interfaces/plugins.js +1 -1
- package/src/langs/ckb.js +0 -1
- package/src/langs/cs.js +0 -1
- package/src/langs/da.js +0 -1
- package/src/langs/de.js +0 -1
- package/src/langs/en.js +0 -1
- package/src/langs/es.js +0 -1
- package/src/langs/fa.js +0 -1
- package/src/langs/fr.js +0 -1
- package/src/langs/he.js +0 -1
- package/src/langs/hu.js +0 -1
- package/src/langs/index.js +27 -1
- package/src/langs/it.js +0 -1
- package/src/langs/ja.js +0 -1
- package/src/langs/km.js +0 -1
- package/src/langs/ko.js +0 -1
- package/src/langs/lv.js +0 -1
- package/src/langs/nl.js +0 -1
- package/src/langs/pl.js +0 -1
- package/src/langs/pt_br.js +0 -1
- package/src/langs/ro.js +0 -1
- package/src/langs/ru.js +0 -1
- package/src/langs/se.js +0 -1
- package/src/langs/tr.js +0 -1
- package/src/langs/uk.js +0 -1
- package/src/langs/ur.js +0 -1
- package/src/langs/zh_cn.js +0 -1
- package/src/modules/contract/Browser.js +58 -14
- package/src/modules/contract/ColorPicker.js +12 -4
- package/src/modules/contract/Controller.js +37 -7
- package/src/modules/contract/Figure.js +156 -36
- package/src/modules/contract/HueSlider.js +27 -4
- package/src/modules/contract/Modal.js +50 -10
- package/src/modules/manager/FileManager.js +50 -8
- package/src/modules/ui/CommandMenu.js +597 -0
- package/src/modules/ui/ModalAnchorEditor.js +33 -6
- package/src/modules/ui/SelectMenu.js +481 -36
- package/src/modules/ui/index.js +1 -0
- package/src/plugins/browser/audioGallery.js +2 -1
- package/src/plugins/browser/fileBrowser.js +9 -2
- package/src/plugins/browser/fileGallery.js +2 -1
- package/src/plugins/browser/imageGallery.js +18 -3
- package/src/plugins/browser/videoGallery.js +13 -4
- package/src/plugins/command/blockquote.js +6 -1
- package/src/plugins/command/codeBlock.js +43 -5
- package/src/plugins/command/exportPDF.js +20 -4
- package/src/plugins/command/fileUpload.js +46 -11
- package/src/plugins/command/list_bulleted.js +6 -1
- package/src/plugins/command/list_numbered.js +6 -1
- package/src/plugins/dropdown/align.js +21 -33
- package/src/plugins/dropdown/backgroundColor.js +10 -2
- package/src/plugins/dropdown/blockStyle.js +17 -22
- package/src/plugins/dropdown/font.js +34 -34
- package/src/plugins/dropdown/hr.js +15 -43
- package/src/plugins/dropdown/layout.js +10 -27
- package/src/plugins/dropdown/lineHeight.js +10 -33
- package/src/plugins/dropdown/list.js +19 -25
- package/src/plugins/dropdown/paragraphStyle.js +16 -24
- package/src/plugins/dropdown/table/index.js +72 -17
- package/src/plugins/dropdown/table/render/table.html.js +3 -1
- package/src/plugins/dropdown/table/services/table.cell.js +33 -7
- package/src/plugins/dropdown/table/services/table.clipboard.js +5 -1
- package/src/plugins/dropdown/table/services/table.grid.js +40 -9
- package/src/plugins/dropdown/table/services/table.resize.js +55 -11
- package/src/plugins/dropdown/table/services/table.selection.js +27 -7
- package/src/plugins/dropdown/table/services/table.style.js +120 -20
- package/src/plugins/dropdown/template.js +13 -29
- package/src/plugins/dropdown/textStyle.js +22 -35
- package/src/plugins/field/autocomplete.js +8 -4
- package/src/plugins/field/slashCommand.js +297 -0
- package/src/plugins/index.js +3 -0
- package/src/plugins/input/fontSize.js +37 -8
- package/src/plugins/input/pageNavigator.js +7 -1
- package/src/plugins/modal/audio.js +71 -17
- package/src/plugins/modal/drawing.js +41 -11
- package/src/plugins/modal/embed.js +92 -22
- package/src/plugins/modal/image/index.js +114 -28
- package/src/plugins/modal/image/services/image.size.js +9 -2
- package/src/plugins/modal/image/services/image.upload.js +38 -4
- package/src/plugins/modal/link.js +9 -2
- package/src/plugins/modal/math.js +10 -2
- package/src/plugins/modal/video/index.js +112 -26
- package/src/plugins/modal/video/render/video.html.js +4 -1
- package/src/plugins/modal/video/services/video.size.js +15 -4
- package/src/plugins/modal/video/services/video.upload.js +10 -2
- package/src/plugins/popup/anchor.js +14 -2
- package/src/suneditor.js +8 -2
- package/src/themes/cobalt.css +12 -0
- package/src/themes/cream.css +12 -0
- package/src/themes/dark.css +12 -0
- package/src/themes/midnight.css +12 -0
- package/src/typedef.js +32 -21
- package/types/assets/icons/defaultIcons.d.ts +1 -0
- package/types/core/config/contextProvider.d.ts +7 -1
- package/types/core/config/eventManager.d.ts +37 -4
- package/types/core/config/optionProvider.d.ts +5 -1
- package/types/core/event/actions/index.d.ts +44 -6
- package/types/core/event/effects/keydown.registry.d.ts +37 -7
- package/types/core/event/effects/ruleHelpers.d.ts +6 -1
- package/types/core/event/eventOrchestrator.d.ts +13 -3
- package/types/core/event/handlers/handler_ww_clipboard.d.ts +15 -3
- package/types/core/event/handlers/handler_ww_dragDrop.d.ts +14 -2
- package/types/core/event/handlers/handler_ww_input.d.ts +10 -2
- package/types/core/event/handlers/handler_ww_key.d.ts +10 -2
- package/types/core/event/handlers/handler_ww_mouse.d.ts +25 -5
- package/types/core/event/ports.d.ts +11 -4
- package/types/core/event/reducers/keydown.reducer.d.ts +12 -3
- package/types/core/event/rules/keydown.rule.backspace.d.ts +6 -1
- package/types/core/kernel/store.d.ts +4 -1
- package/types/core/logic/dom/format.d.ts +32 -14
- package/types/core/logic/dom/html.d.ts +11 -3
- package/types/core/logic/dom/nodeTransform.d.ts +6 -6
- package/types/core/logic/panel/blockHandle.d.ts +64 -0
- package/types/core/logic/panel/blockResolver.d.ts +50 -0
- package/types/core/logic/panel/menu.d.ts +72 -3
- package/types/core/logic/shell/commandDispatcher.d.ts +8 -0
- package/types/core/logic/shell/component.d.ts +5 -3
- package/types/core/logic/shell/shortcuts.d.ts +10 -1
- package/types/core/logic/shell/ui.d.ts +7 -1
- package/types/core/schema/context.d.ts +7 -1
- package/types/core/schema/frameContext.d.ts +36 -4
- package/types/core/schema/options.d.ts +83 -2
- package/types/core/section/constructor.d.ts +38 -1
- package/types/events.d.ts +208 -32
- package/types/helper/converter.d.ts +4 -2
- package/types/helper/dom/domCheck.d.ts +12 -2
- package/types/helper/dom/domQuery.d.ts +35 -7
- package/types/helper/dom/domUtils.d.ts +4 -1
- package/types/interfaces/plugins.d.ts +2 -2
- package/types/langs/_Lang.d.ts +0 -1
- package/types/modules/contract/ColorPicker.d.ts +2 -2
- package/types/modules/contract/Controller.d.ts +7 -0
- package/types/modules/contract/Figure.d.ts +31 -4
- package/types/modules/ui/CommandMenu.d.ts +262 -0
- package/types/modules/ui/SelectMenu.d.ts +56 -3
- package/types/modules/ui/index.d.ts +1 -0
- package/types/plugins/browser/audioGallery.d.ts +1 -1
- package/types/plugins/browser/fileBrowser.d.ts +1 -1
- package/types/plugins/browser/fileGallery.d.ts +1 -1
- package/types/plugins/browser/imageGallery.d.ts +1 -1
- package/types/plugins/browser/videoGallery.d.ts +1 -1
- package/types/plugins/dropdown/align.d.ts +1 -1
- package/types/plugins/dropdown/blockStyle.d.ts +3 -1
- package/types/plugins/dropdown/table/index.d.ts +4 -1
- package/types/plugins/dropdown/table/services/table.clipboard.d.ts +5 -1
- package/types/plugins/dropdown/table/services/table.grid.d.ts +10 -2
- package/types/plugins/field/autocomplete.d.ts +0 -1
- package/types/plugins/field/slashCommand.d.ts +165 -0
- package/types/plugins/index.d.ts +3 -0
- package/types/plugins/modal/link.d.ts +4 -1
- package/types/typedef.d.ts +48 -23
|
@@ -83,7 +83,10 @@ class Selection_ {
|
|
|
83
83
|
getRange() {
|
|
84
84
|
const range = this.#store.get('_range') || this.#createDefaultRange();
|
|
85
85
|
const selection = this.get();
|
|
86
|
-
if (
|
|
86
|
+
if (
|
|
87
|
+
range.collapsed === selection.isCollapsed ||
|
|
88
|
+
!this.#frameContext.get('wysiwyg').contains(selection.focusNode)
|
|
89
|
+
) {
|
|
87
90
|
if (this.#$.component.is(range.startContainer)) {
|
|
88
91
|
const compInfo = this.#$.component.get(range.startContainer);
|
|
89
92
|
const container = compInfo?.container;
|
|
@@ -104,7 +107,9 @@ class Selection_ {
|
|
|
104
107
|
so = selection.anchorOffset,
|
|
105
108
|
eo = selection.focusOffset;
|
|
106
109
|
const compareValue = dom.query.compareElements(sc, ec);
|
|
107
|
-
const rightDir =
|
|
110
|
+
const rightDir =
|
|
111
|
+
compareValue.ancestor &&
|
|
112
|
+
(compareValue.result === 0 ? so <= eo : compareValue.result > 1 ? true : false);
|
|
108
113
|
return this.setRange(rightDir ? sc : ec, rightDir ? so : eo, rightDir ? ec : sc, rightDir ? eo : so);
|
|
109
114
|
}
|
|
110
115
|
}
|
|
@@ -157,18 +162,35 @@ class Selection_ {
|
|
|
157
162
|
if ((dom.check.isBreak(ec) || ec.nodeType === 3) && eo > ec.textContent.length) eo = ec.textContent.length;
|
|
158
163
|
if (this.#$.format.isLine(sc)) {
|
|
159
164
|
sc = sc.childNodes[so > 0 ? sc.childNodes.length - 1 : 0] || sc;
|
|
160
|
-
so =
|
|
165
|
+
so =
|
|
166
|
+
so > 0
|
|
167
|
+
? sc.nodeType === 1 && !dom.check.isBreak(sc)
|
|
168
|
+
? 1
|
|
169
|
+
: sc.textContent
|
|
170
|
+
? sc.textContent.length
|
|
171
|
+
: 0
|
|
172
|
+
: 0;
|
|
161
173
|
}
|
|
162
174
|
if (this.#$.format.isLine(ec)) {
|
|
163
175
|
ec = ec.childNodes[eo > 0 ? ec.childNodes.length - 1 : 0] || ec;
|
|
164
|
-
eo =
|
|
176
|
+
eo =
|
|
177
|
+
eo > 0
|
|
178
|
+
? ec.nodeType === 1 && !dom.check.isBreak(ec)
|
|
179
|
+
? 1
|
|
180
|
+
: ec.textContent
|
|
181
|
+
? ec.textContent.length
|
|
182
|
+
: 0
|
|
183
|
+
: 0;
|
|
165
184
|
}
|
|
166
185
|
|
|
167
186
|
const range = this.#frameContext.get('_wd').createRange();
|
|
168
187
|
|
|
169
188
|
try {
|
|
170
189
|
so = Math.min(so, sc.textContent?.length || 0);
|
|
171
|
-
eo =
|
|
190
|
+
eo =
|
|
191
|
+
eo > 0 && (ec.textContent?.length || 0) === 0 && ec.nodeType === 1
|
|
192
|
+
? 1
|
|
193
|
+
: Math.min(Math.max(eo, 0), ec.textContent?.length || 0);
|
|
172
194
|
range.setStart(sc, so);
|
|
173
195
|
range.setEnd(ec, eo);
|
|
174
196
|
this.#store.set('hasFocus', true);
|
|
@@ -242,7 +264,14 @@ class Selection_ {
|
|
|
242
264
|
if (this.#isNone(range)) {
|
|
243
265
|
const parent = container?.parentElement || this.#frameContext.get('wysiwyg');
|
|
244
266
|
const op = dom.utils.createElement(this.#options.get('defaultLine'), null, '<br>');
|
|
245
|
-
parent.insertBefore(
|
|
267
|
+
parent.insertBefore(
|
|
268
|
+
op,
|
|
269
|
+
container && container !== parent
|
|
270
|
+
? !(/** @type {HTMLElement} */ (container).previousElementSibling)
|
|
271
|
+
? container
|
|
272
|
+
: /** @type {HTMLElement} */ (container).nextElementSibling
|
|
273
|
+
: parent.firstElementChild,
|
|
274
|
+
);
|
|
246
275
|
this.setRange(op.firstElementChild, 0, op.firstElementChild, 1);
|
|
247
276
|
range = this.#store.get('_range');
|
|
248
277
|
}
|
|
@@ -259,7 +288,13 @@ class Selection_ {
|
|
|
259
288
|
getNode() {
|
|
260
289
|
if (!this.#frameContext.get('wysiwyg').contains(this.selectionNode)) this.init();
|
|
261
290
|
if (!this.selectionNode) {
|
|
262
|
-
const selectionNode = /** @type {HTMLElement|Text} */ (
|
|
291
|
+
const selectionNode = /** @type {HTMLElement|Text} */ (
|
|
292
|
+
dom.query.getEdgeChild(
|
|
293
|
+
this.#frameContext.get('wysiwyg').firstChild,
|
|
294
|
+
(current) => current.childNodes.length === 0 || current.nodeType === 3,
|
|
295
|
+
false,
|
|
296
|
+
)
|
|
297
|
+
);
|
|
263
298
|
if (!selectionNode) {
|
|
264
299
|
this.init();
|
|
265
300
|
} else {
|
|
@@ -290,8 +325,12 @@ class Selection_ {
|
|
|
290
325
|
* tooltip.style.top = rects.top + 'px';
|
|
291
326
|
*/
|
|
292
327
|
getRects(target, position) {
|
|
293
|
-
const targetAbs = dom.check.isElement(/** @type {Node} */ (target))
|
|
294
|
-
|
|
328
|
+
const targetAbs = dom.check.isElement(/** @type {Node} */ (target))
|
|
329
|
+
? _w.getComputedStyle(target).position === 'absolute'
|
|
330
|
+
: false;
|
|
331
|
+
target = /** @type {Range} */ (
|
|
332
|
+
!target || dom.check.isText(/** @type {Node} */ (target)) ? this.getRange() : target
|
|
333
|
+
);
|
|
295
334
|
let isStartPosition = position === 'start';
|
|
296
335
|
let scrollLeft = _w.scrollX;
|
|
297
336
|
let scrollTop = _w.scrollY;
|
|
@@ -326,7 +365,9 @@ class Selection_ {
|
|
|
326
365
|
isStartPosition = true;
|
|
327
366
|
}
|
|
328
367
|
|
|
329
|
-
const iframeRects = /^iframe$/i.test(this.#frameContext.get('wysiwygFrame').nodeName)
|
|
368
|
+
const iframeRects = /^iframe$/i.test(this.#frameContext.get('wysiwygFrame').nodeName)
|
|
369
|
+
? this.#frameContext.get('wysiwygFrame').getClientRects()[0]
|
|
370
|
+
: null;
|
|
330
371
|
if (!targetAbs && iframeRects) {
|
|
331
372
|
rects = {
|
|
332
373
|
left: rects.left + iframeRects.left,
|
|
@@ -407,7 +448,10 @@ class Selection_ {
|
|
|
407
448
|
ref = this.setRange(ref, 1, ref, 1);
|
|
408
449
|
}
|
|
409
450
|
} else if (typeof ref?.startContainer === 'undefined') {
|
|
410
|
-
console.warn(
|
|
451
|
+
console.warn(
|
|
452
|
+
'[SUNEDITOR.html.scrollTo.warn] "selectionRange" must be Selection or Range or Node object.',
|
|
453
|
+
ref,
|
|
454
|
+
);
|
|
411
455
|
}
|
|
412
456
|
|
|
413
457
|
const el = dom.query.getParentElement(ref?.startContainer, (current) => current.nodeType === 1);
|
|
@@ -425,11 +469,18 @@ class Selection_ {
|
|
|
425
469
|
const isBottom = this.#store.mode.isBottom;
|
|
426
470
|
const realToolbarHeight = this.#context.get('toolbar_main').offsetHeight;
|
|
427
471
|
const toolbarHeight = this.#$.toolbar.isSticky ? realToolbarHeight : 0;
|
|
428
|
-
const positionToolbarHeight = this.#$.toolbar.isSticky
|
|
472
|
+
const positionToolbarHeight = this.#$.toolbar.isSticky
|
|
473
|
+
? toolbarHeight + this.#options.get('_toolbar_sticky')
|
|
474
|
+
: toolbarHeight;
|
|
429
475
|
const statusbarHeight = this.#frameContext.get('statusbar')?.offsetHeight || 0;
|
|
430
476
|
|
|
431
477
|
if (this.#hasScrollParents) {
|
|
432
|
-
el?.
|
|
478
|
+
const caretRect = this.#$.format.isBrLine(el) ? ref?.getBoundingClientRect?.() : null;
|
|
479
|
+
if (caretRect?.height > 0) {
|
|
480
|
+
this.#scrollCaretIntoView(caretRect, scrollOption.behavior);
|
|
481
|
+
} else {
|
|
482
|
+
el?.scrollIntoView(scrollOption);
|
|
483
|
+
}
|
|
433
484
|
|
|
434
485
|
if (scrollOption?.behavior === 'auto' && scrollY !== _w.scrollY) {
|
|
435
486
|
if (positionToolbarHeight) {
|
|
@@ -455,7 +506,9 @@ class Selection_ {
|
|
|
455
506
|
// --- When there is no upper scroll and it is an iframe ---
|
|
456
507
|
const PADDING = this.#scrollMargin;
|
|
457
508
|
// Reduce effective viewport height by toolbar+offset when bottom toolbar is sticky
|
|
458
|
-
const viewHeight = isAutoHeight
|
|
509
|
+
const viewHeight = isAutoHeight
|
|
510
|
+
? viewportHeight - (isBottom ? positionToolbarHeight : 0)
|
|
511
|
+
: wwFrame.offsetHeight;
|
|
459
512
|
|
|
460
513
|
// Use range rect for accurate height — el.offsetHeight includes nested children (e.g. nested lists)
|
|
461
514
|
const refRect = ref?.getBoundingClientRect?.();
|
|
@@ -476,12 +529,15 @@ class Selection_ {
|
|
|
476
529
|
behavior,
|
|
477
530
|
});
|
|
478
531
|
} else {
|
|
479
|
-
const
|
|
480
|
-
const scrollMargin = viewHeight + scrollY -
|
|
532
|
+
const rectTop = refRect?.height > 0 ? refRect.top + scrollY : this.#$.offset.getGlobal(el).top;
|
|
533
|
+
const scrollMargin = viewHeight + scrollY - rectTop - elH;
|
|
481
534
|
|
|
482
535
|
if (scrollMargin - PADDING > 0 && viewHeight > scrollMargin + PADDING + topToolbarH) return;
|
|
483
536
|
|
|
484
|
-
const newScrollTop =
|
|
537
|
+
const newScrollTop =
|
|
538
|
+
scrollMargin <= PADDING
|
|
539
|
+
? scrollY - scrollMargin + PADDING + statusbarHeight
|
|
540
|
+
: scrollY - scrollMargin + (viewHeight - elH - PADDING);
|
|
485
541
|
_w.scrollTo({
|
|
486
542
|
top: newScrollTop < scrollY ? newScrollTop - topToolbarH : newScrollTop,
|
|
487
543
|
behavior,
|
|
@@ -493,8 +549,15 @@ class Selection_ {
|
|
|
493
549
|
const targetTop = hasRefRect ? refRect.top : el.getBoundingClientRect().top;
|
|
494
550
|
const innerTop = isIframe ? targetTop : targetTop - wwFrame.getBoundingClientRect().top;
|
|
495
551
|
|
|
496
|
-
const
|
|
497
|
-
const
|
|
552
|
+
const topSafe = isBottom ? 0 : toolbarHeight;
|
|
553
|
+
const keepLocalScroll = innerTop >= topSafe && innerTop + PADDING <= viewHeight;
|
|
554
|
+
const rectScroll = isBottom
|
|
555
|
+
? innerTop - PADDING > 0
|
|
556
|
+
? innerTop + PADDING - viewHeight + toolbarHeight
|
|
557
|
+
: innerTop - elH
|
|
558
|
+
: innerTop - PADDING > 0
|
|
559
|
+
? innerTop + PADDING - viewHeight
|
|
560
|
+
: innerTop - (toolbarHeight + elH);
|
|
498
561
|
let newScrollTop = scrollY + rectScroll;
|
|
499
562
|
|
|
500
563
|
// frame scroll
|
|
@@ -507,7 +570,8 @@ class Selection_ {
|
|
|
507
570
|
|
|
508
571
|
// set frame scroll
|
|
509
572
|
if (topMargin > 0) {
|
|
510
|
-
const newFrameY =
|
|
573
|
+
const newFrameY =
|
|
574
|
+
(keepLocalScroll ? innerTop : innerTop + scrollY - newScrollTop) - elH - PADDING - topMargin;
|
|
511
575
|
if (newFrameY < 0) {
|
|
512
576
|
newScrollTop += topToolbarFrame;
|
|
513
577
|
_w.scrollTo({
|
|
@@ -517,7 +581,11 @@ class Selection_ {
|
|
|
517
581
|
}
|
|
518
582
|
}
|
|
519
583
|
if (bottomMargin > 0) {
|
|
520
|
-
const newFrameY =
|
|
584
|
+
const newFrameY =
|
|
585
|
+
(keepLocalScroll ? innerTop : innerTop + scrollY - newScrollTop) +
|
|
586
|
+
elH +
|
|
587
|
+
PADDING -
|
|
588
|
+
(globalRect.height - bottomMargin);
|
|
521
589
|
if (newFrameY > 0) {
|
|
522
590
|
newScrollTop += isBottom ? bottomToolbarFrame : statusbarHeight;
|
|
523
591
|
_w.scrollTo({
|
|
@@ -537,6 +605,34 @@ class Selection_ {
|
|
|
537
605
|
}
|
|
538
606
|
}
|
|
539
607
|
|
|
608
|
+
/**
|
|
609
|
+
* @description Scroll the caret rect into view across all scroll-parents (and the window), non-destructively.
|
|
610
|
+
* @param {DOMRect} caretRect Caret rect in viewport coordinates (`range.getBoundingClientRect()`).
|
|
611
|
+
* @param {ScrollBehavior} [behavior] Scroll behavior.
|
|
612
|
+
*/
|
|
613
|
+
#scrollCaretIntoView(caretRect, behavior) {
|
|
614
|
+
let { top, bottom } = caretRect;
|
|
615
|
+
const containers = [...(this.#kernel._eventOrchestrator.scrollparents || []), _w];
|
|
616
|
+
|
|
617
|
+
for (const container of containers) {
|
|
618
|
+
const isWindow = container === _w;
|
|
619
|
+
const viewTop = isWindow ? 0 : /** @type {HTMLElement} */ (container).getBoundingClientRect().top;
|
|
620
|
+
const viewBottom = isWindow
|
|
621
|
+
? this.#store.get('currentViewportHeight')
|
|
622
|
+
: /** @type {HTMLElement} */ (container).getBoundingClientRect().bottom;
|
|
623
|
+
|
|
624
|
+
let delta = 0;
|
|
625
|
+
if (top < viewTop) delta = top - viewTop;
|
|
626
|
+
else if (bottom > viewBottom) delta = bottom - viewBottom;
|
|
627
|
+
if (delta === 0) continue;
|
|
628
|
+
|
|
629
|
+
container.scrollBy({ top: delta, behavior });
|
|
630
|
+
|
|
631
|
+
top -= delta;
|
|
632
|
+
bottom -= delta;
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
|
|
540
636
|
/**
|
|
541
637
|
* @description Normalizes and resets the selection range to properly target text nodes instead of element nodes for accurate text editing.
|
|
542
638
|
* @returns {boolean} Returns `false` if there is no valid selection.
|
|
@@ -544,7 +640,8 @@ class Selection_ {
|
|
|
544
640
|
resetRangeToTextNode() {
|
|
545
641
|
let rangeObj = this.getRange();
|
|
546
642
|
if (this.#isNone(rangeObj)) {
|
|
547
|
-
if (!dom.check.isWysiwygFrame(rangeObj.startContainer) || !dom.check.isWysiwygFrame(rangeObj.endContainer))
|
|
643
|
+
if (!dom.check.isWysiwygFrame(rangeObj.startContainer) || !dom.check.isWysiwygFrame(rangeObj.endContainer))
|
|
644
|
+
return false;
|
|
548
645
|
const ww = /** @type {HTMLElement} */ (rangeObj.commonAncestorContainer);
|
|
549
646
|
const first = ww.children[rangeObj.startOffset];
|
|
550
647
|
const end = ww.children[rangeObj.endOffset];
|
|
@@ -593,14 +690,23 @@ class Selection_ {
|
|
|
593
690
|
tempChild = tempCon.childNodes;
|
|
594
691
|
if (tempChild.length === 0) break;
|
|
595
692
|
tempCon =
|
|
596
|
-
tempChild[tempOffset > 0 ? tempOffset - 1 : tempOffset] ||
|
|
693
|
+
tempChild[tempOffset > 0 ? tempOffset - 1 : tempOffset] ||
|
|
694
|
+
!/FIGURE/i.test(tempChild[0].nodeName)
|
|
695
|
+
? tempChild[0]
|
|
696
|
+
: /** @type {HTMLElement} */ (tempCon).previousElementSibling ||
|
|
697
|
+
tempCon.previousSibling ||
|
|
698
|
+
startCon;
|
|
597
699
|
tempOffset = tempOffset > 0 ? tempCon.textContent.length : tempOffset;
|
|
598
700
|
}
|
|
599
701
|
|
|
600
702
|
let format = this.#$.format.getLine(tempCon, null);
|
|
601
703
|
if (format === this.#$.format.getBlock(format, null)) {
|
|
602
704
|
tempCon ||= tempConCache;
|
|
603
|
-
format = dom.utils.createElement(
|
|
705
|
+
format = dom.utils.createElement(
|
|
706
|
+
dom.query.getParentElement(tempCon, dom.check.isTableCell)
|
|
707
|
+
? 'DIV'
|
|
708
|
+
: this.#options.get('defaultLine'),
|
|
709
|
+
);
|
|
604
710
|
tempCon.parentNode.insertBefore(format, tempCon);
|
|
605
711
|
if (tempCon !== tempConCache) format.appendChild(tempCon);
|
|
606
712
|
}
|
|
@@ -634,13 +740,20 @@ class Selection_ {
|
|
|
634
740
|
tempChild = tempCon.childNodes;
|
|
635
741
|
if (tempChild.length === 0) break;
|
|
636
742
|
tempCon =
|
|
637
|
-
tempChild[tempOffset > 0 ? tempOffset - 1 : tempOffset] ||
|
|
743
|
+
tempChild[tempOffset > 0 ? tempOffset - 1 : tempOffset] ||
|
|
744
|
+
!/FIGURE/i.test(tempChild[0].nodeName)
|
|
745
|
+
? tempChild[0]
|
|
746
|
+
: /** @type {HTMLElement} */ (tempCon).previousElementSibling ||
|
|
747
|
+
tempCon.previousSibling ||
|
|
748
|
+
startCon;
|
|
638
749
|
tempOffset = tempOffset > 0 ? tempCon.textContent.length : tempOffset;
|
|
639
750
|
}
|
|
640
751
|
|
|
641
752
|
let format = this.#$.format.getLine(tempCon, null);
|
|
642
753
|
if (format === this.#$.format.getBlock(format, null)) {
|
|
643
|
-
format = dom.utils.createElement(
|
|
754
|
+
format = dom.utils.createElement(
|
|
755
|
+
dom.check.isTableCell(format) ? 'DIV' : this.#options.get('defaultLine'),
|
|
756
|
+
);
|
|
644
757
|
tempCon.parentNode.insertBefore(format, tempCon);
|
|
645
758
|
format.appendChild(tempCon);
|
|
646
759
|
}
|
|
@@ -700,7 +813,9 @@ class Selection_ {
|
|
|
700
813
|
this.#store.set('_range', range);
|
|
701
814
|
|
|
702
815
|
if (range.collapsed) {
|
|
703
|
-
if (dom.check.isWysiwygFrame(range.commonAncestorContainer))
|
|
816
|
+
if (dom.check.isWysiwygFrame(range.commonAncestorContainer))
|
|
817
|
+
selectionNode =
|
|
818
|
+
range.commonAncestorContainer.children[range.startOffset] || range.commonAncestorContainer;
|
|
704
819
|
else selectionNode = range.commonAncestorContainer;
|
|
705
820
|
} else {
|
|
706
821
|
selectionNode = selection.anchorNode;
|
|
@@ -719,7 +834,9 @@ class Selection_ {
|
|
|
719
834
|
return (
|
|
720
835
|
(dom.check.isWysiwygFrame(range.startContainer) && dom.check.isWysiwygFrame(range.endContainer)) ||
|
|
721
836
|
/FIGURE/i.test(comm.nodeName) ||
|
|
722
|
-
(this.#$.pluginManager.fileInfo.regExp.test(comm.nodeName) &&
|
|
837
|
+
(this.#$.pluginManager.fileInfo.regExp.test(comm.nodeName) &&
|
|
838
|
+
(!this.#$.pluginManager.fileInfo.tagAttrs[comm.nodeName] ||
|
|
839
|
+
this.#$.pluginManager.fileInfo.tagAttrs[comm.nodeName]?.every((v) => comm.hasAttribute(v)))) ||
|
|
723
840
|
this.#$.component.is(comm)
|
|
724
841
|
);
|
|
725
842
|
}
|
|
@@ -779,7 +896,8 @@ class Selection_ {
|
|
|
779
896
|
this.#hasScrollParents = this.#kernel._eventOrchestrator.scrollparents?.length > 0;
|
|
780
897
|
this.#scrollMargin = !this.#frameContext?.get('wysiwyg')
|
|
781
898
|
? 40
|
|
782
|
-
: (numbers.get(_w.getComputedStyle(this.#frameContext.get('wysiwyg')).scrollMargin, 0) || 40) +
|
|
899
|
+
: (numbers.get(_w.getComputedStyle(this.#frameContext.get('wysiwyg')).scrollMargin, 0) || 40) +
|
|
900
|
+
numbers.get(_w.getComputedStyle(this.#frameContext.get('wrapper')).paddingBottom, 0);
|
|
783
901
|
}
|
|
784
902
|
}
|
|
785
903
|
|