suneditor 3.3.2 → 3.3.3
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.min.js +1 -1
- package/package.json +1 -1
- package/src/core/event/eventOrchestrator.js +2 -0
- package/src/core/event/handlers/handler_ww_key.js +2 -0
- package/src/core/logic/panel/blockHandle.js +42 -7
- package/src/core/logic/shell/component.js +3 -1
- package/src/core/logic/shell/history.js +32 -3
- package/src/modules/contract/Modal.js +1 -0
- package/src/plugins/command/codeBlock.js +9 -1
- package/types/core/logic/panel/blockHandle.d.ts +5 -0
package/package.json
CHANGED
|
@@ -1107,6 +1107,7 @@ class EventOrchestrator extends KernelInjector {
|
|
|
1107
1107
|
}
|
|
1108
1108
|
|
|
1109
1109
|
this.#scrollContainer();
|
|
1110
|
+
this.#ui.blockHandle?.syncScroll();
|
|
1110
1111
|
|
|
1111
1112
|
// document type page
|
|
1112
1113
|
if (this.$.frameContext.has('documentType_use_page')) {
|
|
@@ -1159,6 +1160,7 @@ class EventOrchestrator extends KernelInjector {
|
|
|
1159
1160
|
#OnScroll_Abs() {
|
|
1160
1161
|
this.#menu.dropdownOff();
|
|
1161
1162
|
this.#scrollContainer();
|
|
1163
|
+
this.#ui.blockHandle?.syncScroll();
|
|
1162
1164
|
}
|
|
1163
1165
|
|
|
1164
1166
|
/**
|
|
@@ -22,6 +22,8 @@ const _styleNodes = Object.preventExtensions({ value: [] });
|
|
|
22
22
|
* @param {KeyboardEvent} e - Event object
|
|
23
23
|
*/
|
|
24
24
|
export async function OnKeyDown_wysiwyg(fc, e) {
|
|
25
|
+
this.$.ui.blockHandle?.hideOnKeyDown();
|
|
26
|
+
|
|
25
27
|
if ((this.isComposing = keyCodeMap.isComposing(e))) return true;
|
|
26
28
|
if (this.$.ui.selectMenuOn || !e.isTrusted) return;
|
|
27
29
|
|
|
@@ -54,6 +54,10 @@ class BlockHandle {
|
|
|
54
54
|
#pendingMouseY = undefined;
|
|
55
55
|
/** @type {number|null} */
|
|
56
56
|
#hideTimer = null;
|
|
57
|
+
/** @type {boolean} */
|
|
58
|
+
#keyboardLock = false;
|
|
59
|
+
/** @type {number|undefined} */
|
|
60
|
+
#lastMouseY = undefined;
|
|
57
61
|
/** @type {HTMLElement[]} */
|
|
58
62
|
#hoverLines = [];
|
|
59
63
|
|
|
@@ -123,8 +127,6 @@ class BlockHandle {
|
|
|
123
127
|
em.addEvent(wrapper, 'dragover', this.#onDragOver.bind(this));
|
|
124
128
|
em.addEvent(wrapper, 'drop', this.#onDrop.bind(this));
|
|
125
129
|
}
|
|
126
|
-
|
|
127
|
-
em.addEvent(this.#$.frameContext.get('eventWysiwyg'), 'keydown', this.#onWrapperKeyDown.bind(this), true);
|
|
128
130
|
}
|
|
129
131
|
|
|
130
132
|
/**
|
|
@@ -161,13 +163,24 @@ class BlockHandle {
|
|
|
161
163
|
this.#cancelHide();
|
|
162
164
|
// Lock handle while action menu is open or dragging
|
|
163
165
|
if (this.#actionMenu?.isOpen || this.#isDragging) return;
|
|
166
|
+
|
|
167
|
+
if (this.#keyboardLock) {
|
|
168
|
+
if (mouseY === this.#lastMouseY) return;
|
|
169
|
+
this.#keyboardLock = false;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const framePending = this.#pendingTarget !== null;
|
|
164
173
|
this.#pendingTarget = eventTarget;
|
|
174
|
+
this.#lastMouseY = mouseY;
|
|
165
175
|
this.#pendingMouseY = mouseY;
|
|
166
|
-
if (
|
|
176
|
+
if (framePending) return;
|
|
177
|
+
|
|
167
178
|
this.#rafId = _w.requestAnimationFrame(() => {
|
|
168
179
|
this.#rafId = null;
|
|
169
|
-
|
|
170
|
-
|
|
180
|
+
const target = this.#pendingTarget;
|
|
181
|
+
this.#pendingTarget = null;
|
|
182
|
+
if (target) {
|
|
183
|
+
this.#doPosition(target, this.#pendingMouseY);
|
|
171
184
|
}
|
|
172
185
|
});
|
|
173
186
|
}
|
|
@@ -321,6 +334,7 @@ class BlockHandle {
|
|
|
321
334
|
if (!this.#$) return;
|
|
322
335
|
if (this.#isDragging) return;
|
|
323
336
|
|
|
337
|
+
this.#keyboardLock = false;
|
|
324
338
|
this.#cancelHide();
|
|
325
339
|
|
|
326
340
|
// Don't reposition while action menu is open
|
|
@@ -494,6 +508,24 @@ class BlockHandle {
|
|
|
494
508
|
|
|
495
509
|
const totalOffset = indent + centeringExtra;
|
|
496
510
|
|
|
511
|
+
const toolbarEl = this.#$.context?.get('toolbar_main');
|
|
512
|
+
if (toolbarEl) {
|
|
513
|
+
const tRect = toolbarEl.getBoundingClientRect();
|
|
514
|
+
const handleWidth = this.#handle.offsetWidth || 0;
|
|
515
|
+
const hTop = firstLineCenterVP - handleHeight / 2;
|
|
516
|
+
const hLeft = isRtl ? areaRect.right - totalOffset - handleWidth : areaRect.left + totalOffset;
|
|
517
|
+
if (
|
|
518
|
+
tRect.height > 0 &&
|
|
519
|
+
hTop < tRect.bottom - 1 &&
|
|
520
|
+
hTop + handleHeight > tRect.top + 1 &&
|
|
521
|
+
hLeft < tRect.right &&
|
|
522
|
+
hLeft + handleWidth > tRect.left
|
|
523
|
+
) {
|
|
524
|
+
this.#hideHandle();
|
|
525
|
+
return;
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
|
|
497
529
|
this.#handle.style.top = top + 'px';
|
|
498
530
|
if (isRtl) {
|
|
499
531
|
this.#handle.style.left = '';
|
|
@@ -628,10 +660,13 @@ class BlockHandle {
|
|
|
628
660
|
}
|
|
629
661
|
|
|
630
662
|
/**
|
|
663
|
+
* @internal
|
|
631
664
|
* @description Editor keyboard activity (typing, Enter, etc.)
|
|
632
665
|
*/
|
|
633
|
-
|
|
634
|
-
this.#
|
|
666
|
+
hideOnKeyDown() {
|
|
667
|
+
if (this.#actionMenu?.isOpen) return;
|
|
668
|
+
this.#keyboardLock = true;
|
|
669
|
+
this.hideNow();
|
|
635
670
|
}
|
|
636
671
|
|
|
637
672
|
/**
|
|
@@ -136,6 +136,8 @@ class Component {
|
|
|
136
136
|
|
|
137
137
|
if (insertBehavior === undefined) insertBehavior = this.#options.get('componentInsertBehavior');
|
|
138
138
|
|
|
139
|
+
if (this.isSelected) this.__deselect();
|
|
140
|
+
|
|
139
141
|
const r = this.#$.html.remove();
|
|
140
142
|
const isInline = this.isInline(element);
|
|
141
143
|
this.#$.selection.getRangeAndAddLine(this.#$.selection.getRange(), r.container);
|
|
@@ -195,7 +197,7 @@ class Component {
|
|
|
195
197
|
|
|
196
198
|
const targetElement = /** @type {HTMLElement} */ (oNode || element);
|
|
197
199
|
|
|
198
|
-
if (scrollTo) this.#$.selection.scrollTo(targetElement, { behavior: 'auto' });
|
|
200
|
+
if (scrollTo) this.#$.selection.scrollTo(targetElement, { behavior: 'auto', noFocus: true });
|
|
199
201
|
if (insertBehavior !== null) this.applyInsertBehavior(element, oNode, insertBehavior);
|
|
200
202
|
|
|
201
203
|
return targetElement;
|
|
@@ -1,7 +1,36 @@
|
|
|
1
|
-
import { _w } from '../../../helper/env';
|
|
1
|
+
import { _w, _d } from '../../../helper/env';
|
|
2
2
|
import { getNodeFromPath, getNodePath } from '../../../helper/dom/domQuery';
|
|
3
3
|
import { numbers } from '../../../helper';
|
|
4
4
|
|
|
5
|
+
const TRANSIENT_UI_CLASSES = [
|
|
6
|
+
'se-component-selected',
|
|
7
|
+
'se-figure-over-selected',
|
|
8
|
+
'se-block-hover',
|
|
9
|
+
'se-pre-code-focus',
|
|
10
|
+
];
|
|
11
|
+
const TRANSIENT_UI_CLASS_RE = new RegExp(TRANSIENT_UI_CLASSES.join('|'));
|
|
12
|
+
const TRANSIENT_UI_CLASS_SELECTOR = '.' + TRANSIENT_UI_CLASSES.join(', .');
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @description Strips transient UI-state classes (selection/hover markers) from a snapshot's HTML.
|
|
16
|
+
* - only while a marker is actually present in the serialized content.
|
|
17
|
+
* @param {string} html Serialized wysiwyg content
|
|
18
|
+
* @returns {string} The cleaned content
|
|
19
|
+
*/
|
|
20
|
+
function cleanSnapshot(html) {
|
|
21
|
+
if (!TRANSIENT_UI_CLASS_RE.test(html)) return html;
|
|
22
|
+
|
|
23
|
+
const t = _d.createElement('template');
|
|
24
|
+
t.innerHTML = html;
|
|
25
|
+
|
|
26
|
+
const marked = t.content.querySelectorAll(TRANSIENT_UI_CLASS_SELECTOR);
|
|
27
|
+
for (let i = 0; i < marked.length; i++) {
|
|
28
|
+
marked[i].classList.remove(...TRANSIENT_UI_CLASSES);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return t.innerHTML;
|
|
32
|
+
}
|
|
33
|
+
|
|
5
34
|
/**
|
|
6
35
|
* @description History stack closure
|
|
7
36
|
* @param {SunEditor.Kernel} kernel
|
|
@@ -206,7 +235,7 @@ export default function History(kernel) {
|
|
|
206
235
|
$.pluginManager.checkFileInfo(false);
|
|
207
236
|
|
|
208
237
|
const fc = frameRoots.get(rootKey);
|
|
209
|
-
const current = fc.get('wysiwyg').innerHTML;
|
|
238
|
+
const current = cleanSnapshot(fc.get('wysiwyg').innerHTML);
|
|
210
239
|
const root = rootStack[rootKey];
|
|
211
240
|
if (!current || (root.value[root.index] && current === root.value[root.index].content)) return;
|
|
212
241
|
if (stack.length > stackIndex + 1) refreshRoots(root);
|
|
@@ -319,7 +348,7 @@ export default function History(kernel) {
|
|
|
319
348
|
*/
|
|
320
349
|
overwrite(rootKey) {
|
|
321
350
|
setStack(
|
|
322
|
-
frameRoots.get(rootKey || store.get('rootKey')).get('wysiwyg').innerHTML,
|
|
351
|
+
cleanSnapshot(frameRoots.get(rootKey || store.get('rootKey')).get('wysiwyg').innerHTML),
|
|
323
352
|
null,
|
|
324
353
|
store.get('rootKey'),
|
|
325
354
|
0,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { PluginCommand, PluginDropdown } from '../../interfaces';
|
|
2
|
-
import { converter, dom } from '../../helper';
|
|
2
|
+
import { converter, dom, env } from '../../helper';
|
|
3
3
|
import { Controller } from '../../modules/contract';
|
|
4
4
|
import { SelectMenu } from '../../modules/ui';
|
|
5
5
|
|
|
@@ -133,6 +133,14 @@ class CodeBlock extends PluginCommand {
|
|
|
133
133
|
this.#hoverSelectMenu.on(this.#hoverButton, this.#onHoverSelect.bind(this));
|
|
134
134
|
this.#buildHoverMenu('');
|
|
135
135
|
|
|
136
|
+
this.$.eventManager.addEvent(containerEl, 'mousedown', (e) => {
|
|
137
|
+
if (env.isMobile || this.#hoverSelectMenu.form?.contains(dom.query.getEventTarget(e))) {
|
|
138
|
+
this.$.store.set('_preventBlur', true);
|
|
139
|
+
} else {
|
|
140
|
+
e.preventDefault();
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
|
|
136
144
|
// selectMenu
|
|
137
145
|
this.$.eventManager.addEvent(this.#hoverButton, 'click', (e) => {
|
|
138
146
|
e.preventDefault();
|
|
@@ -47,5 +47,10 @@ declare class BlockHandle {
|
|
|
47
47
|
* @description Cleanup — remove listeners, destroy menus, null references.
|
|
48
48
|
*/
|
|
49
49
|
destroy(): void;
|
|
50
|
+
/**
|
|
51
|
+
* @internal
|
|
52
|
+
* @description Editor keyboard activity (typing, Enter, etc.)
|
|
53
|
+
*/
|
|
54
|
+
hideOnKeyDown(): void;
|
|
50
55
|
#private;
|
|
51
56
|
}
|