@juo/blocks 1.13.0 → 1.15.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.
- package/dist/ExtensionRoot-C3lVJEBl.js +385 -0
- package/dist/block.d.ts.map +1 -1
- package/dist/block.devtools.test.d.ts +2 -0
- package/dist/block.devtools.test.d.ts.map +1 -0
- package/dist/{bridge-w5KQ-czl.js → bridge-xiKEzCGR.js} +146 -32
- package/dist/context.d.ts.map +1 -1
- package/dist/context.devtools.test.d.ts +2 -0
- package/dist/context.devtools.test.d.ts.map +1 -0
- package/dist/core.js +786 -37
- package/dist/{juo-workflow-BlG9CcAG.js → css-runtime-ClH0MEYr.js} +511 -618
- package/dist/devtools/env.d.ts +3 -0
- package/dist/devtools/env.d.ts.map +1 -0
- package/dist/devtools/hook.d.ts +40 -0
- package/dist/devtools/hook.d.ts.map +1 -0
- package/dist/devtools/index.d.ts +5 -0
- package/dist/devtools/index.d.ts.map +1 -0
- package/dist/devtools/instrumentation.d.ts +47 -0
- package/dist/devtools/instrumentation.d.ts.map +1 -0
- package/dist/devtools/protocol.d.ts +77 -0
- package/dist/devtools/protocol.d.ts.map +1 -0
- package/dist/devtools.js +11 -0
- package/dist/editor/bridge.d.ts +8 -0
- package/dist/editor/bridge.d.ts.map +1 -1
- package/dist/editor/canvas-mode-signal.d.ts +22 -0
- package/dist/editor/canvas-mode-signal.d.ts.map +1 -0
- package/dist/editor/canvas-mode.d.ts +15 -0
- package/dist/editor/canvas-mode.d.ts.map +1 -0
- package/dist/editor/canvas-mode.test.d.ts +2 -0
- package/dist/editor/canvas-mode.test.d.ts.map +1 -0
- package/dist/editor/components.d.ts +113 -0
- package/dist/editor/components.d.ts.map +1 -1
- package/dist/editor/components.test.d.ts.map +1 -1
- package/dist/editor/handler.d.ts.map +1 -1
- package/dist/editor/handler.test.d.ts +2 -0
- package/dist/editor/handler.test.d.ts.map +1 -0
- package/dist/editor/layout-command-emitter.d.ts +37 -0
- package/dist/editor/layout-command-emitter.d.ts.map +1 -0
- package/dist/editor/layout-command-emitter.test.d.ts +2 -0
- package/dist/editor/layout-command-emitter.test.d.ts.map +1 -0
- package/dist/editor/layout-system-signal.d.ts +21 -0
- package/dist/editor/layout-system-signal.d.ts.map +1 -0
- package/dist/editor/main.d.ts +1 -0
- package/dist/editor/main.d.ts.map +1 -1
- package/dist/editor/messages.d.ts +96 -3
- package/dist/editor/messages.d.ts.map +1 -1
- package/dist/editor/messages.test.d.ts +2 -0
- package/dist/editor/messages.test.d.ts.map +1 -0
- package/dist/editor/surface-context.d.ts +7 -0
- package/dist/editor/surface-context.d.ts.map +1 -0
- package/dist/editor/surface-context.test.d.ts +2 -0
- package/dist/editor/surface-context.test.d.ts.map +1 -0
- package/dist/editor/wrapper-shared.d.ts +31 -0
- package/dist/editor/wrapper-shared.d.ts.map +1 -0
- package/dist/editor.js +882 -57
- package/dist/gridstack-adapter-CDWbSpbt.js +5489 -0
- package/dist/index-JSv6UH_o.js +169 -0
- package/dist/layout/css-runtime.d.ts +41 -0
- package/dist/layout/css-runtime.d.ts.map +1 -0
- package/dist/layout/css-runtime.test.d.ts +2 -0
- package/dist/layout/css-runtime.test.d.ts.map +1 -0
- package/dist/layout/derive.d.ts +4 -0
- package/dist/layout/derive.d.ts.map +1 -0
- package/dist/layout/derive.test.d.ts +2 -0
- package/dist/layout/derive.test.d.ts.map +1 -0
- package/dist/layout/dividers.d.ts +34 -0
- package/dist/layout/dividers.d.ts.map +1 -0
- package/dist/layout/dividers.test.d.ts +2 -0
- package/dist/layout/dividers.test.d.ts.map +1 -0
- package/dist/layout/engine.d.ts +3 -0
- package/dist/layout/engine.d.ts.map +1 -0
- package/dist/layout/engine.test.d.ts +2 -0
- package/dist/layout/engine.test.d.ts.map +1 -0
- package/dist/layout/grid-utils.d.ts +57 -0
- package/dist/layout/grid-utils.d.ts.map +1 -0
- package/dist/layout/grid-utils.test.d.ts +2 -0
- package/dist/layout/grid-utils.test.d.ts.map +1 -0
- package/dist/layout/index.d.ts +13 -0
- package/dist/layout/index.d.ts.map +1 -0
- package/dist/layout/index.test.d.ts +2 -0
- package/dist/layout/index.test.d.ts.map +1 -0
- package/dist/layout/insert.d.ts +34 -0
- package/dist/layout/insert.d.ts.map +1 -0
- package/dist/layout/insert.test.d.ts +2 -0
- package/dist/layout/insert.test.d.ts.map +1 -0
- package/dist/layout/override.d.ts +10 -0
- package/dist/layout/override.d.ts.map +1 -0
- package/dist/layout/override.test.d.ts +2 -0
- package/dist/layout/override.test.d.ts.map +1 -0
- package/dist/layout/project-css.d.ts +6 -0
- package/dist/layout/project-css.d.ts.map +1 -0
- package/dist/layout/project-css.test.d.ts +2 -0
- package/dist/layout/project-css.test.d.ts.map +1 -0
- package/dist/layout/project-gridstack.d.ts +50 -0
- package/dist/layout/project-gridstack.d.ts.map +1 -0
- package/dist/layout/project-gridstack.test.d.ts +2 -0
- package/dist/layout/project-gridstack.test.d.ts.map +1 -0
- package/dist/layout/reconcile.d.ts +23 -0
- package/dist/layout/reconcile.d.ts.map +1 -0
- package/dist/layout/reconcile.test.d.ts +2 -0
- package/dist/layout/reconcile.test.d.ts.map +1 -0
- package/dist/layout/types.d.ts +118 -0
- package/dist/layout/types.d.ts.map +1 -0
- package/dist/layout-mode-adapter-BBd4JRQd.js +21 -0
- package/dist/main.d.ts +7 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/morph-n4LMxOYo.js +182 -0
- package/dist/preact/block.d.ts.map +1 -1
- package/dist/preact.js +14 -10
- package/dist/project-gridstack-CM783oKI.js +52 -0
- package/dist/react/block.d.ts.map +1 -1
- package/dist/react.js +13 -9
- package/dist/registry.devtools.test.d.ts +2 -0
- package/dist/registry.devtools.test.d.ts.map +1 -0
- package/dist/theme-state.d.ts +16 -0
- package/dist/theme-state.d.ts.map +1 -1
- package/dist/theme-state.layout.test.d.ts +2 -0
- package/dist/theme-state.layout.test.d.ts.map +1 -0
- package/dist/theme-state.test.d.ts +2 -0
- package/dist/theme-state.test.d.ts.map +1 -0
- package/dist/vue/block.d.ts.map +1 -1
- package/dist/vue.js +22 -4
- package/dist/web-components/ExtensionRoot.d.ts +50 -2
- package/dist/web-components/ExtensionRoot.d.ts.map +1 -1
- package/dist/web-components/editor/ExtensionRoot.d.ts +11 -0
- package/dist/web-components/editor/ExtensionRoot.d.ts.map +1 -0
- package/dist/web-components/editor/ExtensionRoot.test.d.ts +2 -0
- package/dist/web-components/editor/ExtensionRoot.test.d.ts.map +1 -0
- package/dist/web-components/editor/InlineText.d.ts +1 -0
- package/dist/web-components/editor/InlineText.d.ts.map +1 -1
- package/dist/web-components/editor/editor-layout-controller.d.ts +28 -0
- package/dist/web-components/editor/editor-layout-controller.d.ts.map +1 -0
- package/dist/web-components/editor/gridstack-adapter.d.ts +3 -0
- package/dist/web-components/editor/gridstack-adapter.d.ts.map +1 -0
- package/dist/web-components/editor/gridstack-adapter.test.d.ts +2 -0
- package/dist/web-components/editor/gridstack-adapter.test.d.ts.map +1 -0
- package/dist/web-components/editor/morph.d.ts +32 -0
- package/dist/web-components/editor/morph.d.ts.map +1 -0
- package/dist/web-components/editor/morph.test.d.ts +2 -0
- package/dist/web-components/editor/morph.test.d.ts.map +1 -0
- package/dist/web-components/layout/layout-controller.d.ts +55 -0
- package/dist/web-components/layout/layout-controller.d.ts.map +1 -0
- package/dist/web-components/layout/view-layout-controller.d.ts +17 -0
- package/dist/web-components/layout/view-layout-controller.d.ts.map +1 -0
- package/dist/web-components/layout/view-layout-controller.test.d.ts +2 -0
- package/dist/web-components/layout/view-layout-controller.test.d.ts.map +1 -0
- package/dist/web-components/layout-grid.d.ts +47 -0
- package/dist/web-components/layout-grid.d.ts.map +1 -0
- package/dist/web-components/layout-grid.test.d.ts +2 -0
- package/dist/web-components/layout-grid.test.d.ts.map +1 -0
- package/dist/web-components/layout-mode-adapter.d.ts +57 -0
- package/dist/web-components/layout-mode-adapter.d.ts.map +1 -0
- package/dist/web-components/layout-mode-adapter.test.d.ts +2 -0
- package/dist/web-components/layout-mode-adapter.test.d.ts.map +1 -0
- package/dist/web-components-editor.js +130 -17
- package/dist/web-components-runtime.js +4 -3
- package/package.json +7 -2
- package/dist/ExtensionRoot-2xTGTu3K.js +0 -219
package/dist/editor.js
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
var __defProp = Object.defineProperty;
|
|
2
2
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
3
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
|
-
import { createBlockInstanceFromObject, indexOverrides, DEFAULT_GLOBAL_STYLES, effect, onRegisterBlock, getDefinedBlocks } from "@juo/blocks";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
4
|
+
import { serializeBlocks, createBlockInstanceFromObject, setActiveSurfaceContext, indexOverrides, canvasMode, getActiveSurfaceContext, emitLayoutCommand, DEFAULT_GLOBAL_STYLES, effect, setLayoutCommandEmitter, setLayoutCommandDispatcher, onRegisterBlock, getDefinedBlocks, clearAllSurfaceContexts } from "@juo/blocks";
|
|
5
|
+
import { canvasMode as canvasMode2 } from "@juo/blocks";
|
|
6
|
+
import { L as LAYOUT_BLOCK_WRAPPER_TAG, a as createEditorBridge, b as createOpenAddBlockMenuMessage, d as createRemoveBlockMessage, i as isBlockWrapperTag, r as resolveOutlineTarget, e as getBlockLabel, f as createLayoutCommandMessage, h as createRegisterBlocksMessage, j as createRegisterRoutesMessage } from "./bridge-xiKEzCGR.js";
|
|
7
|
+
import { k, l, m, c, n, o, p, q, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, g, M, N } from "./bridge-xiKEzCGR.js";
|
|
8
|
+
import { s as setCanvasMode, e as enterLayout } from "./morph-n4LMxOYo.js";
|
|
9
|
+
import { r } from "./morph-n4LMxOYo.js";
|
|
7
10
|
function createEditorHandler(options) {
|
|
8
11
|
const { themeState, onBlockSelection } = options;
|
|
9
12
|
const blockSurfaceIndex = /* @__PURE__ */ new Map();
|
|
@@ -53,19 +56,23 @@ function createEditorHandler(options) {
|
|
|
53
56
|
return "page";
|
|
54
57
|
}
|
|
55
58
|
function handleMessage(message) {
|
|
56
|
-
var _a
|
|
59
|
+
var _a;
|
|
57
60
|
if (message.type === "SET_GLOBAL_STYLES") {
|
|
58
61
|
themeState.setGlobalStyles(message.payload.styles);
|
|
59
62
|
return;
|
|
60
63
|
}
|
|
61
64
|
if (message.type === "PROVIDE_THEME_STATE") {
|
|
62
65
|
const surface = message.payload.surface ?? "page";
|
|
63
|
-
const blocks = ((_a = message.payload.blocks) == null ? void 0 : _a.map(
|
|
64
|
-
(block) => createBlockInstanceFromObject(block)
|
|
65
|
-
)) || [];
|
|
66
66
|
const target = getBlocks(surface);
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
const incoming = message.payload.blocks ?? [];
|
|
68
|
+
const unchanged = JSON.stringify(serializeBlocks(target.value)) === JSON.stringify(incoming);
|
|
69
|
+
if (!unchanged) {
|
|
70
|
+
target.value = incoming.map(
|
|
71
|
+
(block) => createBlockInstanceFromObject(block)
|
|
72
|
+
);
|
|
73
|
+
indexSurface(surface, target.value);
|
|
74
|
+
}
|
|
75
|
+
setActiveSurfaceContext(surface, message.payload.id);
|
|
69
76
|
} else if (message.type === "SELECT_BLOCK") {
|
|
70
77
|
const blockId = message.payload.blockId;
|
|
71
78
|
if (onBlockSelection) {
|
|
@@ -138,12 +145,12 @@ function createEditorHandler(options) {
|
|
|
138
145
|
for (const slotKey of Object.keys(blocks[i].slots || {})) {
|
|
139
146
|
const slotBlocks = blocks[i].slots[slotKey];
|
|
140
147
|
const slotArray = Array.isArray(slotBlocks) ? slotBlocks : [slotBlocks];
|
|
141
|
-
for (let
|
|
142
|
-
if (typeof slotArray[
|
|
148
|
+
for (let j = 0; j < slotArray.length; j++) {
|
|
149
|
+
if (typeof slotArray[j] !== "string" && ((_a2 = slotArray[j]) == null ? void 0 : _a2.id) === targetId) {
|
|
143
150
|
if (position === "before") {
|
|
144
|
-
slotArray.splice(
|
|
151
|
+
slotArray.splice(j, 0, newBlock2);
|
|
145
152
|
} else {
|
|
146
|
-
slotArray.splice(
|
|
153
|
+
slotArray.splice(j + 1, 0, newBlock2);
|
|
147
154
|
}
|
|
148
155
|
blocks[i].slots[slotKey] = slotArray;
|
|
149
156
|
return true;
|
|
@@ -204,7 +211,7 @@ function createEditorHandler(options) {
|
|
|
204
211
|
const slotBlocks = blocks[i].slots[slot];
|
|
205
212
|
const slotArray = Array.isArray(slotBlocks) ? slotBlocks : [slotBlocks];
|
|
206
213
|
const index = slotArray.findIndex(
|
|
207
|
-
(
|
|
214
|
+
(b) => typeof b !== "string" && (b == null ? void 0 : b.id) === blockId
|
|
208
215
|
);
|
|
209
216
|
if (index !== -1) {
|
|
210
217
|
slotArray.splice(index, 1);
|
|
@@ -230,7 +237,7 @@ function createEditorHandler(options) {
|
|
|
230
237
|
const target = getBlocks(surface);
|
|
231
238
|
let resolvedParentId = message.payload.location.parentId;
|
|
232
239
|
if (resolvedParentId === "root") {
|
|
233
|
-
resolvedParentId = ((
|
|
240
|
+
resolvedParentId = ((_a = target.value[0]) == null ? void 0 : _a.id) ?? "root";
|
|
234
241
|
}
|
|
235
242
|
findAndRemoveBlock(
|
|
236
243
|
target.value,
|
|
@@ -248,7 +255,7 @@ function createEditorHandler(options) {
|
|
|
248
255
|
const slotBlocks = block.slots[slot];
|
|
249
256
|
const slotArray = Array.isArray(slotBlocks) ? slotBlocks : [slotBlocks];
|
|
250
257
|
const oldIndex = slotArray.findIndex(
|
|
251
|
-
(
|
|
258
|
+
(b) => typeof b !== "string" && (b == null ? void 0 : b.id) === blockId
|
|
252
259
|
);
|
|
253
260
|
if (oldIndex !== -1) {
|
|
254
261
|
const [moved] = slotArray.splice(oldIndex, 1);
|
|
@@ -282,6 +289,17 @@ function createEditorHandler(options) {
|
|
|
282
289
|
);
|
|
283
290
|
target.value = [...target.value];
|
|
284
291
|
indexSurface(surface, target.value);
|
|
292
|
+
} else if (message.type === "SET_LAYOUTING_MODE") {
|
|
293
|
+
setCanvasMode(message.payload.enabled);
|
|
294
|
+
} else if (message.type === "PROVIDE_LAYOUT_DOCUMENT") {
|
|
295
|
+
const surface = message.payload.surface;
|
|
296
|
+
const target = surface === "overlay" ? themeState.overlay : themeState.page;
|
|
297
|
+
setActiveSurfaceContext(surface, message.payload.id);
|
|
298
|
+
const incoming = message.payload.layout;
|
|
299
|
+
const changed = JSON.stringify(target.layout.value) !== JSON.stringify(incoming);
|
|
300
|
+
if (changed) {
|
|
301
|
+
target.layout.value = incoming;
|
|
302
|
+
}
|
|
285
303
|
}
|
|
286
304
|
}
|
|
287
305
|
indexSurface("page", themeState.page.blocks.value);
|
|
@@ -789,14 +807,39 @@ const addBlockIconSvg = `
|
|
|
789
807
|
<path d="M7 4.77V9.23M4.77 7H9.23" stroke="white" stroke-width="1.14" stroke-linecap="round"/>
|
|
790
808
|
</svg>
|
|
791
809
|
`;
|
|
792
|
-
const
|
|
810
|
+
const layoutToggleSvg = `
|
|
793
811
|
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
794
|
-
<
|
|
795
|
-
<
|
|
796
|
-
<
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
812
|
+
<rect x="8.5" y="0.5" width="5" height="7" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
|
813
|
+
<rect x="8.5" y="9.5" width="5" height="4" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
|
814
|
+
<rect x="0.5" y="0.5" width="5" height="13" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
|
815
|
+
</svg>
|
|
816
|
+
`;
|
|
817
|
+
const dragGripSvg = `
|
|
818
|
+
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
819
|
+
<circle cx="5" cy="3.5" r="1" fill="currentColor"/>
|
|
820
|
+
<circle cx="9" cy="3.5" r="1" fill="currentColor"/>
|
|
821
|
+
<circle cx="5" cy="7" r="1" fill="currentColor"/>
|
|
822
|
+
<circle cx="9" cy="7" r="1" fill="currentColor"/>
|
|
823
|
+
<circle cx="5" cy="10.5" r="1" fill="currentColor"/>
|
|
824
|
+
<circle cx="9" cy="10.5" r="1" fill="currentColor"/>
|
|
825
|
+
</svg>
|
|
826
|
+
`;
|
|
827
|
+
const addCircleOutlineSvg = `
|
|
828
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14" fill="none">
|
|
829
|
+
<rect x="0.5" y="0.5" width="13" height="13" rx="6.5" stroke="currentColor"/>
|
|
830
|
+
<path d="M4.17133 7.0003L9.82818 7.0003" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
|
831
|
+
<path d="M7.00006 9.82843L7.00006 4.17157" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
|
832
|
+
</svg>
|
|
833
|
+
`;
|
|
834
|
+
const fillHorizontalSvg = `
|
|
835
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14" fill="none">
|
|
836
|
+
<path d="M4.50013 4.11285L1.50013 7.00174L4.50013 9.89062M1.50013 7.00174L12.3647 7.00174" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
|
837
|
+
<path d="M9.50024 4.11328L12.5002 7.00217L9.50024 9.89106" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
|
838
|
+
</svg>
|
|
839
|
+
`;
|
|
840
|
+
const trashIconSvg = `
|
|
841
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14" fill="none">
|
|
842
|
+
<path d="M11.375 2.39649V11.5C11.375 12.6046 10.4796 13.5 9.375 13.5H4.375C3.27043 13.5 2.375 12.6046 2.375 11.5V2.39649H4.375M11.375 2.39649H9.375M11.375 2.39649H13.125M9.375 2.39649V0.5H4.375V2.39649M9.375 2.39649H4.375M4.375 2.39649H0.875M5 4.06653V11.0665M7 4.06653V11.0665M9 4.06653V11.0665" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
|
800
843
|
</svg>
|
|
801
844
|
`;
|
|
802
845
|
class BlockWrapper extends HTMLElement {
|
|
@@ -857,8 +900,8 @@ class BlockWrapper extends HTMLElement {
|
|
|
857
900
|
const moreBtn = document.createElement("button");
|
|
858
901
|
moreBtn.type = "button";
|
|
859
902
|
moreBtn.innerHTML = moreIconSvg;
|
|
860
|
-
moreBtn.addEventListener("click", (
|
|
861
|
-
|
|
903
|
+
moreBtn.addEventListener("click", (e) => {
|
|
904
|
+
e.stopPropagation();
|
|
862
905
|
this.toggleMenu();
|
|
863
906
|
});
|
|
864
907
|
const menuEl = document.createElement("div");
|
|
@@ -874,8 +917,8 @@ class BlockWrapper extends HTMLElement {
|
|
|
874
917
|
deleteBtn.className = "block-wrapper__menu-item block-wrapper__menu-item--danger";
|
|
875
918
|
deleteBtn.setAttribute("role", "menuitem");
|
|
876
919
|
deleteBtn.innerHTML = `${trashIconSvg}<span>Delete</span>`;
|
|
877
|
-
deleteBtn.addEventListener("click", (
|
|
878
|
-
|
|
920
|
+
deleteBtn.addEventListener("click", (e) => {
|
|
921
|
+
e.stopPropagation();
|
|
879
922
|
this.closeMenu();
|
|
880
923
|
this.handleRemoveBlock();
|
|
881
924
|
});
|
|
@@ -943,9 +986,9 @@ class BlockWrapper extends HTMLElement {
|
|
|
943
986
|
surface.appendChild(text);
|
|
944
987
|
inner.appendChild(surface);
|
|
945
988
|
btn.appendChild(inner);
|
|
946
|
-
btn.addEventListener("click", (
|
|
947
|
-
|
|
948
|
-
|
|
989
|
+
btn.addEventListener("click", (e) => {
|
|
990
|
+
e.stopPropagation();
|
|
991
|
+
e.preventDefault();
|
|
949
992
|
this.handleAddBlock(position, btn);
|
|
950
993
|
});
|
|
951
994
|
return btn;
|
|
@@ -1051,8 +1094,8 @@ class BlockWrapper extends HTMLElement {
|
|
|
1051
1094
|
if (!this.menuElement) return;
|
|
1052
1095
|
this.menuElement.classList.add("open");
|
|
1053
1096
|
this.isMenuOpen = true;
|
|
1054
|
-
this.closeMenuOnOutsideClick = (
|
|
1055
|
-
if (!this.shadowRoot.contains(
|
|
1097
|
+
this.closeMenuOnOutsideClick = (e) => {
|
|
1098
|
+
if (!this.shadowRoot.contains(e.composedPath()[0])) {
|
|
1056
1099
|
this.closeMenu();
|
|
1057
1100
|
}
|
|
1058
1101
|
};
|
|
@@ -1130,6 +1173,761 @@ class BlockWrapper extends HTMLElement {
|
|
|
1130
1173
|
if (customElements.get("juo-editor-block-wrapper") == null) {
|
|
1131
1174
|
customElements.define("juo-editor-block-wrapper", BlockWrapper);
|
|
1132
1175
|
}
|
|
1176
|
+
const layoutStyles = `
|
|
1177
|
+
<style>
|
|
1178
|
+
:host {
|
|
1179
|
+
display: block;
|
|
1180
|
+
box-sizing: border-box;
|
|
1181
|
+
/* Re-enable hit-testing (mirrors the legacy wrapper). */
|
|
1182
|
+
pointer-events: auto;
|
|
1183
|
+
}
|
|
1184
|
+
|
|
1185
|
+
.layout-block-wrapper {
|
|
1186
|
+
position: relative;
|
|
1187
|
+
box-sizing: border-box;
|
|
1188
|
+
}
|
|
1189
|
+
|
|
1190
|
+
/*
|
|
1191
|
+
* Grid-cell fill chain. The GridStack adapter tags the host with
|
|
1192
|
+
* data-juo-grid-cell; that gates an unbroken height:100% chain from the cell
|
|
1193
|
+
* down to the slotted block root so short blocks fill the cell the merchant
|
|
1194
|
+
* sized instead of top-aligning. In grid mode the slotted content is hidden
|
|
1195
|
+
* and the hardcoded skeleton (below) fills the cell instead.
|
|
1196
|
+
*/
|
|
1197
|
+
:host([data-juo-grid-cell]),
|
|
1198
|
+
:host([data-juo-grid-cell]) .layout-block-wrapper,
|
|
1199
|
+
:host([data-juo-grid-cell]) .layout-block-wrapper__slot-host {
|
|
1200
|
+
height: 100%;
|
|
1201
|
+
}
|
|
1202
|
+
|
|
1203
|
+
:host([data-juo-grid-cell]) ::slotted([data-block-id]) {
|
|
1204
|
+
/* display:block so inline CE block hosts honour height:100% and fill the cell. */
|
|
1205
|
+
display: block;
|
|
1206
|
+
height: 100%;
|
|
1207
|
+
}
|
|
1208
|
+
|
|
1209
|
+
/*
|
|
1210
|
+
* Bare row divider in the SETTLED grid view (mirrors the customer portal).
|
|
1211
|
+
* Paints a hairline centred in the gap above each row leader; the divider gap
|
|
1212
|
+
* top margin grows only boundaries that show a divider. Both are driven by the
|
|
1213
|
+
* breakpoint-aware flags projectToCss sets on the light-DOM grid item
|
|
1214
|
+
* (--juo-divider-row / --juo-divider-line), which inherit across the shadow
|
|
1215
|
+
* boundary the same way --juo-layout-c / --juo-layout-cols already do — so the
|
|
1216
|
+
* divider follows the active breakpoint's row structure with no static
|
|
1217
|
+
* attribute. The unitless flag multiplies into the length: 0 collapses to 0px
|
|
1218
|
+
* (spacing) / a 0-height unpainted box (line). Gated with
|
|
1219
|
+
* :not([data-juo-grid-cell]) so nothing paints while dragging in layout mode
|
|
1220
|
+
* (where the projectToCss stylesheet is absent and the flags are unset anyway).
|
|
1221
|
+
*/
|
|
1222
|
+
:host(:not([data-juo-grid-cell])) {
|
|
1223
|
+
margin-top: calc(var(--juo-layout-divider-gap, 0px) * var(--juo-divider-row, 0));
|
|
1224
|
+
}
|
|
1225
|
+
|
|
1226
|
+
:host(:not([data-juo-grid-cell])) .layout-block-wrapper::before {
|
|
1227
|
+
content: "";
|
|
1228
|
+
position: absolute;
|
|
1229
|
+
top: calc(-0.5 * (var(--juo-layout-gap, var(--card-divider-margin, 20px)) + var(--juo-layout-divider-gap, 0px)) - var(--card-divider-height, 1px) / 2);
|
|
1230
|
+
left: calc(-1 * var(--juo-layout-c, 0) * (100cqw + var(--juo-layout-gap, 0px)) / var(--juo-layout-cols, 12));
|
|
1231
|
+
width: 100cqw;
|
|
1232
|
+
height: calc(var(--card-divider-height, 1px) * var(--juo-divider-line, 0));
|
|
1233
|
+
background: var(--card-divider-background, #e5e5e5);
|
|
1234
|
+
pointer-events: none;
|
|
1235
|
+
}
|
|
1236
|
+
|
|
1237
|
+
/*
|
|
1238
|
+
* Layout-mode skeleton. Hidden while the settled view shows real content; in
|
|
1239
|
+
* grid (drag) mode the slot host is hidden and this shimmer placeholder fills
|
|
1240
|
+
* the cell so the canvas stays uniform while the merchant arranges blocks. The
|
|
1241
|
+
* block name is retained so each cell stays identifiable.
|
|
1242
|
+
*/
|
|
1243
|
+
.layout-block-wrapper__skeleton {
|
|
1244
|
+
display: none;
|
|
1245
|
+
}
|
|
1246
|
+
|
|
1247
|
+
:host([data-juo-grid-cell]) .layout-block-wrapper__slot-host {
|
|
1248
|
+
display: none !important;
|
|
1249
|
+
}
|
|
1250
|
+
|
|
1251
|
+
:host([data-juo-grid-cell]) .layout-block-wrapper__skeleton {
|
|
1252
|
+
display: flex;
|
|
1253
|
+
flex-direction: column;
|
|
1254
|
+
gap: 14px;
|
|
1255
|
+
box-sizing: border-box;
|
|
1256
|
+
height: 100%;
|
|
1257
|
+
padding: 16px 18px;
|
|
1258
|
+
background: #ffffff;
|
|
1259
|
+
border: 1px solid #ececf1;
|
|
1260
|
+
border-radius: 10px;
|
|
1261
|
+
overflow: hidden;
|
|
1262
|
+
/* Ease the placeholder in when entering layout mode instead of snapping.
|
|
1263
|
+
* Long, gentle fade so the card doesn't appear aggressively. */
|
|
1264
|
+
animation: juo-skeleton-in 320ms cubic-bezier(0.22, 1, 0.36, 1) both;
|
|
1265
|
+
}
|
|
1266
|
+
|
|
1267
|
+
@keyframes juo-skeleton-in {
|
|
1268
|
+
from { opacity: 0; }
|
|
1269
|
+
to { opacity: 1; }
|
|
1270
|
+
}
|
|
1271
|
+
|
|
1272
|
+
/* Opacity-only (no translate) so bars breathe in softly rather than jumping. */
|
|
1273
|
+
@keyframes juo-skeleton-bar-in {
|
|
1274
|
+
from { opacity: 0; }
|
|
1275
|
+
to { opacity: 1; }
|
|
1276
|
+
}
|
|
1277
|
+
|
|
1278
|
+
.layout-block-wrapper__skeleton-head {
|
|
1279
|
+
display: flex;
|
|
1280
|
+
align-items: center;
|
|
1281
|
+
gap: 8px;
|
|
1282
|
+
flex-shrink: 0;
|
|
1283
|
+
}
|
|
1284
|
+
|
|
1285
|
+
.layout-block-wrapper__skeleton-icon {
|
|
1286
|
+
display: inline-flex;
|
|
1287
|
+
align-items: center;
|
|
1288
|
+
justify-content: center;
|
|
1289
|
+
color: #9a9aa6;
|
|
1290
|
+
}
|
|
1291
|
+
|
|
1292
|
+
.layout-block-wrapper__skeleton-title {
|
|
1293
|
+
font-family: inherit;
|
|
1294
|
+
font-size: 12px;
|
|
1295
|
+
font-weight: 600;
|
|
1296
|
+
letter-spacing: -0.04px;
|
|
1297
|
+
color: #6b6b76;
|
|
1298
|
+
white-space: nowrap;
|
|
1299
|
+
overflow: hidden;
|
|
1300
|
+
text-overflow: ellipsis;
|
|
1301
|
+
}
|
|
1302
|
+
|
|
1303
|
+
/*
|
|
1304
|
+
* Placeholder bars sit directly under the header with a fixed height and a
|
|
1305
|
+
* uniform gap, so every block's skeleton reads identically. The region grows
|
|
1306
|
+
* to the skeleton's padding box (flex: 1) but the bars stay top-aligned — the
|
|
1307
|
+
* count is intentionally sparse (recomputeSkeletonLines caps it) so the
|
|
1308
|
+
* skeleton reads as a light "block placeholder" rather than a wall of noise.
|
|
1309
|
+
* Per-bar widths are assigned in JS from a block-type-seeded sequence so
|
|
1310
|
+
* adjacent blocks don't share the same width rhythm.
|
|
1311
|
+
*/
|
|
1312
|
+
.layout-block-wrapper__skeleton-lines {
|
|
1313
|
+
display: flex;
|
|
1314
|
+
flex: 1 1 auto;
|
|
1315
|
+
min-height: 0;
|
|
1316
|
+
flex-direction: column;
|
|
1317
|
+
justify-content: flex-start;
|
|
1318
|
+
gap: 12px;
|
|
1319
|
+
overflow: hidden;
|
|
1320
|
+
}
|
|
1321
|
+
|
|
1322
|
+
/* Flat placeholder bars — no shimmer so the layout-mode skeleton reads as a
|
|
1323
|
+
static "block placeholder" rather than a loading state. Width is set in JS
|
|
1324
|
+
(block-type-seeded); the value here is only a pre-measurement default. */
|
|
1325
|
+
.layout-block-wrapper__skeleton-line {
|
|
1326
|
+
width: 82%;
|
|
1327
|
+
height: 12px;
|
|
1328
|
+
flex-shrink: 0;
|
|
1329
|
+
border-radius: 4px;
|
|
1330
|
+
background-color: #ededf2;
|
|
1331
|
+
/* Newly added bars (first measure / resize) fade in softly, lightly
|
|
1332
|
+
* staggered (see nth-child delays) so they don't all snap in together. */
|
|
1333
|
+
animation: juo-skeleton-bar-in 360ms cubic-bezier(0.22, 1, 0.36, 1) both;
|
|
1334
|
+
}
|
|
1335
|
+
|
|
1336
|
+
.layout-block-wrapper__skeleton-line:nth-child(2) { animation-delay: 60ms; }
|
|
1337
|
+
.layout-block-wrapper__skeleton-line:nth-child(3) { animation-delay: 120ms; }
|
|
1338
|
+
.layout-block-wrapper__skeleton-line:nth-child(4) { animation-delay: 180ms; }
|
|
1339
|
+
|
|
1340
|
+
/*
|
|
1341
|
+
* Center hover toolbar — the block's affordances: layout toggle (leading grip
|
|
1342
|
+
* = morph trigger), add-below, fill, and delete. Shown on hover in BOTH view
|
|
1343
|
+
* mode and grid/layout mode (data-juo-grid-cell). Its vertical position is set
|
|
1344
|
+
* by JS (positionToolbar) to the midpoint of the block's VISIBLE portion so it
|
|
1345
|
+
* stays reachable on tall / partially-scrolled blocks; top:50% is the
|
|
1346
|
+
* fully-on-screen default before JS runs.
|
|
1347
|
+
*/
|
|
1348
|
+
.layout-block-wrapper__toolbar {
|
|
1349
|
+
position: absolute;
|
|
1350
|
+
top: 50%;
|
|
1351
|
+
left: 50%;
|
|
1352
|
+
transform: translate(-50%, -50%);
|
|
1353
|
+
z-index: 104;
|
|
1354
|
+
display: none;
|
|
1355
|
+
align-items: center;
|
|
1356
|
+
gap: 6px;
|
|
1357
|
+
box-sizing: border-box;
|
|
1358
|
+
padding: 6px;
|
|
1359
|
+
border-radius: 10px;
|
|
1360
|
+
background: #f5f5f5;
|
|
1361
|
+
border: 1px solid #ffffff;
|
|
1362
|
+
box-shadow: 0 2px 3.5px rgba(0, 0, 0, 0.15);
|
|
1363
|
+
backdrop-filter: blur(17px);
|
|
1364
|
+
-webkit-backdrop-filter: blur(17px);
|
|
1365
|
+
opacity: 0;
|
|
1366
|
+
pointer-events: auto;
|
|
1367
|
+
transition: opacity 140ms ease;
|
|
1368
|
+
}
|
|
1369
|
+
|
|
1370
|
+
:host(:hover) .layout-block-wrapper__toolbar {
|
|
1371
|
+
display: inline-flex;
|
|
1372
|
+
opacity: 1;
|
|
1373
|
+
}
|
|
1374
|
+
|
|
1375
|
+
/* While GridStack is actively dragging / resizing this block, hide the toolbar
|
|
1376
|
+
so it doesn't overlap or interfere with the block being moved. The grid
|
|
1377
|
+
adapter toggles data-juo-grid-interacting on the wrapper under interaction. */
|
|
1378
|
+
:host([data-juo-grid-interacting]) .layout-block-wrapper__toolbar {
|
|
1379
|
+
display: none !important;
|
|
1380
|
+
}
|
|
1381
|
+
|
|
1382
|
+
.layout-block-wrapper__tool-btn {
|
|
1383
|
+
display: inline-flex;
|
|
1384
|
+
align-items: center;
|
|
1385
|
+
justify-content: center;
|
|
1386
|
+
box-sizing: border-box;
|
|
1387
|
+
width: 24px;
|
|
1388
|
+
height: 24px;
|
|
1389
|
+
padding: 0;
|
|
1390
|
+
border: none;
|
|
1391
|
+
border-radius: 6px;
|
|
1392
|
+
background: transparent;
|
|
1393
|
+
color: #121212;
|
|
1394
|
+
cursor: pointer;
|
|
1395
|
+
transition: background 120ms ease;
|
|
1396
|
+
}
|
|
1397
|
+
|
|
1398
|
+
.layout-block-wrapper__tool-btn:hover {
|
|
1399
|
+
background: rgba(0, 0, 0, 0.06);
|
|
1400
|
+
}
|
|
1401
|
+
|
|
1402
|
+
.layout-block-wrapper__tool-btn:disabled {
|
|
1403
|
+
opacity: 0.4;
|
|
1404
|
+
cursor: default;
|
|
1405
|
+
}
|
|
1406
|
+
|
|
1407
|
+
.layout-block-wrapper__tool-btn:disabled:hover {
|
|
1408
|
+
background: transparent;
|
|
1409
|
+
}
|
|
1410
|
+
|
|
1411
|
+
.layout-block-wrapper__tool-btn svg {
|
|
1412
|
+
display: block;
|
|
1413
|
+
}
|
|
1414
|
+
|
|
1415
|
+
/* Leading position swaps between two buttons: the layout toggle in preview
|
|
1416
|
+
mode and the drag grip in layout mode (host tagged data-juo-grid-cell by the
|
|
1417
|
+
GridStack adapter). They are mutually exclusive so only one shows at a time. */
|
|
1418
|
+
.layout-block-wrapper__tool-btn--toggle {
|
|
1419
|
+
display: inline-flex;
|
|
1420
|
+
}
|
|
1421
|
+
|
|
1422
|
+
:host([data-juo-grid-cell]) .layout-block-wrapper__tool-btn--toggle {
|
|
1423
|
+
display: none;
|
|
1424
|
+
}
|
|
1425
|
+
|
|
1426
|
+
.layout-block-wrapper__tool-btn--grip {
|
|
1427
|
+
display: none;
|
|
1428
|
+
cursor: grab;
|
|
1429
|
+
touch-action: none;
|
|
1430
|
+
}
|
|
1431
|
+
|
|
1432
|
+
.layout-block-wrapper__tool-btn--grip:active {
|
|
1433
|
+
cursor: grabbing;
|
|
1434
|
+
}
|
|
1435
|
+
|
|
1436
|
+
:host([data-juo-grid-cell]) .layout-block-wrapper__tool-btn--grip {
|
|
1437
|
+
display: inline-flex;
|
|
1438
|
+
}
|
|
1439
|
+
|
|
1440
|
+
/* The fill toggle only makes sense while arranging, so it is hidden in the
|
|
1441
|
+
settled view and revealed only in layout mode (host tagged data-juo-grid-cell
|
|
1442
|
+
by the GridStack adapter). Add / delete stay visible in both modes. */
|
|
1443
|
+
.layout-block-wrapper__tool-btn--fill-h {
|
|
1444
|
+
display: none;
|
|
1445
|
+
}
|
|
1446
|
+
|
|
1447
|
+
:host([data-juo-grid-cell]) .layout-block-wrapper__tool-btn--fill-h {
|
|
1448
|
+
display: inline-flex;
|
|
1449
|
+
}
|
|
1450
|
+
|
|
1451
|
+
/* Single-column breakpoints (e.g. mobile, cols:1) support reordering but not
|
|
1452
|
+
width fill — there is only one lane — so hide the fill toggle while keeping
|
|
1453
|
+
the drag grip so blocks can still be reordered. Add/delete (tree edits)
|
|
1454
|
+
remain in both modes. */
|
|
1455
|
+
:host([data-juo-grid-single-col]) .layout-block-wrapper__tool-btn--fill-h {
|
|
1456
|
+
display: none;
|
|
1457
|
+
}
|
|
1458
|
+
|
|
1459
|
+
/* Active (pressed) state for the fill toggle — shown while the block spans the
|
|
1460
|
+
full row (data-juo-grid-full-width set on the host by the layout runtime). */
|
|
1461
|
+
:host([data-juo-grid-full-width]) .layout-block-wrapper__tool-btn--fill-h {
|
|
1462
|
+
background: #121212;
|
|
1463
|
+
color: #ffffff;
|
|
1464
|
+
}
|
|
1465
|
+
|
|
1466
|
+
:host([data-juo-grid-full-width]) .layout-block-wrapper__tool-btn--fill-h:hover {
|
|
1467
|
+
background: #121212;
|
|
1468
|
+
}
|
|
1469
|
+
|
|
1470
|
+
@media (prefers-reduced-motion: reduce) {
|
|
1471
|
+
.layout-block-wrapper__toolbar,
|
|
1472
|
+
.layout-block-wrapper__tool-btn {
|
|
1473
|
+
transition: none;
|
|
1474
|
+
}
|
|
1475
|
+
|
|
1476
|
+
.layout-block-wrapper__skeleton,
|
|
1477
|
+
.layout-block-wrapper__skeleton-line {
|
|
1478
|
+
animation: none;
|
|
1479
|
+
}
|
|
1480
|
+
}
|
|
1481
|
+
</style>
|
|
1482
|
+
`;
|
|
1483
|
+
const _LayoutBlockWrapper = class _LayoutBlockWrapper extends HTMLElement {
|
|
1484
|
+
constructor() {
|
|
1485
|
+
super();
|
|
1486
|
+
__publicField(this, "block", null);
|
|
1487
|
+
__publicField(this, "editorBridge", createEditorBridge());
|
|
1488
|
+
__publicField(this, "skeletonTitle", null);
|
|
1489
|
+
__publicField(this, "skeletonLines", null);
|
|
1490
|
+
__publicField(this, "skeletonResizeObserver", null);
|
|
1491
|
+
__publicField(this, "toolbar", null);
|
|
1492
|
+
__publicField(this, "toolbarRafId", 0);
|
|
1493
|
+
__publicField(this, "toolbarScrollListening", false);
|
|
1494
|
+
__publicField(this, "hoverOutlineTarget", null);
|
|
1495
|
+
__publicField(this, "selectionOutlineTarget", null);
|
|
1496
|
+
__publicField(this, "skeletonRafId", 0);
|
|
1497
|
+
__publicField(this, "scheduleSkeletonRecompute", () => {
|
|
1498
|
+
if (typeof requestAnimationFrame !== "function") {
|
|
1499
|
+
this.recomputeSkeletonLines();
|
|
1500
|
+
return;
|
|
1501
|
+
}
|
|
1502
|
+
if (this.skeletonRafId) return;
|
|
1503
|
+
this.skeletonRafId = requestAnimationFrame(() => {
|
|
1504
|
+
this.skeletonRafId = 0;
|
|
1505
|
+
this.recomputeSkeletonLines();
|
|
1506
|
+
});
|
|
1507
|
+
});
|
|
1508
|
+
/**
|
|
1509
|
+
* Pointerdown on the layout toggle grip.
|
|
1510
|
+
*
|
|
1511
|
+
* - View mode: "arm" layout mode — the canvas morphs into GridStack, after
|
|
1512
|
+
* which the merchant drags/resizes natively. Passing THIS element (not its
|
|
1513
|
+
* id) lets the morph controller scroll + pop the exact block grabbed.
|
|
1514
|
+
* stopPropagation keeps the bridge's global-click selection — and the morph
|
|
1515
|
+
* controller's click-away exit — from also firing.
|
|
1516
|
+
* - Layout mode: the grip IS GridStack's drag handle, so we do nothing here and
|
|
1517
|
+
* let the event fall through. GridStack starts the drag off `mousedown` (a
|
|
1518
|
+
* separate event from this `pointerdown`), so it is unaffected by the
|
|
1519
|
+
* toolbar's pointerdown stop; toggling back to view would abort the drag
|
|
1520
|
+
* before it begins.
|
|
1521
|
+
*/
|
|
1522
|
+
__publicField(this, "handleMorphGrab", (e) => {
|
|
1523
|
+
if (e.button !== 0) return;
|
|
1524
|
+
if (canvasMode.value) return;
|
|
1525
|
+
e.stopPropagation();
|
|
1526
|
+
enterLayout(this);
|
|
1527
|
+
});
|
|
1528
|
+
__publicField(this, "handleHoverEnter", () => {
|
|
1529
|
+
this.startToolbarTracking();
|
|
1530
|
+
if (this.classList.contains("active")) return;
|
|
1531
|
+
if (this.hasAttribute("data-juo-grid-cell")) return;
|
|
1532
|
+
const target = this.paintTarget();
|
|
1533
|
+
if (!target) return;
|
|
1534
|
+
this.hoverOutlineTarget = target;
|
|
1535
|
+
target.style.outline = "1px solid #060606";
|
|
1536
|
+
target.style.outlineOffset = "0";
|
|
1537
|
+
});
|
|
1538
|
+
__publicField(this, "handleHoverLeave", () => {
|
|
1539
|
+
this.stopToolbarTracking();
|
|
1540
|
+
if (!this.hoverOutlineTarget) return;
|
|
1541
|
+
this.hoverOutlineTarget.style.outline = "";
|
|
1542
|
+
this.hoverOutlineTarget.style.outlineOffset = "";
|
|
1543
|
+
this.hoverOutlineTarget = null;
|
|
1544
|
+
});
|
|
1545
|
+
/**
|
|
1546
|
+
* Center the toolbar on the block's VISIBLE portion so it stays reachable when
|
|
1547
|
+
* the block is taller than / partially scrolled out of the viewport. When the
|
|
1548
|
+
* block is fully on screen this equals its geometric center.
|
|
1549
|
+
*/
|
|
1550
|
+
__publicField(this, "positionToolbar", () => {
|
|
1551
|
+
if (!this.toolbar) return;
|
|
1552
|
+
const rect = this.getBoundingClientRect();
|
|
1553
|
+
if (rect.height <= 0) return;
|
|
1554
|
+
const viewportH = typeof window !== "undefined" && window.innerHeight ? window.innerHeight : rect.bottom;
|
|
1555
|
+
const visibleTop = Math.max(rect.top, 0);
|
|
1556
|
+
const visibleBottom = Math.min(rect.bottom, viewportH);
|
|
1557
|
+
const midpoint = visibleBottom > visibleTop ? (visibleTop + visibleBottom) / 2 : rect.top + rect.height / 2;
|
|
1558
|
+
const relative = Math.min(Math.max(midpoint - rect.top, 0), rect.height);
|
|
1559
|
+
this.toolbar.style.top = `${relative}px`;
|
|
1560
|
+
});
|
|
1561
|
+
__publicField(this, "scheduleToolbarReposition", () => {
|
|
1562
|
+
if (typeof requestAnimationFrame !== "function") {
|
|
1563
|
+
this.positionToolbar();
|
|
1564
|
+
return;
|
|
1565
|
+
}
|
|
1566
|
+
if (this.toolbarRafId) return;
|
|
1567
|
+
this.toolbarRafId = requestAnimationFrame(() => {
|
|
1568
|
+
this.toolbarRafId = 0;
|
|
1569
|
+
this.positionToolbar();
|
|
1570
|
+
});
|
|
1571
|
+
});
|
|
1572
|
+
this.attachShadow({ mode: "open" });
|
|
1573
|
+
const styleElement = document.createElement("style");
|
|
1574
|
+
styleElement.textContent = layoutStyles.replace(/<style>|<\/style>/g, "").trim();
|
|
1575
|
+
this.shadowRoot.appendChild(styleElement);
|
|
1576
|
+
this.setupTemplate();
|
|
1577
|
+
}
|
|
1578
|
+
static get observedAttributes() {
|
|
1579
|
+
return ["data-block-id", "data-juo-grid-cell"];
|
|
1580
|
+
}
|
|
1581
|
+
attributeChangedCallback(name) {
|
|
1582
|
+
if (name === "data-juo-grid-cell") this.scheduleSkeletonRecompute();
|
|
1583
|
+
}
|
|
1584
|
+
setupTemplate() {
|
|
1585
|
+
const wrapper = document.createElement("div");
|
|
1586
|
+
wrapper.className = "layout-block-wrapper";
|
|
1587
|
+
const slotHost = document.createElement("div");
|
|
1588
|
+
slotHost.className = "layout-block-wrapper__slot-host";
|
|
1589
|
+
slotHost.appendChild(document.createElement("slot"));
|
|
1590
|
+
wrapper.appendChild(slotHost);
|
|
1591
|
+
const skeleton = document.createElement("div");
|
|
1592
|
+
skeleton.className = "layout-block-wrapper__skeleton";
|
|
1593
|
+
skeleton.setAttribute("aria-hidden", "true");
|
|
1594
|
+
const skeletonHead = document.createElement("div");
|
|
1595
|
+
skeletonHead.className = "layout-block-wrapper__skeleton-head";
|
|
1596
|
+
const skeletonIcon = document.createElement("span");
|
|
1597
|
+
skeletonIcon.className = "layout-block-wrapper__skeleton-icon";
|
|
1598
|
+
skeletonIcon.innerHTML = blockIconSvg;
|
|
1599
|
+
const skeletonTitle = document.createElement("span");
|
|
1600
|
+
skeletonTitle.className = "layout-block-wrapper__skeleton-title";
|
|
1601
|
+
skeletonHead.appendChild(skeletonIcon);
|
|
1602
|
+
skeletonHead.appendChild(skeletonTitle);
|
|
1603
|
+
const skeletonLines = document.createElement("div");
|
|
1604
|
+
skeletonLines.className = "layout-block-wrapper__skeleton-lines";
|
|
1605
|
+
for (let i = 0; i < 3; i++) {
|
|
1606
|
+
const line = document.createElement("span");
|
|
1607
|
+
line.className = "layout-block-wrapper__skeleton-line";
|
|
1608
|
+
skeletonLines.appendChild(line);
|
|
1609
|
+
}
|
|
1610
|
+
skeleton.appendChild(skeletonHead);
|
|
1611
|
+
skeleton.appendChild(skeletonLines);
|
|
1612
|
+
wrapper.appendChild(skeleton);
|
|
1613
|
+
this.skeletonTitle = skeletonTitle;
|
|
1614
|
+
this.skeletonLines = skeletonLines;
|
|
1615
|
+
const toolbar = this.buildToolbar();
|
|
1616
|
+
wrapper.appendChild(toolbar);
|
|
1617
|
+
this.toolbar = toolbar;
|
|
1618
|
+
this.shadowRoot.appendChild(wrapper);
|
|
1619
|
+
this.editorBridge.onMessage((message) => {
|
|
1620
|
+
var _a;
|
|
1621
|
+
if (message.type === "SELECT_BLOCK") {
|
|
1622
|
+
this.updateActiveState(message.payload.blockId === ((_a = this.block) == null ? void 0 : _a.id));
|
|
1623
|
+
}
|
|
1624
|
+
});
|
|
1625
|
+
}
|
|
1626
|
+
/**
|
|
1627
|
+
* Build the center hover toolbar. Buttons (left→right): layout toggle (grip,
|
|
1628
|
+
* leading), add-below, delete, fill-horizontal.
|
|
1629
|
+
* pointerdown/click are stopped at the container so selecting a tool never
|
|
1630
|
+
* bubbles to the bridge's global-click selection.
|
|
1631
|
+
*/
|
|
1632
|
+
buildToolbar() {
|
|
1633
|
+
const toolbar = document.createElement("div");
|
|
1634
|
+
toolbar.className = "layout-block-wrapper__toolbar";
|
|
1635
|
+
toolbar.setAttribute("role", "toolbar");
|
|
1636
|
+
toolbar.setAttribute("aria-label", "Block actions");
|
|
1637
|
+
toolbar.addEventListener("pointerdown", (e) => e.stopPropagation());
|
|
1638
|
+
toolbar.addEventListener("click", (e) => e.stopPropagation());
|
|
1639
|
+
const toggle = this.createToolButton(
|
|
1640
|
+
layoutToggleSvg,
|
|
1641
|
+
"Edit layout",
|
|
1642
|
+
"layout-block-wrapper__tool-btn--toggle"
|
|
1643
|
+
);
|
|
1644
|
+
toggle.addEventListener(
|
|
1645
|
+
"pointerdown",
|
|
1646
|
+
(e) => this.handleMorphGrab(e)
|
|
1647
|
+
);
|
|
1648
|
+
const grip = this.createToolButton(
|
|
1649
|
+
dragGripSvg,
|
|
1650
|
+
"Drag to reposition",
|
|
1651
|
+
"layout-block-wrapper__tool-btn--grip"
|
|
1652
|
+
);
|
|
1653
|
+
grip.addEventListener(
|
|
1654
|
+
"pointerdown",
|
|
1655
|
+
(e) => this.handleMorphGrab(e)
|
|
1656
|
+
);
|
|
1657
|
+
const addBtn = this.createToolButton(
|
|
1658
|
+
addCircleOutlineSvg,
|
|
1659
|
+
"Add block below",
|
|
1660
|
+
"layout-block-wrapper__tool-btn--add"
|
|
1661
|
+
);
|
|
1662
|
+
addBtn.addEventListener("click", (e) => {
|
|
1663
|
+
e.stopPropagation();
|
|
1664
|
+
this.handleAddBelow(addBtn);
|
|
1665
|
+
});
|
|
1666
|
+
const deleteBtn = this.createToolButton(trashIconSvg, "Delete block");
|
|
1667
|
+
deleteBtn.addEventListener("click", (e) => {
|
|
1668
|
+
e.stopPropagation();
|
|
1669
|
+
this.handleRemoveBlock();
|
|
1670
|
+
});
|
|
1671
|
+
const fillH = this.createToolButton(
|
|
1672
|
+
fillHorizontalSvg,
|
|
1673
|
+
"Fill horizontally",
|
|
1674
|
+
"layout-block-wrapper__tool-btn--fill-h"
|
|
1675
|
+
);
|
|
1676
|
+
fillH.addEventListener("click", (e) => {
|
|
1677
|
+
e.stopPropagation();
|
|
1678
|
+
this.handleFillWidth();
|
|
1679
|
+
});
|
|
1680
|
+
toolbar.append(toggle, grip, addBtn, fillH, deleteBtn);
|
|
1681
|
+
return toolbar;
|
|
1682
|
+
}
|
|
1683
|
+
createToolButton(svg, label, extraClass) {
|
|
1684
|
+
const btn = document.createElement("button");
|
|
1685
|
+
btn.type = "button";
|
|
1686
|
+
btn.className = "layout-block-wrapper__tool-btn";
|
|
1687
|
+
if (extraClass) btn.classList.add(extraClass);
|
|
1688
|
+
btn.setAttribute("aria-label", label);
|
|
1689
|
+
btn.setAttribute("title", label);
|
|
1690
|
+
btn.innerHTML = svg;
|
|
1691
|
+
return btn;
|
|
1692
|
+
}
|
|
1693
|
+
/** Open the add-block menu anchored to the toolbar button, inserting AFTER. */
|
|
1694
|
+
handleAddBelow(button) {
|
|
1695
|
+
if (!this.block) return;
|
|
1696
|
+
const rect = button.getBoundingClientRect();
|
|
1697
|
+
this.editorBridge.sendMessage(
|
|
1698
|
+
createOpenAddBlockMenuMessage({
|
|
1699
|
+
targetBlockId: this.block.id,
|
|
1700
|
+
position: "after",
|
|
1701
|
+
anchor: { x: rect.right, y: rect.top }
|
|
1702
|
+
})
|
|
1703
|
+
);
|
|
1704
|
+
}
|
|
1705
|
+
/**
|
|
1706
|
+
* Traverse up the DOM (crossing shadow-root boundaries) to resolve the
|
|
1707
|
+
* containing block wrapper's id, then send REMOVE_BLOCK. Mirrors the legacy
|
|
1708
|
+
* wrapper's removal, but recognizes either wrapper tag (grid nesting uses the
|
|
1709
|
+
* layout wrapper).
|
|
1710
|
+
*/
|
|
1711
|
+
handleRemoveBlock() {
|
|
1712
|
+
if (!this.block) return;
|
|
1713
|
+
const extensionRoot = this.closest("juo-extension-root");
|
|
1714
|
+
const slotName = (extensionRoot == null ? void 0 : extensionRoot.getAttribute("name")) || "default";
|
|
1715
|
+
let parentId = "root";
|
|
1716
|
+
let current = this;
|
|
1717
|
+
while (current) {
|
|
1718
|
+
const parent = this.getParentElement(current);
|
|
1719
|
+
if (!parent) break;
|
|
1720
|
+
if (parent !== this && isBlockWrapperTag(parent.tagName)) {
|
|
1721
|
+
const parentBlockId = parent.getAttribute("data-block-id");
|
|
1722
|
+
if (parentBlockId) {
|
|
1723
|
+
parentId = parentBlockId;
|
|
1724
|
+
break;
|
|
1725
|
+
}
|
|
1726
|
+
}
|
|
1727
|
+
current = parent;
|
|
1728
|
+
}
|
|
1729
|
+
this.editorBridge.sendMessage(
|
|
1730
|
+
createRemoveBlockMessage(
|
|
1731
|
+
{ blockId: this.block.id, location: { slot: slotName, parentId } },
|
|
1732
|
+
this.block.id
|
|
1733
|
+
)
|
|
1734
|
+
);
|
|
1735
|
+
}
|
|
1736
|
+
/** Resolve the parent element, crossing shadow-root boundaries. */
|
|
1737
|
+
getParentElement(element) {
|
|
1738
|
+
const root = element.getRootNode();
|
|
1739
|
+
if (root instanceof ShadowRoot) return root.host;
|
|
1740
|
+
return element.parentElement;
|
|
1741
|
+
}
|
|
1742
|
+
/**
|
|
1743
|
+
* Toggle the block's sticky fill flag. Emitted as a layout command; the parent
|
|
1744
|
+
* engine flips the flag, expands the block into its free row-band space, pushes
|
|
1745
|
+
* the change to history + re-syncs the iframe.
|
|
1746
|
+
*/
|
|
1747
|
+
handleFillWidth() {
|
|
1748
|
+
if (!this.block) return;
|
|
1749
|
+
const surface = this.closest(
|
|
1750
|
+
'juo-extension-root[surface="overlay"]'
|
|
1751
|
+
) ? "overlay" : "page";
|
|
1752
|
+
const ctx = getActiveSurfaceContext(surface);
|
|
1753
|
+
if (!ctx) return;
|
|
1754
|
+
emitLayoutCommand({
|
|
1755
|
+
surface,
|
|
1756
|
+
id: ctx.id,
|
|
1757
|
+
command: { kind: "fillWidth", blockId: this.block.id }
|
|
1758
|
+
});
|
|
1759
|
+
}
|
|
1760
|
+
connectedCallback() {
|
|
1761
|
+
const isInOverlay = this.closest('juo-extension-root[surface="overlay"]') !== null;
|
|
1762
|
+
if (isInOverlay && this.toolbar) {
|
|
1763
|
+
this.toolbar.style.display = "none";
|
|
1764
|
+
}
|
|
1765
|
+
const isWorkflowPreview = (() => {
|
|
1766
|
+
try {
|
|
1767
|
+
const params = new URLSearchParams(window.location.search);
|
|
1768
|
+
return params.get("workflow-mode") === "true";
|
|
1769
|
+
} catch {
|
|
1770
|
+
return false;
|
|
1771
|
+
}
|
|
1772
|
+
})();
|
|
1773
|
+
if (isWorkflowPreview && !isInOverlay) {
|
|
1774
|
+
this.style.pointerEvents = "none";
|
|
1775
|
+
}
|
|
1776
|
+
this.addEventListener("mouseenter", this.handleHoverEnter);
|
|
1777
|
+
this.addEventListener("mouseleave", this.handleHoverLeave);
|
|
1778
|
+
if (typeof ResizeObserver !== "undefined" && this.skeletonLines) {
|
|
1779
|
+
this.skeletonResizeObserver = new ResizeObserver(
|
|
1780
|
+
this.scheduleSkeletonRecompute
|
|
1781
|
+
);
|
|
1782
|
+
this.skeletonResizeObserver.observe(this.skeletonLines);
|
|
1783
|
+
}
|
|
1784
|
+
}
|
|
1785
|
+
disconnectedCallback() {
|
|
1786
|
+
var _a;
|
|
1787
|
+
this.stopToolbarTracking();
|
|
1788
|
+
(_a = this.skeletonResizeObserver) == null ? void 0 : _a.disconnect();
|
|
1789
|
+
this.skeletonResizeObserver = null;
|
|
1790
|
+
if (this.skeletonRafId) {
|
|
1791
|
+
cancelAnimationFrame(this.skeletonRafId);
|
|
1792
|
+
this.skeletonRafId = 0;
|
|
1793
|
+
}
|
|
1794
|
+
}
|
|
1795
|
+
startToolbarTracking() {
|
|
1796
|
+
this.positionToolbar();
|
|
1797
|
+
if (this.toolbarScrollListening || typeof window === "undefined") return;
|
|
1798
|
+
this.toolbarScrollListening = true;
|
|
1799
|
+
window.addEventListener("scroll", this.scheduleToolbarReposition, true);
|
|
1800
|
+
window.addEventListener("resize", this.scheduleToolbarReposition);
|
|
1801
|
+
}
|
|
1802
|
+
stopToolbarTracking() {
|
|
1803
|
+
if (this.toolbarScrollListening && typeof window !== "undefined") {
|
|
1804
|
+
this.toolbarScrollListening = false;
|
|
1805
|
+
window.removeEventListener("scroll", this.scheduleToolbarReposition, true);
|
|
1806
|
+
window.removeEventListener("resize", this.scheduleToolbarReposition);
|
|
1807
|
+
}
|
|
1808
|
+
if (this.toolbarRafId) {
|
|
1809
|
+
cancelAnimationFrame(this.toolbarRafId);
|
|
1810
|
+
this.toolbarRafId = 0;
|
|
1811
|
+
}
|
|
1812
|
+
}
|
|
1813
|
+
paintTarget() {
|
|
1814
|
+
const slotted = this.firstElementChild;
|
|
1815
|
+
if (!slotted || slotted.hasAttribute("data-empty")) return null;
|
|
1816
|
+
return resolveOutlineTarget(slotted);
|
|
1817
|
+
}
|
|
1818
|
+
updateActiveState(isActive) {
|
|
1819
|
+
if (isActive) {
|
|
1820
|
+
this.classList.add("active");
|
|
1821
|
+
this.handleHoverLeave();
|
|
1822
|
+
if (this.hasAttribute("data-juo-grid-cell")) return;
|
|
1823
|
+
const target = this.paintTarget();
|
|
1824
|
+
if (!target) return;
|
|
1825
|
+
this.selectionOutlineTarget = target;
|
|
1826
|
+
target.style.outline = "2px solid #060606";
|
|
1827
|
+
target.style.outlineOffset = "0";
|
|
1828
|
+
} else {
|
|
1829
|
+
this.classList.remove("active");
|
|
1830
|
+
if (this.selectionOutlineTarget) {
|
|
1831
|
+
this.selectionOutlineTarget.style.outline = "";
|
|
1832
|
+
this.selectionOutlineTarget.style.outlineOffset = "";
|
|
1833
|
+
this.selectionOutlineTarget = null;
|
|
1834
|
+
}
|
|
1835
|
+
}
|
|
1836
|
+
}
|
|
1837
|
+
/**
|
|
1838
|
+
* Match the placeholder bars to the (dynamic) cell height. Bars are a fixed
|
|
1839
|
+
* height with a uniform gap and stay top-aligned under the header, so every
|
|
1840
|
+
* skeleton reads identically. The count scales gently with height but is
|
|
1841
|
+
* halved and capped so tall cells don't fill with noise; very short cells
|
|
1842
|
+
* (< 2 bars) drop the bars entirely and show just the header. Count depends
|
|
1843
|
+
* only on the cell height (not on the bars), so there is no measure→mutate
|
|
1844
|
+
* feedback loop.
|
|
1845
|
+
*/
|
|
1846
|
+
recomputeSkeletonLines() {
|
|
1847
|
+
var _a;
|
|
1848
|
+
if (!this.skeletonLines) return;
|
|
1849
|
+
if (!this.hasAttribute("data-juo-grid-cell")) return;
|
|
1850
|
+
const avail = this.skeletonLines.clientHeight;
|
|
1851
|
+
if (avail <= 0) return;
|
|
1852
|
+
const { SKELETON_LINE_H: LINE_H, SKELETON_GAP: GAP, SKELETON_MAX_BARS: MAX } = _LayoutBlockWrapper;
|
|
1853
|
+
const fit = Math.floor((avail + GAP) / (LINE_H + GAP));
|
|
1854
|
+
const count = fit < 2 ? 0 : Math.min(MAX, Math.max(2, Math.round(fit / 2)));
|
|
1855
|
+
const current = this.skeletonLines.childElementCount;
|
|
1856
|
+
if (count > current) {
|
|
1857
|
+
for (let i = current; i < count; i++) {
|
|
1858
|
+
const line = document.createElement("span");
|
|
1859
|
+
line.className = "layout-block-wrapper__skeleton-line";
|
|
1860
|
+
this.skeletonLines.appendChild(line);
|
|
1861
|
+
}
|
|
1862
|
+
} else if (count < current) {
|
|
1863
|
+
for (let i = current; i > count; i--) {
|
|
1864
|
+
(_a = this.skeletonLines.lastElementChild) == null ? void 0 : _a.remove();
|
|
1865
|
+
}
|
|
1866
|
+
}
|
|
1867
|
+
this.applyBarWidths();
|
|
1868
|
+
}
|
|
1869
|
+
/**
|
|
1870
|
+
* Stable offset into {@link LayoutBlockWrapper.SKELETON_BAR_WIDTHS} derived
|
|
1871
|
+
* from the block type, so each block type has its own width rhythm and
|
|
1872
|
+
* adjacent (differently-typed) blocks don't line up.
|
|
1873
|
+
*/
|
|
1874
|
+
skeletonWidthOffset() {
|
|
1875
|
+
var _a;
|
|
1876
|
+
const key = ((_a = this.block) == null ? void 0 : _a.definition.name) ?? "";
|
|
1877
|
+
let hash = 0;
|
|
1878
|
+
for (let i = 0; i < key.length; i++) {
|
|
1879
|
+
hash = hash * 31 + key.charCodeAt(i) >>> 0;
|
|
1880
|
+
}
|
|
1881
|
+
return hash % _LayoutBlockWrapper.SKELETON_BAR_WIDTHS.length;
|
|
1882
|
+
}
|
|
1883
|
+
/** Assign each bar its width from the block-type-seeded sequence. */
|
|
1884
|
+
applyBarWidths() {
|
|
1885
|
+
if (!this.skeletonLines) return;
|
|
1886
|
+
const widths = _LayoutBlockWrapper.SKELETON_BAR_WIDTHS;
|
|
1887
|
+
const offset = this.skeletonWidthOffset();
|
|
1888
|
+
const bars = this.skeletonLines.children;
|
|
1889
|
+
for (let i = 0; i < bars.length; i++) {
|
|
1890
|
+
bars[i].style.width = `${widths[(offset + i) % widths.length]}%`;
|
|
1891
|
+
}
|
|
1892
|
+
}
|
|
1893
|
+
setBlock(block) {
|
|
1894
|
+
this.block = block;
|
|
1895
|
+
this.setAttribute("data-block-id", block.id);
|
|
1896
|
+
if (this.skeletonTitle) {
|
|
1897
|
+
this.skeletonTitle.textContent = getBlockLabel(block);
|
|
1898
|
+
}
|
|
1899
|
+
this.applyBarWidths();
|
|
1900
|
+
}
|
|
1901
|
+
};
|
|
1902
|
+
/**
|
|
1903
|
+
* Height-tiers for the placeholder bar count. Deliberately sparse: the bars
|
|
1904
|
+
* are a hint at "a block lives here", not a faithful line count, so we show
|
|
1905
|
+
* few and cap hard to avoid a noisy wall of identical bars on tall blocks.
|
|
1906
|
+
* Cells too short for >= 2 bars render header-only (no lonely single bar).
|
|
1907
|
+
*/
|
|
1908
|
+
__publicField(_LayoutBlockWrapper, "SKELETON_LINE_H", 12);
|
|
1909
|
+
__publicField(_LayoutBlockWrapper, "SKELETON_GAP", 12);
|
|
1910
|
+
__publicField(_LayoutBlockWrapper, "SKELETON_MAX_BARS", 4);
|
|
1911
|
+
/**
|
|
1912
|
+
* Per-block width sequence. Widths are read from this palette starting at a
|
|
1913
|
+
* block-type-seeded offset so neighbouring blocks of different types get a
|
|
1914
|
+
* different width rhythm (deterministic — the same block type always renders
|
|
1915
|
+
* the same sequence). Chosen to look like varied text lines, none too short.
|
|
1916
|
+
*/
|
|
1917
|
+
__publicField(_LayoutBlockWrapper, "SKELETON_BAR_WIDTHS", [
|
|
1918
|
+
92,
|
|
1919
|
+
68,
|
|
1920
|
+
84,
|
|
1921
|
+
58,
|
|
1922
|
+
96,
|
|
1923
|
+
74,
|
|
1924
|
+
88,
|
|
1925
|
+
62
|
|
1926
|
+
]);
|
|
1927
|
+
let LayoutBlockWrapper = _LayoutBlockWrapper;
|
|
1928
|
+
if (customElements.get(LAYOUT_BLOCK_WRAPPER_TAG) == null) {
|
|
1929
|
+
customElements.define(LAYOUT_BLOCK_WRAPPER_TAG, LayoutBlockWrapper);
|
|
1930
|
+
}
|
|
1133
1931
|
async function serializeBlock(block) {
|
|
1134
1932
|
let initialValue = block.initialValue;
|
|
1135
1933
|
if (typeof initialValue === "function") {
|
|
@@ -1157,7 +1955,7 @@ async function serializeBlock(block) {
|
|
|
1157
1955
|
}
|
|
1158
1956
|
})
|
|
1159
1957
|
);
|
|
1160
|
-
const loaded = entries.filter((
|
|
1958
|
+
const loaded = entries.filter((e) => e !== null);
|
|
1161
1959
|
if (loaded.length > 0) {
|
|
1162
1960
|
locales = Object.fromEntries(loaded);
|
|
1163
1961
|
}
|
|
@@ -1194,6 +1992,19 @@ async function setupEditorMode(deps) {
|
|
|
1194
1992
|
const handler = createEditorHandler({
|
|
1195
1993
|
themeState
|
|
1196
1994
|
});
|
|
1995
|
+
setLayoutCommandEmitter(({ surface, id, rects, breakpoint }) => {
|
|
1996
|
+
editor.sendMessage(
|
|
1997
|
+
createLayoutCommandMessage({
|
|
1998
|
+
surface,
|
|
1999
|
+
id,
|
|
2000
|
+
command: { kind: "setRects", rects },
|
|
2001
|
+
breakpoint
|
|
2002
|
+
})
|
|
2003
|
+
);
|
|
2004
|
+
});
|
|
2005
|
+
setLayoutCommandDispatcher(({ surface, id, command }) => {
|
|
2006
|
+
editor.sendMessage(createLayoutCommandMessage({ surface, id, command }));
|
|
2007
|
+
});
|
|
1197
2008
|
const { unsubscribe } = editor.onMessage((message) => {
|
|
1198
2009
|
handler.handleMessage(message);
|
|
1199
2010
|
});
|
|
@@ -1218,42 +2029,56 @@ async function setupEditorMode(deps) {
|
|
|
1218
2029
|
unsubscribeRegister();
|
|
1219
2030
|
unsubscribe();
|
|
1220
2031
|
editor.destroy();
|
|
2032
|
+
setLayoutCommandEmitter(null);
|
|
2033
|
+
setLayoutCommandDispatcher(null);
|
|
2034
|
+
clearAllSurfaceContexts();
|
|
1221
2035
|
};
|
|
1222
2036
|
}
|
|
1223
2037
|
export {
|
|
1224
2038
|
BlockWrapper,
|
|
1225
2039
|
EDITOR_BODY_BOTTOM_PADDING_PX,
|
|
1226
2040
|
EDITOR_BODY_TOP_PADDING_PX,
|
|
2041
|
+
LayoutBlockWrapper,
|
|
1227
2042
|
buildEditorCanvasStyleContent,
|
|
1228
|
-
|
|
1229
|
-
k as
|
|
2043
|
+
canvasMode2 as canvasMode,
|
|
2044
|
+
k as createAddBlockMenuClosedMessage,
|
|
2045
|
+
l as createAddBlockMessage,
|
|
1230
2046
|
createEditorBridge,
|
|
1231
2047
|
createEditorHandler,
|
|
1232
|
-
|
|
1233
|
-
|
|
2048
|
+
m as createFocusInlineTextMessage,
|
|
2049
|
+
createLayoutCommandMessage,
|
|
2050
|
+
c as createLayoutingModeChangedMessage,
|
|
2051
|
+
n as createMoveBlockMessage,
|
|
1234
2052
|
createOpenAddBlockMenuMessage,
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
2053
|
+
o as createProvideGlobalStylesMessage,
|
|
2054
|
+
p as createProvideInitialGlobalStylesMessage,
|
|
2055
|
+
q as createProvideLayoutDocumentMessage,
|
|
2056
|
+
s as createProvideLayoutMessage,
|
|
2057
|
+
t as createProvideThemeStateMessage,
|
|
2058
|
+
u as createProvideTranslationOverridesMessage,
|
|
2059
|
+
v as createRegisterBlockTranslationKeysMessage,
|
|
1240
2060
|
createRegisterBlocksMessage,
|
|
1241
2061
|
createRegisterRoutesMessage,
|
|
1242
2062
|
createRemoveBlockMessage,
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
2063
|
+
w as createReportBlockContentSizeMessage,
|
|
2064
|
+
x as createReportContentHeightMessage,
|
|
2065
|
+
y as createRequestCloseAddBlockMenuMessage,
|
|
2066
|
+
z as createRequestGlobalStylesMessage,
|
|
2067
|
+
A as createRequestThemeStateMessage,
|
|
2068
|
+
B as createRequestTranslationOverridesMessage,
|
|
2069
|
+
C as createScrollSyncMessage,
|
|
2070
|
+
D as createSelectBlockMessage,
|
|
2071
|
+
E as createSetBlockPresetMessage,
|
|
2072
|
+
F as createSetGlobalStylesMessage,
|
|
2073
|
+
G as createSetLayoutingModeMessage,
|
|
2074
|
+
H as createSetLocaleMessage,
|
|
2075
|
+
I as createUpdateBlockPropsMessage,
|
|
2076
|
+
J as createUpdateBlockTranslationMessage,
|
|
2077
|
+
K as createUpsertThemeStateMessage,
|
|
2078
|
+
g as getEditorBridge,
|
|
2079
|
+
M as isEditorMessage,
|
|
2080
|
+
N as isIframeMessage,
|
|
2081
|
+
r as resetCanvasMode,
|
|
2082
|
+
setCanvasMode,
|
|
1258
2083
|
setupEditorMode
|
|
1259
2084
|
};
|