@sequent-org/moodboard 1.4.21 → 1.4.23
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/package.json
CHANGED
|
@@ -3,6 +3,9 @@ import { Events } from '../../../core/events/Events.js';
|
|
|
3
3
|
export function onMouseDown(event) {
|
|
4
4
|
// Если активен текстовый редактор, закрываем его при клике вне
|
|
5
5
|
if (this.textEditor.active) {
|
|
6
|
+
// Помечаем, что закрытие инициировано кликом вне редактора.
|
|
7
|
+
// Это используется в blur-handler, чтобы избежать двойного finalize в одном цикле.
|
|
8
|
+
this.textEditor._closingByOutside = true;
|
|
6
9
|
const activeEditorType = this.textEditor.objectType;
|
|
7
10
|
if (this.textEditor.objectType === 'file') {
|
|
8
11
|
this._closeFileNameEditor(true);
|
|
@@ -120,7 +120,11 @@ export function createTextEditorFinalize(controller, {
|
|
|
120
120
|
updateGlobalTextEditorHandlesLayer();
|
|
121
121
|
|
|
122
122
|
if (!commitValue) {
|
|
123
|
-
|
|
123
|
+
// Safety against race conditions: when a newly-created editor is blurred by
|
|
124
|
+
// tool-switch/outside click, do not auto-delete the object. Explicit cancel
|
|
125
|
+
// (Esc -> commit === false) still removes empty creation.
|
|
126
|
+
const shouldDeleteEmptyNewCreation = isNewCreation && objectId && commit === false;
|
|
127
|
+
if (shouldDeleteEmptyNewCreation) {
|
|
124
128
|
controller.eventBus.emit(Events.Tool.ObjectsDelete, { objects: [objectId] });
|
|
125
129
|
}
|
|
126
130
|
return;
|
|
@@ -168,12 +172,21 @@ export function bindTextEditorInteractions(controller, {
|
|
|
168
172
|
finalize,
|
|
169
173
|
}) {
|
|
170
174
|
const blurHandler = () => {
|
|
171
|
-
const
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
175
|
+
const editorObjectId = controller?.textEditor?.objectId || null;
|
|
176
|
+
setTimeout(() => {
|
|
177
|
+
// Если редактор уже закрыт/переключен другим обработчиком (outside click),
|
|
178
|
+
// blur не должен дублировать finalize.
|
|
179
|
+
if (!controller?.textEditor?.active) return;
|
|
180
|
+
if ((controller?.textEditor?.objectId || null) !== editorObjectId) return;
|
|
181
|
+
if (controller?.textEditor?._closingByOutside) return;
|
|
182
|
+
|
|
183
|
+
const value = (textarea.value || '').trim();
|
|
184
|
+
if (isNewCreation && value.length === 0) {
|
|
185
|
+
finalize(false);
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
finalize(true);
|
|
189
|
+
}, 0);
|
|
177
190
|
};
|
|
178
191
|
|
|
179
192
|
const keydownHandler = (e) => {
|
|
@@ -216,6 +229,7 @@ export function closeTextEditorFromState(controller, commit) {
|
|
|
216
229
|
const properties = controller.textEditor.properties;
|
|
217
230
|
const isNewCreation = controller.textEditor.isNewCreation;
|
|
218
231
|
const initialContent = controller.textEditor.initialContent ?? '';
|
|
232
|
+
const shouldDeleteEmptyNewCreation = !commitValue && !!isNewCreation && !!objectId;
|
|
219
233
|
|
|
220
234
|
if (objectId) {
|
|
221
235
|
if (typeof window !== 'undefined' && window.moodboardHtmlTextLayer) {
|
|
@@ -240,7 +254,12 @@ export function closeTextEditorFromState(controller, commit) {
|
|
|
240
254
|
|
|
241
255
|
textarea.remove();
|
|
242
256
|
controller.textEditor = { active: false, objectId: null, textarea: null, world: null, objectType: 'text' };
|
|
243
|
-
if (!commitValue)
|
|
257
|
+
if (!commitValue) {
|
|
258
|
+
if (shouldDeleteEmptyNewCreation) {
|
|
259
|
+
controller.eventBus.emit(Events.Tool.ObjectsDelete, { objects: [objectId] });
|
|
260
|
+
}
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
244
263
|
if (objectId == null) {
|
|
245
264
|
controller.eventBus.emit(Events.UI.ToolbarAction, {
|
|
246
265
|
type: objectType,
|
|
@@ -58,8 +58,22 @@ export function openTextEditor(object, create = false) {
|
|
|
58
58
|
return;
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
// Закрываем предыдущий редактор, если он
|
|
62
|
-
|
|
61
|
+
// Закрываем предыдущий редактор, если он открыт.
|
|
62
|
+
// Защита от повторного открытия того же объекта в один цикл событий:
|
|
63
|
+
// не пересоздаём textarea/обёртку, если уже редактируем этот объект.
|
|
64
|
+
if (this.textEditor.active) {
|
|
65
|
+
const sameEditorObject = !!(
|
|
66
|
+
objectId &&
|
|
67
|
+
this.textEditor.objectId &&
|
|
68
|
+
this.textEditor.objectId === objectId &&
|
|
69
|
+
this.textEditor.objectType === objectType
|
|
70
|
+
);
|
|
71
|
+
if (sameEditorObject && this.textEditor.textarea) {
|
|
72
|
+
try { this.textEditor.textarea.focus(); } catch (_) {}
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
this._closeTextEditor(true);
|
|
76
|
+
}
|
|
63
77
|
|
|
64
78
|
// Если это редактирование существующего объекта, получаем его данные
|
|
65
79
|
if (!create && objectId) {
|