@ohhwells/bridge 0.1.83 → 0.1.84-next.249
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/index.cjs +550 -128
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +15 -1
- package/dist/index.d.ts +15 -1
- package/dist/index.js +549 -128
- package/dist/index.js.map +1 -1
- package/dist/pages.cjs +141 -0
- package/dist/pages.cjs.map +1 -0
- package/dist/pages.d.cts +45 -0
- package/dist/pages.d.ts +45 -0
- package/dist/pages.js +107 -0
- package/dist/pages.js.map +1 -0
- package/dist/social-glyphs.cjs +1 -1
- package/dist/social-glyphs.cjs.map +1 -1
- package/dist/social-glyphs.js +1 -1
- package/dist/social-glyphs.js.map +1 -1
- package/dist/styles.css +58 -0
- package/package.json +8 -3
package/dist/index.js
CHANGED
|
@@ -69,6 +69,7 @@ function isRenderableTree(value) {
|
|
|
69
69
|
|
|
70
70
|
// src/lib/ai-sections-store.ts
|
|
71
71
|
var AI_SECTIONS_KEY = "__ohw_ai_sections";
|
|
72
|
+
var AI_SLOT_KEY_PREFIX = "ai.";
|
|
72
73
|
var EMPTY_AI_SECTIONS = { v: 1, sections: [] };
|
|
73
74
|
function parseAiSectionsState(raw) {
|
|
74
75
|
if (!raw) return EMPTY_AI_SECTIONS;
|
|
@@ -112,6 +113,63 @@ function applyTreeToState(state, payload) {
|
|
|
112
113
|
const others = state.sections.filter((existing) => existing.id !== entry.id);
|
|
113
114
|
return { ...state, v: 1, sections: [...others, entry] };
|
|
114
115
|
}
|
|
116
|
+
function foldAlignIntoTrees(state, store) {
|
|
117
|
+
const byId = new Map(state.sections.map((entry) => [entry.id, entry]));
|
|
118
|
+
const nextTrees = /* @__PURE__ */ new Map();
|
|
119
|
+
const treeFor = (id) => {
|
|
120
|
+
const cloned = nextTrees.get(id);
|
|
121
|
+
if (cloned) return cloned;
|
|
122
|
+
const entry = byId.get(id);
|
|
123
|
+
if (!entry) return void 0;
|
|
124
|
+
const fresh = {
|
|
125
|
+
...entry.tree,
|
|
126
|
+
rows: entry.tree.rows.map((row) => ({ ...row, blocks: row.blocks.map((block) => ({ ...block })) }))
|
|
127
|
+
};
|
|
128
|
+
nextTrees.set(id, fresh);
|
|
129
|
+
return fresh;
|
|
130
|
+
};
|
|
131
|
+
const nodes = {};
|
|
132
|
+
for (const [key, override] of Object.entries(store.nodes)) {
|
|
133
|
+
const match = override.align !== void 0 && key.startsWith(AI_SLOT_KEY_PREFIX) ? key.match(/^ai\.(.+?)\.r(\d+)\.b(\d+)(?:\.|$)/) : null;
|
|
134
|
+
const tree = match ? treeFor(match[1]) : void 0;
|
|
135
|
+
const block = match && tree ? tree.rows[Number(match[2])]?.blocks[Number(match[3])] : void 0;
|
|
136
|
+
if (!block) {
|
|
137
|
+
nodes[key] = override;
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
block.align = override.align;
|
|
141
|
+
const rest = { ...override };
|
|
142
|
+
delete rest.align;
|
|
143
|
+
if (Object.keys(rest).length > 0) nodes[key] = rest;
|
|
144
|
+
}
|
|
145
|
+
const sections = {};
|
|
146
|
+
for (const [sectionId, override] of Object.entries(store.sections)) {
|
|
147
|
+
const tree = override.align !== void 0 ? treeFor(sectionId) : void 0;
|
|
148
|
+
if (!tree) {
|
|
149
|
+
sections[sectionId] = override;
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
for (const row of tree.rows) {
|
|
153
|
+
for (const block of row.blocks) block.align = override.align;
|
|
154
|
+
}
|
|
155
|
+
const rest = { ...override };
|
|
156
|
+
delete rest.align;
|
|
157
|
+
if (Object.keys(rest).length > 0) sections[sectionId] = rest;
|
|
158
|
+
}
|
|
159
|
+
if (nextTrees.size === 0) return { state, store, changed: false };
|
|
160
|
+
return {
|
|
161
|
+
state: {
|
|
162
|
+
...state,
|
|
163
|
+
v: 1,
|
|
164
|
+
sections: state.sections.map((entry) => {
|
|
165
|
+
const tree = nextTrees.get(entry.id);
|
|
166
|
+
return tree ? { ...entry, tree } : entry;
|
|
167
|
+
})
|
|
168
|
+
},
|
|
169
|
+
store: { v: 1, sections, nodes },
|
|
170
|
+
changed: true
|
|
171
|
+
};
|
|
172
|
+
}
|
|
115
173
|
function removeFromState(state, id) {
|
|
116
174
|
return { ...state, v: 1, sections: state.sections.filter((entry) => entry.id !== id) };
|
|
117
175
|
}
|
|
@@ -183,6 +241,17 @@ var BRAND_VAR_PREFIX = "--ohw-brand-";
|
|
|
183
241
|
var BRAND_VAR_NAMES = ["primary", "accent", "light", "dark", "surface", "border", "muted"].map(
|
|
184
242
|
(role) => `${BRAND_VAR_PREFIX}${role}`
|
|
185
243
|
);
|
|
244
|
+
var LEGACY_BRAND_VAR_NAMES = [
|
|
245
|
+
"primary",
|
|
246
|
+
"accent",
|
|
247
|
+
"background",
|
|
248
|
+
"text",
|
|
249
|
+
"text-muted",
|
|
250
|
+
"surface",
|
|
251
|
+
"border",
|
|
252
|
+
"on-primary",
|
|
253
|
+
"navbar-background"
|
|
254
|
+
].map((role) => `--brand-${role}`);
|
|
186
255
|
var FONT_VARS = {
|
|
187
256
|
heading: ["--font-heading", "--font-display", "--brand-font-heading"],
|
|
188
257
|
body: ["--font-body", "--brand-font-body"]
|
|
@@ -191,14 +260,29 @@ var BRAND_FONT_LINK_ID = "ohw-brand-fonts";
|
|
|
191
260
|
function brandColorVars(kit) {
|
|
192
261
|
const { dark, primary, accent, light } = kit.palette;
|
|
193
262
|
const mix = (a, aPct, b) => `color-mix(in srgb, ${a} ${aPct}%, ${b})`;
|
|
263
|
+
const surface = mix(light, 95, dark);
|
|
264
|
+
const border = mix(light, 85, dark);
|
|
265
|
+
const muted = mix(dark, 62, light);
|
|
194
266
|
return {
|
|
195
267
|
[`${BRAND_VAR_PREFIX}primary`]: primary,
|
|
196
268
|
[`${BRAND_VAR_PREFIX}accent`]: accent,
|
|
197
269
|
[`${BRAND_VAR_PREFIX}light`]: light,
|
|
198
270
|
[`${BRAND_VAR_PREFIX}dark`]: dark,
|
|
199
|
-
[`${BRAND_VAR_PREFIX}surface`]:
|
|
200
|
-
[`${BRAND_VAR_PREFIX}border`]:
|
|
201
|
-
[`${BRAND_VAR_PREFIX}muted`]:
|
|
271
|
+
[`${BRAND_VAR_PREFIX}surface`]: surface,
|
|
272
|
+
[`${BRAND_VAR_PREFIX}border`]: border,
|
|
273
|
+
[`${BRAND_VAR_PREFIX}muted`]: muted,
|
|
274
|
+
// The BrandProvider contract every template actually renders from (see LEGACY_BRAND_VAR_NAMES).
|
|
275
|
+
"--brand-primary": primary,
|
|
276
|
+
"--brand-accent": accent,
|
|
277
|
+
"--brand-background": light,
|
|
278
|
+
"--brand-text": dark,
|
|
279
|
+
"--brand-text-muted": muted,
|
|
280
|
+
"--brand-surface": surface,
|
|
281
|
+
"--brand-border": border,
|
|
282
|
+
// Buttons/bands painted in the primary colour assume it's dark/saturated enough to need
|
|
283
|
+
// light text on top — the same assumption LOGO_IMAGE's light-on-dark navbar mark makes.
|
|
284
|
+
"--brand-on-primary": light,
|
|
285
|
+
"--brand-navbar-background": dark
|
|
202
286
|
};
|
|
203
287
|
}
|
|
204
288
|
function parseBrandKit(raw) {
|
|
@@ -239,7 +323,7 @@ function loadBrandFonts(families) {
|
|
|
239
323
|
function applyBrandToDom(kit) {
|
|
240
324
|
const root = document.documentElement;
|
|
241
325
|
if (!kit) {
|
|
242
|
-
for (const name of BRAND_VAR_NAMES) root.style.removeProperty(name);
|
|
326
|
+
for (const name of [...BRAND_VAR_NAMES, ...LEGACY_BRAND_VAR_NAMES]) root.style.removeProperty(name);
|
|
243
327
|
for (const name of [...FONT_VARS.heading, ...FONT_VARS.body]) root.style.removeProperty(name);
|
|
244
328
|
document.getElementById(BRAND_FONT_LINK_ID)?.remove();
|
|
245
329
|
return;
|
|
@@ -304,6 +388,9 @@ function styleSheetCss() {
|
|
|
304
388
|
`[data-ohw-style-spacing="${spacing}"] { padding-top: ${px}px !important; padding-bottom: ${px}px !important; }`
|
|
305
389
|
);
|
|
306
390
|
}
|
|
391
|
+
for (const align of ["left", "center", "right"]) {
|
|
392
|
+
rules.push(`[data-ohw-style-align="${align}"] { text-align: ${align} !important; }`);
|
|
393
|
+
}
|
|
307
394
|
return rules.join("\n");
|
|
308
395
|
}
|
|
309
396
|
var STYLE_FONT_LINK_ID = "ohw-style-fonts";
|
|
@@ -330,10 +417,24 @@ var SECTION_ATTRS = {
|
|
|
330
417
|
textDistribution: "data-ohw-style-distribution",
|
|
331
418
|
headlineScale: "data-ohw-style-headline",
|
|
332
419
|
imageAspect: "data-ohw-style-aspect",
|
|
333
|
-
spacing: "data-ohw-style-spacing"
|
|
420
|
+
spacing: "data-ohw-style-spacing",
|
|
421
|
+
align: "data-ohw-style-align"
|
|
334
422
|
};
|
|
335
423
|
var NODE_WROTE_ATTR = "data-ohw-style-node";
|
|
336
|
-
var NODE_PROPS = [
|
|
424
|
+
var NODE_PROPS = [
|
|
425
|
+
"color",
|
|
426
|
+
"font-family",
|
|
427
|
+
"font-size",
|
|
428
|
+
"background",
|
|
429
|
+
"text-align",
|
|
430
|
+
"justify-content",
|
|
431
|
+
"align-items"
|
|
432
|
+
];
|
|
433
|
+
var ALIGN_JUSTIFY = {
|
|
434
|
+
left: "flex-start",
|
|
435
|
+
center: "center",
|
|
436
|
+
right: "flex-end"
|
|
437
|
+
};
|
|
337
438
|
function saveInline(el, prop) {
|
|
338
439
|
const attr = `data-ohw-style-prev-${prop}`;
|
|
339
440
|
if (el.hasAttribute(attr)) return;
|
|
@@ -377,6 +478,10 @@ function clearNodeProps(root) {
|
|
|
377
478
|
function buttonSurfaceOf(el) {
|
|
378
479
|
return el.closest("a, button") ?? el;
|
|
379
480
|
}
|
|
481
|
+
function alignSubjectOf(el) {
|
|
482
|
+
const button = el.closest('[data-ohw-role="button"]');
|
|
483
|
+
return button?.parentElement ?? el;
|
|
484
|
+
}
|
|
380
485
|
function applyStylesToDom(store) {
|
|
381
486
|
ensureStyleSheet();
|
|
382
487
|
clearSectionAttrs(document);
|
|
@@ -422,6 +527,18 @@ function applyStylesToDom(store) {
|
|
|
422
527
|
el.style.setProperty("font-size", `${override.fontSize}px`, "important");
|
|
423
528
|
el.setAttribute(NODE_WROTE_ATTR, "");
|
|
424
529
|
}
|
|
530
|
+
if (override.align !== void 0) {
|
|
531
|
+
const subject = alignSubjectOf(el);
|
|
532
|
+
saveInline(subject, "text-align");
|
|
533
|
+
saveInline(subject, "justify-content");
|
|
534
|
+
subject.style.setProperty("text-align", override.align, "important");
|
|
535
|
+
subject.style.setProperty(
|
|
536
|
+
"justify-content",
|
|
537
|
+
ALIGN_JUSTIFY[override.align] ?? "flex-start",
|
|
538
|
+
"important"
|
|
539
|
+
);
|
|
540
|
+
subject.setAttribute(NODE_WROTE_ATTR, "");
|
|
541
|
+
}
|
|
425
542
|
if (override.buttonBackground !== void 0 || override.buttonText !== void 0) {
|
|
426
543
|
const surface = buttonSurfaceOf(el);
|
|
427
544
|
if (override.buttonBackground !== void 0) {
|
|
@@ -517,6 +634,22 @@ function accentBandContext(brand) {
|
|
|
517
634
|
function textAttrs(ctx, path) {
|
|
518
635
|
return ctx.keyFor ? { "data-ohw-key": ctx.keyFor(path), "data-ohw-editable": "text" } : {};
|
|
519
636
|
}
|
|
637
|
+
var AI_RESPONSIVE_CSS = [
|
|
638
|
+
"@media (max-width: 960px) {",
|
|
639
|
+
" [data-ai-responsive] [data-ai-grid] { grid-template-columns: repeat(2, 1fr) !important; }",
|
|
640
|
+
' [data-ai-responsive] [data-ai-grid="1"] { grid-template-columns: 1fr !important; }',
|
|
641
|
+
"}",
|
|
642
|
+
"@media (max-width: 640px) {",
|
|
643
|
+
" [data-ai-responsive] [data-ai-grid] { grid-template-columns: 1fr !important; }",
|
|
644
|
+
" [data-ai-responsive] [data-ai-columns] > * { grid-column: 1 / -1 !important; }",
|
|
645
|
+
// Group containers flatten to a column on phones; span placements come along for free.
|
|
646
|
+
" [data-ai-responsive] [data-ai-group] { display: flex !important; flex-direction: column !important; }",
|
|
647
|
+
" [data-ai-responsive] [data-ai-group] > * { grid-column: auto !important; }",
|
|
648
|
+
" [data-ai-responsive] [data-ai-section-inner] { padding-left: 20px !important; padding-right: 20px !important; }",
|
|
649
|
+
" [data-ai-responsive] { overflow-x: hidden; }",
|
|
650
|
+
" [data-ai-responsive] img { max-width: 100%; }",
|
|
651
|
+
"}"
|
|
652
|
+
].join("\n");
|
|
520
653
|
var TRANSPARENT_PX = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
|
|
521
654
|
function MediaBox({
|
|
522
655
|
refValue,
|
|
@@ -529,13 +662,17 @@ function MediaBox({
|
|
|
529
662
|
const url = refValue ? ctx.resolveMedia(refValue) : null;
|
|
530
663
|
const isIcon = /^(lucide|simple):/.test(refValue);
|
|
531
664
|
const aspectRatio = aspect && /^\d+:\d+$/.test(aspect) ? aspect.replace(":", " / ") : void 0;
|
|
532
|
-
const editAttrs = ctx.keyFor && editPath
|
|
665
|
+
const editAttrs = ctx.keyFor && editPath ? {
|
|
666
|
+
"data-ohw-key": ctx.keyFor(editPath),
|
|
667
|
+
"data-ohw-editable": isIcon ? "icon" : "image"
|
|
668
|
+
} : {};
|
|
533
669
|
if (isIcon) {
|
|
534
670
|
const Icon = refValue.startsWith("lucide:") ? lucideByName(refValue.slice(7)) : null;
|
|
535
671
|
return /* @__PURE__ */ jsx(
|
|
536
672
|
"span",
|
|
537
673
|
{
|
|
538
674
|
"data-ai-icon": refValue,
|
|
675
|
+
...editAttrs,
|
|
539
676
|
style: {
|
|
540
677
|
display: "inline-flex",
|
|
541
678
|
width: 48,
|
|
@@ -630,7 +767,7 @@ function TextBlock({ slots, ctx, path }) {
|
|
|
630
767
|
}
|
|
631
768
|
function SectionHeaderBlock({ node, ctx, path }) {
|
|
632
769
|
const slots = node.slots ?? {};
|
|
633
|
-
const align = slots.alignment === "center" ? "center" : "left";
|
|
770
|
+
const align = node.align ?? (slots.alignment === "center" ? "center" : "left");
|
|
634
771
|
const children = node.children ?? [];
|
|
635
772
|
const buttonRowIdx = children.findIndex((c) => c.type === "button-row");
|
|
636
773
|
const buttonRow = buttonRowIdx >= 0 ? children[buttonRowIdx] : void 0;
|
|
@@ -674,7 +811,7 @@ function SectionHeaderBlock({ node, ctx, path }) {
|
|
|
674
811
|
display: "flex",
|
|
675
812
|
gap: AI_TREE_TOKENS.spacing6,
|
|
676
813
|
marginTop: AI_TREE_TOKENS.spacing8,
|
|
677
|
-
justifyContent: align === "center" ? "center" : "flex-start"
|
|
814
|
+
justifyContent: align === "center" ? "center" : align === "right" ? "flex-end" : "flex-start"
|
|
678
815
|
},
|
|
679
816
|
children: (buttonRow.children ?? []).map((button, i) => /* @__PURE__ */ jsx(
|
|
680
817
|
ButtonEl,
|
|
@@ -1007,7 +1144,7 @@ function CardBlock({ node, ctx, path }) {
|
|
|
1007
1144
|
editPath: `${path}.media`
|
|
1008
1145
|
}
|
|
1009
1146
|
) : null;
|
|
1010
|
-
const centered = slots.alignment === "center";
|
|
1147
|
+
const centered = (node.align ?? slots.alignment) === "center";
|
|
1011
1148
|
const content = /* @__PURE__ */ jsxs(
|
|
1012
1149
|
"div",
|
|
1013
1150
|
{
|
|
@@ -1421,7 +1558,7 @@ function CollectionBlock({ node, ctx, path }) {
|
|
|
1421
1558
|
return /* @__PURE__ */ jsx(
|
|
1422
1559
|
"div",
|
|
1423
1560
|
{
|
|
1424
|
-
"data-ai-grid":
|
|
1561
|
+
"data-ai-grid": String(itemsPerRow),
|
|
1425
1562
|
style: {
|
|
1426
1563
|
display: "grid",
|
|
1427
1564
|
gridTemplateColumns: `repeat(${itemsPerRow}, 1fr)`,
|
|
@@ -1726,11 +1863,25 @@ function AiTreeRenderer({
|
|
|
1726
1863
|
}
|
|
1727
1864
|
})();
|
|
1728
1865
|
const distributed = !isOverlay && settings.textDistribution;
|
|
1866
|
+
const rowAlignItems = (rowAlign) => {
|
|
1867
|
+
if (rowAlign === "top") return "start";
|
|
1868
|
+
if (rowAlign === "bottom") return "end";
|
|
1869
|
+
if (rowAlign === "center" || rowAlign === "stretch") return rowAlign;
|
|
1870
|
+
if (distributed === "space-between") return "stretch";
|
|
1871
|
+
return (distributed ?? settings.verticalPosition) === "top" ? "start" : "center";
|
|
1872
|
+
};
|
|
1873
|
+
const cellAlignStyle = (blockAlign) => blockAlign ? {
|
|
1874
|
+
display: "flex",
|
|
1875
|
+
flexDirection: "column",
|
|
1876
|
+
alignItems: blockAlign === "left" ? "flex-start" : blockAlign === "right" ? "flex-end" : "center",
|
|
1877
|
+
textAlign: blockAlign
|
|
1878
|
+
} : {};
|
|
1729
1879
|
return /* @__PURE__ */ jsxs(
|
|
1730
1880
|
"section",
|
|
1731
1881
|
{
|
|
1732
1882
|
"data-ai-section": tree.tag ?? "",
|
|
1733
1883
|
...bgAttrs,
|
|
1884
|
+
"data-ai-responsive": "",
|
|
1734
1885
|
style: {
|
|
1735
1886
|
position: "relative",
|
|
1736
1887
|
padding: `${pad}px 0`,
|
|
@@ -1741,12 +1892,13 @@ function AiTreeRenderer({
|
|
|
1741
1892
|
color: settings.sectionBackground === "accent" ? blockBrand.palette.dark : void 0
|
|
1742
1893
|
},
|
|
1743
1894
|
children: [
|
|
1744
|
-
|
|
1895
|
+
/* @__PURE__ */ jsx("style", { children: AI_RESPONSIVE_CSS }),
|
|
1745
1896
|
/* @__PURE__ */ jsx("style", { children: AI_MOBILE_CSS }),
|
|
1897
|
+
isOverlay && backgroundUrl && /* @__PURE__ */ jsx("div", { style: { position: "absolute", inset: 0, background: `rgba(255,255,255,${overlayAlpha})` } }),
|
|
1746
1898
|
/* @__PURE__ */ jsx(
|
|
1747
1899
|
"div",
|
|
1748
1900
|
{
|
|
1749
|
-
"data-ai-
|
|
1901
|
+
"data-ai-section-inner": "",
|
|
1750
1902
|
style: {
|
|
1751
1903
|
position: "relative",
|
|
1752
1904
|
maxWidth: AI_TREE_TOKENS.sectionMaxWidth,
|
|
@@ -1757,12 +1909,12 @@ function AiTreeRenderer({
|
|
|
1757
1909
|
children: tree.rows.map((row, r2) => /* @__PURE__ */ jsx(
|
|
1758
1910
|
"div",
|
|
1759
1911
|
{
|
|
1760
|
-
"data-ai-
|
|
1912
|
+
"data-ai-columns": "",
|
|
1761
1913
|
style: {
|
|
1762
1914
|
display: "grid",
|
|
1763
1915
|
gridTemplateColumns: "repeat(12, 1fr)",
|
|
1764
1916
|
gap: AI_TREE_TOKENS.spacing6,
|
|
1765
|
-
alignItems:
|
|
1917
|
+
alignItems: rowAlignItems(row.align),
|
|
1766
1918
|
marginTop: r2 > 0 ? AI_TREE_TOKENS.spacing8 : 0
|
|
1767
1919
|
},
|
|
1768
1920
|
children: (row.blocks ?? []).map((block, b) => /* @__PURE__ */ jsx(
|
|
@@ -1772,6 +1924,8 @@ function AiTreeRenderer({
|
|
|
1772
1924
|
style: {
|
|
1773
1925
|
gridColumn: `span ${Math.min(12, Math.max(1, block.span))}`,
|
|
1774
1926
|
minWidth: 0,
|
|
1927
|
+
// Horizontal placement of the block's content within its column.
|
|
1928
|
+
...cellAlignStyle(block.align),
|
|
1775
1929
|
// space-between: each column becomes a flex column whose content spreads over
|
|
1776
1930
|
// the full row height instead of clumping at the top.
|
|
1777
1931
|
...distributed === "space-between" ? { display: "flex", flexDirection: "column", justifyContent: "space-between" } : {}
|
|
@@ -7359,6 +7513,9 @@ function applyFieldType(wrapper, type) {
|
|
|
7359
7513
|
el.style.removeProperty("min-height");
|
|
7360
7514
|
el.style.removeProperty("resize");
|
|
7361
7515
|
el.removeAttribute("rows");
|
|
7516
|
+
if (el.className) {
|
|
7517
|
+
el.className = el.className.split(/\s+/).filter((token) => !/textarea/i.test(token)).join(" ");
|
|
7518
|
+
}
|
|
7362
7519
|
};
|
|
7363
7520
|
const applyDefaults = (el) => {
|
|
7364
7521
|
el.setAttribute("placeholder", defaults.placeholder);
|
|
@@ -7780,6 +7937,7 @@ function MediaOverlay({
|
|
|
7780
7937
|
(prev) => prev && prev.fullWidth === width && prev.height === height ? prev : { fullWidth: width, height }
|
|
7781
7938
|
);
|
|
7782
7939
|
}, [isVideo]);
|
|
7940
|
+
const replaceLabel = isVideo ? "Replace video" : hover.elementType === "bg-image" ? "Replace background" : "Replace image";
|
|
7783
7941
|
const replaceMode = buttonSize ? replaceButtonMode({ width: rect.width, height: rect.height }, buttonSize) : "none";
|
|
7784
7942
|
const box = {
|
|
7785
7943
|
position: "fixed",
|
|
@@ -7909,17 +8067,17 @@ function MediaOverlay({
|
|
|
7909
8067
|
},
|
|
7910
8068
|
children: [
|
|
7911
8069
|
isVideo ? /* @__PURE__ */ jsx15(Film, { size: 14 }) : /* @__PURE__ */ jsx15(ImageIcon, { size: 14 }),
|
|
7912
|
-
|
|
8070
|
+
replaceLabel
|
|
7913
8071
|
]
|
|
7914
8072
|
}
|
|
7915
8073
|
),
|
|
7916
|
-
replaceMode
|
|
8074
|
+
showChrome && replaceMode !== "none" && /* @__PURE__ */ jsxs7(
|
|
7917
8075
|
Button,
|
|
7918
8076
|
{
|
|
7919
8077
|
"data-ohw-media-overlay": "",
|
|
7920
8078
|
variant: "outline",
|
|
7921
8079
|
size: "sm",
|
|
7922
|
-
"aria-label":
|
|
8080
|
+
"aria-label": replaceLabel,
|
|
7923
8081
|
className: "gap-1.5 cursor-pointer hover:bg-background",
|
|
7924
8082
|
style: {
|
|
7925
8083
|
...OVERLAY_BUTTON_STYLE,
|
|
@@ -7942,7 +8100,7 @@ function MediaOverlay({
|
|
|
7942
8100
|
},
|
|
7943
8101
|
children: [
|
|
7944
8102
|
isVideo ? /* @__PURE__ */ jsx15(Film, { size: 14 }) : /* @__PURE__ */ jsx15(ImageIcon, { size: 14 }),
|
|
7945
|
-
replaceMode === "full" ?
|
|
8103
|
+
replaceMode === "full" ? replaceLabel : null
|
|
7946
8104
|
]
|
|
7947
8105
|
}
|
|
7948
8106
|
)
|
|
@@ -8148,6 +8306,27 @@ function deleteSectionInstance(instanceId, currentPath, existingEntries) {
|
|
|
8148
8306
|
function restoreSectionInstance(instanceId, currentPath, existingEntries) {
|
|
8149
8307
|
return setSectionRemoved(instanceId, currentPath, existingEntries, false);
|
|
8150
8308
|
}
|
|
8309
|
+
function duplicateSectionInstance(instanceId, newId, currentPath, existingEntries) {
|
|
8310
|
+
const original = findByInstanceId(instanceId);
|
|
8311
|
+
if (!original) return null;
|
|
8312
|
+
const clone = original.cloneNode(true);
|
|
8313
|
+
clone.setAttribute("data-ohw-instance", newId);
|
|
8314
|
+
const keyRekeys = rekeySectionSubtree(clone, newId);
|
|
8315
|
+
original.insertAdjacentElement("afterend", clone);
|
|
8316
|
+
const byId = new Map(existingEntries.map((e) => [e.instanceId, e]));
|
|
8317
|
+
const entries = topLevelSections().map((el, order) => {
|
|
8318
|
+
const id = instanceIdOf(el);
|
|
8319
|
+
return {
|
|
8320
|
+
instanceId: id,
|
|
8321
|
+
type: el.getAttribute("data-ohw-section") ?? "",
|
|
8322
|
+
order,
|
|
8323
|
+
pagePath: currentPath,
|
|
8324
|
+
...byId.get(id)?.removed ? { removed: true } : {}
|
|
8325
|
+
};
|
|
8326
|
+
});
|
|
8327
|
+
applyPersistedOrder(entries);
|
|
8328
|
+
return { entries, keyRekeys };
|
|
8329
|
+
}
|
|
8151
8330
|
function newInstanceId() {
|
|
8152
8331
|
return typeof crypto !== "undefined" && "randomUUID" in crypto ? crypto.randomUUID() : `instance-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
8153
8332
|
}
|
|
@@ -8162,14 +8341,20 @@ function getPageSectionOrderEntries(raw, currentPath) {
|
|
|
8162
8341
|
}
|
|
8163
8342
|
function rekeySectionSubtree(root, instanceId) {
|
|
8164
8343
|
const suffix = `::${instanceId}`;
|
|
8344
|
+
const pairs = [];
|
|
8165
8345
|
const rekey = (el, attr) => {
|
|
8166
8346
|
const current = el.getAttribute(attr);
|
|
8167
|
-
if (current)
|
|
8347
|
+
if (!current) return;
|
|
8348
|
+
const base = current.includes("::") ? current.slice(0, current.indexOf("::")) : current;
|
|
8349
|
+
const next = `${base}${suffix}`;
|
|
8350
|
+
el.setAttribute(attr, next);
|
|
8351
|
+
pairs.push({ from: current, to: next });
|
|
8168
8352
|
};
|
|
8169
8353
|
if (root.hasAttribute("data-ohw-key")) rekey(root, "data-ohw-key");
|
|
8170
8354
|
if (root.hasAttribute("data-ohw-href-key")) rekey(root, "data-ohw-href-key");
|
|
8171
8355
|
root.querySelectorAll("[data-ohw-key]").forEach((el) => rekey(el, "data-ohw-key"));
|
|
8172
8356
|
root.querySelectorAll("[data-ohw-href-key]").forEach((el) => rekey(el, "data-ohw-href-key"));
|
|
8357
|
+
return pairs;
|
|
8173
8358
|
}
|
|
8174
8359
|
function initSectionInstancesFromContent(content, currentPath) {
|
|
8175
8360
|
document.querySelectorAll("[data-ohw-section]:not([data-ohw-instance])").forEach((el) => {
|
|
@@ -11609,7 +11794,7 @@ function applySocialsDisplayToRow(row, display) {
|
|
|
11609
11794
|
const icon = item.querySelector(ICON_SELECTOR);
|
|
11610
11795
|
if (label) label.style.display = display.text ? "" : "none";
|
|
11611
11796
|
if (icon) icon.style.display = display.icon ? "" : "none";
|
|
11612
|
-
layOutIconAndLabel(item, Boolean(display.text
|
|
11797
|
+
layOutIconAndLabel(item, Boolean(display.text));
|
|
11613
11798
|
});
|
|
11614
11799
|
allowRowToWrap(row);
|
|
11615
11800
|
}
|
|
@@ -11621,6 +11806,9 @@ function layOutIconAndLabel(item, on) {
|
|
|
11621
11806
|
item.style.gap = "";
|
|
11622
11807
|
item.style.whiteSpace = "";
|
|
11623
11808
|
item.style.flex = "";
|
|
11809
|
+
item.style.width = "";
|
|
11810
|
+
item.style.height = "";
|
|
11811
|
+
item.style.padding = "";
|
|
11624
11812
|
return;
|
|
11625
11813
|
}
|
|
11626
11814
|
item.style.display = on ? "inline-flex" : "";
|
|
@@ -11628,6 +11816,9 @@ function layOutIconAndLabel(item, on) {
|
|
|
11628
11816
|
item.style.gap = on ? "8px" : "";
|
|
11629
11817
|
item.style.whiteSpace = on ? "nowrap" : "";
|
|
11630
11818
|
item.style.flex = on ? "0 0 auto" : "";
|
|
11819
|
+
item.style.width = on ? "auto" : "";
|
|
11820
|
+
item.style.height = on ? "auto" : "";
|
|
11821
|
+
item.style.padding = on ? "0 12px" : "";
|
|
11631
11822
|
}
|
|
11632
11823
|
function allowRowToWrap(row) {
|
|
11633
11824
|
const display = row.ownerDocument.defaultView?.getComputedStyle(row).display ?? "";
|
|
@@ -12583,6 +12774,15 @@ function resolveLogoDisplayText(text) {
|
|
|
12583
12774
|
function isFooterLogoRoot(root) {
|
|
12584
12775
|
return Boolean(root.closest("footer") || root.closest('[data-ohw-section="footer"]'));
|
|
12585
12776
|
}
|
|
12777
|
+
var NAV_IMAGE_KEYS = ["nav-logo-image", "logo-image"];
|
|
12778
|
+
var FOOTER_IMAGE_KEYS = ["footer-logo", "footer-logo-image", "footer-logo-img"];
|
|
12779
|
+
function firstNonEmptyContentValue(content, keys) {
|
|
12780
|
+
for (const key of keys) {
|
|
12781
|
+
const value = content[key];
|
|
12782
|
+
if (typeof value === "string" && value.trim()) return value.trim();
|
|
12783
|
+
}
|
|
12784
|
+
return null;
|
|
12785
|
+
}
|
|
12586
12786
|
function imageKeyForRoot(root) {
|
|
12587
12787
|
return isFooterLogoRoot(root) ? "footer-logo" : "nav-logo-image";
|
|
12588
12788
|
}
|
|
@@ -12632,9 +12832,10 @@ function applyLogoIdentity(text, isPlaceholder) {
|
|
|
12632
12832
|
});
|
|
12633
12833
|
return display;
|
|
12634
12834
|
}
|
|
12635
|
-
function applyLogoImage(url, alt) {
|
|
12835
|
+
function applyLogoImage(url, alt, placement) {
|
|
12636
12836
|
const displayAlt = resolveLogoDisplayText(alt);
|
|
12637
12837
|
document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]').forEach((root) => {
|
|
12838
|
+
if (placement && (isFooterLogoRoot(root) ? "footer" : "navbar") !== placement) return;
|
|
12638
12839
|
ensureLogoHrefKey(root);
|
|
12639
12840
|
const imageKey = imageKeyForRoot(root);
|
|
12640
12841
|
const textKey = textKeyForRoot(root);
|
|
@@ -12755,7 +12956,12 @@ function applyLogoFromContent(content) {
|
|
|
12755
12956
|
const logoImageUrl = typeof rawLogoImage === "string" && rawLogoImage.trim() ? rawLogoImage.trim() : null;
|
|
12756
12957
|
const imageExplicitlyCleared = LOGO_IMAGE_KEYS.some((key) => key in content) && !logoImageUrl;
|
|
12757
12958
|
const logoIsPlaceholder = LOGO_PLACEHOLDER_KEY in content ? content[LOGO_PLACEHOLDER_KEY] !== "false" : !logoImageUrl && (!logoText.trim() || logoText === PLACEHOLDER_BUSINESS_NAME);
|
|
12758
|
-
|
|
12959
|
+
const navImageUrl = firstNonEmptyContentValue(content, NAV_IMAGE_KEYS);
|
|
12960
|
+
const footerImageUrl = firstNonEmptyContentValue(content, FOOTER_IMAGE_KEYS);
|
|
12961
|
+
if (navImageUrl && footerImageUrl && navImageUrl !== footerImageUrl) {
|
|
12962
|
+
applyLogoImage(navImageUrl, logoAlt, "navbar");
|
|
12963
|
+
applyLogoImage(footerImageUrl, logoAlt, "footer");
|
|
12964
|
+
} else if (logoImageUrl) {
|
|
12759
12965
|
applyLogoImage(logoImageUrl, logoAlt);
|
|
12760
12966
|
} else {
|
|
12761
12967
|
if (imageExplicitlyCleared) applyLogoImage(null, logoAlt);
|
|
@@ -12886,6 +13092,7 @@ function readLogoSizeState(content, placement) {
|
|
|
12886
13092
|
function getLogoElement(el) {
|
|
12887
13093
|
const marked = el.closest('[data-ohw-role="logo"], [data-ohw-logo]');
|
|
12888
13094
|
if (marked) return marked;
|
|
13095
|
+
if (el.closest('[data-ohw-editable="icon"]')) return null;
|
|
12889
13096
|
const root = el.closest("nav, [data-ohw-nav-root], footer");
|
|
12890
13097
|
if (!root) return null;
|
|
12891
13098
|
const anchor = el.closest("a");
|
|
@@ -14820,21 +15027,10 @@ function parseSchedulingInsertAfter(insertAfter) {
|
|
|
14820
15027
|
insertBefore: insertAfter.slice(idx + INSERT_BEFORE_MARKER.length)
|
|
14821
15028
|
};
|
|
14822
15029
|
}
|
|
14823
|
-
function
|
|
14824
|
-
|
|
14825
|
-
const
|
|
14826
|
-
|
|
14827
|
-
return { effectiveInsertAfter, insertBefore };
|
|
14828
|
-
}
|
|
14829
|
-
function getSchedulingMountPoint(insertAfter) {
|
|
14830
|
-
const { anchor } = parseSchedulingInsertAfter(insertAfter);
|
|
14831
|
-
let anchorEl = document.querySelector(`[data-ohw-section="${anchor}"]`);
|
|
14832
|
-
if (!anchorEl && anchor === "scheduling") {
|
|
14833
|
-
const widgets = Array.from(document.querySelectorAll('[data-ohw-section^="scheduling-"]'));
|
|
14834
|
-
anchorEl = widgets.at(-1) ?? null;
|
|
14835
|
-
}
|
|
14836
|
-
if (!anchorEl) return null;
|
|
14837
|
-
return anchorEl.closest('[data-ohw-section-container="scheduling"]') ?? anchorEl;
|
|
15030
|
+
function resolveEntryAnchor(entry) {
|
|
15031
|
+
if (entry.anchorId !== void 0) return { anchorId: entry.anchorId, beforeId: entry.beforeId ?? null };
|
|
15032
|
+
const parsed = parseSchedulingInsertAfter(entry.insertAfter);
|
|
15033
|
+
return { anchorId: parsed.anchor, beforeId: parsed.insertBefore };
|
|
14838
15034
|
}
|
|
14839
15035
|
function schedulingMountDepth(insertAfter) {
|
|
14840
15036
|
if (!insertAfter.includes(INSERT_BEFORE_MARKER)) return 0;
|
|
@@ -14851,8 +15047,7 @@ function getPageSchedulingEntries(raw) {
|
|
|
14851
15047
|
}
|
|
14852
15048
|
}
|
|
14853
15049
|
function isSchedulingWidgetMissing(entry) {
|
|
14854
|
-
|
|
14855
|
-
return !document.querySelector(`[data-ohw-section="${schedulingSectionId(effectiveInsertAfter)}"]`);
|
|
15050
|
+
return !document.querySelector(`[data-ohw-section="${schedulingSectionId(entry.insertAfter)}"]`);
|
|
14856
15051
|
}
|
|
14857
15052
|
function hasMissingSchedulingWidgets(entries) {
|
|
14858
15053
|
return entries.some(isSchedulingWidgetMissing);
|
|
@@ -14882,16 +15077,17 @@ function initSectionsFromContent(content, removeExisting = false) {
|
|
|
14882
15077
|
} catch {
|
|
14883
15078
|
}
|
|
14884
15079
|
}
|
|
14885
|
-
function mountSchedulingWidget(
|
|
14886
|
-
const
|
|
14887
|
-
const sectionId = schedulingSectionId(
|
|
15080
|
+
function mountSchedulingWidget(anchorId, notifyOnConnect = false, scheduleId, beforeId, existingWidgetId) {
|
|
15081
|
+
const widgetId = existingWidgetId ?? (beforeId ? `${anchorId}${INSERT_BEFORE_MARKER}${beforeId}` : anchorId);
|
|
15082
|
+
const sectionId = schedulingSectionId(widgetId);
|
|
14888
15083
|
if (document.querySelector(`[data-ohw-section="${sectionId}"]`)) return false;
|
|
14889
|
-
const
|
|
14890
|
-
if (!
|
|
15084
|
+
const anchorEl = document.querySelector(`[data-ohw-section="${anchorId}"]`);
|
|
15085
|
+
if (!anchorEl) return false;
|
|
15086
|
+
const mountPoint = anchorEl.closest('[data-ohw-section-container="scheduling"]') ?? anchorEl;
|
|
14891
15087
|
const container = document.createElement("div");
|
|
14892
15088
|
container.dataset.ohwSectionContainer = "scheduling";
|
|
14893
|
-
if (
|
|
14894
|
-
const beforeAnchor = document.querySelector(`[data-ohw-section="${
|
|
15089
|
+
if (beforeId) {
|
|
15090
|
+
const beforeAnchor = document.querySelector(`[data-ohw-section="${beforeId}"]`);
|
|
14895
15091
|
const beforePoint = beforeAnchor?.closest('[data-ohw-section-container="scheduling"]') ?? beforeAnchor;
|
|
14896
15092
|
if (!beforePoint) return false;
|
|
14897
15093
|
beforePoint.insertAdjacentElement("beforebegin", container);
|
|
@@ -14902,19 +15098,25 @@ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId,
|
|
|
14902
15098
|
}
|
|
14903
15099
|
tail.insertAdjacentElement("afterend", container);
|
|
14904
15100
|
}
|
|
14905
|
-
|
|
14906
|
-
|
|
14907
|
-
|
|
14908
|
-
|
|
14909
|
-
|
|
14910
|
-
|
|
14911
|
-
|
|
14912
|
-
|
|
14913
|
-
|
|
14914
|
-
|
|
14915
|
-
|
|
14916
|
-
|
|
14917
|
-
|
|
15101
|
+
try {
|
|
15102
|
+
const root = createRoot2(container);
|
|
15103
|
+
flushSync2(() => {
|
|
15104
|
+
root.render(
|
|
15105
|
+
/* @__PURE__ */ jsx33(
|
|
15106
|
+
SchedulingWidget,
|
|
15107
|
+
{
|
|
15108
|
+
notifyOnConnect,
|
|
15109
|
+
initialScheduleId: scheduleId,
|
|
15110
|
+
insertAfter: widgetId
|
|
15111
|
+
}
|
|
15112
|
+
)
|
|
15113
|
+
);
|
|
15114
|
+
});
|
|
15115
|
+
} catch (err) {
|
|
15116
|
+
console.error("[ow:scheduling] render threw", err);
|
|
15117
|
+
container.remove();
|
|
15118
|
+
return false;
|
|
15119
|
+
}
|
|
14918
15120
|
const tracker = getSectionsTracker();
|
|
14919
15121
|
let sections = [];
|
|
14920
15122
|
try {
|
|
@@ -14922,10 +15124,12 @@ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId,
|
|
|
14922
15124
|
} catch {
|
|
14923
15125
|
}
|
|
14924
15126
|
const inEditor = typeof window !== "undefined" && window.self !== window.top;
|
|
14925
|
-
if (inEditor && !sections.find((s) => s.type === "scheduling" && s.insertAfter ===
|
|
15127
|
+
if (inEditor && !sections.find((s) => s.type === "scheduling" && s.insertAfter === widgetId)) {
|
|
14926
15128
|
sections.push({
|
|
14927
15129
|
type: "scheduling",
|
|
14928
|
-
insertAfter:
|
|
15130
|
+
insertAfter: widgetId,
|
|
15131
|
+
anchorId,
|
|
15132
|
+
beforeId: beforeId ?? null,
|
|
14929
15133
|
pagePath: window.location.pathname,
|
|
14930
15134
|
...scheduleId ? { scheduleId } : {}
|
|
14931
15135
|
});
|
|
@@ -14939,7 +15143,8 @@ function mountSchedulingEntries(entries, notifyOnConnect = false) {
|
|
|
14939
15143
|
for (let i = pending.length - 1; i >= 0; i--) {
|
|
14940
15144
|
const entry = pending[i];
|
|
14941
15145
|
const shouldNotify = typeof notifyOnConnect === "function" ? notifyOnConnect(entry) : notifyOnConnect;
|
|
14942
|
-
|
|
15146
|
+
const { anchorId, beforeId } = resolveEntryAnchor(entry);
|
|
15147
|
+
if (mountSchedulingWidget(anchorId, shouldNotify, entry.scheduleId ?? null, beforeId, entry.insertAfter)) {
|
|
14943
15148
|
pending.splice(i, 1);
|
|
14944
15149
|
}
|
|
14945
15150
|
}
|
|
@@ -15097,6 +15302,11 @@ function applyLinkByKey(key, val) {
|
|
|
15097
15302
|
hrefAnchors.forEach((el) => applyLinkHref(el, val));
|
|
15098
15303
|
}
|
|
15099
15304
|
}
|
|
15305
|
+
function isInsideLinkEditor(target) {
|
|
15306
|
+
return Boolean(
|
|
15307
|
+
target.closest("[data-ohw-link-popover-root]") || target.closest("[data-ohw-link-modal-root]") || target.closest("[data-ohw-link-page-dropdown]") || target.closest("[data-ohw-section-picker]") || target.closest("[data-ohw-navbar-container-chrome]") || target.closest("[data-ohw-navbar-add-button]") || target.closest("[data-ohw-footer-container-chrome]") || target.closest("[data-ohw-footer-add-button]") || target.closest("[data-ohw-more-menu]") || target.closest('[data-slot="dropdown-menu-content"]') || target.closest('[data-slot="popover-content"]') || target.closest('[data-slot="dialog-content"]') || target.closest('[data-slot="dialog-overlay"]')
|
|
15308
|
+
);
|
|
15309
|
+
}
|
|
15100
15310
|
function isInsideFloatingPanel(target) {
|
|
15101
15311
|
return Boolean(target.closest("[data-ohw-floating-panel]"));
|
|
15102
15312
|
}
|
|
@@ -15104,11 +15314,6 @@ function isPointOverFloatingPanel(clientX, clientY) {
|
|
|
15104
15314
|
const el = document.elementFromPoint(clientX, clientY);
|
|
15105
15315
|
return Boolean(el instanceof Element && el.closest("[data-ohw-floating-panel]"));
|
|
15106
15316
|
}
|
|
15107
|
-
function isInsideLinkEditor(target) {
|
|
15108
|
-
return Boolean(
|
|
15109
|
-
target.closest("[data-ohw-link-popover-root]") || target.closest("[data-ohw-link-modal-root]") || target.closest("[data-ohw-link-page-dropdown]") || target.closest("[data-ohw-section-picker]") || target.closest("[data-ohw-navbar-container-chrome]") || target.closest("[data-ohw-navbar-add-button]") || target.closest("[data-ohw-footer-container-chrome]") || target.closest("[data-ohw-footer-add-button]") || target.closest("[data-ohw-more-menu]") || target.closest('[data-slot="dropdown-menu-content"]') || target.closest('[data-slot="popover-content"]') || target.closest('[data-slot="dialog-content"]') || target.closest('[data-slot="dialog-overlay"]')
|
|
15110
|
-
);
|
|
15111
|
-
}
|
|
15112
15317
|
function getHrefKeyFromElement(el) {
|
|
15113
15318
|
if (!el) return null;
|
|
15114
15319
|
const anchor = el.closest("[data-ohw-href-key]");
|
|
@@ -15367,7 +15572,7 @@ function getNavigationSelectionParent(el) {
|
|
|
15367
15572
|
if (!isFooterLinksContainer(el) && (el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isInferredFooterGroup2(el))) {
|
|
15368
15573
|
return getFooterLinksContainer();
|
|
15369
15574
|
}
|
|
15370
|
-
if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-nav-drawer") || isFooterLinksContainer(el)) {
|
|
15575
|
+
if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-nav-drawer") || el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isFooterLinksContainer(el) || isInferredFooterGroup2(el)) {
|
|
15371
15576
|
return getNavigationRoot(el);
|
|
15372
15577
|
}
|
|
15373
15578
|
return null;
|
|
@@ -15582,7 +15787,6 @@ var ICONS = {
|
|
|
15582
15787
|
insertUnorderedList: '<line x1="8" y1="6" x2="21" y2="6"/><line x1="8" y1="12" x2="21" y2="12"/><line x1="8" y1="18" x2="21" y2="18"/><line x1="3" y1="6" x2="3.01" y2="6"/><line x1="3" y1="12" x2="3.01" y2="12"/><line x1="3" y1="18" x2="3.01" y2="18"/>',
|
|
15583
15788
|
insertOrderedList: '<line x1="10" y1="6" x2="21" y2="6"/><line x1="10" y1="12" x2="21" y2="12"/><line x1="10" y1="18" x2="21" y2="18"/><path d="M4 6h1v4"/><path d="M4 10h2"/><path d="M6 18H4c0-1 2-2 2-3s-1-1.5-2-1"/>'
|
|
15584
15789
|
};
|
|
15585
|
-
var HEIGHT_SETTLE_DELAYS = [150, 400, 800];
|
|
15586
15790
|
var SELECTION_CHROME_GAP2 = 4;
|
|
15587
15791
|
var TOOLBAR_STROKE_GAP2 = 4;
|
|
15588
15792
|
var TOOLBAR_OFFSET_FROM_ELEMENT = SELECTION_CHROME_GAP2 + TOOLBAR_STROKE_GAP2;
|
|
@@ -15962,6 +16166,8 @@ function StateToggle({
|
|
|
15962
16166
|
);
|
|
15963
16167
|
}
|
|
15964
16168
|
var contentCache = /* @__PURE__ */ new Map();
|
|
16169
|
+
var fetchedContentPaths = /* @__PURE__ */ new Set();
|
|
16170
|
+
var brandingCache = /* @__PURE__ */ new Map();
|
|
15965
16171
|
var OHW_LOADER_STYLE = {
|
|
15966
16172
|
position: "fixed",
|
|
15967
16173
|
inset: 0,
|
|
@@ -15999,6 +16205,89 @@ function OhwLoaderSpinner() {
|
|
|
15999
16205
|
)
|
|
16000
16206
|
] });
|
|
16001
16207
|
}
|
|
16208
|
+
function OhwBrandMark() {
|
|
16209
|
+
return /* @__PURE__ */ jsxs20(
|
|
16210
|
+
"svg",
|
|
16211
|
+
{
|
|
16212
|
+
width: "16",
|
|
16213
|
+
height: "16",
|
|
16214
|
+
viewBox: "0 0 48 48",
|
|
16215
|
+
fill: "none",
|
|
16216
|
+
"aria-hidden": true,
|
|
16217
|
+
style: { display: "block", flexShrink: 0 },
|
|
16218
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
16219
|
+
children: [
|
|
16220
|
+
/* @__PURE__ */ jsx33(
|
|
16221
|
+
"mask",
|
|
16222
|
+
{
|
|
16223
|
+
id: "ohw-badge-mark",
|
|
16224
|
+
style: { maskType: "luminance" },
|
|
16225
|
+
maskUnits: "userSpaceOnUse",
|
|
16226
|
+
x: "0",
|
|
16227
|
+
y: "0",
|
|
16228
|
+
width: "48",
|
|
16229
|
+
height: "48",
|
|
16230
|
+
children: /* @__PURE__ */ jsx33("path", { d: "M23.8741 48C37.0594 48 47.7481 37.2548 47.7481 24C47.7481 10.7452 37.0594 0 23.8741 0C10.6888 0 0 10.7452 0 24C0 37.2548 10.6888 48 23.8741 48Z", fill: "white" })
|
|
16231
|
+
}
|
|
16232
|
+
),
|
|
16233
|
+
/* @__PURE__ */ jsxs20("g", { mask: "url(#ohw-badge-mark)", children: [
|
|
16234
|
+
/* @__PURE__ */ jsx33("path", { d: "M23.8731 48.0497C37.0584 48.0497 47.7472 37.3046 47.7472 24.0497C47.7472 10.7949 37.0584 0.0497208 23.8731 0.0497208C10.6878 0.0497208 -0.000976562 10.7949 -0.000976562 24.0497C-0.000976562 37.3046 10.6878 48.0497 23.8731 48.0497Z", fill: "#0078E5" }),
|
|
16235
|
+
/* @__PURE__ */ jsx33("path", { d: "M17.1307 14.7172C13.1687 14.7172 9.38102 18.1154 8.65114 22.34C8.38885 23.8488 8.5598 25.2581 9.06929 26.4451C6.20005 29.1677 1.77216 27.8721 -1.40212 26.1536C-2.73618 25.4317 -3.92695 27.4745 -2.59037 28.1981C1.33389 30.3226 6.86037 31.6621 10.4402 28.4188C11.4718 29.3859 12.867 29.9621 14.4894 29.9621C18.4161 29.9621 22.2038 26.5318 22.9337 22.34C23.6636 18.1162 21.0566 14.7172 17.1298 14.7172H17.1307ZM19.9798 22.34C19.5281 25.0399 17.2689 27.231 14.9754 27.231C12.6466 27.231 11.1877 25.0399 11.6394 22.34C12.1262 19.6401 14.3151 17.4482 16.6438 17.4482C18.9374 17.4482 20.4667 19.6401 19.9798 22.34Z", fill: "white" }),
|
|
16236
|
+
/* @__PURE__ */ jsx33("path", { d: "M40.0017 27.0262C39.1797 27.081 38.2721 26.995 37.4668 26.7415C37.3344 26.6993 37.28 26.5401 37.3529 26.4205C37.5959 26.0212 37.8255 25.6152 38.009 25.1889C38.1071 24.9918 38.2018 24.793 38.2897 24.5908C38.3274 24.5041 38.4163 24.451 38.5101 24.4619C38.63 24.4754 38.7054 24.4821 38.8881 24.4821L39.1529 24.4796L39.8283 24.4543C45.9229 24.0492 50.4765 20.4319 54.8466 16.9014C56.0172 15.9554 57.6932 17.6208 56.5116 18.5752C51.7687 22.4065 47.1966 26.5081 40.9319 26.9689", fill: "white" }),
|
|
16237
|
+
/* @__PURE__ */ jsx33("path", { d: "M37.9687 24.27C38.4472 23.1319 38.7656 21.9045 38.9609 20.6991C39.5927 16.76 38.5058 14.2193 36.1553 14.2193C34.1835 14.2193 33.1469 17.2427 32.9199 18.8694C32.743 19.9872 32.5914 22.1219 33.6028 23.9524C33.7553 24.259 34.15 24.7712 34.471 25.1259C34.5447 25.2067 34.6746 25.2 34.7349 25.1082C34.9528 24.7788 35.1615 24.4039 35.3584 24.0257C35.5444 23.6677 35.5888 23.6138 35.8587 23.0207C35.8838 22.966 35.8813 22.9002 35.8478 22.8505C35.5888 22.4597 35.2168 21.9787 35.1204 21.4614C34.9184 20.4455 34.9436 19.2257 35.2218 18.1078C35.4413 17.3118 35.7195 16.7844 35.9039 16.5106C35.9466 16.4466 36.0279 16.4129 36.0975 16.4449C36.369 16.5671 36.5827 16.8838 36.7385 17.396C37.0167 18.2089 37.0167 19.3782 36.814 20.6999C36.6991 21.5271 36.4771 22.3729 36.1746 23.1673C36.1293 23.308 36.0757 23.4461 36.0187 23.5826C36.0187 23.5868 36.0187 23.591 36.0187 23.5961C35.9911 23.6946 35.9207 23.8067 35.8846 23.901C35.5536 24.5497 35.2344 25.1697 34.8439 25.7838C34.8388 25.7863 34.8346 25.7914 34.8296 25.7931C34.6528 26.0525 34.4718 26.2901 34.2866 26.4965C34.2774 26.5099 34.2682 26.5234 34.2589 26.5369C34.2405 26.5638 34.2179 26.5815 34.1944 26.595C33.5064 27.3212 32.7665 27.6893 32.0123 27.6893C31.8606 27.6893 31.6838 27.664 31.507 27.4349C31.3042 27.1299 30.85 26.0879 31.2539 22.9112C31.4785 21.3949 31.8011 20.0268 31.931 19.5408C31.9579 19.4413 31.8908 19.3419 31.7886 19.3293L30.0062 19.1162C29.9241 19.1061 29.8478 19.1566 29.8252 19.2366C29.2704 21.1615 27.0305 27.6885 24.9599 27.6885C24.328 27.6885 24.1512 26.6211 24.1001 26.2909C23.775 23.6264 25.528 18.5492 29.5302 16.2267C29.6048 16.1838 29.635 16.0928 29.5998 16.0136L28.9042 14.467C28.8632 14.3752 28.7501 14.3389 28.6638 14.3886C25.8079 16.0414 24.1847 18.5231 23.2915 20.3436C22.2046 22.5793 21.6993 25.0189 21.9515 26.8738C22.1795 28.7794 23.1398 29.872 24.6054 29.872C26.0543 29.872 27.4369 28.9066 28.7098 27.0187C28.7953 26.8915 28.9889 26.9311 29.0149 27.0819C29.2646 28.5283 29.9811 29.872 31.6579 29.872C33.5282 29.872 35.3232 28.7288 36.7134 26.6447C36.7712 26.5874 36.7972 26.5411 36.8181 26.4906C36.8232 26.4931 36.8282 26.4948 36.8332 26.4973C37.01 26.2025 37.181 25.9051 37.3444 25.6027C37.4508 25.4005 37.5572 25.1992 37.6586 24.9945C37.7181 24.874 37.7743 24.7527 37.8262 24.6289C37.838 24.6002 37.8547 24.5665 37.8706 24.5337", fill: "white" }),
|
|
16238
|
+
/* @__PURE__ */ jsx33("path", { d: "M30.5839 31.6397C25.7546 34.8577 19.4773 34.7853 14.6907 31.5243C13.5368 30.7384 12.5044 32.6498 13.6474 33.4281C19.034 37.0985 26.3077 37.096 31.7218 33.488C32.8791 32.7172 31.7478 30.8639 30.5839 31.6397Z", fill: "white" })
|
|
16239
|
+
] })
|
|
16240
|
+
]
|
|
16241
|
+
}
|
|
16242
|
+
);
|
|
16243
|
+
}
|
|
16244
|
+
var OHW_BADGE_STYLE = {
|
|
16245
|
+
position: "fixed",
|
|
16246
|
+
left: 20,
|
|
16247
|
+
bottom: 20,
|
|
16248
|
+
zIndex: 2147483e3,
|
|
16249
|
+
boxSizing: "border-box",
|
|
16250
|
+
display: "inline-flex",
|
|
16251
|
+
alignItems: "center",
|
|
16252
|
+
gap: 0,
|
|
16253
|
+
padding: "6px 8px",
|
|
16254
|
+
margin: 0,
|
|
16255
|
+
background: "#ffffff",
|
|
16256
|
+
border: "1px solid #e7e5e4",
|
|
16257
|
+
borderRadius: 9999,
|
|
16258
|
+
boxShadow: "0 1px 3px rgba(0, 0, 0, 0.1)",
|
|
16259
|
+
color: "#0c0a09",
|
|
16260
|
+
textDecoration: "none",
|
|
16261
|
+
fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif"
|
|
16262
|
+
};
|
|
16263
|
+
var OHW_BADGE_LABEL_STYLE = {
|
|
16264
|
+
padding: "0 4px",
|
|
16265
|
+
fontSize: 14,
|
|
16266
|
+
lineHeight: "24px",
|
|
16267
|
+
fontWeight: 500,
|
|
16268
|
+
fontStyle: "normal",
|
|
16269
|
+
letterSpacing: "normal",
|
|
16270
|
+
textTransform: "none",
|
|
16271
|
+
color: "#0c0a09",
|
|
16272
|
+
whiteSpace: "nowrap"
|
|
16273
|
+
};
|
|
16274
|
+
function MadeWithOhhWells() {
|
|
16275
|
+
return /* @__PURE__ */ jsxs20(
|
|
16276
|
+
"a",
|
|
16277
|
+
{
|
|
16278
|
+
href: "https://ohhwells.com",
|
|
16279
|
+
target: "_blank",
|
|
16280
|
+
rel: "noopener noreferrer",
|
|
16281
|
+
"aria-label": "Made with OhhWells",
|
|
16282
|
+
"data-ohw-badge": "",
|
|
16283
|
+
style: OHW_BADGE_STYLE,
|
|
16284
|
+
children: [
|
|
16285
|
+
/* @__PURE__ */ jsx33(OhwBrandMark, {}),
|
|
16286
|
+
/* @__PURE__ */ jsx33("span", { style: OHW_BADGE_LABEL_STYLE, children: "Made with OhhWells" })
|
|
16287
|
+
]
|
|
16288
|
+
}
|
|
16289
|
+
);
|
|
16290
|
+
}
|
|
16002
16291
|
var OHW_LOADER_PREHYDRATE_SCRIPT = `(function(){try{var p=location.hostname.split(".");var fromHost=p.length>=3&&p[0]!=="www"?p[0]:"";var fromQuery=new URLSearchParams(location.search).get("subdomain")||"";if(!fromHost&&!fromQuery)return;var e=document.getElementById("ohw-loader");if(e)e.style.display="flex"}catch(e){}})();`;
|
|
16003
16292
|
function resolveSubdomain(subdomainFromQuery) {
|
|
16004
16293
|
if (subdomainFromQuery) return subdomainFromQuery;
|
|
@@ -16058,6 +16347,7 @@ function OhhwellsBridge() {
|
|
|
16058
16347
|
}
|
|
16059
16348
|
}, []);
|
|
16060
16349
|
const [fetchState, setFetchState] = useState13("idle");
|
|
16350
|
+
const [showBranding, setShowBranding] = useState13(false);
|
|
16061
16351
|
const autoSaveTimers = useRef10(/* @__PURE__ */ new Map());
|
|
16062
16352
|
const activeElRef = useRef10(null);
|
|
16063
16353
|
const pointerHeldRef = useRef10(false);
|
|
@@ -16406,13 +16696,6 @@ function OhhwellsBridge() {
|
|
|
16406
16696
|
const [isItemDragging, setIsItemDragging] = useState13(false);
|
|
16407
16697
|
const [isFooterFrameSelection, setIsFooterFrameSelection] = useState13(false);
|
|
16408
16698
|
isFooterFrameSelectionRef.current = isFooterFrameSelection;
|
|
16409
|
-
const [floatingPanel, setFloatingPanel] = useState13(null);
|
|
16410
|
-
const floatingPanelOpenRef = useRef10(false);
|
|
16411
|
-
floatingPanelOpenRef.current = floatingPanel !== null;
|
|
16412
|
-
const [floatingPanelPos, setFloatingPanelPos] = useState13(null);
|
|
16413
|
-
const [logoSizeDraft, setLogoSizeDraft] = useState13(null);
|
|
16414
|
-
const [editorViewport, setEditorViewport] = useState13("desktop");
|
|
16415
|
-
const [parentScrollSnap, setParentScrollSnap] = useState13(null);
|
|
16416
16699
|
const [navDropdownPreviewOpen, setNavDropdownPreviewOpen] = useState13(null);
|
|
16417
16700
|
const [footerHeadingVisible, setFooterHeadingVisible] = useState13(null);
|
|
16418
16701
|
const footerDragRef = useRef10(null);
|
|
@@ -16430,6 +16713,13 @@ function OhhwellsBridge() {
|
|
|
16430
16713
|
const brandKitRef = useRef10("");
|
|
16431
16714
|
const stylesRef = useRef10("");
|
|
16432
16715
|
const pendingDeleteUndoRef = useRef10(null);
|
|
16716
|
+
const [floatingPanel, setFloatingPanel] = useState13(null);
|
|
16717
|
+
const floatingPanelOpenRef = useRef10(false);
|
|
16718
|
+
const setFloatingPanelRef = useRef10(setFloatingPanel);
|
|
16719
|
+
const [floatingPanelPos, setFloatingPanelPos] = useState13(null);
|
|
16720
|
+
const [logoSizeDraft, setLogoSizeDraft] = useState13(null);
|
|
16721
|
+
const [editorViewport, setEditorViewport] = useState13("desktop");
|
|
16722
|
+
const [parentScrollSnap, setParentScrollSnap] = useState13(null);
|
|
16433
16723
|
const [sitePages, setSitePages] = useState13([]);
|
|
16434
16724
|
const [sectionsByPath, setSectionsByPath] = useState13({});
|
|
16435
16725
|
const sectionsPrefetchGenRef = useRef10(0);
|
|
@@ -16438,7 +16728,18 @@ function OhhwellsBridge() {
|
|
|
16438
16728
|
const linkPopoverOpenRef = useRef10(false);
|
|
16439
16729
|
const linkPopoverGraceUntilRef = useRef10(0);
|
|
16440
16730
|
setLinkPopoverRef.current = setLinkPopover;
|
|
16731
|
+
setFloatingPanelRef.current = setFloatingPanel;
|
|
16441
16732
|
linkPopoverSessionRef.current = linkPopover;
|
|
16733
|
+
floatingPanelOpenRef.current = Boolean(floatingPanel);
|
|
16734
|
+
useEffect13(() => {
|
|
16735
|
+
const syncViewport = () => {
|
|
16736
|
+
const next = window.innerWidth <= 480 ? "mobile" : "desktop";
|
|
16737
|
+
setEditorViewport((prev) => prev === next ? prev : next);
|
|
16738
|
+
};
|
|
16739
|
+
syncViewport();
|
|
16740
|
+
window.addEventListener("resize", syncViewport);
|
|
16741
|
+
return () => window.removeEventListener("resize", syncViewport);
|
|
16742
|
+
}, []);
|
|
16442
16743
|
const {
|
|
16443
16744
|
navDragRef,
|
|
16444
16745
|
navDropSlots,
|
|
@@ -17766,14 +18067,15 @@ function OhhwellsBridge() {
|
|
|
17766
18067
|
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
17767
18068
|
}
|
|
17768
18069
|
applyBrandChrome(content);
|
|
18070
|
+
initSectionInstancesFromContent(content, window.location.pathname);
|
|
17769
18071
|
for (const [key, val] of Object.entries(content)) {
|
|
17770
18072
|
if (key === "__ohw_sections") continue;
|
|
17771
18073
|
if (key === AI_SECTIONS_KEY) continue;
|
|
18074
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
18075
|
+
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
17772
18076
|
if (key === BRAND_KIT_KEY) continue;
|
|
17773
18077
|
if (key === STYLE_STORE_KEY) continue;
|
|
17774
18078
|
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
17775
|
-
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
17776
|
-
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
17777
18079
|
if (applyVideoSettingNode(key, val)) continue;
|
|
17778
18080
|
if (applyCarouselNode(key, val)) continue;
|
|
17779
18081
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
@@ -17821,7 +18123,6 @@ function OhhwellsBridge() {
|
|
|
17821
18123
|
if (isEditModeRef.current) requestMissingSocialIconsRef.current();
|
|
17822
18124
|
enforceLinkHrefs();
|
|
17823
18125
|
initSectionsFromContent(content, true);
|
|
17824
|
-
initSectionInstancesFromContent(content, window.location.pathname);
|
|
17825
18126
|
sectionsLoadedRef.current = true;
|
|
17826
18127
|
pendingScheduleConfigRequests.current.splice(0).forEach(processConfigRequest);
|
|
17827
18128
|
if (imageLoads.length === 0) return Promise.resolve();
|
|
@@ -17833,16 +18134,22 @@ function OhhwellsBridge() {
|
|
|
17833
18134
|
};
|
|
17834
18135
|
const cached = contentCache.get(subdomain);
|
|
17835
18136
|
if (cached) {
|
|
18137
|
+
setShowBranding(brandingCache.get(subdomain) ?? false);
|
|
17836
18138
|
applyContent(cached).finally(() => setFetchState("done"));
|
|
17837
18139
|
return;
|
|
17838
18140
|
}
|
|
17839
18141
|
let cancelled = false;
|
|
17840
18142
|
setFetchState("loading");
|
|
17841
18143
|
const apiUrl = process.env.NEXT_PUBLIC_FLOWOPS_API_URL ?? "https://flowops-backend-staging-2yfdh7pwpq-as.a.run.app";
|
|
17842
|
-
|
|
18144
|
+
const initialPath = pathname;
|
|
18145
|
+
fetchedContentPaths.add(`${subdomain}::${initialPath}`);
|
|
18146
|
+
fetch(`${apiUrl}/api/public/sites/${subdomain}/content?path=${encodeURIComponent(initialPath)}`, { cache: "no-store" }).then((r2) => r2.ok ? r2.json() : null).then((data) => {
|
|
17843
18147
|
if (cancelled) return;
|
|
17844
18148
|
const content = data?.content ?? {};
|
|
18149
|
+
const branding = Boolean(data?.showBranding);
|
|
17845
18150
|
contentCache.set(subdomain, content);
|
|
18151
|
+
brandingCache.set(subdomain, branding);
|
|
18152
|
+
setShowBranding(branding);
|
|
17846
18153
|
return applyContent(content);
|
|
17847
18154
|
}).catch(() => {
|
|
17848
18155
|
}).finally(() => {
|
|
@@ -17975,11 +18282,11 @@ function OhhwellsBridge() {
|
|
|
17975
18282
|
for (const [key, val] of Object.entries(content)) {
|
|
17976
18283
|
if (key === "__ohw_sections") continue;
|
|
17977
18284
|
if (key === AI_SECTIONS_KEY) continue;
|
|
18285
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
18286
|
+
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
17978
18287
|
if (key === BRAND_KIT_KEY) continue;
|
|
17979
18288
|
if (key === STYLE_STORE_KEY) continue;
|
|
17980
18289
|
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
17981
|
-
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
17982
|
-
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
17983
18290
|
if (applyVideoSettingNode(key, val)) continue;
|
|
17984
18291
|
if (applyCarouselNode(key, val)) continue;
|
|
17985
18292
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
@@ -18025,6 +18332,17 @@ function OhhwellsBridge() {
|
|
|
18025
18332
|
debounceTimer = setTimeout(applyFromCache, 150);
|
|
18026
18333
|
};
|
|
18027
18334
|
applyFromCache();
|
|
18335
|
+
const pathCacheKey = `${subdomain}::${pathname}`;
|
|
18336
|
+
if (!fetchedContentPaths.has(pathCacheKey)) {
|
|
18337
|
+
fetchedContentPaths.add(pathCacheKey);
|
|
18338
|
+
const apiUrl = process.env.NEXT_PUBLIC_FLOWOPS_API_URL ?? "https://flowops-backend-staging-2yfdh7pwpq-as.a.run.app";
|
|
18339
|
+
fetch(`${apiUrl}/api/public/sites/${subdomain}/content?path=${encodeURIComponent(pathname)}`, { cache: "no-store" }).then((r2) => r2.ok ? r2.json() : null).then((data) => {
|
|
18340
|
+
if (!data?.content) return;
|
|
18341
|
+
contentCache.set(subdomain, data.content);
|
|
18342
|
+
applyFromCache();
|
|
18343
|
+
}).catch(() => {
|
|
18344
|
+
});
|
|
18345
|
+
}
|
|
18028
18346
|
observer = new MutationObserver(scheduleApply);
|
|
18029
18347
|
observer.observe(document.body, { childList: true, subtree: true });
|
|
18030
18348
|
return () => {
|
|
@@ -18138,25 +18456,13 @@ function OhhwellsBridge() {
|
|
|
18138
18456
|
};
|
|
18139
18457
|
const t1 = setTimeout(measure, 50);
|
|
18140
18458
|
const t2 = setTimeout(measure, 500);
|
|
18141
|
-
|
|
18142
|
-
|
|
18143
|
-
const clearResizeTimers = () => {
|
|
18144
|
-
resizeTimers.forEach(clearTimeout);
|
|
18145
|
-
resizeTimers = [];
|
|
18146
|
-
};
|
|
18147
|
-
const handleResize = () => {
|
|
18148
|
-
if (window.innerWidth === lastWidth) return;
|
|
18149
|
-
lastWidth = window.innerWidth;
|
|
18150
|
-
clearResizeTimers();
|
|
18151
|
-
resizeTimers = HEIGHT_SETTLE_DELAYS.map((delay) => setTimeout(measure, delay));
|
|
18152
|
-
};
|
|
18153
|
-
window.addEventListener("resize", handleResize);
|
|
18459
|
+
const ro = new ResizeObserver(schedule);
|
|
18460
|
+
ro.observe(document.body);
|
|
18154
18461
|
return () => {
|
|
18155
18462
|
clearTimeout(t1);
|
|
18156
18463
|
clearTimeout(t2);
|
|
18157
18464
|
if (raf != null) cancelAnimationFrame(raf);
|
|
18158
|
-
|
|
18159
|
-
window.removeEventListener("resize", handleResize);
|
|
18465
|
+
ro.disconnect();
|
|
18160
18466
|
};
|
|
18161
18467
|
}, [pathname, isEditMode, postToParent2]);
|
|
18162
18468
|
useEffect13(() => {
|
|
@@ -18402,9 +18708,6 @@ function OhhwellsBridge() {
|
|
|
18402
18708
|
if (target.closest("[data-ohw-state-toggle]")) return;
|
|
18403
18709
|
if (target.closest("[data-ohw-max-badge]")) return;
|
|
18404
18710
|
if (isInsideLinkEditor(target)) return;
|
|
18405
|
-
if (selectedMediaElRef.current && !selectedMediaElRef.current.contains(target) && !target.closest("[data-ohw-media-overlay], [data-ohw-edit-chrome], [data-ohw-item-interaction]")) {
|
|
18406
|
-
clearMediaSelectionRef.current();
|
|
18407
|
-
}
|
|
18408
18711
|
if (isInsideFloatingPanel(target)) return;
|
|
18409
18712
|
if (target.closest("[data-ohw-form-toolbar]")) return;
|
|
18410
18713
|
if (target.closest(
|
|
@@ -18412,6 +18715,9 @@ function OhhwellsBridge() {
|
|
|
18412
18715
|
)) {
|
|
18413
18716
|
return;
|
|
18414
18717
|
}
|
|
18718
|
+
if (selectedMediaElRef.current && !selectedMediaElRef.current.contains(target) && !target.closest("[data-ohw-media-overlay], [data-ohw-edit-chrome], [data-ohw-item-interaction]")) {
|
|
18719
|
+
clearMediaSelectionRef.current();
|
|
18720
|
+
}
|
|
18415
18721
|
{
|
|
18416
18722
|
const formEl = getFormElement(target);
|
|
18417
18723
|
const onSuccessText = target.closest(`[${SUCCESS_TEXT_ATTR}]`);
|
|
@@ -18563,14 +18869,6 @@ function OhhwellsBridge() {
|
|
|
18563
18869
|
}
|
|
18564
18870
|
const clickedButton = findClosestButtonLike(target);
|
|
18565
18871
|
const buttonOnMedia = Boolean(clickedButton && isMediaEditable(editable) && editable.contains(clickedButton));
|
|
18566
|
-
console.log("[click-debug]", {
|
|
18567
|
-
editableType: editable.dataset.ohwEditable,
|
|
18568
|
-
editableTag: editable.tagName,
|
|
18569
|
-
targetTag: target.tagName,
|
|
18570
|
-
clickedButtonTag: clickedButton?.tagName ?? null,
|
|
18571
|
-
buttonOnMedia,
|
|
18572
|
-
isMediaEditableEditable: isMediaEditable(editable)
|
|
18573
|
-
});
|
|
18574
18872
|
if (isMediaEditable(editable) && !buttonOnMedia) {
|
|
18575
18873
|
e.preventDefault();
|
|
18576
18874
|
e.stopPropagation();
|
|
@@ -18597,11 +18895,6 @@ function OhhwellsBridge() {
|
|
|
18597
18895
|
const hrefLookupTarget = buttonOnMedia ? clickedButton : editable;
|
|
18598
18896
|
const hrefCtx = getHrefKeyFromElement(hrefLookupTarget);
|
|
18599
18897
|
const navAnchor = hrefCtx ? getNavigationItemAnchor(hrefCtx.anchor) : null;
|
|
18600
|
-
console.log("[click-debug 2]", {
|
|
18601
|
-
hrefLookupTargetTag: hrefLookupTarget.tagName,
|
|
18602
|
-
hrefCtx: hrefCtx ? { key: hrefCtx.key } : null,
|
|
18603
|
-
navAnchorTag: navAnchor?.tagName ?? null
|
|
18604
|
-
});
|
|
18605
18898
|
if (navAnchor) {
|
|
18606
18899
|
e.preventDefault();
|
|
18607
18900
|
e.stopPropagation();
|
|
@@ -18771,6 +19064,9 @@ function OhhwellsBridge() {
|
|
|
18771
19064
|
setHoveredItemRect(null);
|
|
18772
19065
|
hoveredNavContainerRef.current = null;
|
|
18773
19066
|
setHoveredNavContainerRect(null);
|
|
19067
|
+
siblingHintElRef.current = null;
|
|
19068
|
+
setSiblingHintRect(null);
|
|
19069
|
+
setSiblingHintRects([]);
|
|
18774
19070
|
return;
|
|
18775
19071
|
}
|
|
18776
19072
|
{
|
|
@@ -18889,7 +19185,6 @@ function OhhwellsBridge() {
|
|
|
18889
19185
|
hoveredNavContainerRef.current = null;
|
|
18890
19186
|
setHoveredNavContainerRect(null);
|
|
18891
19187
|
hoveredItemElRef.current = editable;
|
|
18892
|
-
setHoveredItemRect(isSelectedForHoverRef.current(editable) ? null : editable.getBoundingClientRect());
|
|
18893
19188
|
}
|
|
18894
19189
|
}
|
|
18895
19190
|
}
|
|
@@ -19186,7 +19481,7 @@ function OhhwellsBridge() {
|
|
|
19186
19481
|
}
|
|
19187
19482
|
};
|
|
19188
19483
|
const probeImageAt = (clientX, clientY, isDragOver = false, fromParentViewport = false) => {
|
|
19189
|
-
if (linkPopoverOpenRef.current) {
|
|
19484
|
+
if (linkPopoverOpenRef.current || floatingPanelOpenRef.current && isPointOverFloatingPanel(clientX, clientY)) {
|
|
19190
19485
|
if (hoveredImageRef.current) {
|
|
19191
19486
|
hoveredImageRef.current = null;
|
|
19192
19487
|
hoveredImageHasTextOverlapRef.current = false;
|
|
@@ -19551,8 +19846,7 @@ function OhhwellsBridge() {
|
|
|
19551
19846
|
};
|
|
19552
19847
|
const handleMouseMove = (e) => {
|
|
19553
19848
|
const { clientX, clientY } = e;
|
|
19554
|
-
if (
|
|
19555
|
-
if (isOverEditorChrome(clientX, clientY)) {
|
|
19849
|
+
if (document.documentElement.hasAttribute("data-ohw-panel-dragging") || floatingPanelOpenRef.current && isPointOverFloatingPanel(clientX, clientY) || isOverEditorChrome(clientX, clientY)) {
|
|
19556
19850
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
19557
19851
|
formHoverElRef.current = null;
|
|
19558
19852
|
setFormHoverRect(null);
|
|
@@ -19560,6 +19854,12 @@ function OhhwellsBridge() {
|
|
|
19560
19854
|
setHoveredItemRect(null);
|
|
19561
19855
|
hoveredNavContainerRef.current = null;
|
|
19562
19856
|
setHoveredNavContainerRect(null);
|
|
19857
|
+
siblingHintElRef.current = null;
|
|
19858
|
+
setSiblingHintRect(null);
|
|
19859
|
+
setSiblingHintRects([]);
|
|
19860
|
+
dismissImageHover();
|
|
19861
|
+
clearImageHover();
|
|
19862
|
+
setSectionGap(null);
|
|
19563
19863
|
return;
|
|
19564
19864
|
}
|
|
19565
19865
|
if (probeSocialsRowAt(clientX, clientY)) return;
|
|
@@ -19571,7 +19871,11 @@ function OhhwellsBridge() {
|
|
|
19571
19871
|
if (e.data?.type !== "ow:pointer-sync") return;
|
|
19572
19872
|
const { clientX, clientY } = e.data;
|
|
19573
19873
|
if (typeof clientX !== "number" || typeof clientY !== "number") return;
|
|
19574
|
-
if (
|
|
19874
|
+
if (document.documentElement.hasAttribute("data-ohw-panel-dragging") || floatingPanelOpenRef.current && isPointOverFloatingPanel(clientX, clientY)) {
|
|
19875
|
+
dismissImageHover();
|
|
19876
|
+
clearImageHover();
|
|
19877
|
+
return;
|
|
19878
|
+
}
|
|
19575
19879
|
if (probeSocialsRowAt(clientX, clientY)) return;
|
|
19576
19880
|
probeSectionGapAt(clientX, clientY);
|
|
19577
19881
|
probeImageAt(clientX, clientY);
|
|
@@ -19871,6 +20175,7 @@ function OhhwellsBridge() {
|
|
|
19871
20175
|
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
19872
20176
|
}
|
|
19873
20177
|
applyBrandChrome(content);
|
|
20178
|
+
initSectionInstancesFromContent(content, window.location.pathname);
|
|
19874
20179
|
let sectionsJson = null;
|
|
19875
20180
|
for (const [key, val] of Object.entries(content)) {
|
|
19876
20181
|
if (key === "__ohw_sections") {
|
|
@@ -19878,11 +20183,11 @@ function OhhwellsBridge() {
|
|
|
19878
20183
|
continue;
|
|
19879
20184
|
}
|
|
19880
20185
|
if (key === AI_SECTIONS_KEY) continue;
|
|
20186
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
20187
|
+
if (LOGO_IMAGE_KEYS.includes(key) && !String(val ?? "").trim()) continue;
|
|
19881
20188
|
if (key === BRAND_KIT_KEY) continue;
|
|
19882
20189
|
if (key === STYLE_STORE_KEY) continue;
|
|
19883
20190
|
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
19884
|
-
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
19885
|
-
if (LOGO_IMAGE_KEYS.includes(key) && !String(val ?? "").trim()) continue;
|
|
19886
20191
|
if (applyVideoSettingNode(key, val)) continue;
|
|
19887
20192
|
if (applyCarouselNode(key, val)) continue;
|
|
19888
20193
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
@@ -19912,7 +20217,6 @@ function OhhwellsBridge() {
|
|
|
19912
20217
|
sectionsLoadedRef.current = true;
|
|
19913
20218
|
pendingScheduleConfigRequests.current.splice(0).forEach(processConfigRequest);
|
|
19914
20219
|
}
|
|
19915
|
-
initSectionInstancesFromContent(content, window.location.pathname);
|
|
19916
20220
|
editContentRef.current = { ...editContentRef.current, ...content };
|
|
19917
20221
|
reconcileNavbarItemsFromContent(editContentRef.current);
|
|
19918
20222
|
reconcileFooterOrderFromContent(editContentRef.current);
|
|
@@ -20057,12 +20361,35 @@ function OhhwellsBridge() {
|
|
|
20057
20361
|
window.addEventListener("message", handleAiSetBrand);
|
|
20058
20362
|
const handleAiSetStyles = (e) => {
|
|
20059
20363
|
if (e.data?.type !== "ow:ai-set-styles") return;
|
|
20060
|
-
|
|
20364
|
+
let value = typeof e.data.value === "string" ? e.data.value : "";
|
|
20061
20365
|
const previous = stylesRef.current;
|
|
20366
|
+
let previousSections;
|
|
20367
|
+
const store = parseStyleStore(value);
|
|
20368
|
+
if (store) {
|
|
20369
|
+
const folded = foldAlignIntoTrees(parseAiSectionsState(aiSectionsRef.current), store);
|
|
20370
|
+
if (folded.changed) {
|
|
20371
|
+
const nextSections = serializeAiSectionsState(folded.state);
|
|
20372
|
+
if (nextSections !== aiSectionsRef.current) {
|
|
20373
|
+
previousSections = aiSectionsRef.current;
|
|
20374
|
+
aiSectionsRef.current = nextSections;
|
|
20375
|
+
applyAiSectionsToDom(folded.state);
|
|
20376
|
+
postToParentRef.current({
|
|
20377
|
+
type: "ow:change",
|
|
20378
|
+
nodes: [{ key: AI_SECTIONS_KEY, text: nextSections }]
|
|
20379
|
+
});
|
|
20380
|
+
}
|
|
20381
|
+
value = JSON.stringify(folded.store);
|
|
20382
|
+
}
|
|
20383
|
+
}
|
|
20062
20384
|
stylesRef.current = value;
|
|
20063
20385
|
applyStylesToDom(parseStyleStore(value));
|
|
20064
20386
|
postToParentRef.current({ type: "ow:change", nodes: [{ key: STYLE_STORE_KEY, text: value }] });
|
|
20065
|
-
postToParentRef.current({
|
|
20387
|
+
postToParentRef.current({
|
|
20388
|
+
type: "ow:ai-styles-applied",
|
|
20389
|
+
previous,
|
|
20390
|
+
value,
|
|
20391
|
+
...previousSections !== void 0 ? { previousSections } : {}
|
|
20392
|
+
});
|
|
20066
20393
|
};
|
|
20067
20394
|
window.addEventListener("message", handleAiSetStyles);
|
|
20068
20395
|
const handleGetBrand = (e) => {
|
|
@@ -20134,6 +20461,34 @@ function OhhwellsBridge() {
|
|
|
20134
20461
|
});
|
|
20135
20462
|
};
|
|
20136
20463
|
window.addEventListener("message", handleDeleteSection);
|
|
20464
|
+
const handleDuplicateSection = (e) => {
|
|
20465
|
+
if (e.data?.type !== "ow:duplicate-section") return;
|
|
20466
|
+
const instanceId = typeof e.data.instanceId === "string" ? e.data.instanceId : "";
|
|
20467
|
+
if (!instanceId) return;
|
|
20468
|
+
const newId = newInstanceId();
|
|
20469
|
+
const currentEntries = getPageSectionOrderEntries(editContentRef.current[SECTION_ORDER_KEY], window.location.pathname);
|
|
20470
|
+
const result = duplicateSectionInstance(instanceId, newId, window.location.pathname, currentEntries);
|
|
20471
|
+
if (!result) return;
|
|
20472
|
+
const { entries, keyRekeys } = result;
|
|
20473
|
+
const orderJson = JSON.stringify(entries);
|
|
20474
|
+
const nodes = [{ key: SECTION_ORDER_KEY, text: orderJson }];
|
|
20475
|
+
for (const { from, to } of keyRekeys) {
|
|
20476
|
+
const inherited = editContentRef.current[from];
|
|
20477
|
+
if (inherited !== void 0) nodes.push({ key: to, text: inherited });
|
|
20478
|
+
}
|
|
20479
|
+
editContentRef.current = {
|
|
20480
|
+
...editContentRef.current,
|
|
20481
|
+
...Object.fromEntries(nodes.map(({ key, text }) => [key, text]))
|
|
20482
|
+
};
|
|
20483
|
+
setAiSectionOrder(orderJson, window.location.pathname);
|
|
20484
|
+
postToParentRef.current({ type: "ow:change", nodes });
|
|
20485
|
+
window.dispatchEvent(new Event("resize"));
|
|
20486
|
+
const duplicateHeight = document.body.scrollHeight;
|
|
20487
|
+
if (duplicateHeight > 50) postToParentRef.current({ type: "ow:height", height: duplicateHeight });
|
|
20488
|
+
const clone = document.querySelector(`[data-ohw-instance="${CSS.escape(newId)}"]`);
|
|
20489
|
+
if (clone) aiSectionApiRef.current?.selectFromElement(clone);
|
|
20490
|
+
};
|
|
20491
|
+
window.addEventListener("message", handleDuplicateSection);
|
|
20137
20492
|
const handleDeactivate = (e) => {
|
|
20138
20493
|
if (e.data?.type !== "ow:deactivate") return;
|
|
20139
20494
|
if (document.documentElement.hasAttribute("data-ohw-panel-dragging")) return;
|
|
@@ -20143,6 +20498,12 @@ function OhhwellsBridge() {
|
|
|
20143
20498
|
closeLinkPopoverRef.current();
|
|
20144
20499
|
return;
|
|
20145
20500
|
}
|
|
20501
|
+
if (floatingPanelOpenRef.current) {
|
|
20502
|
+
setFloatingPanelRef.current(null);
|
|
20503
|
+
deselectRef.current();
|
|
20504
|
+
deactivateRef.current();
|
|
20505
|
+
return;
|
|
20506
|
+
}
|
|
20146
20507
|
deselectRef.current();
|
|
20147
20508
|
deactivateRef.current();
|
|
20148
20509
|
clearMediaSelectionRef.current();
|
|
@@ -20417,8 +20778,12 @@ function OhhwellsBridge() {
|
|
|
20417
20778
|
if (inserted) {
|
|
20418
20779
|
const tracker = getSectionsTracker();
|
|
20419
20780
|
postToParentRef.current({ type: "ow:change", nodes: [{ key: "__ohw_sections", text: tracker.textContent ?? "[]" }] });
|
|
20420
|
-
const
|
|
20421
|
-
|
|
20781
|
+
const reportHeight = () => {
|
|
20782
|
+
const h = document.body.scrollHeight;
|
|
20783
|
+
if (h > 50) postToParentRef.current({ type: "ow:height", height: h });
|
|
20784
|
+
};
|
|
20785
|
+
reportHeight();
|
|
20786
|
+
setTimeout(reportHeight, 500);
|
|
20422
20787
|
}
|
|
20423
20788
|
};
|
|
20424
20789
|
const handleSwitchSchedule = (e) => {
|
|
@@ -20820,11 +21185,12 @@ function OhhwellsBridge() {
|
|
|
20820
21185
|
window.removeEventListener("message", handleMoveSection);
|
|
20821
21186
|
window.removeEventListener("message", handlePanelDragging);
|
|
20822
21187
|
window.removeEventListener("message", handleDeleteSection);
|
|
21188
|
+
window.removeEventListener("message", handleDuplicateSection);
|
|
20823
21189
|
window.removeEventListener("message", handleDeactivate);
|
|
20824
|
-
document.documentElement.removeAttribute("data-ohw-panel-dragging");
|
|
20825
21190
|
window.removeEventListener("message", handleToastAction);
|
|
20826
21191
|
window.removeEventListener("message", handleFormCount);
|
|
20827
21192
|
window.removeEventListener("message", handleUiEscape);
|
|
21193
|
+
document.documentElement.removeAttribute("data-ohw-panel-dragging");
|
|
20828
21194
|
autoSaveTimers.current.forEach(clearTimeout);
|
|
20829
21195
|
autoSaveTimers.current.clear();
|
|
20830
21196
|
if (imageUnhoverTimerRef.current) clearTimeout(imageUnhoverTimerRef.current);
|
|
@@ -21027,7 +21393,7 @@ function OhhwellsBridge() {
|
|
|
21027
21393
|
postToParent2({
|
|
21028
21394
|
type: "ow:ready",
|
|
21029
21395
|
version: "1",
|
|
21030
|
-
bridgeVersion: "0.1.
|
|
21396
|
+
bridgeVersion: "0.1.84",
|
|
21031
21397
|
path: pathname,
|
|
21032
21398
|
nodes: collectEditableNodes(editContentRef.current),
|
|
21033
21399
|
sections
|
|
@@ -21490,6 +21856,7 @@ function OhhwellsBridge() {
|
|
|
21490
21856
|
return /* @__PURE__ */ jsxs20(Fragment8, { children: [
|
|
21491
21857
|
/* @__PURE__ */ jsx33("div", { id: "ohw-loader", suppressHydrationWarning: true, style: { ...OHW_LOADER_STYLE, display: "none" }, children: /* @__PURE__ */ jsx33(OhwLoaderSpinner, {}) }),
|
|
21492
21858
|
/* @__PURE__ */ jsx33("script", { suppressHydrationWarning: true, dangerouslySetInnerHTML: { __html: OHW_LOADER_PREHYDRATE_SCRIPT } }),
|
|
21859
|
+
subdomain && !isEditMode && showBranding && /* @__PURE__ */ jsx33(MadeWithOhhWells, {}),
|
|
21493
21860
|
bridgeRoot ? createPortal2(
|
|
21494
21861
|
/* @__PURE__ */ jsxs20(Fragment8, { children: [
|
|
21495
21862
|
/* @__PURE__ */ jsx33("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
|
|
@@ -21945,6 +22312,59 @@ function OhhwellsBridge() {
|
|
|
21945
22312
|
) : null
|
|
21946
22313
|
] });
|
|
21947
22314
|
}
|
|
22315
|
+
|
|
22316
|
+
// src/ui/EmptySection.tsx
|
|
22317
|
+
import Link3 from "next/link";
|
|
22318
|
+
import { Fragment as Fragment9, jsx as jsx34, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
22319
|
+
function EmptySection({ title, homeHref = "/", eyebrowKey, titleKey, subtitleKey }) {
|
|
22320
|
+
return /* @__PURE__ */ jsxs21(Fragment9, { children: [
|
|
22321
|
+
/* @__PURE__ */ jsx34(
|
|
22322
|
+
"p",
|
|
22323
|
+
{
|
|
22324
|
+
style: {
|
|
22325
|
+
fontFamily: "var(--brand-font-body)",
|
|
22326
|
+
fontSize: "0.75rem",
|
|
22327
|
+
fontWeight: 500,
|
|
22328
|
+
letterSpacing: "0.15em",
|
|
22329
|
+
textTransform: "uppercase",
|
|
22330
|
+
color: "var(--brand-accent)",
|
|
22331
|
+
marginBottom: "1.5rem"
|
|
22332
|
+
},
|
|
22333
|
+
children: /* @__PURE__ */ jsx34(Link3, { href: homeHref, style: { color: "inherit" }, children: /* @__PURE__ */ jsx34("span", { ...eyebrowKey ? { "data-ohw-editable": "text", "data-ohw-key": eyebrowKey } : {}, children: "Home" }) })
|
|
22334
|
+
}
|
|
22335
|
+
),
|
|
22336
|
+
/* @__PURE__ */ jsx34(
|
|
22337
|
+
"h1",
|
|
22338
|
+
{
|
|
22339
|
+
style: {
|
|
22340
|
+
fontFamily: "var(--brand-font-heading)",
|
|
22341
|
+
fontSize: "clamp(2rem, 3.5vw, 2.75rem)",
|
|
22342
|
+
lineHeight: 1.1,
|
|
22343
|
+
letterSpacing: "-0.025em",
|
|
22344
|
+
color: "var(--brand-text)",
|
|
22345
|
+
marginBottom: "1rem"
|
|
22346
|
+
},
|
|
22347
|
+
...titleKey ? { "data-ohw-editable": "text", "data-ohw-key": titleKey, "data-ohw-max-length": 80 } : {},
|
|
22348
|
+
children: title
|
|
22349
|
+
}
|
|
22350
|
+
),
|
|
22351
|
+
/* @__PURE__ */ jsx34(
|
|
22352
|
+
"p",
|
|
22353
|
+
{
|
|
22354
|
+
style: {
|
|
22355
|
+
fontFamily: "var(--brand-font-body)",
|
|
22356
|
+
fontSize: "1rem",
|
|
22357
|
+
lineHeight: 1.7,
|
|
22358
|
+
fontWeight: 300,
|
|
22359
|
+
color: "var(--brand-text-muted)",
|
|
22360
|
+
maxWidth: "340px"
|
|
22361
|
+
},
|
|
22362
|
+
...subtitleKey ? { "data-ohw-editable": "text", "data-ohw-key": subtitleKey, "data-ohw-max-length": 160 } : {},
|
|
22363
|
+
children: "This page doesn't have any content yet."
|
|
22364
|
+
}
|
|
22365
|
+
)
|
|
22366
|
+
] });
|
|
22367
|
+
}
|
|
21948
22368
|
export {
|
|
21949
22369
|
AI_DEFAULT_BRAND,
|
|
21950
22370
|
AI_TREE_SCHEMA_VERSIONS,
|
|
@@ -21961,6 +22381,7 @@ export {
|
|
|
21961
22381
|
DropdownMenuItem,
|
|
21962
22382
|
DropdownMenuSeparator,
|
|
21963
22383
|
DropdownMenuTrigger,
|
|
22384
|
+
EmptySection,
|
|
21964
22385
|
ItemActionToolbar,
|
|
21965
22386
|
ItemInteractionLayer,
|
|
21966
22387
|
LinkEditorPanel,
|