@kubohiroya/turbowarp-extension-data-editor 0.6.0 → 0.7.0

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.
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@kubohiroya/turbowarp-extension-data-editor",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "repository": "https://github.com/kubohiroya/turbowarp-extension-data-editor",
5
- "revision": "91533dbbffa9eb9d3b50be8084b85dae5184f9dc",
5
+ "revision": "d96532a91bc6046d4a3fda878425b30d6d10483e",
6
6
  "sourceState": "commit",
7
- "sourceSha256": "6d60745c40f7b4258f2c80c1e9ec316988e2d7cf8d68042130e156a76255d95d",
7
+ "sourceSha256": "daf5c14dd2a7eafbc5208413f168eb42fc817978e8517a66c31838dc48aa1841",
8
8
  "capabilities": {
9
9
  "preparedSource": 1
10
10
  }
@@ -0,0 +1,8 @@
1
+ interface WindowLabels {
2
+ readonly headerClassName?: string | undefined;
3
+ readonly maximize?: string | undefined;
4
+ readonly restore?: string | undefined;
5
+ }
6
+ /** Add window controls to the injected host frame without depending on GUI internals. */
7
+ export declare function attachEditorDialogWindow(body: HTMLElement, labels: WindowLabels): (() => void) | undefined;
8
+ export {};
@@ -0,0 +1,155 @@
1
+ /** Add window controls to the injected host frame without depending on GUI internals. */
2
+ export function attachEditorDialogWindow(body, labels) {
3
+ var _a;
4
+ const dialog = body.closest('[role="dialog"]');
5
+ const header = (labels.headerClassName ? dialog === null || dialog === void 0 ? void 0 : dialog.getElementsByClassName(labels.headerClassName)[0] :
6
+ dialog === null || dialog === void 0 ? void 0 : dialog.querySelector('header'));
7
+ const content = body.closest('[data-block-editor-body]');
8
+ if (!dialog || !header || !content || !((_a = header.parentElement) === null || _a === void 0 ? void 0 : _a.contains(content)))
9
+ return;
10
+ const doc = dialog.ownerDocument, win = doc.defaultView;
11
+ if (!win)
12
+ return;
13
+ const frame = header.parentElement;
14
+ const initialStyle = dialog.style.cssText;
15
+ const language = doc.documentElement.lang || new URLSearchParams(win.location.search).get('lang') || win.navigator.language;
16
+ const japanese = language.startsWith('ja');
17
+ const maximizeLabel = labels.maximize || (japanese ? '全画面化' : 'Maximize');
18
+ const restoreLabel = labels.restore || (japanese ? '元のサイズに戻す' : 'Restore window');
19
+ let restoreBounds = null;
20
+ let gesture = null;
21
+ const handles = [];
22
+ dialog.setAttribute('data-block-editor-window', '');
23
+ if (frame !== dialog)
24
+ frame.setAttribute('data-block-editor-window-frame', '');
25
+ header.setAttribute('data-block-editor-titlebar', '');
26
+ const maximize = doc.createElement('button');
27
+ maximize.type = 'button';
28
+ maximize.setAttribute('data-block-editor-maximize', '');
29
+ const closeContainer = header.lastElementChild;
30
+ if (closeContainer === null || closeContainer === void 0 ? void 0 : closeContainer.querySelector('button, [role="button"]'))
31
+ closeContainer.prepend(maximize);
32
+ else
33
+ header.insertBefore(maximize, closeContainer);
34
+ const viewport = () => ({ width: win.innerWidth, height: win.innerHeight });
35
+ const bounds = () => {
36
+ const { x, y, width, height } = dialog.getBoundingClientRect();
37
+ return { x, y, width, height };
38
+ };
39
+ const clamp = (value, min, max) => Math.min(Math.max(value, min), max);
40
+ function fit(rect) {
41
+ const view = viewport();
42
+ const width = clamp(rect.width, Math.min(360, view.width), view.width);
43
+ const height = clamp(rect.height, Math.min(280, view.height), view.height);
44
+ return { width, height, x: clamp(rect.x, 0, view.width - width), y: clamp(rect.y, 0, view.height - height) };
45
+ }
46
+ function place(rect) {
47
+ Object.assign(dialog.style, { margin: '0', inset: 'auto', transform: 'none', maxHeight: '100dvh',
48
+ left: `${rect.x}px`, top: `${rect.y}px`, width: `${rect.width}px`, height: `${rect.height}px` });
49
+ }
50
+ function stop(event) {
51
+ if (!gesture || (event && 'pointerId' in event && event.pointerId !== gesture.id))
52
+ return;
53
+ const { target, id } = gesture;
54
+ gesture = null;
55
+ if (target.hasPointerCapture(id))
56
+ target.releasePointerCapture(id);
57
+ dialog.removeAttribute('data-block-editor-dragging');
58
+ }
59
+ function start(event, edge) {
60
+ if (restoreBounds || gesture || event.button !== 0 || !event.isPrimary)
61
+ return;
62
+ if (!edge && event.target.closest('button, a, input, select, textarea, [role="button"]'))
63
+ return;
64
+ event.preventDefault();
65
+ const target = event.currentTarget;
66
+ gesture = { id: event.pointerId, target, edge, x: event.clientX, y: event.clientY, rect: fit(bounds()) };
67
+ place(gesture.rect);
68
+ target.setPointerCapture(event.pointerId);
69
+ dialog.setAttribute('data-block-editor-dragging', '');
70
+ }
71
+ function move(event) {
72
+ if (!gesture || event.pointerId !== gesture.id)
73
+ return;
74
+ const { rect, edge } = gesture, view = viewport();
75
+ const dx = event.clientX - gesture.x, dy = event.clientY - gesture.y;
76
+ if (!edge) {
77
+ place(fit({ ...rect, x: rect.x + dx, y: rect.y + dy }));
78
+ return;
79
+ }
80
+ const minWidth = Math.min(360, view.width), minHeight = Math.min(280, view.height);
81
+ let left = rect.x, top = rect.y, right = rect.x + rect.width, bottom = rect.y + rect.height;
82
+ if (edge.includes('w'))
83
+ left = clamp(left + dx, 0, right - minWidth);
84
+ if (edge.includes('e'))
85
+ right = clamp(right + dx, left + minWidth, view.width);
86
+ if (edge.includes('n'))
87
+ top = clamp(top + dy, 0, bottom - minHeight);
88
+ if (edge.includes('s'))
89
+ bottom = clamp(bottom + dy, top + minHeight, view.height);
90
+ place({ x: left, y: top, width: right - left, height: bottom - top });
91
+ }
92
+ const startMove = (event) => start(event, '');
93
+ header.addEventListener('pointerdown', startMove);
94
+ for (const edge of ['n', 'e', 's', 'w', 'ne', 'se', 'sw', 'nw']) {
95
+ const handle = doc.createElement('div');
96
+ handle.setAttribute('data-block-editor-resize', edge);
97
+ handle.setAttribute('aria-hidden', 'true');
98
+ handle.addEventListener('pointerdown', event => start(event, edge));
99
+ dialog.append(handle);
100
+ handles.push(handle);
101
+ }
102
+ function updateButton() {
103
+ const label = restoreBounds ? restoreLabel : maximizeLabel;
104
+ maximize.setAttribute('aria-label', label);
105
+ maximize.setAttribute('aria-pressed', String(Boolean(restoreBounds)));
106
+ maximize.title = label;
107
+ maximize.textContent = restoreBounds ? '❐' : '⛶';
108
+ dialog.toggleAttribute('data-block-editor-maximized', Boolean(restoreBounds));
109
+ }
110
+ function toggle() {
111
+ stop();
112
+ if (restoreBounds) {
113
+ place(fit(restoreBounds));
114
+ restoreBounds = null;
115
+ }
116
+ else {
117
+ restoreBounds = bounds();
118
+ place({ x: 0, y: 0, ...viewport() });
119
+ }
120
+ updateButton();
121
+ }
122
+ function resize() {
123
+ stop();
124
+ if (restoreBounds)
125
+ place({ x: 0, y: 0, ...viewport() });
126
+ else
127
+ place(fit(bounds()));
128
+ }
129
+ maximize.addEventListener('click', toggle);
130
+ win.addEventListener('pointermove', move);
131
+ win.addEventListener('pointerup', stop);
132
+ win.addEventListener('pointercancel', stop);
133
+ win.addEventListener('blur', stop);
134
+ win.addEventListener('resize', resize);
135
+ dialog.addEventListener('lostpointercapture', stop);
136
+ updateButton();
137
+ return () => {
138
+ stop();
139
+ header.removeEventListener('pointerdown', startMove);
140
+ win.removeEventListener('pointermove', move);
141
+ win.removeEventListener('pointerup', stop);
142
+ win.removeEventListener('pointercancel', stop);
143
+ win.removeEventListener('blur', stop);
144
+ win.removeEventListener('resize', resize);
145
+ dialog.removeEventListener('lostpointercapture', stop);
146
+ maximize.remove();
147
+ handles.forEach(handle => handle.remove());
148
+ dialog.style.cssText = initialStyle;
149
+ for (const name of ['window', 'maximized', 'dragging'])
150
+ dialog.removeAttribute(`data-block-editor-${name}`);
151
+ if (frame !== dialog)
152
+ frame.removeAttribute('data-block-editor-window-frame');
153
+ header.removeAttribute('data-block-editor-titlebar');
154
+ };
155
+ }
package/dist/react.css CHANGED
@@ -349,3 +349,73 @@
349
349
  color: var(--block-editor-error-text, #a61b1b);
350
350
  margin-bottom: 0;
351
351
  }
352
+
353
+ /* Window controls also work with a host modal rendered through a portal. */
354
+ :global([data-block-editor-window]) {
355
+ position: fixed;
356
+ top: min(60px, 5vh);
357
+ left: 50%;
358
+ transform: translateX(-50%);
359
+ display: flex;
360
+ flex-direction: column;
361
+ box-sizing: border-box;
362
+ margin: 0;
363
+ max-width: 100vw;
364
+ max-height: calc(100dvh - min(60px, 5vh) - 16px);
365
+ }
366
+ :global([data-block-editor-window-frame]) {
367
+ display: flex;
368
+ flex: 1 1 auto;
369
+ flex-direction: column;
370
+ min-width: 0;
371
+ min-height: 0;
372
+ }
373
+ :global([data-block-editor-titlebar]) {
374
+ flex: 0 0 auto;
375
+ cursor: move;
376
+ touch-action: none;
377
+ user-select: none;
378
+ }
379
+ :global([data-block-editor-titlebar]) > div:first-child { cursor: inherit; }
380
+ :global([data-block-editor-window]) :global([data-block-editor-body]) {
381
+ flex: 1 1 auto;
382
+ min-height: 0;
383
+ max-height: none;
384
+ box-sizing: border-box;
385
+ }
386
+ :global([data-block-editor-window]) .editor-body { flex: 1 1 auto; }
387
+ :global([data-block-editor-maximize]) {
388
+ display: inline-grid;
389
+ flex: 0 0 auto;
390
+ place-items: center;
391
+ width: 34px;
392
+ height: 34px;
393
+ margin-inline-end: 8px;
394
+ padding: 0;
395
+ border: 1px solid currentColor;
396
+ border-radius: 5px;
397
+ background: transparent;
398
+ color: inherit;
399
+ font: 24px/1 system-ui, sans-serif;
400
+ cursor: pointer;
401
+ }
402
+ :global([data-block-editor-maximize]):focus-visible { outline: 2px solid currentColor; outline-offset: 2px; }
403
+ :global([data-block-editor-maximized]) { border-radius: 0; max-height: 100dvh; }
404
+ :global([data-block-editor-maximized]) :global([data-block-editor-titlebar]) { cursor: default; }
405
+ :global([data-block-editor-dragging]), :global([data-block-editor-dragging]) * { user-select: none; }
406
+ :global([data-block-editor-resize]) { position: absolute; z-index: 10; touch-action: none; }
407
+ :global([data-block-editor-resize="n"]), :global([data-block-editor-resize="s"]) { left: 9px; right: 9px; height: 7px; cursor: ns-resize; }
408
+ :global([data-block-editor-resize="n"]) { top: 0; }
409
+ :global([data-block-editor-resize="s"]) { bottom: 0; }
410
+ :global([data-block-editor-resize="e"]), :global([data-block-editor-resize="w"]) { top: 9px; bottom: 9px; width: 7px; cursor: ew-resize; }
411
+ :global([data-block-editor-resize="e"]) { right: 0; }
412
+ :global([data-block-editor-resize="w"]) { left: 0; }
413
+ :global([data-block-editor-resize="ne"]), :global([data-block-editor-resize="se"]),
414
+ :global([data-block-editor-resize="sw"]), :global([data-block-editor-resize="nw"]) { width: 10px; height: 10px; }
415
+ :global([data-block-editor-resize="ne"]), :global([data-block-editor-resize="nw"]) { top: 0; }
416
+ :global([data-block-editor-resize="se"]), :global([data-block-editor-resize="sw"]) { bottom: 0; }
417
+ :global([data-block-editor-resize="ne"]), :global([data-block-editor-resize="se"]) { right: 0; }
418
+ :global([data-block-editor-resize="nw"]), :global([data-block-editor-resize="sw"]) { left: 0; }
419
+ :global([data-block-editor-resize="ne"]), :global([data-block-editor-resize="sw"]) { cursor: nesw-resize; }
420
+ :global([data-block-editor-resize="nw"]), :global([data-block-editor-resize="se"]) { cursor: nwse-resize; }
421
+ :global([data-block-editor-maximized]) > :global([data-block-editor-resize]) { display: none; }
package/dist/react.d.ts CHANGED
@@ -35,6 +35,8 @@ export interface EditorDialogMessages {
35
35
  readonly structuralNode: string;
36
36
  /** Fixed forms retain technical diagnostics in the API while showing a localized summary. */
37
37
  readonly invalidInput?: string;
38
+ readonly maximize?: string;
39
+ readonly restore?: string;
38
40
  }
39
41
  export interface EditorNodeAppearance {
40
42
  readonly name?: string;
@@ -75,6 +77,7 @@ export declare class BlockEditorDialog extends React.Component<BlockEditorDialog
75
77
  private removeListener;
76
78
  private unmountBody;
77
79
  private stopFieldErrors;
80
+ private stopWindow;
78
81
  constructor(props: BlockEditorDialogProps);
79
82
  componentDidMount(): void;
80
83
  componentWillUnmount(): void;
package/dist/react.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import bindBlockEditorFieldErrors from './field-errors.js';
2
+ import { attachEditorDialogWindow } from './dialog-window.js';
2
3
  export { default as bindBlockEditorFieldErrors } from './field-errors.js';
3
4
  import * as React from 'react';
4
5
  import { BlockEditorConflictError } from './types.js';
@@ -164,18 +165,19 @@ export class BlockEditorDialog extends React.Component {
164
165
  this.mountBody();
165
166
  }
166
167
  componentWillUnmount() {
167
- var _a, _b, _c, _d;
168
+ var _a, _b, _c, _d, _e;
168
169
  this.unmounting = true;
169
170
  this.mounted = false;
170
171
  if (this.focusFrame !== undefined)
171
172
  cancelAnimationFrame(this.focusFrame);
172
173
  this.removeListener();
173
174
  (_a = this.stopFieldErrors) === null || _a === void 0 ? void 0 : _a.call(this);
175
+ (_b = this.stopWindow) === null || _b === void 0 ? void 0 : _b.call(this);
174
176
  try {
175
- (_b = this.unmountBody) === null || _b === void 0 ? void 0 : _b.call(this);
177
+ (_c = this.unmountBody) === null || _c === void 0 ? void 0 : _c.call(this);
176
178
  }
177
179
  catch (error) {
178
- (_d = (_c = this.props).onError) === null || _d === void 0 ? void 0 : _d.call(_c, error);
180
+ (_e = (_d = this.props).onError) === null || _e === void 0 ? void 0 : _e.call(_d, error);
179
181
  }
180
182
  finally {
181
183
  this.props.session.dispose();
@@ -185,6 +187,12 @@ export class BlockEditorDialog extends React.Component {
185
187
  if (!this.body || this.unmountBody || this.state.mountFailed)
186
188
  return;
187
189
  try {
190
+ if (!this.stopWindow)
191
+ this.stopWindow = attachEditorDialogWindow(this.body, {
192
+ headerClassName: this.props.styles.header,
193
+ maximize: this.props.messages.maximize,
194
+ restore: this.props.messages.restore
195
+ });
188
196
  if (!this.stopFieldErrors)
189
197
  this.stopFieldErrors = bindBlockEditorFieldErrors(this.body);
190
198
  if (typeof this.props.session.getNodes !== 'function')
@@ -224,7 +232,7 @@ export class BlockEditorDialog extends React.Component {
224
232
  /ブロック|block/i.test(messages.title) ? messages.title.replace(/ブロック|block/i, () => name) :
225
233
  `${name}: ${messages.title}` : messages.title;
226
234
  return React.createElement(ModalComponent, { className: `${styles.modalContent || ''} ${hierarchy ? styles.hierarchyModal : ''} ${this.props.className || ''}`, contentLabel: title, ...((appearance === null || appearance === void 0 ? void 0 : appearance.iconURI) ? { headerImage: appearance.iconURI } : {}), headerClassName: styles.header, id: "blockEditorModal", onRequestClose: this.handleClose },
227
- React.createElement("div", { "aria-busy": saving, className: styles.body, onCompositionStart: () => { this.composing = true; }, onCompositionEnd: () => { this.composing = false; }, onKeyDownCapture: event => {
235
+ React.createElement("div", { "aria-busy": saving, className: styles.body, "data-block-editor-body": "", onCompositionStart: () => { this.composing = true; }, onCompositionEnd: () => { this.composing = false; }, onKeyDownCapture: event => {
228
236
  if (this.composing || event.nativeEvent.isComposing || event.keyCode === 229)
229
237
  event.stopPropagation();
230
238
  } },
@@ -14180,14 +14180,24 @@
14180
14180
  "imports": [],
14181
14181
  "format": "esm"
14182
14182
  },
14183
+ "dist/dialog-window.js": {
14184
+ "bytes": 7349,
14185
+ "imports": [],
14186
+ "format": "esm"
14187
+ },
14183
14188
  "dist/react.js": {
14184
- "bytes": 14377,
14189
+ "bytes": 14863,
14185
14190
  "imports": [
14186
14191
  {
14187
14192
  "path": "dist/field-errors.js",
14188
14193
  "kind": "import-statement",
14189
14194
  "original": "./field-errors.js"
14190
14195
  },
14196
+ {
14197
+ "path": "dist/dialog-window.js",
14198
+ "kind": "import-statement",
14199
+ "original": "./dialog-window.js"
14200
+ },
14191
14201
  {
14192
14202
  "path": "dist/field-errors.js",
14193
14203
  "kind": "import-statement",
@@ -16825,7 +16835,7 @@
16825
16835
  "imports": [],
16826
16836
  "exports": [],
16827
16837
  "inputs": {},
16828
- "bytes": 30867
16838
+ "bytes": 43883
16829
16839
  },
16830
16840
  "dist/webpack4/react.js": {
16831
16841
  "imports": [
@@ -16852,11 +16862,14 @@
16852
16862
  "dist/field-errors.js": {
16853
16863
  "bytesInOutput": 3769
16854
16864
  },
16865
+ "dist/dialog-window.js": {
16866
+ "bytesInOutput": 6802
16867
+ },
16855
16868
  "dist/react.js": {
16856
- "bytesInOutput": 13029
16869
+ "bytesInOutput": 13396
16857
16870
  }
16858
16871
  },
16859
- "bytes": 17088
16872
+ "bytes": 24283
16860
16873
  },
16861
16874
  "dist/webpack4/turbowarp.js.map": {
16862
16875
  "imports": [],
@@ -96,6 +96,168 @@ var bindBlockEditorFieldErrors = (container) => {
96
96
  };
97
97
  var field_errors_default = bindBlockEditorFieldErrors;
98
98
 
99
+ // dist/dialog-window.js
100
+ function attachEditorDialogWindow(body, labels) {
101
+ var _a;
102
+ const dialog = body.closest('[role="dialog"]');
103
+ const header = labels.headerClassName ? dialog === null || dialog === void 0 ? void 0 : dialog.getElementsByClassName(labels.headerClassName)[0] : dialog === null || dialog === void 0 ? void 0 : dialog.querySelector("header");
104
+ const content = body.closest("[data-block-editor-body]");
105
+ if (!dialog || !header || !content || !((_a = header.parentElement) === null || _a === void 0 ? void 0 : _a.contains(content)))
106
+ return;
107
+ const doc = dialog.ownerDocument, win = doc.defaultView;
108
+ if (!win)
109
+ return;
110
+ const frame = header.parentElement;
111
+ const initialStyle = dialog.style.cssText;
112
+ const language = doc.documentElement.lang || new URLSearchParams(win.location.search).get("lang") || win.navigator.language;
113
+ const japanese = language.startsWith("ja");
114
+ const maximizeLabel = labels.maximize || (japanese ? "\u5168\u753B\u9762\u5316" : "Maximize");
115
+ const restoreLabel = labels.restore || (japanese ? "\u5143\u306E\u30B5\u30A4\u30BA\u306B\u623B\u3059" : "Restore window");
116
+ let restoreBounds = null;
117
+ let gesture = null;
118
+ const handles = [];
119
+ dialog.setAttribute("data-block-editor-window", "");
120
+ if (frame !== dialog)
121
+ frame.setAttribute("data-block-editor-window-frame", "");
122
+ header.setAttribute("data-block-editor-titlebar", "");
123
+ const maximize = doc.createElement("button");
124
+ maximize.type = "button";
125
+ maximize.setAttribute("data-block-editor-maximize", "");
126
+ const closeContainer = header.lastElementChild;
127
+ if (closeContainer === null || closeContainer === void 0 ? void 0 : closeContainer.querySelector('button, [role="button"]'))
128
+ closeContainer.prepend(maximize);
129
+ else
130
+ header.insertBefore(maximize, closeContainer);
131
+ const viewport = () => ({ width: win.innerWidth, height: win.innerHeight });
132
+ const bounds = () => {
133
+ const { x, y, width, height } = dialog.getBoundingClientRect();
134
+ return { x, y, width, height };
135
+ };
136
+ const clamp = (value, min, max) => Math.min(Math.max(value, min), max);
137
+ function fit(rect) {
138
+ const view = viewport();
139
+ const width = clamp(rect.width, Math.min(360, view.width), view.width);
140
+ const height = clamp(rect.height, Math.min(280, view.height), view.height);
141
+ return { width, height, x: clamp(rect.x, 0, view.width - width), y: clamp(rect.y, 0, view.height - height) };
142
+ }
143
+ function place(rect) {
144
+ Object.assign(dialog.style, {
145
+ margin: "0",
146
+ inset: "auto",
147
+ transform: "none",
148
+ maxHeight: "100dvh",
149
+ left: `${rect.x}px`,
150
+ top: `${rect.y}px`,
151
+ width: `${rect.width}px`,
152
+ height: `${rect.height}px`
153
+ });
154
+ }
155
+ function stop(event) {
156
+ if (!gesture || event && "pointerId" in event && event.pointerId !== gesture.id)
157
+ return;
158
+ const { target, id } = gesture;
159
+ gesture = null;
160
+ if (target.hasPointerCapture(id))
161
+ target.releasePointerCapture(id);
162
+ dialog.removeAttribute("data-block-editor-dragging");
163
+ }
164
+ function start(event, edge) {
165
+ if (restoreBounds || gesture || event.button !== 0 || !event.isPrimary)
166
+ return;
167
+ if (!edge && event.target.closest('button, a, input, select, textarea, [role="button"]'))
168
+ return;
169
+ event.preventDefault();
170
+ const target = event.currentTarget;
171
+ gesture = { id: event.pointerId, target, edge, x: event.clientX, y: event.clientY, rect: fit(bounds()) };
172
+ place(gesture.rect);
173
+ target.setPointerCapture(event.pointerId);
174
+ dialog.setAttribute("data-block-editor-dragging", "");
175
+ }
176
+ function move(event) {
177
+ if (!gesture || event.pointerId !== gesture.id)
178
+ return;
179
+ const { rect, edge } = gesture, view = viewport();
180
+ const dx = event.clientX - gesture.x, dy = event.clientY - gesture.y;
181
+ if (!edge) {
182
+ place(fit({ ...rect, x: rect.x + dx, y: rect.y + dy }));
183
+ return;
184
+ }
185
+ const minWidth = Math.min(360, view.width), minHeight = Math.min(280, view.height);
186
+ let left = rect.x, top = rect.y, right = rect.x + rect.width, bottom = rect.y + rect.height;
187
+ if (edge.includes("w"))
188
+ left = clamp(left + dx, 0, right - minWidth);
189
+ if (edge.includes("e"))
190
+ right = clamp(right + dx, left + minWidth, view.width);
191
+ if (edge.includes("n"))
192
+ top = clamp(top + dy, 0, bottom - minHeight);
193
+ if (edge.includes("s"))
194
+ bottom = clamp(bottom + dy, top + minHeight, view.height);
195
+ place({ x: left, y: top, width: right - left, height: bottom - top });
196
+ }
197
+ const startMove = (event) => start(event, "");
198
+ header.addEventListener("pointerdown", startMove);
199
+ for (const edge of ["n", "e", "s", "w", "ne", "se", "sw", "nw"]) {
200
+ const handle = doc.createElement("div");
201
+ handle.setAttribute("data-block-editor-resize", edge);
202
+ handle.setAttribute("aria-hidden", "true");
203
+ handle.addEventListener("pointerdown", (event) => start(event, edge));
204
+ dialog.append(handle);
205
+ handles.push(handle);
206
+ }
207
+ function updateButton() {
208
+ const label = restoreBounds ? restoreLabel : maximizeLabel;
209
+ maximize.setAttribute("aria-label", label);
210
+ maximize.setAttribute("aria-pressed", String(Boolean(restoreBounds)));
211
+ maximize.title = label;
212
+ maximize.textContent = restoreBounds ? "\u2750" : "\u26F6";
213
+ dialog.toggleAttribute("data-block-editor-maximized", Boolean(restoreBounds));
214
+ }
215
+ function toggle() {
216
+ stop();
217
+ if (restoreBounds) {
218
+ place(fit(restoreBounds));
219
+ restoreBounds = null;
220
+ } else {
221
+ restoreBounds = bounds();
222
+ place({ x: 0, y: 0, ...viewport() });
223
+ }
224
+ updateButton();
225
+ }
226
+ function resize() {
227
+ stop();
228
+ if (restoreBounds)
229
+ place({ x: 0, y: 0, ...viewport() });
230
+ else
231
+ place(fit(bounds()));
232
+ }
233
+ maximize.addEventListener("click", toggle);
234
+ win.addEventListener("pointermove", move);
235
+ win.addEventListener("pointerup", stop);
236
+ win.addEventListener("pointercancel", stop);
237
+ win.addEventListener("blur", stop);
238
+ win.addEventListener("resize", resize);
239
+ dialog.addEventListener("lostpointercapture", stop);
240
+ updateButton();
241
+ return () => {
242
+ stop();
243
+ header.removeEventListener("pointerdown", startMove);
244
+ win.removeEventListener("pointermove", move);
245
+ win.removeEventListener("pointerup", stop);
246
+ win.removeEventListener("pointercancel", stop);
247
+ win.removeEventListener("blur", stop);
248
+ win.removeEventListener("resize", resize);
249
+ dialog.removeEventListener("lostpointercapture", stop);
250
+ maximize.remove();
251
+ handles.forEach((handle) => handle.remove());
252
+ dialog.style.cssText = initialStyle;
253
+ for (const name of ["window", "maximized", "dragging"])
254
+ dialog.removeAttribute(`data-block-editor-${name}`);
255
+ if (frame !== dialog)
256
+ frame.removeAttribute("data-block-editor-window-frame");
257
+ header.removeAttribute("data-block-editor-titlebar");
258
+ };
259
+ }
260
+
99
261
  // dist/react.js
100
262
  import * as React from "react";
101
263
  var NodeBody = class extends React.Component {
@@ -280,17 +442,18 @@ var BlockEditorDialog = class extends React.Component {
280
442
  this.mountBody();
281
443
  }
282
444
  componentWillUnmount() {
283
- var _a, _b, _c, _d;
445
+ var _a, _b, _c, _d, _e;
284
446
  this.unmounting = true;
285
447
  this.mounted = false;
286
448
  if (this.focusFrame !== void 0)
287
449
  cancelAnimationFrame(this.focusFrame);
288
450
  this.removeListener();
289
451
  (_a = this.stopFieldErrors) === null || _a === void 0 ? void 0 : _a.call(this);
452
+ (_b = this.stopWindow) === null || _b === void 0 ? void 0 : _b.call(this);
290
453
  try {
291
- (_b = this.unmountBody) === null || _b === void 0 ? void 0 : _b.call(this);
454
+ (_c = this.unmountBody) === null || _c === void 0 ? void 0 : _c.call(this);
292
455
  } catch (error) {
293
- (_d = (_c = this.props).onError) === null || _d === void 0 ? void 0 : _d.call(_c, error);
456
+ (_e = (_d = this.props).onError) === null || _e === void 0 ? void 0 : _e.call(_d, error);
294
457
  } finally {
295
458
  this.props.session.dispose();
296
459
  }
@@ -299,6 +462,12 @@ var BlockEditorDialog = class extends React.Component {
299
462
  if (!this.body || this.unmountBody || this.state.mountFailed)
300
463
  return;
301
464
  try {
465
+ if (!this.stopWindow)
466
+ this.stopWindow = attachEditorDialogWindow(this.body, {
467
+ headerClassName: this.props.styles.header,
468
+ maximize: this.props.messages.maximize,
469
+ restore: this.props.messages.restore
470
+ });
302
471
  if (!this.stopFieldErrors)
303
472
  this.stopFieldErrors = field_errors_default(this.body);
304
473
  if (typeof this.props.session.getNodes !== "function")
@@ -336,7 +505,7 @@ var BlockEditorDialog = class extends React.Component {
336
505
  { className: `${styles.modalContent || ""} ${hierarchy ? styles.hierarchyModal : ""} ${this.props.className || ""}`, contentLabel: title, ...(appearance === null || appearance === void 0 ? void 0 : appearance.iconURI) ? { headerImage: appearance.iconURI } : {}, headerClassName: styles.header, id: "blockEditorModal", onRequestClose: this.handleClose },
337
506
  React.createElement(
338
507
  "div",
339
- { "aria-busy": saving, className: styles.body, onCompositionStart: () => {
508
+ { "aria-busy": saving, className: styles.body, "data-block-editor-body": "", onCompositionStart: () => {
340
509
  this.composing = true;
341
510
  }, onCompositionEnd: () => {
342
511
  this.composing = false;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../field-errors.js", "../react.js"],
4
- "sourcesContent": ["// RJSF owns validation and messages; this adapter only decorates its rendered errors.\nconst bindBlockEditorFieldErrors = (container) => {\n const originals = new Map();\n const originalValue = (element, name) => {\n const values = originals.get(element);\n const previous = values && values.get(name);\n const current = element.getAttribute(name);\n return previous && current === previous.applied ? previous.original : current;\n };\n const setAttribute = (element, name, value) => {\n if (element.getAttribute(name) === value)\n return;\n const original = originalValue(element, name);\n if (!originals.has(element))\n originals.set(element, new Map());\n originals.get(element).set(name, { original, applied: value });\n element.setAttribute(name, value);\n };\n const restore = (element) => {\n for (const [name, { original, applied }] of originals.get(element)) {\n // Do not overwrite attributes subsequently changed by RJSF or a custom widget.\n if (element.getAttribute(name) !== applied)\n continue;\n if (original === null)\n element.removeAttribute(name);\n else\n element.setAttribute(name, original);\n }\n originals.delete(element);\n };\n const sync = () => {\n const invalid = new Set();\n const decorate = (element, messages, group = false) => {\n invalid.add(element);\n setAttribute(element, 'aria-invalid', 'true');\n setAttribute(element, 'data-block-editor-invalid', group ? 'group' : 'true');\n const descriptions = new Set((originalValue(element, 'aria-describedby') || '')\n .split(/\\s+/).filter(Boolean));\n for (const message of messages)\n descriptions.add(message.id);\n setAttribute(element, 'aria-describedby', [...descriptions].join(' '));\n if (group && !originalValue(element, 'role'))\n setAttribute(element, 'role', 'group');\n if (group && !element.hasAttribute('aria-label') && !originalValue(element, 'aria-labelledby')) {\n const titles = messages.map(message => message.id.replace(/__error$/, '__title'))\n .filter(id => {\n const title = element.ownerDocument.getElementById(id);\n return title && element.contains(title);\n });\n if (titles.length)\n setAttribute(element, 'aria-labelledby', titles.join(' '));\n }\n };\n for (const field of container.querySelectorAll('.rjsf .field.has-error')) {\n const messages = [...field.querySelectorAll('.error-detail[id]')].filter(message => { var _a; return message.closest('.field') === field && ((_a = message.textContent) === null || _a === void 0 ? void 0 : _a.trim()); });\n if (!messages.length)\n continue;\n if (field.classList.contains('field-object') || field.classList.contains('field-array')) {\n // Group constraints must not mark otherwise valid descendant controls as invalid.\n decorate(field, messages, true);\n continue;\n }\n for (const control of field.querySelectorAll('input:not([type=\"hidden\"]), select, textarea')) {\n if (control.closest('.field') !== field)\n continue;\n const descriptions = (control.getAttribute('aria-describedby') || '').split(/\\s+/);\n const ownMessages = messages.filter(message => descriptions.includes(message.id) ||\n message.id === `${control.id}__error`);\n if (ownMessages.length)\n decorate(control, ownMessages);\n }\n }\n for (const element of originals.keys()) {\n if (!invalid.has(element))\n restore(element);\n }\n };\n const observer = new container.ownerDocument.defaultView.MutationObserver(sync);\n observer.observe(container, { childList: true,\n subtree: true,\n characterData: true,\n attributes: true,\n attributeFilter: ['class', 'id'] });\n sync();\n return () => {\n observer.disconnect();\n for (const element of originals.keys())\n restore(element);\n };\n};\nexport default bindBlockEditorFieldErrors;\n", "import bindBlockEditorFieldErrors from './field-errors.js';\nexport { default as bindBlockEditorFieldErrors } from './field-errors.js';\nimport * as React from 'react';\nimport { BlockEditorConflictError } from './types.js';\nimport { BlockEditorStructureError } from './descendant-types.js';\nclass NodeBody extends React.Component {\n constructor() {\n super(...arguments);\n this.body = null;\n }\n componentDidMount() {\n try {\n this.unmountBody = this.props.editor.mount(this.body);\n }\n catch (error) {\n this.props.onError(error);\n }\n }\n componentWillUnmount() {\n var _a;\n try {\n (_a = this.unmountBody) === null || _a === void 0 ? void 0 : _a.call(this);\n }\n catch (error) {\n this.props.onError(error);\n }\n }\n render() { return React.createElement(\"div\", { ref: body => { this.body = body; } }); }\n}\nlet nextBodyId = 0;\nclass DescendantTree extends React.Component {\n constructor(props) {\n super(props);\n this.nodes = this.props.session.getNodes();\n this.children = new Map();\n this.sections = new Map();\n this.bodyIds = new Map();\n for (const node of this.nodes) {\n const path = node.inputPath;\n const parent = path.length ? path[path.length - 1].blockId : null;\n if (!this.children.has(parent))\n this.children.set(parent, []);\n this.children.get(parent).push(node);\n this.bodyIds.set(node.reference.blockId, `block-editor-node-${++nextBodyId}`);\n }\n this.state = { failedIcons: new Set(), expanded: new Set(this.nodes.filter(node => this.nodes.length <= 30 || node.inputPath.length === 0).map(node => node.reference.blockId)) };\n }\n componentWillUnmount() {\n if (this.focusFrame !== undefined)\n cancelAnimationFrame(this.focusFrame);\n }\n reveal(issue) {\n if (!issue || !('reference' in issue))\n return;\n const expanded = new Set(this.state.expanded);\n for (const step of issue.inputPath)\n expanded.add(step.blockId);\n expanded.add(issue.reference.blockId);\n this.setState({ expanded }, () => {\n if (this.focusFrame !== undefined)\n cancelAnimationFrame(this.focusFrame);\n this.focusFrame = requestAnimationFrame(() => {\n var _a;\n const section = this.sections.get(issue.reference.blockId);\n if (!section)\n return;\n const controls = [...section.querySelectorAll('input, textarea, select')];\n const path = (issue.path || '').replace(/^\\./, '').replace(/\\[(\\d+)\\]/g, '_$1').replace(/\\./g, '_');\n const field = controls.find(control => path && control.id.endsWith(`_${path}`)) || controls[0];\n const target = field || section.querySelector('button');\n target === null || target === void 0 ? void 0 : target.focus();\n (_a = target === null || target === void 0 ? void 0 : target.scrollIntoView) === null || _a === void 0 ? void 0 : _a.call(target, { block: 'nearest' });\n });\n });\n }\n toggle(id) {\n const expanded = new Set(this.state.expanded);\n if (expanded.has(id))\n expanded.delete(id);\n else\n expanded.add(id);\n this.setState({ expanded });\n }\n renderNode(node) {\n var _a, _b, _c;\n const { styles, session, messages } = this.props;\n const id = node.reference.blockId;\n const expanded = this.state.expanded.has(id);\n const editor = (_a = session.getEditor) === null || _a === void 0 ? void 0 : _a.call(session, id);\n const step = node.inputPath[node.inputPath.length - 1];\n const appearance = ((_b = this.props.nodeAppearances) === null || _b === void 0 ? void 0 : _b[id]) || {};\n const label = appearance.name || ((_c = this.props.nodeLabels) === null || _c === void 0 ? void 0 : _c[id]) || node.opcode;\n const style = {\n '--block-editor-node-colour': appearance.colour,\n '--block-editor-node-tint': appearance.tint\n };\n return React.createElement(\"section\", { className: styles.treeNode, \"data-block-editor-node\": id, key: id, style: style, ref: section => { if (section)\n this.sections.set(id, section);\n else\n this.sections.delete(id); } },\n React.createElement(\"h3\", { className: styles.nodeHeading },\n React.createElement(\"button\", { \"aria-controls\": this.bodyIds.get(id), \"aria-expanded\": expanded, \"data-block-editor-toggle\": id, disabled: this.props.disabled, type: \"button\", onClick: () => this.toggle(id) },\n React.createElement(\"span\", { \"aria-hidden\": \"true\" }, expanded ? '\u25BE ' : '\u25B8 '),\n appearance.iconURI && !this.state.failedIcons.has(id) ? React.createElement(\"img\", { alt: \"\", \"aria-hidden\": \"true\", className: styles.nodeIcon, \"data-block-editor-node-icon\": id, draggable: false, src: appearance.iconURI, onError: () => this.setState(state => ({ failedIcons: new Set([...state.failedIcons, id]) })) }) : null,\n React.createElement(\"span\", { className: styles.nodeCaption },\n React.createElement(\"span\", { \"data-block-editor-node-name\": id }, label),\n React.createElement(\"span\", { className: styles.nodeIdentity },\n step ? React.createElement(\"span\", { className: styles.branchName }, `${step.input} \u00B7 ${step.index + 1}: `) : null,\n id)))),\n React.createElement(\"div\", { hidden: !expanded, id: this.bodyIds.get(id) }, expanded ? React.createElement(React.Fragment, null,\n editor ? React.createElement(NodeBody, { editor: editor, onError: this.props.onError }) :\n React.createElement(\"p\", { className: styles.structuralNode }, messages.structuralNode),\n (this.children.get(id) || []).map(child => this.renderNode(child))) : null));\n }\n render() {\n return React.createElement(\"div\", { className: this.props.styles.tree }, (this.children.get(null) || []).map(node => this.renderNode(node)));\n }\n}\n/** The host injects its modal, localized strings and stylesheet mapping; no GUI imports are needed. */\nexport class BlockEditorDialog extends React.Component {\n constructor(props) {\n super(props);\n this.mounted = false;\n this.unmounting = false;\n this.composing = false;\n this.body = null;\n this.tree = null;\n this.removeListener = () => { };\n this.handleBody = (body) => {\n this.body = body;\n if (this.mounted)\n this.mountBody();\n };\n this.handleMountError = (error) => {\n var _a, _b;\n (_b = (_a = this.props).onError) === null || _b === void 0 ? void 0 : _b.call(_a, error);\n if (!this.unmounting)\n this.setState({ mountFailed: true });\n };\n this.handleClose = () => {\n if (this.props.session.cancel())\n return;\n if (this.props.session.getState().status !== 'saving')\n this.props.onClose();\n };\n this.handleSave = async () => {\n var _a;\n const result = await this.props.session.save();\n if (result.status === 'saved')\n this.props.onClose();\n if (result.status === 'invalid')\n (_a = this.tree) === null || _a === void 0 ? void 0 : _a.reveal(result.issues[0]);\n };\n this.state = { ...props.session.getState(), mountFailed: false };\n }\n componentDidMount() {\n this.mounted = true;\n this.removeListener = this.props.session.subscribe(() => {\n const state = this.props.session.getState();\n this.setState(state);\n if (['cancelled', 'disposed', 'invalidated'].includes(state.status))\n this.props.onClose();\n });\n this.mountBody();\n }\n componentWillUnmount() {\n var _a, _b, _c, _d;\n this.unmounting = true;\n this.mounted = false;\n if (this.focusFrame !== undefined)\n cancelAnimationFrame(this.focusFrame);\n this.removeListener();\n (_a = this.stopFieldErrors) === null || _a === void 0 ? void 0 : _a.call(this);\n try {\n (_b = this.unmountBody) === null || _b === void 0 ? void 0 : _b.call(this);\n }\n catch (error) {\n (_d = (_c = this.props).onError) === null || _d === void 0 ? void 0 : _d.call(_c, error);\n }\n finally {\n this.props.session.dispose();\n }\n }\n mountBody() {\n if (!this.body || this.unmountBody || this.state.mountFailed)\n return;\n try {\n if (!this.stopFieldErrors)\n this.stopFieldErrors = bindBlockEditorFieldErrors(this.body);\n if (typeof this.props.session.getNodes !== 'function')\n this.unmountBody = this.props.session.mount(this.body);\n // The modal establishes its focus scope after creating the portal.\n this.focusFrame = requestAnimationFrame(() => {\n if (!this.mounted)\n return;\n const first = this.body.querySelector('input, textarea, select') ||\n this.body.querySelector('button, [tabindex=\"0\"]');\n first === null || first === void 0 ? void 0 : first.focus();\n });\n }\n catch (error) {\n this.handleMountError(error);\n }\n }\n render() {\n var _a, _b, _c, _d;\n const { styles, messages, ModalComponent, session } = this.props;\n const saving = this.state.status === 'saving';\n const hierarchy = typeof session.getNodes === 'function';\n let fixed = false;\n if (session.getFixedInputView && (this.state.status === 'editing' || saving)) {\n try {\n fixed = Boolean(session.getFixedInputView());\n }\n catch (_e) {\n fixed = true;\n }\n }\n const root = (_a = session.getNodes) === null || _a === void 0 ? void 0 : _a.call(session).find(node => node.inputPath.length === 0);\n const rootId = ((_b = session.reference) === null || _b === void 0 ? void 0 : _b.blockId) || (root === null || root === void 0 ? void 0 : root.reference.blockId);\n const appearance = rootId ? (_c = this.props.nodeAppearances) === null || _c === void 0 ? void 0 : _c[rootId] : undefined;\n const name = (appearance === null || appearance === void 0 ? void 0 : appearance.name) || (rootId ? (_d = this.props.nodeLabels) === null || _d === void 0 ? void 0 : _d[rootId] : undefined) || (root === null || root === void 0 ? void 0 : root.opcode);\n const title = name ? messages.title.includes('{name}') ? messages.title.replace('{name}', () => name) :\n /\u30D6\u30ED\u30C3\u30AF|block/i.test(messages.title) ? messages.title.replace(/\u30D6\u30ED\u30C3\u30AF|block/i, () => name) :\n `${name}: ${messages.title}` : messages.title;\n return React.createElement(ModalComponent, { className: `${styles.modalContent || ''} ${hierarchy ? styles.hierarchyModal : ''} ${this.props.className || ''}`, contentLabel: title, ...((appearance === null || appearance === void 0 ? void 0 : appearance.iconURI) ? { headerImage: appearance.iconURI } : {}), headerClassName: styles.header, id: \"blockEditorModal\", onRequestClose: this.handleClose },\n React.createElement(\"div\", { \"aria-busy\": saving, className: styles.body, onCompositionStart: () => { this.composing = true; }, onCompositionEnd: () => { this.composing = false; }, onKeyDownCapture: event => {\n if (this.composing || event.nativeEvent.isComposing || event.keyCode === 229)\n event.stopPropagation();\n } },\n React.createElement(\"div\", { className: styles.editorBody },\n React.createElement(\"div\", { ref: this.handleBody }, hierarchy ? React.createElement(DescendantTree, { session: session, styles: styles, messages: messages, disabled: saving, nodeAppearances: this.props.nodeAppearances, nodeLabels: this.props.nodeLabels, onError: this.handleMountError, ref: tree => { this.tree = tree; } }) : null),\n React.createElement(\"div\", { \"aria-live\": \"polite\", className: styles.errors, role: \"status\" },\n saving ? messages.saving : null,\n fixed && this.state.issues.length ? React.createElement(\"p\", null, messages.invalidInput || messages.failed) : this.state.issues.map((issue, index) => {\n var _a;\n return hierarchy && 'reference' in issue ?\n React.createElement(\"button\", { className: styles.nodeError, \"data-block-editor-issue\": index, disabled: saving, key: index, type: \"button\", onClick: () => { var _a; return (_a = this.tree) === null || _a === void 0 ? void 0 : _a.reveal(issue); } },\n ((_a = this.props.nodeLabels) === null || _a === void 0 ? void 0 : _a[issue.reference.blockId]) || issue.reference.blockId,\n ': ',\n issue.message) : React.createElement(\"p\", { key: index }, issue.message);\n }),\n this.state.error instanceof BlockEditorStructureError ? messages.structureError :\n this.state.error instanceof BlockEditorConflictError ? messages.conflict :\n (this.state.error || this.state.mountFailed) ? messages.failed : null)),\n React.createElement(\"div\", { className: styles.buttons },\n React.createElement(\"button\", { disabled: saving, type: \"button\", onClick: this.handleClose }, messages.cancel),\n React.createElement(\"button\", { \"data-block-editor-save\": \"\", disabled: !this.state.canSave || this.state.mountFailed, type: \"button\", onClick: this.handleSave }, saving ? messages.saving : hierarchy ? messages.saveAll : messages.save))));\n }\n}\n"],
5
- "mappings": "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",
3
+ "sources": ["../field-errors.js", "../dialog-window.js", "../react.js"],
4
+ "sourcesContent": ["// RJSF owns validation and messages; this adapter only decorates its rendered errors.\nconst bindBlockEditorFieldErrors = (container) => {\n const originals = new Map();\n const originalValue = (element, name) => {\n const values = originals.get(element);\n const previous = values && values.get(name);\n const current = element.getAttribute(name);\n return previous && current === previous.applied ? previous.original : current;\n };\n const setAttribute = (element, name, value) => {\n if (element.getAttribute(name) === value)\n return;\n const original = originalValue(element, name);\n if (!originals.has(element))\n originals.set(element, new Map());\n originals.get(element).set(name, { original, applied: value });\n element.setAttribute(name, value);\n };\n const restore = (element) => {\n for (const [name, { original, applied }] of originals.get(element)) {\n // Do not overwrite attributes subsequently changed by RJSF or a custom widget.\n if (element.getAttribute(name) !== applied)\n continue;\n if (original === null)\n element.removeAttribute(name);\n else\n element.setAttribute(name, original);\n }\n originals.delete(element);\n };\n const sync = () => {\n const invalid = new Set();\n const decorate = (element, messages, group = false) => {\n invalid.add(element);\n setAttribute(element, 'aria-invalid', 'true');\n setAttribute(element, 'data-block-editor-invalid', group ? 'group' : 'true');\n const descriptions = new Set((originalValue(element, 'aria-describedby') || '')\n .split(/\\s+/).filter(Boolean));\n for (const message of messages)\n descriptions.add(message.id);\n setAttribute(element, 'aria-describedby', [...descriptions].join(' '));\n if (group && !originalValue(element, 'role'))\n setAttribute(element, 'role', 'group');\n if (group && !element.hasAttribute('aria-label') && !originalValue(element, 'aria-labelledby')) {\n const titles = messages.map(message => message.id.replace(/__error$/, '__title'))\n .filter(id => {\n const title = element.ownerDocument.getElementById(id);\n return title && element.contains(title);\n });\n if (titles.length)\n setAttribute(element, 'aria-labelledby', titles.join(' '));\n }\n };\n for (const field of container.querySelectorAll('.rjsf .field.has-error')) {\n const messages = [...field.querySelectorAll('.error-detail[id]')].filter(message => { var _a; return message.closest('.field') === field && ((_a = message.textContent) === null || _a === void 0 ? void 0 : _a.trim()); });\n if (!messages.length)\n continue;\n if (field.classList.contains('field-object') || field.classList.contains('field-array')) {\n // Group constraints must not mark otherwise valid descendant controls as invalid.\n decorate(field, messages, true);\n continue;\n }\n for (const control of field.querySelectorAll('input:not([type=\"hidden\"]), select, textarea')) {\n if (control.closest('.field') !== field)\n continue;\n const descriptions = (control.getAttribute('aria-describedby') || '').split(/\\s+/);\n const ownMessages = messages.filter(message => descriptions.includes(message.id) ||\n message.id === `${control.id}__error`);\n if (ownMessages.length)\n decorate(control, ownMessages);\n }\n }\n for (const element of originals.keys()) {\n if (!invalid.has(element))\n restore(element);\n }\n };\n const observer = new container.ownerDocument.defaultView.MutationObserver(sync);\n observer.observe(container, { childList: true,\n subtree: true,\n characterData: true,\n attributes: true,\n attributeFilter: ['class', 'id'] });\n sync();\n return () => {\n observer.disconnect();\n for (const element of originals.keys())\n restore(element);\n };\n};\nexport default bindBlockEditorFieldErrors;\n", "/** Add window controls to the injected host frame without depending on GUI internals. */\nexport function attachEditorDialogWindow(body, labels) {\n var _a;\n const dialog = body.closest('[role=\"dialog\"]');\n const header = (labels.headerClassName ? dialog === null || dialog === void 0 ? void 0 : dialog.getElementsByClassName(labels.headerClassName)[0] :\n dialog === null || dialog === void 0 ? void 0 : dialog.querySelector('header'));\n const content = body.closest('[data-block-editor-body]');\n if (!dialog || !header || !content || !((_a = header.parentElement) === null || _a === void 0 ? void 0 : _a.contains(content)))\n return;\n const doc = dialog.ownerDocument, win = doc.defaultView;\n if (!win)\n return;\n const frame = header.parentElement;\n const initialStyle = dialog.style.cssText;\n const language = doc.documentElement.lang || new URLSearchParams(win.location.search).get('lang') || win.navigator.language;\n const japanese = language.startsWith('ja');\n const maximizeLabel = labels.maximize || (japanese ? '\u5168\u753B\u9762\u5316' : 'Maximize');\n const restoreLabel = labels.restore || (japanese ? '\u5143\u306E\u30B5\u30A4\u30BA\u306B\u623B\u3059' : 'Restore window');\n let restoreBounds = null;\n let gesture = null;\n const handles = [];\n dialog.setAttribute('data-block-editor-window', '');\n if (frame !== dialog)\n frame.setAttribute('data-block-editor-window-frame', '');\n header.setAttribute('data-block-editor-titlebar', '');\n const maximize = doc.createElement('button');\n maximize.type = 'button';\n maximize.setAttribute('data-block-editor-maximize', '');\n const closeContainer = header.lastElementChild;\n if (closeContainer === null || closeContainer === void 0 ? void 0 : closeContainer.querySelector('button, [role=\"button\"]'))\n closeContainer.prepend(maximize);\n else\n header.insertBefore(maximize, closeContainer);\n const viewport = () => ({ width: win.innerWidth, height: win.innerHeight });\n const bounds = () => {\n const { x, y, width, height } = dialog.getBoundingClientRect();\n return { x, y, width, height };\n };\n const clamp = (value, min, max) => Math.min(Math.max(value, min), max);\n function fit(rect) {\n const view = viewport();\n const width = clamp(rect.width, Math.min(360, view.width), view.width);\n const height = clamp(rect.height, Math.min(280, view.height), view.height);\n return { width, height, x: clamp(rect.x, 0, view.width - width), y: clamp(rect.y, 0, view.height - height) };\n }\n function place(rect) {\n Object.assign(dialog.style, { margin: '0', inset: 'auto', transform: 'none', maxHeight: '100dvh',\n left: `${rect.x}px`, top: `${rect.y}px`, width: `${rect.width}px`, height: `${rect.height}px` });\n }\n function stop(event) {\n if (!gesture || (event && 'pointerId' in event && event.pointerId !== gesture.id))\n return;\n const { target, id } = gesture;\n gesture = null;\n if (target.hasPointerCapture(id))\n target.releasePointerCapture(id);\n dialog.removeAttribute('data-block-editor-dragging');\n }\n function start(event, edge) {\n if (restoreBounds || gesture || event.button !== 0 || !event.isPrimary)\n return;\n if (!edge && event.target.closest('button, a, input, select, textarea, [role=\"button\"]'))\n return;\n event.preventDefault();\n const target = event.currentTarget;\n gesture = { id: event.pointerId, target, edge, x: event.clientX, y: event.clientY, rect: fit(bounds()) };\n place(gesture.rect);\n target.setPointerCapture(event.pointerId);\n dialog.setAttribute('data-block-editor-dragging', '');\n }\n function move(event) {\n if (!gesture || event.pointerId !== gesture.id)\n return;\n const { rect, edge } = gesture, view = viewport();\n const dx = event.clientX - gesture.x, dy = event.clientY - gesture.y;\n if (!edge) {\n place(fit({ ...rect, x: rect.x + dx, y: rect.y + dy }));\n return;\n }\n const minWidth = Math.min(360, view.width), minHeight = Math.min(280, view.height);\n let left = rect.x, top = rect.y, right = rect.x + rect.width, bottom = rect.y + rect.height;\n if (edge.includes('w'))\n left = clamp(left + dx, 0, right - minWidth);\n if (edge.includes('e'))\n right = clamp(right + dx, left + minWidth, view.width);\n if (edge.includes('n'))\n top = clamp(top + dy, 0, bottom - minHeight);\n if (edge.includes('s'))\n bottom = clamp(bottom + dy, top + minHeight, view.height);\n place({ x: left, y: top, width: right - left, height: bottom - top });\n }\n const startMove = (event) => start(event, '');\n header.addEventListener('pointerdown', startMove);\n for (const edge of ['n', 'e', 's', 'w', 'ne', 'se', 'sw', 'nw']) {\n const handle = doc.createElement('div');\n handle.setAttribute('data-block-editor-resize', edge);\n handle.setAttribute('aria-hidden', 'true');\n handle.addEventListener('pointerdown', event => start(event, edge));\n dialog.append(handle);\n handles.push(handle);\n }\n function updateButton() {\n const label = restoreBounds ? restoreLabel : maximizeLabel;\n maximize.setAttribute('aria-label', label);\n maximize.setAttribute('aria-pressed', String(Boolean(restoreBounds)));\n maximize.title = label;\n maximize.textContent = restoreBounds ? '\u2750' : '\u26F6';\n dialog.toggleAttribute('data-block-editor-maximized', Boolean(restoreBounds));\n }\n function toggle() {\n stop();\n if (restoreBounds) {\n place(fit(restoreBounds));\n restoreBounds = null;\n }\n else {\n restoreBounds = bounds();\n place({ x: 0, y: 0, ...viewport() });\n }\n updateButton();\n }\n function resize() {\n stop();\n if (restoreBounds)\n place({ x: 0, y: 0, ...viewport() });\n else\n place(fit(bounds()));\n }\n maximize.addEventListener('click', toggle);\n win.addEventListener('pointermove', move);\n win.addEventListener('pointerup', stop);\n win.addEventListener('pointercancel', stop);\n win.addEventListener('blur', stop);\n win.addEventListener('resize', resize);\n dialog.addEventListener('lostpointercapture', stop);\n updateButton();\n return () => {\n stop();\n header.removeEventListener('pointerdown', startMove);\n win.removeEventListener('pointermove', move);\n win.removeEventListener('pointerup', stop);\n win.removeEventListener('pointercancel', stop);\n win.removeEventListener('blur', stop);\n win.removeEventListener('resize', resize);\n dialog.removeEventListener('lostpointercapture', stop);\n maximize.remove();\n handles.forEach(handle => handle.remove());\n dialog.style.cssText = initialStyle;\n for (const name of ['window', 'maximized', 'dragging'])\n dialog.removeAttribute(`data-block-editor-${name}`);\n if (frame !== dialog)\n frame.removeAttribute('data-block-editor-window-frame');\n header.removeAttribute('data-block-editor-titlebar');\n };\n}\n", "import bindBlockEditorFieldErrors from './field-errors.js';\nimport { attachEditorDialogWindow } from './dialog-window.js';\nexport { default as bindBlockEditorFieldErrors } from './field-errors.js';\nimport * as React from 'react';\nimport { BlockEditorConflictError } from './types.js';\nimport { BlockEditorStructureError } from './descendant-types.js';\nclass NodeBody extends React.Component {\n constructor() {\n super(...arguments);\n this.body = null;\n }\n componentDidMount() {\n try {\n this.unmountBody = this.props.editor.mount(this.body);\n }\n catch (error) {\n this.props.onError(error);\n }\n }\n componentWillUnmount() {\n var _a;\n try {\n (_a = this.unmountBody) === null || _a === void 0 ? void 0 : _a.call(this);\n }\n catch (error) {\n this.props.onError(error);\n }\n }\n render() { return React.createElement(\"div\", { ref: body => { this.body = body; } }); }\n}\nlet nextBodyId = 0;\nclass DescendantTree extends React.Component {\n constructor(props) {\n super(props);\n this.nodes = this.props.session.getNodes();\n this.children = new Map();\n this.sections = new Map();\n this.bodyIds = new Map();\n for (const node of this.nodes) {\n const path = node.inputPath;\n const parent = path.length ? path[path.length - 1].blockId : null;\n if (!this.children.has(parent))\n this.children.set(parent, []);\n this.children.get(parent).push(node);\n this.bodyIds.set(node.reference.blockId, `block-editor-node-${++nextBodyId}`);\n }\n this.state = { failedIcons: new Set(), expanded: new Set(this.nodes.filter(node => this.nodes.length <= 30 || node.inputPath.length === 0).map(node => node.reference.blockId)) };\n }\n componentWillUnmount() {\n if (this.focusFrame !== undefined)\n cancelAnimationFrame(this.focusFrame);\n }\n reveal(issue) {\n if (!issue || !('reference' in issue))\n return;\n const expanded = new Set(this.state.expanded);\n for (const step of issue.inputPath)\n expanded.add(step.blockId);\n expanded.add(issue.reference.blockId);\n this.setState({ expanded }, () => {\n if (this.focusFrame !== undefined)\n cancelAnimationFrame(this.focusFrame);\n this.focusFrame = requestAnimationFrame(() => {\n var _a;\n const section = this.sections.get(issue.reference.blockId);\n if (!section)\n return;\n const controls = [...section.querySelectorAll('input, textarea, select')];\n const path = (issue.path || '').replace(/^\\./, '').replace(/\\[(\\d+)\\]/g, '_$1').replace(/\\./g, '_');\n const field = controls.find(control => path && control.id.endsWith(`_${path}`)) || controls[0];\n const target = field || section.querySelector('button');\n target === null || target === void 0 ? void 0 : target.focus();\n (_a = target === null || target === void 0 ? void 0 : target.scrollIntoView) === null || _a === void 0 ? void 0 : _a.call(target, { block: 'nearest' });\n });\n });\n }\n toggle(id) {\n const expanded = new Set(this.state.expanded);\n if (expanded.has(id))\n expanded.delete(id);\n else\n expanded.add(id);\n this.setState({ expanded });\n }\n renderNode(node) {\n var _a, _b, _c;\n const { styles, session, messages } = this.props;\n const id = node.reference.blockId;\n const expanded = this.state.expanded.has(id);\n const editor = (_a = session.getEditor) === null || _a === void 0 ? void 0 : _a.call(session, id);\n const step = node.inputPath[node.inputPath.length - 1];\n const appearance = ((_b = this.props.nodeAppearances) === null || _b === void 0 ? void 0 : _b[id]) || {};\n const label = appearance.name || ((_c = this.props.nodeLabels) === null || _c === void 0 ? void 0 : _c[id]) || node.opcode;\n const style = {\n '--block-editor-node-colour': appearance.colour,\n '--block-editor-node-tint': appearance.tint\n };\n return React.createElement(\"section\", { className: styles.treeNode, \"data-block-editor-node\": id, key: id, style: style, ref: section => { if (section)\n this.sections.set(id, section);\n else\n this.sections.delete(id); } },\n React.createElement(\"h3\", { className: styles.nodeHeading },\n React.createElement(\"button\", { \"aria-controls\": this.bodyIds.get(id), \"aria-expanded\": expanded, \"data-block-editor-toggle\": id, disabled: this.props.disabled, type: \"button\", onClick: () => this.toggle(id) },\n React.createElement(\"span\", { \"aria-hidden\": \"true\" }, expanded ? '\u25BE ' : '\u25B8 '),\n appearance.iconURI && !this.state.failedIcons.has(id) ? React.createElement(\"img\", { alt: \"\", \"aria-hidden\": \"true\", className: styles.nodeIcon, \"data-block-editor-node-icon\": id, draggable: false, src: appearance.iconURI, onError: () => this.setState(state => ({ failedIcons: new Set([...state.failedIcons, id]) })) }) : null,\n React.createElement(\"span\", { className: styles.nodeCaption },\n React.createElement(\"span\", { \"data-block-editor-node-name\": id }, label),\n React.createElement(\"span\", { className: styles.nodeIdentity },\n step ? React.createElement(\"span\", { className: styles.branchName }, `${step.input} \u00B7 ${step.index + 1}: `) : null,\n id)))),\n React.createElement(\"div\", { hidden: !expanded, id: this.bodyIds.get(id) }, expanded ? React.createElement(React.Fragment, null,\n editor ? React.createElement(NodeBody, { editor: editor, onError: this.props.onError }) :\n React.createElement(\"p\", { className: styles.structuralNode }, messages.structuralNode),\n (this.children.get(id) || []).map(child => this.renderNode(child))) : null));\n }\n render() {\n return React.createElement(\"div\", { className: this.props.styles.tree }, (this.children.get(null) || []).map(node => this.renderNode(node)));\n }\n}\n/** The host injects its modal, localized strings and stylesheet mapping; no GUI imports are needed. */\nexport class BlockEditorDialog extends React.Component {\n constructor(props) {\n super(props);\n this.mounted = false;\n this.unmounting = false;\n this.composing = false;\n this.body = null;\n this.tree = null;\n this.removeListener = () => { };\n this.handleBody = (body) => {\n this.body = body;\n if (this.mounted)\n this.mountBody();\n };\n this.handleMountError = (error) => {\n var _a, _b;\n (_b = (_a = this.props).onError) === null || _b === void 0 ? void 0 : _b.call(_a, error);\n if (!this.unmounting)\n this.setState({ mountFailed: true });\n };\n this.handleClose = () => {\n if (this.props.session.cancel())\n return;\n if (this.props.session.getState().status !== 'saving')\n this.props.onClose();\n };\n this.handleSave = async () => {\n var _a;\n const result = await this.props.session.save();\n if (result.status === 'saved')\n this.props.onClose();\n if (result.status === 'invalid')\n (_a = this.tree) === null || _a === void 0 ? void 0 : _a.reveal(result.issues[0]);\n };\n this.state = { ...props.session.getState(), mountFailed: false };\n }\n componentDidMount() {\n this.mounted = true;\n this.removeListener = this.props.session.subscribe(() => {\n const state = this.props.session.getState();\n this.setState(state);\n if (['cancelled', 'disposed', 'invalidated'].includes(state.status))\n this.props.onClose();\n });\n this.mountBody();\n }\n componentWillUnmount() {\n var _a, _b, _c, _d, _e;\n this.unmounting = true;\n this.mounted = false;\n if (this.focusFrame !== undefined)\n cancelAnimationFrame(this.focusFrame);\n this.removeListener();\n (_a = this.stopFieldErrors) === null || _a === void 0 ? void 0 : _a.call(this);\n (_b = this.stopWindow) === null || _b === void 0 ? void 0 : _b.call(this);\n try {\n (_c = this.unmountBody) === null || _c === void 0 ? void 0 : _c.call(this);\n }\n catch (error) {\n (_e = (_d = this.props).onError) === null || _e === void 0 ? void 0 : _e.call(_d, error);\n }\n finally {\n this.props.session.dispose();\n }\n }\n mountBody() {\n if (!this.body || this.unmountBody || this.state.mountFailed)\n return;\n try {\n if (!this.stopWindow)\n this.stopWindow = attachEditorDialogWindow(this.body, {\n headerClassName: this.props.styles.header,\n maximize: this.props.messages.maximize,\n restore: this.props.messages.restore\n });\n if (!this.stopFieldErrors)\n this.stopFieldErrors = bindBlockEditorFieldErrors(this.body);\n if (typeof this.props.session.getNodes !== 'function')\n this.unmountBody = this.props.session.mount(this.body);\n // The modal establishes its focus scope after creating the portal.\n this.focusFrame = requestAnimationFrame(() => {\n if (!this.mounted)\n return;\n const first = this.body.querySelector('input, textarea, select') ||\n this.body.querySelector('button, [tabindex=\"0\"]');\n first === null || first === void 0 ? void 0 : first.focus();\n });\n }\n catch (error) {\n this.handleMountError(error);\n }\n }\n render() {\n var _a, _b, _c, _d;\n const { styles, messages, ModalComponent, session } = this.props;\n const saving = this.state.status === 'saving';\n const hierarchy = typeof session.getNodes === 'function';\n let fixed = false;\n if (session.getFixedInputView && (this.state.status === 'editing' || saving)) {\n try {\n fixed = Boolean(session.getFixedInputView());\n }\n catch (_e) {\n fixed = true;\n }\n }\n const root = (_a = session.getNodes) === null || _a === void 0 ? void 0 : _a.call(session).find(node => node.inputPath.length === 0);\n const rootId = ((_b = session.reference) === null || _b === void 0 ? void 0 : _b.blockId) || (root === null || root === void 0 ? void 0 : root.reference.blockId);\n const appearance = rootId ? (_c = this.props.nodeAppearances) === null || _c === void 0 ? void 0 : _c[rootId] : undefined;\n const name = (appearance === null || appearance === void 0 ? void 0 : appearance.name) || (rootId ? (_d = this.props.nodeLabels) === null || _d === void 0 ? void 0 : _d[rootId] : undefined) || (root === null || root === void 0 ? void 0 : root.opcode);\n const title = name ? messages.title.includes('{name}') ? messages.title.replace('{name}', () => name) :\n /\u30D6\u30ED\u30C3\u30AF|block/i.test(messages.title) ? messages.title.replace(/\u30D6\u30ED\u30C3\u30AF|block/i, () => name) :\n `${name}: ${messages.title}` : messages.title;\n return React.createElement(ModalComponent, { className: `${styles.modalContent || ''} ${hierarchy ? styles.hierarchyModal : ''} ${this.props.className || ''}`, contentLabel: title, ...((appearance === null || appearance === void 0 ? void 0 : appearance.iconURI) ? { headerImage: appearance.iconURI } : {}), headerClassName: styles.header, id: \"blockEditorModal\", onRequestClose: this.handleClose },\n React.createElement(\"div\", { \"aria-busy\": saving, className: styles.body, \"data-block-editor-body\": \"\", onCompositionStart: () => { this.composing = true; }, onCompositionEnd: () => { this.composing = false; }, onKeyDownCapture: event => {\n if (this.composing || event.nativeEvent.isComposing || event.keyCode === 229)\n event.stopPropagation();\n } },\n React.createElement(\"div\", { className: styles.editorBody },\n React.createElement(\"div\", { ref: this.handleBody }, hierarchy ? React.createElement(DescendantTree, { session: session, styles: styles, messages: messages, disabled: saving, nodeAppearances: this.props.nodeAppearances, nodeLabels: this.props.nodeLabels, onError: this.handleMountError, ref: tree => { this.tree = tree; } }) : null),\n React.createElement(\"div\", { \"aria-live\": \"polite\", className: styles.errors, role: \"status\" },\n saving ? messages.saving : null,\n fixed && this.state.issues.length ? React.createElement(\"p\", null, messages.invalidInput || messages.failed) : this.state.issues.map((issue, index) => {\n var _a;\n return hierarchy && 'reference' in issue ?\n React.createElement(\"button\", { className: styles.nodeError, \"data-block-editor-issue\": index, disabled: saving, key: index, type: \"button\", onClick: () => { var _a; return (_a = this.tree) === null || _a === void 0 ? void 0 : _a.reveal(issue); } },\n ((_a = this.props.nodeLabels) === null || _a === void 0 ? void 0 : _a[issue.reference.blockId]) || issue.reference.blockId,\n ': ',\n issue.message) : React.createElement(\"p\", { key: index }, issue.message);\n }),\n this.state.error instanceof BlockEditorStructureError ? messages.structureError :\n this.state.error instanceof BlockEditorConflictError ? messages.conflict :\n (this.state.error || this.state.mountFailed) ? messages.failed : null)),\n React.createElement(\"div\", { className: styles.buttons },\n React.createElement(\"button\", { disabled: saving, type: \"button\", onClick: this.handleClose }, messages.cancel),\n React.createElement(\"button\", { \"data-block-editor-save\": \"\", disabled: !this.state.canSave || this.state.mountFailed, type: \"button\", onClick: this.handleSave }, saving ? messages.saving : hierarchy ? messages.saveAll : messages.save))));\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["_a"]
7
7
  }
@@ -0,0 +1,50 @@
1
+ # 共通編集ダイアログの移動・サイズ変更
2
+
3
+ 関連: [共通UI契約 Issue #7](https://github.com/kubohiroya/turbowarp-extension-data-editor/issues/7)。2026-10-31のユーザー追加依頼によるローカル変更で、作業ブランチは `fix/ui/dialog-window` です。ユーザーの追加承認に基づき、今回の差分のcommit・push・PR作成・CI成功後のSquash Merge・npm/GitHub Release公開を行います。
4
+
5
+ `BlockEditorDialog` の単一編集・階層編集に共通して、次の操作を提供します。
6
+
7
+ - タイトルのドラッグで移動。
8
+ - 四辺・四隅のドラッグでサイズ変更。
9
+ - Xの左の「全画面化」でブラウザー内いっぱいに最大化し、「元のサイズに戻す」で以前の位置・サイズへ復元。
10
+
11
+ 画面外への移動を制限し、最小サイズは360×280px、画面が小さい場合は画面内に収めます。本文はスクロールし、ヘッダーと保存・キャンセルは固定表示します。操作中もフォームを再mountせず、草稿・展開状態・編集セッションを保持します。閉じるとポインターと画面サイズ変更の監視を解放します。
12
+
13
+ ホストは従来どおり `ModalComponent` とCSSの対応表を注入します。モーダルの `role="dialog"` と、`headerClassName` または `header` 要素を使い、GUI内部をimportしません。共通コアへのReact依存も追加しません。`EditorDialogMessages.maximize`・`restore` は任意で、未指定の場合は画面の言語属性、URLの `lang`、ブラウザー言語から日本語/英語を選びます。
14
+
15
+ 依存順は、既存共通UI→ウィンドウ操作とCSS→ホストの組み込みビルド→実Editor確認です。既存の `blockEditorDialogs` 等のフラグ運用を維持します。
16
+
17
+ ## 受け入れ基準・検証
18
+
19
+ - [x] 単一・階層の両編集で移動・四辺四隅のリサイズ・最大化と復元ができる。
20
+ - [x] ウィンドウ操作でフォームを再mountせず、入力中の草稿を保持する。
21
+ - [x] 保存は既存のセッション経由で反映し、キャンセルでは変更を破棄する。
22
+ - [x] 最小サイズ・320px幅・390px幅でも閉じる・保存・キャンセルを操作できる。
23
+ - [x] 日英のボタン名、キーボードでの最大化、破棄時の監視解除を確認する。
24
+ - [x] 型検査・配布ビルド・既存ダイアログ表示テスト・実Editorの固定入力保存を確認する。
25
+
26
+ ```sh
27
+ npm run build
28
+ node --test test/react-dialog.test.mjs test/fixed-dialog.test.mjs
29
+ node --test test/e2e/layout/dialog-window.mjs
30
+ ```
31
+
32
+ ## 運用ログ(2026-10-31 JST)
33
+
34
+ - start: 0.6.0の共通UIを基点に隔離ブランチで着手。元checkoutの既存WIPは保持。
35
+ - blocked: 初回の型検査でDOM要素のnull絞り込み、ブラウザー試験で初期高さと画面境界の条件を検出し、修正。
36
+ - done: 型検査と配布ビルド、既存表示4件・ウィンドウ操作のブラウザー4件が成功。画面サイズ変更の検証はresizeイベントの反映を待って確認。
37
+ - done: 実Editorの固定入力を10→37.5へ編集し、移動・最大化・狭幅・復元後の保存に成功。ページ例外0。
38
+
39
+ ## 切戻し
40
+
41
+ 即時の機能停止はホストの `blockEditorDialogs` をOFFにして再起動します。ウィンドウ操作だけを戻す場合は、本差分の `react.tsx`・`react.css`・`dialog-window.ts` を揃えて戻して共通配布物とホストを再ビルドします。保存済みの引数形式とSB3は変更しません。
42
+
43
+ ## 公開手順(2026-10-31 JST)
44
+
45
+ - branch: `fix/ui/dialog-window` / base: `main`。対象は共通UI・CSS・型・関連テスト・CIと0.7.0の版更新。
46
+ - 直列: data-editor CI→Squash Merge→main CI→v0.7.0のRelease/npm公開→Editorの固定依存更新・公開。
47
+ - 既存結果の前提を維持し、今回追加した4ブラウザーケースを通常CIでも実行します。
48
+ - 受け入れ基準: 両CIとRelease成功、npmの版・merge revision一致、公開Editorで両ダイアログ操作を確認。
49
+ - ロールバック: Editorの固定core版を0.6.0へ戻し、対応する固定SHAと一緒に再配信。元SB3と作業ファイルは保持。
50
+ - start: ユーザーが今回の2リポジトリの公開操作を明示承認。
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "url": "https://github.com/kubohiroya"
6
6
  },
7
7
  "name": "@kubohiroya/turbowarp-extension-data-editor",
8
- "version": "0.6.0",
8
+ "version": "0.7.0",
9
9
  "description": "Custom editor sessions and UI for structured data handled by TurboWarp extensions",
10
10
  "type": "module",
11
11
  "sideEffects": [