@sequent-org/moodboard 1.4.22 → 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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sequent-org/moodboard",
3
- "version": "1.4.22",
3
+ "version": "1.4.23",
4
4
  "type": "module",
5
5
  "description": "Interactive moodboard",
6
6
  "main": "./src/index.js",
@@ -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);
@@ -172,12 +172,21 @@ export function bindTextEditorInteractions(controller, {
172
172
  finalize,
173
173
  }) {
174
174
  const blurHandler = () => {
175
- const value = (textarea.value || '').trim();
176
- if (isNewCreation && value.length === 0) {
177
- finalize(false);
178
- return;
179
- }
180
- finalize(true);
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);
181
190
  };
182
191
 
183
192
  const keydownHandler = (e) => {
@@ -220,6 +229,7 @@ export function closeTextEditorFromState(controller, commit) {
220
229
  const properties = controller.textEditor.properties;
221
230
  const isNewCreation = controller.textEditor.isNewCreation;
222
231
  const initialContent = controller.textEditor.initialContent ?? '';
232
+ const shouldDeleteEmptyNewCreation = !commitValue && !!isNewCreation && !!objectId;
223
233
 
224
234
  if (objectId) {
225
235
  if (typeof window !== 'undefined' && window.moodboardHtmlTextLayer) {
@@ -244,7 +254,12 @@ export function closeTextEditorFromState(controller, commit) {
244
254
 
245
255
  textarea.remove();
246
256
  controller.textEditor = { active: false, objectId: null, textarea: null, world: null, objectType: 'text' };
247
- if (!commitValue) return;
257
+ if (!commitValue) {
258
+ if (shouldDeleteEmptyNewCreation) {
259
+ controller.eventBus.emit(Events.Tool.ObjectsDelete, { objects: [objectId] });
260
+ }
261
+ return;
262
+ }
248
263
  if (objectId == null) {
249
264
  controller.eventBus.emit(Events.UI.ToolbarAction, {
250
265
  type: objectType,
@@ -58,8 +58,22 @@ export function openTextEditor(object, create = false) {
58
58
  return;
59
59
  }
60
60
 
61
- // Закрываем предыдущий редактор, если он открыт
62
- if (this.textEditor.active) this._closeTextEditor(true);
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) {