@ohhwells/bridge 0.1.54 → 0.1.55-next.160
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 +2642 -388
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +18 -3
- package/dist/index.d.ts +18 -3
- package/dist/index.js +2644 -385
- 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/styles.css +108 -0
- package/package.json +6 -1
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
// src/OhhwellsBridge.tsx
|
|
4
|
-
import React11, { useCallback as
|
|
4
|
+
import React11, { useCallback as useCallback7, useEffect as useEffect12, useLayoutEffect as useLayoutEffect4, useRef as useRef9, useState as useState11 } from "react";
|
|
5
5
|
import { createRoot as createRoot2 } from "react-dom/client";
|
|
6
6
|
import { flushSync as flushSync2 } from "react-dom";
|
|
7
7
|
|
|
@@ -118,6 +118,129 @@ function deleteSectionFromState(state, sectionId) {
|
|
|
118
118
|
return { ...state, v: 1, sections: state.sections, removed: [...removed, sectionId] };
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
+
// src/lib/brand-chrome.ts
|
|
122
|
+
var BRAND_NAME_KEY = "__ohw_brand_name";
|
|
123
|
+
var BRAND_TITLE_KEY = "__ohw_site_title";
|
|
124
|
+
var BRAND_FAVICON_LETTER_KEY = "__ohw_favicon_letter";
|
|
125
|
+
var BRAND_CHROME_KEYS = /* @__PURE__ */ new Set([
|
|
126
|
+
BRAND_NAME_KEY,
|
|
127
|
+
BRAND_TITLE_KEY,
|
|
128
|
+
BRAND_FAVICON_LETTER_KEY
|
|
129
|
+
]);
|
|
130
|
+
function upsertMeta(selector, attr, token, value) {
|
|
131
|
+
let el = document.head.querySelector(selector);
|
|
132
|
+
if (!el) {
|
|
133
|
+
el = document.createElement("meta");
|
|
134
|
+
el.setAttribute(attr, token);
|
|
135
|
+
document.head.appendChild(el);
|
|
136
|
+
}
|
|
137
|
+
if (el.getAttribute("content") !== value) el.setAttribute("content", value);
|
|
138
|
+
}
|
|
139
|
+
function escapeXml(value) {
|
|
140
|
+
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
141
|
+
}
|
|
142
|
+
function applyLetterFavicon(letter) {
|
|
143
|
+
const svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect width="64" height="64" rx="12" fill="#111827"/><text x="32" y="46" font-family="system-ui,-apple-system,Segoe UI,sans-serif" font-size="40" font-weight="700" text-anchor="middle" fill="#ffffff">${escapeXml(letter)}</text></svg>`;
|
|
144
|
+
const href = `data:image/svg+xml,${encodeURIComponent(svg)}`;
|
|
145
|
+
let link = document.head.querySelector('link[rel="icon"]');
|
|
146
|
+
if (!link) {
|
|
147
|
+
link = document.createElement("link");
|
|
148
|
+
link.rel = "icon";
|
|
149
|
+
document.head.appendChild(link);
|
|
150
|
+
}
|
|
151
|
+
link.type = "image/svg+xml";
|
|
152
|
+
if (link.href !== href) link.href = href;
|
|
153
|
+
}
|
|
154
|
+
function applyBrandChrome(content) {
|
|
155
|
+
const name = content[BRAND_NAME_KEY];
|
|
156
|
+
if (typeof name === "string" && name.length > 0) {
|
|
157
|
+
document.querySelectorAll("[data-ohw-wordmark]").forEach((el) => {
|
|
158
|
+
if (el.textContent !== name) el.textContent = name;
|
|
159
|
+
if (el.getAttribute("title") !== name) el.setAttribute("title", name);
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
const title = content[BRAND_TITLE_KEY];
|
|
163
|
+
if (typeof title === "string" && title.length > 0) {
|
|
164
|
+
if (document.title !== title) document.title = title;
|
|
165
|
+
upsertMeta('meta[property="og:title"]', "property", "og:title", title);
|
|
166
|
+
upsertMeta('meta[name="twitter:title"]', "name", "twitter:title", title);
|
|
167
|
+
}
|
|
168
|
+
const letter = content[BRAND_FAVICON_LETTER_KEY];
|
|
169
|
+
if (typeof letter === "string" && letter.length > 0) {
|
|
170
|
+
applyLetterFavicon(letter);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// src/lib/brand-kit.ts
|
|
175
|
+
var BRAND_KIT_KEY = "__ohw_brand";
|
|
176
|
+
var BRAND_VAR_PREFIX = "--ohw-brand-";
|
|
177
|
+
var BRAND_VAR_NAMES = ["primary", "accent", "light", "dark", "surface", "border", "muted"].map(
|
|
178
|
+
(role) => `${BRAND_VAR_PREFIX}${role}`
|
|
179
|
+
);
|
|
180
|
+
var FONT_VARS = { heading: ["--font-heading", "--font-display"], body: ["--font-body"] };
|
|
181
|
+
var BRAND_FONT_LINK_ID = "ohw-brand-fonts";
|
|
182
|
+
function brandColorVars(kit) {
|
|
183
|
+
const { dark, primary, accent, light } = kit.palette;
|
|
184
|
+
const mix = (a, aPct, b) => `color-mix(in srgb, ${a} ${aPct}%, ${b})`;
|
|
185
|
+
return {
|
|
186
|
+
[`${BRAND_VAR_PREFIX}primary`]: primary,
|
|
187
|
+
[`${BRAND_VAR_PREFIX}accent`]: accent,
|
|
188
|
+
[`${BRAND_VAR_PREFIX}light`]: light,
|
|
189
|
+
[`${BRAND_VAR_PREFIX}dark`]: dark,
|
|
190
|
+
[`${BRAND_VAR_PREFIX}surface`]: mix(light, 95, dark),
|
|
191
|
+
[`${BRAND_VAR_PREFIX}border`]: mix(light, 85, dark),
|
|
192
|
+
[`${BRAND_VAR_PREFIX}muted`]: mix(dark, 62, light)
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
function parseBrandKit(raw) {
|
|
196
|
+
if (!raw) return null;
|
|
197
|
+
try {
|
|
198
|
+
const parsed = JSON.parse(raw);
|
|
199
|
+
const p = parsed?.palette;
|
|
200
|
+
const f = parsed?.fonts;
|
|
201
|
+
if (!p || !f || typeof p.dark !== "string" || typeof p.primary !== "string" || typeof p.accent !== "string" || typeof p.light !== "string" || typeof f.heading !== "string" || typeof f.body !== "string") {
|
|
202
|
+
return null;
|
|
203
|
+
}
|
|
204
|
+
return {
|
|
205
|
+
palette: { dark: p.dark, primary: p.primary, accent: p.accent, light: p.light },
|
|
206
|
+
fonts: { heading: f.heading, body: f.body }
|
|
207
|
+
};
|
|
208
|
+
} catch {
|
|
209
|
+
return null;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
function familyOf(stack) {
|
|
213
|
+
const first = stack.split(",")[0]?.trim() ?? "";
|
|
214
|
+
return first.replace(/^['"]|['"]$/g, "");
|
|
215
|
+
}
|
|
216
|
+
function loadBrandFonts(families) {
|
|
217
|
+
const unique = [...new Set(families.map((f) => f.trim()).filter(Boolean))];
|
|
218
|
+
if (unique.length === 0) return;
|
|
219
|
+
const spec = unique.map((f) => `${f.replace(/ /g, "+")}:400,500,600,700`).join("|");
|
|
220
|
+
const href = `https://fonts.googleapis.com/css?family=${spec}&display=swap`;
|
|
221
|
+
let link = document.getElementById(BRAND_FONT_LINK_ID);
|
|
222
|
+
if (!link) {
|
|
223
|
+
link = document.createElement("link");
|
|
224
|
+
link.id = BRAND_FONT_LINK_ID;
|
|
225
|
+
link.rel = "stylesheet";
|
|
226
|
+
document.head.appendChild(link);
|
|
227
|
+
}
|
|
228
|
+
if (link.href !== href) link.href = href;
|
|
229
|
+
}
|
|
230
|
+
function applyBrandToDom(kit) {
|
|
231
|
+
const root = document.documentElement;
|
|
232
|
+
if (!kit) {
|
|
233
|
+
for (const name of BRAND_VAR_NAMES) root.style.removeProperty(name);
|
|
234
|
+
for (const name of [...FONT_VARS.heading, ...FONT_VARS.body]) root.style.removeProperty(name);
|
|
235
|
+
document.getElementById(BRAND_FONT_LINK_ID)?.remove();
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
for (const [name, value] of Object.entries(brandColorVars(kit))) root.style.setProperty(name, value);
|
|
239
|
+
for (const name of FONT_VARS.heading) root.style.setProperty(name, kit.fonts.heading);
|
|
240
|
+
for (const name of FONT_VARS.body) root.style.setProperty(name, kit.fonts.body);
|
|
241
|
+
loadBrandFonts([familyOf(kit.fonts.heading), familyOf(kit.fonts.body)]);
|
|
242
|
+
}
|
|
243
|
+
|
|
121
244
|
// src/ui/ai-tree/aiSectionsManager.tsx
|
|
122
245
|
import { flushSync } from "react-dom";
|
|
123
246
|
import { createRoot } from "react-dom/client";
|
|
@@ -150,6 +273,17 @@ var FEATURE_LINE_CSS = [
|
|
|
150
273
|
function textAttrs(ctx, path) {
|
|
151
274
|
return ctx.keyFor ? { "data-ohw-key": ctx.keyFor(path), "data-ohw-editable": "text" } : {};
|
|
152
275
|
}
|
|
276
|
+
var AI_RESPONSIVE_CSS = [
|
|
277
|
+
"@media (max-width: 960px) {",
|
|
278
|
+
" [data-ai-responsive] [data-ai-grid] { grid-template-columns: repeat(2, 1fr) !important; }",
|
|
279
|
+
' [data-ai-responsive] [data-ai-grid="1"] { grid-template-columns: 1fr !important; }',
|
|
280
|
+
"}",
|
|
281
|
+
"@media (max-width: 640px) {",
|
|
282
|
+
" [data-ai-responsive] [data-ai-grid] { grid-template-columns: 1fr !important; }",
|
|
283
|
+
" [data-ai-responsive] [data-ai-columns] > * { grid-column: 1 / -1 !important; }",
|
|
284
|
+
" [data-ai-responsive] [data-ai-section-inner] { padding-left: 20px !important; padding-right: 20px !important; }",
|
|
285
|
+
"}"
|
|
286
|
+
].join("\n");
|
|
153
287
|
var TRANSPARENT_PX = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
|
|
154
288
|
function MediaBox({
|
|
155
289
|
refValue,
|
|
@@ -162,13 +296,17 @@ function MediaBox({
|
|
|
162
296
|
const url = refValue ? ctx.resolveMedia(refValue) : null;
|
|
163
297
|
const isIcon = /^(lucide|simple):/.test(refValue);
|
|
164
298
|
const aspectRatio = aspect && /^\d+:\d+$/.test(aspect) ? aspect.replace(":", " / ") : void 0;
|
|
165
|
-
const editAttrs = ctx.keyFor && editPath
|
|
299
|
+
const editAttrs = ctx.keyFor && editPath ? {
|
|
300
|
+
"data-ohw-key": ctx.keyFor(editPath),
|
|
301
|
+
"data-ohw-editable": isIcon ? "icon" : "image"
|
|
302
|
+
} : {};
|
|
166
303
|
if (isIcon) {
|
|
167
304
|
const Icon = refValue.startsWith("lucide:") ? lucideByName(refValue.slice(7)) : null;
|
|
168
305
|
return /* @__PURE__ */ jsx(
|
|
169
306
|
"span",
|
|
170
307
|
{
|
|
171
308
|
"data-ai-icon": refValue,
|
|
309
|
+
...editAttrs,
|
|
172
310
|
style: {
|
|
173
311
|
display: "inline-flex",
|
|
174
312
|
width: 48,
|
|
@@ -888,6 +1026,7 @@ function Carousel({ items, itemsPerRow, ctx }) {
|
|
|
888
1026
|
children: pageGroups.map((group, p) => /* @__PURE__ */ jsx(
|
|
889
1027
|
"div",
|
|
890
1028
|
{
|
|
1029
|
+
"data-ai-grid": String(itemsPerRow),
|
|
891
1030
|
style: {
|
|
892
1031
|
flex: "0 0 100%",
|
|
893
1032
|
display: "grid",
|
|
@@ -991,6 +1130,7 @@ function CollectionBlock({ node, ctx, path }) {
|
|
|
991
1130
|
return /* @__PURE__ */ jsx(
|
|
992
1131
|
"div",
|
|
993
1132
|
{
|
|
1133
|
+
"data-ai-grid": String(itemsPerRow),
|
|
994
1134
|
style: {
|
|
995
1135
|
display: "grid",
|
|
996
1136
|
gridTemplateColumns: `repeat(${itemsPerRow}, 1fr)`,
|
|
@@ -1154,6 +1294,7 @@ function AiTreeRenderer({ tree, brand, resolveMedia, editKeyPrefix }) {
|
|
|
1154
1294
|
{
|
|
1155
1295
|
"data-ai-section": tree.tag ?? "",
|
|
1156
1296
|
...bgAttrs,
|
|
1297
|
+
"data-ai-responsive": "",
|
|
1157
1298
|
style: {
|
|
1158
1299
|
position: "relative",
|
|
1159
1300
|
padding: `${pad}px 0`,
|
|
@@ -1163,10 +1304,12 @@ function AiTreeRenderer({ tree, brand, resolveMedia, editKeyPrefix }) {
|
|
|
1163
1304
|
backgroundPosition: "center"
|
|
1164
1305
|
},
|
|
1165
1306
|
children: [
|
|
1307
|
+
/* @__PURE__ */ jsx("style", { children: AI_RESPONSIVE_CSS }),
|
|
1166
1308
|
isOverlay && backgroundUrl && /* @__PURE__ */ jsx("div", { style: { position: "absolute", inset: 0, background: `rgba(255,255,255,${overlayAlpha})` } }),
|
|
1167
1309
|
/* @__PURE__ */ jsx(
|
|
1168
1310
|
"div",
|
|
1169
1311
|
{
|
|
1312
|
+
"data-ai-section-inner": "",
|
|
1170
1313
|
style: {
|
|
1171
1314
|
position: "relative",
|
|
1172
1315
|
maxWidth: AI_TREE_TOKENS.sectionMaxWidth,
|
|
@@ -1177,6 +1320,7 @@ function AiTreeRenderer({ tree, brand, resolveMedia, editKeyPrefix }) {
|
|
|
1177
1320
|
children: tree.rows.map((row, r2) => /* @__PURE__ */ jsx(
|
|
1178
1321
|
"div",
|
|
1179
1322
|
{
|
|
1323
|
+
"data-ai-columns": "",
|
|
1180
1324
|
style: {
|
|
1181
1325
|
display: "grid",
|
|
1182
1326
|
gridTemplateColumns: "repeat(12, 1fr)",
|
|
@@ -1200,17 +1344,34 @@ import { jsx as jsx2 } from "react/jsx-runtime";
|
|
|
1200
1344
|
var CONTAINER_ATTR = "data-ohw-ai-generated";
|
|
1201
1345
|
var REPLACED_ATTR = "data-ohw-ai-replaced-by";
|
|
1202
1346
|
var REMOVED_ATTR = "data-ohw-ai-removed";
|
|
1347
|
+
function readRootVar(name) {
|
|
1348
|
+
if (typeof document === "undefined") return "";
|
|
1349
|
+
return getComputedStyle(document.documentElement).getPropertyValue(name).trim();
|
|
1350
|
+
}
|
|
1351
|
+
function deriveBrandOverride() {
|
|
1352
|
+
const dark = readRootVar("--ohw-brand-dark");
|
|
1353
|
+
const primary = readRootVar("--ohw-brand-primary");
|
|
1354
|
+
const light = readRootVar("--ohw-brand-light");
|
|
1355
|
+
if (!dark || !primary || !light) return null;
|
|
1356
|
+
const accent = readRootVar("--ohw-brand-accent");
|
|
1357
|
+
const heading = readRootVar("--font-heading") || readRootVar("--font-display");
|
|
1358
|
+
const body = readRootVar("--font-body");
|
|
1359
|
+
return {
|
|
1360
|
+
palette: { dark, primary, accent: accent || dark, light },
|
|
1361
|
+
fonts: {
|
|
1362
|
+
heading: heading || AI_DEFAULT_BRAND.fonts.heading,
|
|
1363
|
+
body: body || AI_DEFAULT_BRAND.fonts.body
|
|
1364
|
+
}
|
|
1365
|
+
};
|
|
1366
|
+
}
|
|
1203
1367
|
function deriveTemplateBrand() {
|
|
1204
|
-
|
|
1205
|
-
const
|
|
1206
|
-
const
|
|
1207
|
-
const dark = read("--color-dark");
|
|
1208
|
-
const primary = read("--color-primary");
|
|
1209
|
-
const light = read("--color-light");
|
|
1368
|
+
const dark = readRootVar("--color-dark");
|
|
1369
|
+
const primary = readRootVar("--color-primary");
|
|
1370
|
+
const light = readRootVar("--color-light");
|
|
1210
1371
|
if (!dark || !primary || !light) return null;
|
|
1211
|
-
const accent =
|
|
1212
|
-
const heading =
|
|
1213
|
-
const body =
|
|
1372
|
+
const accent = readRootVar("--color-accent");
|
|
1373
|
+
const heading = readRootVar("--font-heading") || readRootVar("--font-display");
|
|
1374
|
+
const body = readRootVar("--font-body");
|
|
1214
1375
|
return {
|
|
1215
1376
|
palette: { dark, primary, accent: accent || dark, light },
|
|
1216
1377
|
fonts: {
|
|
@@ -1302,7 +1463,9 @@ function syncReplacedOriginals(state) {
|
|
|
1302
1463
|
}
|
|
1303
1464
|
function applyAiSectionsToDom(state, options) {
|
|
1304
1465
|
if (typeof document === "undefined") return;
|
|
1466
|
+
const brandOverride = deriveBrandOverride();
|
|
1305
1467
|
const templateBrand = deriveTemplateBrand();
|
|
1468
|
+
const brandKey = brandOverride ? JSON.stringify(brandOverride) : "";
|
|
1306
1469
|
const activeIds = new Set(state.sections.map((entry) => entry.id));
|
|
1307
1470
|
for (const [id, section] of mounted) {
|
|
1308
1471
|
if (!activeIds.has(id)) {
|
|
@@ -1312,7 +1475,7 @@ function applyAiSectionsToDom(state, options) {
|
|
|
1312
1475
|
}
|
|
1313
1476
|
}
|
|
1314
1477
|
for (const entry of state.sections) {
|
|
1315
|
-
const serialized = JSON.stringify(entry);
|
|
1478
|
+
const serialized = JSON.stringify(entry) + brandKey;
|
|
1316
1479
|
const existing = mounted.get(entry.id);
|
|
1317
1480
|
if (existing && existing.serialized === serialized && existing.container.isConnected) {
|
|
1318
1481
|
continue;
|
|
@@ -1336,7 +1499,7 @@ function applyAiSectionsToDom(state, options) {
|
|
|
1336
1499
|
AiTreeRenderer,
|
|
1337
1500
|
{
|
|
1338
1501
|
tree: entry.tree,
|
|
1339
|
-
brand: entry.brand ?? options?.brand ?? templateBrand ?? void 0,
|
|
1502
|
+
brand: brandOverride ?? entry.brand ?? options?.brand ?? templateBrand ?? void 0,
|
|
1340
1503
|
resolveMedia,
|
|
1341
1504
|
editKeyPrefix: `ai.${entry.id}`
|
|
1342
1505
|
}
|
|
@@ -1953,7 +2116,7 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
1953
2116
|
const autoId = useId();
|
|
1954
2117
|
const insertAfter = insertAfterProp ?? autoId;
|
|
1955
2118
|
const [schedule, setSchedule] = useState2(null);
|
|
1956
|
-
const [loading, setLoading] = useState2(
|
|
2119
|
+
const [loading, setLoading] = useState2(initialScheduleId !== null);
|
|
1957
2120
|
const [inEditor, setInEditor] = useState2(false);
|
|
1958
2121
|
const [isHovered, setIsHovered] = useState2(false);
|
|
1959
2122
|
const [modalState, setModalState] = useState2(null);
|
|
@@ -2127,8 +2290,10 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
2127
2290
|
"*"
|
|
2128
2291
|
);
|
|
2129
2292
|
};
|
|
2130
|
-
if (!inEditor && !loading && !schedule) return null;
|
|
2131
2293
|
const sectionId = `scheduling-${insertAfter}`;
|
|
2294
|
+
if (!inEditor && !loading && !schedule) {
|
|
2295
|
+
return /* @__PURE__ */ jsx4("section", { "data-ohw-section": sectionId, "data-ohw-scheduling-anchor": insertAfter, style: { display: "none" } });
|
|
2296
|
+
}
|
|
2132
2297
|
return /* @__PURE__ */ jsxs3(
|
|
2133
2298
|
"section",
|
|
2134
2299
|
{
|
|
@@ -5697,7 +5862,7 @@ CustomToolbarButton.displayName = "CustomToolbarButton";
|
|
|
5697
5862
|
|
|
5698
5863
|
// src/ui/item-action-toolbar.tsx
|
|
5699
5864
|
import { useState as useState3 } from "react";
|
|
5700
|
-
import { Copy, CornerLeftUp, Heading, Link, MoreHorizontal, Plus, Trash2 } from "lucide-react";
|
|
5865
|
+
import { Brush, Copy, CornerLeftUp, Heading, Link, MoreHorizontal, Plus, Trash2 } from "lucide-react";
|
|
5701
5866
|
|
|
5702
5867
|
// src/ui/dropdown-menu.tsx
|
|
5703
5868
|
import { DropdownMenu as DropdownMenuPrimitive } from "radix-ui";
|
|
@@ -5862,6 +6027,7 @@ function ToolbarActionTooltip({
|
|
|
5862
6027
|
function ItemActionToolbar({
|
|
5863
6028
|
onEditLink,
|
|
5864
6029
|
onAddItem,
|
|
6030
|
+
onStyle,
|
|
5865
6031
|
onSelectParent,
|
|
5866
6032
|
onDuplicate,
|
|
5867
6033
|
onDelete,
|
|
@@ -5873,6 +6039,8 @@ function ItemActionToolbar({
|
|
|
5873
6039
|
deleteDisabled = false,
|
|
5874
6040
|
showEditLink = true,
|
|
5875
6041
|
showAddItem = true,
|
|
6042
|
+
showStyle = false,
|
|
6043
|
+
styleActive = false,
|
|
5876
6044
|
showMore = true,
|
|
5877
6045
|
tooltipSide = "bottom",
|
|
5878
6046
|
dropdownOpen = null,
|
|
@@ -5946,6 +6114,22 @@ function ItemActionToolbar({
|
|
|
5946
6114
|
children: /* @__PURE__ */ jsx11(Link, { className: "size-4 shrink-0", "aria-hidden": true })
|
|
5947
6115
|
}
|
|
5948
6116
|
) : null,
|
|
6117
|
+
showStyle ? /* @__PURE__ */ jsx11(
|
|
6118
|
+
ToolbarActionTooltip,
|
|
6119
|
+
{
|
|
6120
|
+
label: "Style",
|
|
6121
|
+
side: tooltipSide,
|
|
6122
|
+
buttonProps: {
|
|
6123
|
+
active: styleActive,
|
|
6124
|
+
onMouseDown: (e) => {
|
|
6125
|
+
e.preventDefault();
|
|
6126
|
+
e.stopPropagation();
|
|
6127
|
+
onStyle?.();
|
|
6128
|
+
}
|
|
6129
|
+
},
|
|
6130
|
+
children: /* @__PURE__ */ jsx11(Brush, { className: "size-4 shrink-0", "aria-hidden": true })
|
|
6131
|
+
}
|
|
6132
|
+
) : null,
|
|
5949
6133
|
showAddItem ? /* @__PURE__ */ jsx11(
|
|
5950
6134
|
ToolbarActionTooltip,
|
|
5951
6135
|
{
|
|
@@ -6063,6 +6247,7 @@ var FOCUS_RING = `0 0 0 4px color-mix(in srgb, ${PRIMARY} 12%, transparent)`;
|
|
|
6063
6247
|
var DRAG_SHADOW = "0px 4px 6px -1px rgba(0, 0, 0, 0.1), 0px 2px 4px -2px rgba(0, 0, 0, 0.1)";
|
|
6064
6248
|
var TOOLBAR_EDGE_MARGIN = 4;
|
|
6065
6249
|
var SELECTION_CHROME_GAP = 4;
|
|
6250
|
+
var HOVER_CHROME_GAP = 2;
|
|
6066
6251
|
var TOOLBAR_STROKE_GAP = 4;
|
|
6067
6252
|
function getChromeZIndex(state) {
|
|
6068
6253
|
switch (state) {
|
|
@@ -6218,10 +6403,11 @@ function ItemInteractionLayer({
|
|
|
6218
6403
|
onItemPointerDown,
|
|
6219
6404
|
onItemClick,
|
|
6220
6405
|
itemDragSurface = true,
|
|
6221
|
-
chromeGap
|
|
6406
|
+
chromeGap,
|
|
6222
6407
|
className
|
|
6223
6408
|
}) {
|
|
6224
6409
|
if (state === "default") return null;
|
|
6410
|
+
const gap = chromeGap ?? (state === "hover" ? HOVER_CHROME_GAP : SELECTION_CHROME_GAP);
|
|
6225
6411
|
const isActive = state === "active-top" || state === "active-bottom";
|
|
6226
6412
|
const isDragging = state === "dragging";
|
|
6227
6413
|
const showToolbar = isActive && toolbar;
|
|
@@ -6237,10 +6423,10 @@ function ItemInteractionLayer({
|
|
|
6237
6423
|
className: cn("pointer-events-none", className),
|
|
6238
6424
|
style: {
|
|
6239
6425
|
position: "fixed",
|
|
6240
|
-
top: rect.top -
|
|
6241
|
-
left: rect.left -
|
|
6242
|
-
width: rect.width +
|
|
6243
|
-
height: rect.height +
|
|
6426
|
+
top: rect.top - gap,
|
|
6427
|
+
left: rect.left - gap,
|
|
6428
|
+
width: rect.width + gap * 2,
|
|
6429
|
+
height: rect.height + gap * 2,
|
|
6244
6430
|
zIndex: getChromeZIndex(state)
|
|
6245
6431
|
},
|
|
6246
6432
|
children: [
|
|
@@ -9452,9 +9638,453 @@ function deleteNavbarItem(sourceAnchor) {
|
|
|
9452
9638
|
};
|
|
9453
9639
|
}
|
|
9454
9640
|
|
|
9641
|
+
// src/lib/icon-markup.ts
|
|
9642
|
+
var GLYPH_SELECTOR = "svg, img";
|
|
9643
|
+
function referenceBox(slot) {
|
|
9644
|
+
const row = slot.closest("[data-ohw-socials-row]") ?? slot.closest("a")?.parentElement ?? null;
|
|
9645
|
+
const neighbour = row ? Array.from(row.querySelectorAll('[data-ohw-editable="icon"]')).find((el) => el !== slot) : null;
|
|
9646
|
+
const source = (neighbour ?? slot).querySelector(GLYPH_SELECTOR);
|
|
9647
|
+
const box = source?.getBoundingClientRect() ?? null;
|
|
9648
|
+
return box?.width && box.height ? box : null;
|
|
9649
|
+
}
|
|
9650
|
+
function iconMarkupSizedFor(slot, markup) {
|
|
9651
|
+
const box = referenceBox(slot);
|
|
9652
|
+
if (!box) return markup;
|
|
9653
|
+
const holder = document.createElement("div");
|
|
9654
|
+
holder.innerHTML = markup;
|
|
9655
|
+
const glyph = holder.querySelector(GLYPH_SELECTOR);
|
|
9656
|
+
if (!glyph) return markup;
|
|
9657
|
+
glyph.style.width = `${Math.round(box.width)}px`;
|
|
9658
|
+
glyph.style.height = `${Math.round(box.height)}px`;
|
|
9659
|
+
return holder.innerHTML;
|
|
9660
|
+
}
|
|
9661
|
+
function applyIconMarkup(slot, markup) {
|
|
9662
|
+
if (!markup) return;
|
|
9663
|
+
const coloured = iconMarkupInheritingColour(markup);
|
|
9664
|
+
const sized = iconMarkupSizedFor(slot, coloured);
|
|
9665
|
+
if (slot.innerHTML !== sized) slot.innerHTML = sized;
|
|
9666
|
+
if (sized === coloured) {
|
|
9667
|
+
requestAnimationFrame(() => {
|
|
9668
|
+
if (!slot.isConnected) return;
|
|
9669
|
+
const resized = iconMarkupSizedFor(slot, coloured);
|
|
9670
|
+
if (resized !== coloured && slot.innerHTML !== resized) slot.innerHTML = resized;
|
|
9671
|
+
});
|
|
9672
|
+
}
|
|
9673
|
+
}
|
|
9674
|
+
function detectIconStyle(el) {
|
|
9675
|
+
const row = el.closest("[data-ohw-socials-row]");
|
|
9676
|
+
const glyphs = Array.from((row ?? el).querySelectorAll("svg"));
|
|
9677
|
+
const outlined = glyphs.some((svg) => {
|
|
9678
|
+
return Array.from(svg.querySelectorAll("*")).some((node) => {
|
|
9679
|
+
return node.getAttribute("stroke") !== null && node.getAttribute("stroke") !== "none";
|
|
9680
|
+
});
|
|
9681
|
+
});
|
|
9682
|
+
return outlined ? "outline" : "fill";
|
|
9683
|
+
}
|
|
9684
|
+
function iconMarkupInheritingColour(markup) {
|
|
9685
|
+
const holder = document.createElement("div");
|
|
9686
|
+
holder.innerHTML = markup;
|
|
9687
|
+
holder.querySelectorAll("svg *").forEach((node) => {
|
|
9688
|
+
if (node.getAttribute("fill") && node.getAttribute("fill") !== "none") {
|
|
9689
|
+
node.setAttribute("fill", "currentColor");
|
|
9690
|
+
}
|
|
9691
|
+
if (node.getAttribute("stroke") && node.getAttribute("stroke") !== "none") {
|
|
9692
|
+
node.setAttribute("stroke", "currentColor");
|
|
9693
|
+
}
|
|
9694
|
+
});
|
|
9695
|
+
return holder.innerHTML;
|
|
9696
|
+
}
|
|
9697
|
+
|
|
9698
|
+
// src/lib/socials-items.ts
|
|
9699
|
+
var ICON_SELECTOR = '[data-ohw-editable="icon"]';
|
|
9700
|
+
var SOCIAL_KEY_RE = /(^|-)social(s)?(-|$)/i;
|
|
9701
|
+
var SOCIALS_ROW_ATTR = "data-ohw-socials-row";
|
|
9702
|
+
var SOCIALS_ITEM_ATTR = "data-ohw-social-item";
|
|
9703
|
+
function isSocialItem(el) {
|
|
9704
|
+
if (!el) return false;
|
|
9705
|
+
const anchor = el instanceof HTMLAnchorElement ? el : el.closest("a");
|
|
9706
|
+
if (!anchor) return false;
|
|
9707
|
+
if (SOCIAL_KEY_RE.test(anchor.getAttribute("data-ohw-href-key") ?? "")) return true;
|
|
9708
|
+
return anchor.querySelectorAll(ICON_SELECTOR).length === 1;
|
|
9709
|
+
}
|
|
9710
|
+
function getSocialItem(el) {
|
|
9711
|
+
const anchor = el.closest("a");
|
|
9712
|
+
return isSocialItem(anchor) ? anchor : null;
|
|
9713
|
+
}
|
|
9714
|
+
function findSocialsRow(el) {
|
|
9715
|
+
const item = getSocialItem(el);
|
|
9716
|
+
if (!item) return null;
|
|
9717
|
+
const wrapper = item.parentElement;
|
|
9718
|
+
const row = wrapper && wrapper.querySelectorAll("a").length === 1 && wrapper.matches("li, div, span") ? wrapper.parentElement : wrapper;
|
|
9719
|
+
if (!row) return null;
|
|
9720
|
+
const anchors = Array.from(row.querySelectorAll("a"));
|
|
9721
|
+
if (!anchors.length || !anchors.every((anchor) => isSocialItem(anchor))) return null;
|
|
9722
|
+
return row;
|
|
9723
|
+
}
|
|
9724
|
+
function isSocialsRow(el) {
|
|
9725
|
+
const anchors = Array.from(el.querySelectorAll("a"));
|
|
9726
|
+
return anchors.length > 0 && anchors.every((anchor) => isSocialItem(anchor));
|
|
9727
|
+
}
|
|
9728
|
+
function listSocialItems(row) {
|
|
9729
|
+
return Array.from(row.children).map((child) => {
|
|
9730
|
+
if (!(child instanceof HTMLElement)) return null;
|
|
9731
|
+
const anchor = child.matches("a") ? child : child.querySelector("a");
|
|
9732
|
+
return isSocialItem(anchor) ? anchor : null;
|
|
9733
|
+
}).filter((item) => item !== null);
|
|
9734
|
+
}
|
|
9735
|
+
function socialRowUnit(item) {
|
|
9736
|
+
const row = findSocialsRow(item);
|
|
9737
|
+
let node = item;
|
|
9738
|
+
while (node.parentElement && node.parentElement !== row) {
|
|
9739
|
+
node = node.parentElement;
|
|
9740
|
+
}
|
|
9741
|
+
return node;
|
|
9742
|
+
}
|
|
9743
|
+
function listSocialsRows(root = document) {
|
|
9744
|
+
const rows = /* @__PURE__ */ new Set();
|
|
9745
|
+
root.querySelectorAll(`${ICON_SELECTOR}, a[data-ohw-href-key]`).forEach((el) => {
|
|
9746
|
+
const row = findSocialsRow(el);
|
|
9747
|
+
if (row) rows.add(row);
|
|
9748
|
+
});
|
|
9749
|
+
root.querySelectorAll(`[${SOCIALS_ROW_ATTR}]`).forEach((row) => rows.add(row));
|
|
9750
|
+
return Array.from(rows);
|
|
9751
|
+
}
|
|
9752
|
+
var rowTemplates = /* @__PURE__ */ new Map();
|
|
9753
|
+
function markSocialsRows(root = document) {
|
|
9754
|
+
root.querySelectorAll(`[${SOCIALS_ITEM_ATTR}]`).forEach((item) => {
|
|
9755
|
+
item.removeAttribute(SOCIALS_ITEM_ATTR);
|
|
9756
|
+
});
|
|
9757
|
+
listSocialsRows(root).forEach((row) => {
|
|
9758
|
+
row.setAttribute(SOCIALS_ROW_ATTR, "");
|
|
9759
|
+
const items = listSocialItems(row);
|
|
9760
|
+
if (items[0]) rowTemplates.set(rowKeyOf(row), socialRowUnit(items[0]).outerHTML);
|
|
9761
|
+
items.forEach((item, index) => {
|
|
9762
|
+
item.setAttribute(SOCIALS_ITEM_ATTR, String(index));
|
|
9763
|
+
const iconKey = socialIconKey(item);
|
|
9764
|
+
if (iconKey) ensureLabelSlot(item, iconKey);
|
|
9765
|
+
});
|
|
9766
|
+
});
|
|
9767
|
+
}
|
|
9768
|
+
var SOCIALS_LABEL_ATTR = "data-ohw-social-label";
|
|
9769
|
+
function ensureLabelSlot(item, iconKey) {
|
|
9770
|
+
if (socialLabelElement(item)) return;
|
|
9771
|
+
const label = document.createElement("span");
|
|
9772
|
+
label.setAttribute("data-ohw-key", `${iconKey}-label`);
|
|
9773
|
+
label.setAttribute("data-ohw-editable", "text");
|
|
9774
|
+
label.setAttribute(SOCIALS_LABEL_ATTR, "");
|
|
9775
|
+
label.style.display = "none";
|
|
9776
|
+
label.textContent = item.getAttribute("aria-label") ?? "";
|
|
9777
|
+
item.appendChild(label);
|
|
9778
|
+
}
|
|
9779
|
+
function socialLabelElement(item) {
|
|
9780
|
+
return item.querySelector(
|
|
9781
|
+
`[${SOCIALS_LABEL_ATTR}], [data-ohw-editable="text"], [data-ohw-editable="plain"]`
|
|
9782
|
+
);
|
|
9783
|
+
}
|
|
9784
|
+
function socialLabelKey(iconKey) {
|
|
9785
|
+
return `${iconKey}-label`;
|
|
9786
|
+
}
|
|
9787
|
+
function applyStoredValues(item, content) {
|
|
9788
|
+
const hrefKey = socialHrefKey(item);
|
|
9789
|
+
const iconKey = socialIconKey(item);
|
|
9790
|
+
if (hrefKey && content[hrefKey] !== void 0) item.setAttribute("href", content[hrefKey]);
|
|
9791
|
+
if (iconKey) {
|
|
9792
|
+
const glyph = item.querySelector(ICON_SELECTOR);
|
|
9793
|
+
if (glyph && content[iconKey]) applyIconMarkup(glyph, content[iconKey]);
|
|
9794
|
+
const label = item.querySelector(`[${SOCIALS_LABEL_ATTR}]`);
|
|
9795
|
+
label?.setAttribute("data-ohw-key", socialLabelKey(iconKey));
|
|
9796
|
+
const stored = content[socialLabelKey(iconKey)];
|
|
9797
|
+
if (label && stored) label.textContent = stored;
|
|
9798
|
+
}
|
|
9799
|
+
}
|
|
9800
|
+
function socialPlatformKey(iconKey) {
|
|
9801
|
+
return `${iconKey}-platform`;
|
|
9802
|
+
}
|
|
9803
|
+
function socialHrefKey(item) {
|
|
9804
|
+
return item.getAttribute("data-ohw-href-key");
|
|
9805
|
+
}
|
|
9806
|
+
function socialIconKey(item) {
|
|
9807
|
+
return item.querySelector(ICON_SELECTOR)?.dataset.ohwKey ?? null;
|
|
9808
|
+
}
|
|
9809
|
+
var SOCIALS_ORDER_KEY = "__ohw_socials_order";
|
|
9810
|
+
function fromMarkup(markup) {
|
|
9811
|
+
const holder = document.createElement("div");
|
|
9812
|
+
holder.innerHTML = markup;
|
|
9813
|
+
return holder.firstElementChild instanceof HTMLElement ? holder.firstElementChild : null;
|
|
9814
|
+
}
|
|
9815
|
+
var rowKeys = /* @__PURE__ */ new WeakMap();
|
|
9816
|
+
function rowKeyOf(row) {
|
|
9817
|
+
const first = listSocialItems(row)[0];
|
|
9818
|
+
const itemKey = first ? socialIconKey(first) ?? socialHrefKey(first)?.replace(/-href$/, "") : null;
|
|
9819
|
+
const derived = itemKey?.replace(/-[^-]+$/, "") || null;
|
|
9820
|
+
if (derived) rowKeys.set(row, derived);
|
|
9821
|
+
return derived ?? rowKeys.get(row) ?? "social";
|
|
9822
|
+
}
|
|
9823
|
+
function getSocialsOrderFromDom(root = document) {
|
|
9824
|
+
const order = {};
|
|
9825
|
+
listSocialsRows(root).forEach((row) => {
|
|
9826
|
+
order[rowKeyOf(row)] = listSocialItems(row).map((item) => socialHrefKey(item)).filter((key) => Boolean(key));
|
|
9827
|
+
});
|
|
9828
|
+
return order;
|
|
9829
|
+
}
|
|
9830
|
+
function hasStoredValue(content, hrefKey) {
|
|
9831
|
+
const iconKey = hrefKey.replace(/-href$/, "");
|
|
9832
|
+
return Boolean(content[hrefKey]) || Boolean(content[iconKey]);
|
|
9833
|
+
}
|
|
9834
|
+
function parseSocialsOrder(raw) {
|
|
9835
|
+
if (!raw) return null;
|
|
9836
|
+
try {
|
|
9837
|
+
const parsed = JSON.parse(raw);
|
|
9838
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
9839
|
+
} catch {
|
|
9840
|
+
return null;
|
|
9841
|
+
}
|
|
9842
|
+
}
|
|
9843
|
+
function nextSocialIndex(row, rowKey, content) {
|
|
9844
|
+
const used = listSocialItems(row).map((item) => socialHrefKey(item)).concat(Object.keys(content)).map((key) => key?.match(new RegExp(`^${rowKey}-(\\d+)`))?.[1]).map((digits) => digits === void 0 ? -1 : Number(digits));
|
|
9845
|
+
return Math.max(-1, ...used) + 1;
|
|
9846
|
+
}
|
|
9847
|
+
function insertSocialItem(row, after, content = {}) {
|
|
9848
|
+
const rowKey = rowKeyOf(row);
|
|
9849
|
+
const template = listSocialItems(row)[0];
|
|
9850
|
+
const remembered = rowTemplates.get(rowKey);
|
|
9851
|
+
if (!template && !remembered) return null;
|
|
9852
|
+
const index = nextSocialIndex(row, rowKey, content);
|
|
9853
|
+
const iconKey = `${rowKey}-${index}`;
|
|
9854
|
+
const hrefKey = `${iconKey}-href`;
|
|
9855
|
+
const templateUnit = template ? socialRowUnit(template) : null;
|
|
9856
|
+
const unit = templateUnit ? templateUnit.cloneNode(true) : fromMarkup(remembered);
|
|
9857
|
+
const item = unit && (unit.matches("a") ? unit : unit.querySelector("a"));
|
|
9858
|
+
if (!unit || !item) return null;
|
|
9859
|
+
item.setAttribute("data-ohw-href-key", hrefKey);
|
|
9860
|
+
item.setAttribute("href", "");
|
|
9861
|
+
item.removeAttribute("aria-label");
|
|
9862
|
+
item.querySelectorAll("[data-ohw-hovered], [data-ohw-selected]").forEach((el) => {
|
|
9863
|
+
el.removeAttribute("data-ohw-hovered");
|
|
9864
|
+
el.removeAttribute("data-ohw-selected");
|
|
9865
|
+
});
|
|
9866
|
+
const icon = item.querySelector(ICON_SELECTOR);
|
|
9867
|
+
icon?.setAttribute("data-ohw-key", iconKey);
|
|
9868
|
+
item.querySelector(`[${SOCIALS_LABEL_ATTR}]`)?.remove();
|
|
9869
|
+
const afterUnit = after ? socialRowUnit(after) : null;
|
|
9870
|
+
if (afterUnit && afterUnit.parentElement === row) afterUnit.insertAdjacentElement("afterend", unit);
|
|
9871
|
+
else row.appendChild(unit);
|
|
9872
|
+
markSocialsRows(row.ownerDocument);
|
|
9873
|
+
return { item, hrefKey, iconKey, order: getSocialsOrderFromDom(row.ownerDocument) };
|
|
9874
|
+
}
|
|
9875
|
+
function duplicateSocialItem(item, content) {
|
|
9876
|
+
const row = findSocialsRow(item);
|
|
9877
|
+
const created = row ? insertSocialItem(row, item, content) : null;
|
|
9878
|
+
if (!created) return null;
|
|
9879
|
+
const sourceHref = socialHrefKey(item);
|
|
9880
|
+
const sourceIcon = socialIconKey(item);
|
|
9881
|
+
const link = created.item;
|
|
9882
|
+
if (sourceHref) link.setAttribute("href", item.getAttribute("href") ?? "");
|
|
9883
|
+
const glyph = item.querySelector(ICON_SELECTOR)?.innerHTML;
|
|
9884
|
+
if (glyph) {
|
|
9885
|
+
const slot = link.querySelector(ICON_SELECTOR);
|
|
9886
|
+
if (slot) slot.innerHTML = glyph;
|
|
9887
|
+
}
|
|
9888
|
+
return {
|
|
9889
|
+
...created,
|
|
9890
|
+
copiedFrom: { href: sourceHref, icon: sourceIcon }
|
|
9891
|
+
};
|
|
9892
|
+
}
|
|
9893
|
+
function removeSocialItem(item, content) {
|
|
9894
|
+
const row = findSocialsRow(item);
|
|
9895
|
+
if (!row) return null;
|
|
9896
|
+
const hrefKey = socialHrefKey(item);
|
|
9897
|
+
const iconKey = socialIconKey(item);
|
|
9898
|
+
const removedKeys = [hrefKey, iconKey].filter((key) => Boolean(key));
|
|
9899
|
+
if (!removedKeys.length) return null;
|
|
9900
|
+
const previousOrder = getSocialsOrderFromDom(row.ownerDocument);
|
|
9901
|
+
const previousContent = Object.fromEntries(
|
|
9902
|
+
removedKeys.filter((key) => key in content).map((key) => [key, content[key]])
|
|
9903
|
+
);
|
|
9904
|
+
const unit = socialRowUnit(item);
|
|
9905
|
+
const nextSibling = unit.nextElementSibling;
|
|
9906
|
+
unit.remove();
|
|
9907
|
+
markSocialsRows(row.ownerDocument);
|
|
9908
|
+
return {
|
|
9909
|
+
removedKeys,
|
|
9910
|
+
previousContent,
|
|
9911
|
+
order: getSocialsOrderFromDom(row.ownerDocument),
|
|
9912
|
+
previousOrder,
|
|
9913
|
+
undo: () => {
|
|
9914
|
+
if (nextSibling) nextSibling.before(unit);
|
|
9915
|
+
else row.appendChild(unit);
|
|
9916
|
+
markSocialsRows(row.ownerDocument);
|
|
9917
|
+
}
|
|
9918
|
+
};
|
|
9919
|
+
}
|
|
9920
|
+
function applySocialsOrder(order, root = document) {
|
|
9921
|
+
listSocialsRows(root).forEach((row) => {
|
|
9922
|
+
const wanted = order[rowKeyOf(row)];
|
|
9923
|
+
if (!wanted) return;
|
|
9924
|
+
const byKey = new Map(listSocialItems(row).map((item) => [socialHrefKey(item), item]));
|
|
9925
|
+
wanted.forEach((key) => {
|
|
9926
|
+
const item = byKey.get(key);
|
|
9927
|
+
if (item) row.appendChild(socialRowUnit(item));
|
|
9928
|
+
});
|
|
9929
|
+
});
|
|
9930
|
+
markSocialsRows(root);
|
|
9931
|
+
}
|
|
9932
|
+
function reconcileSocialsFromContent(content, root = document) {
|
|
9933
|
+
markSocialsRows(root);
|
|
9934
|
+
const stored = parseSocialsOrder(content[SOCIALS_ORDER_KEY]);
|
|
9935
|
+
if (!stored) return;
|
|
9936
|
+
listSocialsRows(root).forEach((row) => {
|
|
9937
|
+
const wanted = stored[rowKeyOf(row)];
|
|
9938
|
+
if (!wanted) return;
|
|
9939
|
+
if (!wanted.length) return;
|
|
9940
|
+
wanted.forEach((key) => {
|
|
9941
|
+
if (listSocialItems(row).some((item) => socialHrefKey(item) === key)) return;
|
|
9942
|
+
if (!hasStoredValue(content, key)) return;
|
|
9943
|
+
const created = insertSocialItem(row, null, content);
|
|
9944
|
+
if (created) {
|
|
9945
|
+
created.item.setAttribute("data-ohw-href-key", key);
|
|
9946
|
+
created.item.querySelector(ICON_SELECTOR)?.setAttribute("data-ohw-key", key.replace(/-href$/, ""));
|
|
9947
|
+
applyStoredValues(created.item, content);
|
|
9948
|
+
}
|
|
9949
|
+
});
|
|
9950
|
+
const present = listSocialItems(row);
|
|
9951
|
+
const surviving = present.filter((item) => {
|
|
9952
|
+
const key = socialHrefKey(item);
|
|
9953
|
+
return !key || wanted.includes(key);
|
|
9954
|
+
});
|
|
9955
|
+
if (surviving.length) {
|
|
9956
|
+
present.forEach((item) => {
|
|
9957
|
+
if (!surviving.includes(item)) socialRowUnit(item).remove();
|
|
9958
|
+
});
|
|
9959
|
+
}
|
|
9960
|
+
});
|
|
9961
|
+
applySocialsOrder(stored, root);
|
|
9962
|
+
}
|
|
9963
|
+
var DROP_BAR_THICKNESS = 3;
|
|
9964
|
+
var DROP_BAR_GAP = 8;
|
|
9965
|
+
function buildSocialDropSlots(row) {
|
|
9966
|
+
const items = listSocialItems(row);
|
|
9967
|
+
if (!items.length) return [];
|
|
9968
|
+
const rects = items.map((item) => item.getBoundingClientRect());
|
|
9969
|
+
return items.concat(items[items.length - 1]).map((_, index) => {
|
|
9970
|
+
const previous = rects[index - 1];
|
|
9971
|
+
const next = rects[index];
|
|
9972
|
+
const centre = previous && next ? (previous.right + next.left) / 2 : next ? next.left - DROP_BAR_GAP : previous.right + DROP_BAR_GAP;
|
|
9973
|
+
const rect = next ?? previous;
|
|
9974
|
+
return {
|
|
9975
|
+
insertIndex: index,
|
|
9976
|
+
columnIndex: -1,
|
|
9977
|
+
left: centre - DROP_BAR_THICKNESS / 2,
|
|
9978
|
+
top: rect.top,
|
|
9979
|
+
width: DROP_BAR_THICKNESS,
|
|
9980
|
+
height: rect.height,
|
|
9981
|
+
direction: "vertical"
|
|
9982
|
+
};
|
|
9983
|
+
});
|
|
9984
|
+
}
|
|
9985
|
+
function findSocialByHrefKey(hrefKey, root = document) {
|
|
9986
|
+
const el = root.querySelector(`[data-ohw-href-key="${CSS.escape(hrefKey)}"]`);
|
|
9987
|
+
return el ? getSocialItem(el) : null;
|
|
9988
|
+
}
|
|
9989
|
+
function buildSocialDropSlotsForKey(hrefKey, root = document) {
|
|
9990
|
+
const item = findSocialByHrefKey(hrefKey, root);
|
|
9991
|
+
const row = item ? findSocialsRow(item) : null;
|
|
9992
|
+
return row ? buildSocialDropSlots(row) : [];
|
|
9993
|
+
}
|
|
9994
|
+
function hitTestSocialDropSlot(clientX, clientY, draggedHrefKey, root = document) {
|
|
9995
|
+
const distanceTo = (slot) => {
|
|
9996
|
+
const dx = clientX - (slot.left + slot.width / 2);
|
|
9997
|
+
const dy = clientY < slot.top ? slot.top - clientY : Math.max(0, clientY - (slot.top + slot.height));
|
|
9998
|
+
return Math.hypot(dx, dy);
|
|
9999
|
+
};
|
|
10000
|
+
const slots = buildSocialDropSlotsForKey(draggedHrefKey, root);
|
|
10001
|
+
return slots.reduce((best, slot) => {
|
|
10002
|
+
return !best || distanceTo(slot) < distanceTo(best) ? slot : best;
|
|
10003
|
+
}, null);
|
|
10004
|
+
}
|
|
10005
|
+
function planSocialMove(hrefKey, insertIndex, root = document) {
|
|
10006
|
+
const item = findSocialByHrefKey(hrefKey, root);
|
|
10007
|
+
const row = item ? findSocialsRow(item) : null;
|
|
10008
|
+
if (!row) return null;
|
|
10009
|
+
const order = getSocialsOrderFromDom(root);
|
|
10010
|
+
const key = rowKeyOf(row);
|
|
10011
|
+
const current = order[key];
|
|
10012
|
+
if (!current) return null;
|
|
10013
|
+
const from = current.indexOf(hrefKey);
|
|
10014
|
+
if (from < 0) return null;
|
|
10015
|
+
const next = current.filter((_, index) => index !== from);
|
|
10016
|
+
next.splice(insertIndex > from ? insertIndex - 1 : insertIndex, 0, hrefKey);
|
|
10017
|
+
return { ...order, [key]: next };
|
|
10018
|
+
}
|
|
10019
|
+
var SOCIALS_DISPLAY_KEY = "__ohw_socials_display";
|
|
10020
|
+
function readSocialsDisplay(row) {
|
|
10021
|
+
const items = listSocialItems(row);
|
|
10022
|
+
const visible = (el) => Boolean(el) && el.style.display !== "none" && el.getAttribute("data-ohw-hidden") === null;
|
|
10023
|
+
return {
|
|
10024
|
+
text: items.some((item) => visible(socialLabelElement(item))),
|
|
10025
|
+
icon: items.some((item) => visible(item.querySelector(ICON_SELECTOR)))
|
|
10026
|
+
};
|
|
10027
|
+
}
|
|
10028
|
+
function parseSocialsDisplay(raw) {
|
|
10029
|
+
if (!raw) return null;
|
|
10030
|
+
try {
|
|
10031
|
+
const parsed = JSON.parse(raw);
|
|
10032
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
10033
|
+
} catch {
|
|
10034
|
+
return null;
|
|
10035
|
+
}
|
|
10036
|
+
}
|
|
10037
|
+
function socialsDisplayFor(row, content) {
|
|
10038
|
+
return parseSocialsDisplay(content[SOCIALS_DISPLAY_KEY])?.[rowKeyOf(row)] ?? readSocialsDisplay(row);
|
|
10039
|
+
}
|
|
10040
|
+
function socialsDisplayWith(row, display, content) {
|
|
10041
|
+
return { ...parseSocialsDisplay(content[SOCIALS_DISPLAY_KEY]) ?? {}, [rowKeyOf(row)]: display };
|
|
10042
|
+
}
|
|
10043
|
+
function applySocialsDisplayToRow(row, display) {
|
|
10044
|
+
listSocialItems(row).forEach((item) => {
|
|
10045
|
+
const label = socialLabelElement(item);
|
|
10046
|
+
const icon = item.querySelector(ICON_SELECTOR);
|
|
10047
|
+
if (label) label.style.display = display.text ? "" : "none";
|
|
10048
|
+
if (icon) icon.style.display = display.icon ? "" : "none";
|
|
10049
|
+
});
|
|
10050
|
+
}
|
|
10051
|
+
function applySocialsDisplayFromContent(content, root = document) {
|
|
10052
|
+
const stored = parseSocialsDisplay(content[SOCIALS_DISPLAY_KEY]);
|
|
10053
|
+
if (!stored) return;
|
|
10054
|
+
listSocialsRows(root).forEach((row) => {
|
|
10055
|
+
const display = stored[rowKeyOf(row)];
|
|
10056
|
+
if (!display) return;
|
|
10057
|
+
if (display.icon) {
|
|
10058
|
+
listSocialItems(row).forEach((item) => {
|
|
10059
|
+
const iconKey = ensureIconSlot(item);
|
|
10060
|
+
const slot = item.querySelector(ICON_SELECTOR);
|
|
10061
|
+
if (iconKey && slot && content[iconKey]) applyIconMarkup(slot, content[iconKey]);
|
|
10062
|
+
});
|
|
10063
|
+
}
|
|
10064
|
+
applySocialsDisplayToRow(row, display);
|
|
10065
|
+
});
|
|
10066
|
+
}
|
|
10067
|
+
function socialsMissingIcons(row) {
|
|
10068
|
+
return listSocialItems(row).filter((item) => !item.querySelector(ICON_SELECTOR)).map((item) => ({ hrefKey: socialHrefKey(item) ?? "", url: item.getAttribute("href") ?? "" })).filter((entry) => Boolean(entry.hrefKey));
|
|
10069
|
+
}
|
|
10070
|
+
function ensureIconSlot(item) {
|
|
10071
|
+
const existing = item.querySelector(ICON_SELECTOR);
|
|
10072
|
+
if (existing) return existing.dataset.ohwKey ?? null;
|
|
10073
|
+
const hrefKey = socialHrefKey(item);
|
|
10074
|
+
if (!hrefKey) return null;
|
|
10075
|
+
const iconKey = hrefKey.replace(/-href$/, "");
|
|
10076
|
+
const slot = document.createElement("span");
|
|
10077
|
+
slot.setAttribute("data-ohw-key", iconKey);
|
|
10078
|
+
slot.setAttribute("data-ohw-editable", "icon");
|
|
10079
|
+
slot.style.display = "inline-flex";
|
|
10080
|
+
item.prepend(slot);
|
|
10081
|
+
return iconKey;
|
|
10082
|
+
}
|
|
10083
|
+
|
|
9455
10084
|
// src/lib/footer-items.ts
|
|
9456
10085
|
var FOOTER_ORDER_KEY = "__ohw_footer_order";
|
|
9457
10086
|
var MAX_FOOTER_COLUMNS = 18;
|
|
10087
|
+
var MAX_FOOTER_ITEMS_PER_COLUMN = 7;
|
|
9458
10088
|
var FOOTER_HREF_RE = /^footer-(\d+)-(\d+)-href$/;
|
|
9459
10089
|
function parseFooterHrefKey(key) {
|
|
9460
10090
|
if (!key) return null;
|
|
@@ -9672,6 +10302,13 @@ function getNextFooterColumnIndex() {
|
|
|
9672
10302
|
function canAddFooterColumn() {
|
|
9673
10303
|
return listFooterColumns().length < MAX_FOOTER_COLUMNS;
|
|
9674
10304
|
}
|
|
10305
|
+
function canAddFooterItem(column) {
|
|
10306
|
+
return listFooterLinksInColumn(column).length < MAX_FOOTER_ITEMS_PER_COLUMN;
|
|
10307
|
+
}
|
|
10308
|
+
function resolveFooterColumnForAdd(selected) {
|
|
10309
|
+
if (selected.hasAttribute("data-ohw-footer-col")) return selected;
|
|
10310
|
+
return selected.closest("[data-ohw-footer-col]") ?? (listFooterColumns().includes(selected) ? selected : null);
|
|
10311
|
+
}
|
|
9675
10312
|
function buildFooterHeading(colIndex, text) {
|
|
9676
10313
|
const heading = document.createElement("p");
|
|
9677
10314
|
heading.setAttribute("data-ohw-editable", "text");
|
|
@@ -10296,6 +10933,329 @@ function deleteFooterColumn(column) {
|
|
|
10296
10933
|
};
|
|
10297
10934
|
}
|
|
10298
10935
|
|
|
10936
|
+
// src/lib/logo-identity.ts
|
|
10937
|
+
var LOGO_TEXT_KEYS = ["nav-logo-text", "footer-logo-text", "logo-text"];
|
|
10938
|
+
var LOGO_IMAGE_KEYS = ["nav-logo-image", "footer-logo", "footer-logo-image"];
|
|
10939
|
+
var LOGO_HREF_KEYS = ["nav-logo-href", "footer-logo-href", "logo-href"];
|
|
10940
|
+
var LOGO_PLACEHOLDER_KEY = "logo-is-placeholder";
|
|
10941
|
+
var LOGO_ALT_KEY = "logo-alt";
|
|
10942
|
+
var LOGO_IMAGE_URL_KEY = "nav-logo-image";
|
|
10943
|
+
var PLACEHOLDER_BUSINESS_NAME = "Business name";
|
|
10944
|
+
function resolveLogoDisplayText(text) {
|
|
10945
|
+
const trimmed = (text ?? "").trim();
|
|
10946
|
+
return trimmed || PLACEHOLDER_BUSINESS_NAME;
|
|
10947
|
+
}
|
|
10948
|
+
function isFooterLogoRoot(root) {
|
|
10949
|
+
return Boolean(root.closest("footer") || root.closest('[data-ohw-section="footer"]'));
|
|
10950
|
+
}
|
|
10951
|
+
function imageKeyForRoot(root) {
|
|
10952
|
+
return isFooterLogoRoot(root) ? "footer-logo" : "nav-logo-image";
|
|
10953
|
+
}
|
|
10954
|
+
function textKeyForRoot(root) {
|
|
10955
|
+
return isFooterLogoRoot(root) ? "footer-logo-text" : "nav-logo-text";
|
|
10956
|
+
}
|
|
10957
|
+
function ensureLogoHrefKey(root) {
|
|
10958
|
+
if (!(root instanceof HTMLAnchorElement)) return;
|
|
10959
|
+
if (root.hasAttribute("data-ohw-href-key")) return;
|
|
10960
|
+
root.setAttribute("data-ohw-href-key", isFooterLogoRoot(root) ? "footer-logo-href" : "nav-logo-href");
|
|
10961
|
+
}
|
|
10962
|
+
function applyLogoIdentity(text, isPlaceholder) {
|
|
10963
|
+
const display = resolveLogoDisplayText(text);
|
|
10964
|
+
const placeholder = isPlaceholder || !text.trim() || display === PLACEHOLDER_BUSINESS_NAME;
|
|
10965
|
+
for (const key of LOGO_TEXT_KEYS) {
|
|
10966
|
+
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
10967
|
+
if (el.textContent !== display) el.textContent = display;
|
|
10968
|
+
});
|
|
10969
|
+
}
|
|
10970
|
+
for (const key of LOGO_IMAGE_KEYS) {
|
|
10971
|
+
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
10972
|
+
const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
|
|
10973
|
+
if (img) img.alt = display;
|
|
10974
|
+
});
|
|
10975
|
+
}
|
|
10976
|
+
document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]').forEach((el) => {
|
|
10977
|
+
if (placeholder) el.setAttribute("data-ohw-placeholder", "");
|
|
10978
|
+
else el.removeAttribute("data-ohw-placeholder");
|
|
10979
|
+
});
|
|
10980
|
+
return display;
|
|
10981
|
+
}
|
|
10982
|
+
function applyLogoImage(url, alt) {
|
|
10983
|
+
const displayAlt = resolveLogoDisplayText(alt);
|
|
10984
|
+
document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]').forEach((root) => {
|
|
10985
|
+
ensureLogoHrefKey(root);
|
|
10986
|
+
const imageKey = imageKeyForRoot(root);
|
|
10987
|
+
const textKey = textKeyForRoot(root);
|
|
10988
|
+
let img = root.querySelector(`img[data-ohw-key="${imageKey}"]`) ?? (root.querySelector(`[data-ohw-key="${imageKey}"]`) instanceof HTMLImageElement ? root.querySelector(`[data-ohw-key="${imageKey}"]`) : null) ?? root.querySelector("img");
|
|
10989
|
+
let textEl = root.querySelector(`[data-ohw-key="${textKey}"]`) ?? root.querySelector('[data-ohw-key="logo-text"]');
|
|
10990
|
+
if (url) {
|
|
10991
|
+
if (!img) {
|
|
10992
|
+
img = document.createElement("img");
|
|
10993
|
+
img.setAttribute("data-ohw-editable", "image");
|
|
10994
|
+
img.setAttribute("data-ohw-key", imageKey);
|
|
10995
|
+
img.alt = displayAlt;
|
|
10996
|
+
img.style.height = "";
|
|
10997
|
+
img.style.maxHeight = "none";
|
|
10998
|
+
img.style.width = "auto";
|
|
10999
|
+
img.style.display = "block";
|
|
11000
|
+
img.style.objectFit = "contain";
|
|
11001
|
+
root.insertBefore(img, root.firstChild);
|
|
11002
|
+
} else {
|
|
11003
|
+
img.setAttribute("data-ohw-editable", "image");
|
|
11004
|
+
img.setAttribute("data-ohw-key", imageKey);
|
|
11005
|
+
}
|
|
11006
|
+
img.removeAttribute("srcset");
|
|
11007
|
+
img.removeAttribute("sizes");
|
|
11008
|
+
img.src = url;
|
|
11009
|
+
img.alt = displayAlt;
|
|
11010
|
+
img.style.display = "block";
|
|
11011
|
+
if (textEl) textEl.style.display = "none";
|
|
11012
|
+
root.removeAttribute("data-ohw-placeholder");
|
|
11013
|
+
return;
|
|
11014
|
+
}
|
|
11015
|
+
if (img) {
|
|
11016
|
+
img.removeAttribute("src");
|
|
11017
|
+
img.removeAttribute("srcset");
|
|
11018
|
+
img.removeAttribute("sizes");
|
|
11019
|
+
img.alt = displayAlt;
|
|
11020
|
+
img.style.display = "none";
|
|
11021
|
+
}
|
|
11022
|
+
if (!textEl) {
|
|
11023
|
+
textEl = document.createElement("span");
|
|
11024
|
+
textEl.setAttribute("data-ohw-editable", "plain");
|
|
11025
|
+
textEl.setAttribute("data-ohw-key", textKey);
|
|
11026
|
+
root.appendChild(textEl);
|
|
11027
|
+
}
|
|
11028
|
+
textEl.style.display = "";
|
|
11029
|
+
if (textEl.textContent !== displayAlt) textEl.textContent = displayAlt;
|
|
11030
|
+
if (!displayAlt.trim() || displayAlt === PLACEHOLDER_BUSINESS_NAME) {
|
|
11031
|
+
root.setAttribute("data-ohw-placeholder", "");
|
|
11032
|
+
} else {
|
|
11033
|
+
root.removeAttribute("data-ohw-placeholder");
|
|
11034
|
+
}
|
|
11035
|
+
});
|
|
11036
|
+
}
|
|
11037
|
+
function applyLogoHref(href) {
|
|
11038
|
+
const target = href.trim() || "/";
|
|
11039
|
+
document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]').forEach((root) => {
|
|
11040
|
+
ensureLogoHrefKey(root);
|
|
11041
|
+
if (root instanceof HTMLAnchorElement) {
|
|
11042
|
+
root.setAttribute("href", target);
|
|
11043
|
+
}
|
|
11044
|
+
});
|
|
11045
|
+
for (const key of LOGO_HREF_KEYS) setStoredLinkHref(key, target);
|
|
11046
|
+
}
|
|
11047
|
+
function readLogoIdentityFromDom() {
|
|
11048
|
+
let imageUrl = null;
|
|
11049
|
+
for (const key of LOGO_IMAGE_KEYS) {
|
|
11050
|
+
const el = document.querySelector(`[data-ohw-key="${key}"]`);
|
|
11051
|
+
const img = el instanceof HTMLImageElement ? el : el?.querySelector("img");
|
|
11052
|
+
const attrSrc = img?.getAttribute("src")?.trim() ?? "";
|
|
11053
|
+
if (attrSrc && !attrSrc.startsWith("data:") && img && img.style.display !== "none") {
|
|
11054
|
+
imageUrl = img.currentSrc || img.src;
|
|
11055
|
+
break;
|
|
11056
|
+
}
|
|
11057
|
+
}
|
|
11058
|
+
let text = PLACEHOLDER_BUSINESS_NAME;
|
|
11059
|
+
let isPlaceholder = true;
|
|
11060
|
+
for (const key of LOGO_TEXT_KEYS) {
|
|
11061
|
+
const el = document.querySelector(`[data-ohw-key="${key}"]`);
|
|
11062
|
+
if (el?.textContent?.trim()) {
|
|
11063
|
+
text = el.textContent.trim();
|
|
11064
|
+
const logoRoot2 = el.closest('[data-ohw-role="logo"], [data-ohw-logo]');
|
|
11065
|
+
isPlaceholder = logoRoot2?.hasAttribute("data-ohw-placeholder") === true || text === PLACEHOLDER_BUSINESS_NAME;
|
|
11066
|
+
break;
|
|
11067
|
+
}
|
|
11068
|
+
}
|
|
11069
|
+
if (imageUrl) {
|
|
11070
|
+
const logoImg = document.querySelector(
|
|
11071
|
+
'[data-ohw-key="nav-logo-image"], [data-ohw-key="footer-logo"]'
|
|
11072
|
+
);
|
|
11073
|
+
const alt = logoImg?.alt?.trim() || text;
|
|
11074
|
+
isPlaceholder = false;
|
|
11075
|
+
const hrefEl = document.querySelector(
|
|
11076
|
+
'a[data-ohw-role="logo"], a[data-ohw-logo], [data-ohw-role="logo"]'
|
|
11077
|
+
);
|
|
11078
|
+
const href2 = (hrefEl instanceof HTMLAnchorElement ? hrefEl.getAttribute("href") : null) || hrefEl?.closest("a")?.getAttribute("href") || "/";
|
|
11079
|
+
return { text, isPlaceholder, imageUrl, href: href2, alt };
|
|
11080
|
+
}
|
|
11081
|
+
const logoRoot = document.querySelector('[data-ohw-role="logo"], [data-ohw-logo]');
|
|
11082
|
+
const href = (logoRoot instanceof HTMLAnchorElement ? logoRoot.getAttribute("href") : null) || logoRoot?.closest("a")?.getAttribute("href") || "/";
|
|
11083
|
+
return { text, isPlaceholder, imageUrl: null, href, alt: text };
|
|
11084
|
+
}
|
|
11085
|
+
function applyLogoFromContent(content) {
|
|
11086
|
+
const hasLogoIdentity = LOGO_PLACEHOLDER_KEY in content || LOGO_TEXT_KEYS.some((key) => key in content) || LOGO_IMAGE_KEYS.some((key) => key in content) || LOGO_ALT_KEY in content || LOGO_HREF_KEYS.some((key) => key in content);
|
|
11087
|
+
if (!hasLogoIdentity) return false;
|
|
11088
|
+
const logoText = content[LOGO_TEXT_KEYS[0]] ?? content[LOGO_TEXT_KEYS[1]] ?? readLogoIdentityFromDom().text;
|
|
11089
|
+
const logoAlt = content[LOGO_ALT_KEY] ?? logoText;
|
|
11090
|
+
const rawLogoImage = content[LOGO_IMAGE_URL_KEY] ?? content["footer-logo"] ?? content["footer-logo-image"] ?? null;
|
|
11091
|
+
const logoImageUrl = typeof rawLogoImage === "string" && rawLogoImage.trim() ? rawLogoImage.trim() : null;
|
|
11092
|
+
const imageExplicitlyCleared = LOGO_IMAGE_KEYS.some((key) => key in content) && !logoImageUrl;
|
|
11093
|
+
const logoIsPlaceholder = LOGO_PLACEHOLDER_KEY in content ? content[LOGO_PLACEHOLDER_KEY] !== "false" : !logoImageUrl && (!logoText.trim() || logoText === PLACEHOLDER_BUSINESS_NAME);
|
|
11094
|
+
if (logoImageUrl) {
|
|
11095
|
+
applyLogoImage(logoImageUrl, logoAlt);
|
|
11096
|
+
} else {
|
|
11097
|
+
if (imageExplicitlyCleared) applyLogoImage(null, logoAlt);
|
|
11098
|
+
applyLogoIdentity(logoText, logoIsPlaceholder);
|
|
11099
|
+
}
|
|
11100
|
+
const logoHref = content["nav-logo-href"] ?? content["footer-logo-href"] ?? content["logo-href"];
|
|
11101
|
+
if (typeof logoHref === "string" && logoHref.trim()) {
|
|
11102
|
+
applyLogoHref(logoHref);
|
|
11103
|
+
}
|
|
11104
|
+
return true;
|
|
11105
|
+
}
|
|
11106
|
+
|
|
11107
|
+
// src/lib/logo-size.ts
|
|
11108
|
+
var LOGO_SIZE_DEFAULTS = {
|
|
11109
|
+
navbar: 28,
|
|
11110
|
+
footer: 32
|
|
11111
|
+
};
|
|
11112
|
+
var LOGO_SIZE_MIN = 16;
|
|
11113
|
+
var LOGO_SIZE_MAX = 80;
|
|
11114
|
+
var LOGO_SIZE_DESKTOP_KEYS = {
|
|
11115
|
+
navbar: "nav-logo-size",
|
|
11116
|
+
footer: "footer-logo-size"
|
|
11117
|
+
};
|
|
11118
|
+
var LOGO_SIZE_MOBILE_KEYS = {
|
|
11119
|
+
navbar: "nav-logo-size-mobile",
|
|
11120
|
+
footer: "footer-logo-size-mobile"
|
|
11121
|
+
};
|
|
11122
|
+
var LOGO_SIZE_KEYS = [
|
|
11123
|
+
LOGO_SIZE_DESKTOP_KEYS.navbar,
|
|
11124
|
+
LOGO_SIZE_DESKTOP_KEYS.footer,
|
|
11125
|
+
LOGO_SIZE_MOBILE_KEYS.navbar,
|
|
11126
|
+
LOGO_SIZE_MOBILE_KEYS.footer
|
|
11127
|
+
];
|
|
11128
|
+
function isFooterLogoRoot2(root) {
|
|
11129
|
+
return Boolean(root.closest("footer") || root.closest('[data-ohw-section="footer"]'));
|
|
11130
|
+
}
|
|
11131
|
+
function getLogoPlacement(root) {
|
|
11132
|
+
return isFooterLogoRoot2(root) ? "footer" : "navbar";
|
|
11133
|
+
}
|
|
11134
|
+
function parseLogoSizePx(raw, fallback) {
|
|
11135
|
+
if (raw == null || raw === "") return fallback;
|
|
11136
|
+
const n = Number.parseFloat(raw);
|
|
11137
|
+
if (!Number.isFinite(n)) return fallback;
|
|
11138
|
+
return Math.min(LOGO_SIZE_MAX, Math.max(LOGO_SIZE_MIN, Math.round(n)));
|
|
11139
|
+
}
|
|
11140
|
+
function isMobileLogoSizeFollowing(content, placement) {
|
|
11141
|
+
const raw = content[LOGO_SIZE_MOBILE_KEYS[placement]];
|
|
11142
|
+
return raw == null || raw.trim() === "";
|
|
11143
|
+
}
|
|
11144
|
+
function resolveDesktopLogoSize(content, placement) {
|
|
11145
|
+
return parseLogoSizePx(content[LOGO_SIZE_DESKTOP_KEYS[placement]], LOGO_SIZE_DEFAULTS[placement]);
|
|
11146
|
+
}
|
|
11147
|
+
function resolveMobileLogoSize(content, placement) {
|
|
11148
|
+
if (isMobileLogoSizeFollowing(content, placement)) {
|
|
11149
|
+
return resolveDesktopLogoSize(content, placement);
|
|
11150
|
+
}
|
|
11151
|
+
return parseLogoSizePx(
|
|
11152
|
+
content[LOGO_SIZE_MOBILE_KEYS[placement]],
|
|
11153
|
+
resolveDesktopLogoSize(content, placement)
|
|
11154
|
+
);
|
|
11155
|
+
}
|
|
11156
|
+
function setRootSizeVars(root, desktopPx, mobilePx, following) {
|
|
11157
|
+
root.style.setProperty("--ohw-logo-size", `${desktopPx}px`);
|
|
11158
|
+
if (following) {
|
|
11159
|
+
root.style.removeProperty("--ohw-logo-size-mobile");
|
|
11160
|
+
} else {
|
|
11161
|
+
root.style.setProperty("--ohw-logo-size-mobile", `${mobilePx}px`);
|
|
11162
|
+
}
|
|
11163
|
+
root.querySelectorAll("img").forEach((img) => {
|
|
11164
|
+
img.style.height = "";
|
|
11165
|
+
img.style.maxHeight = "none";
|
|
11166
|
+
img.style.width = "auto";
|
|
11167
|
+
img.style.objectFit = "contain";
|
|
11168
|
+
});
|
|
11169
|
+
}
|
|
11170
|
+
function applyLogoSizes(content) {
|
|
11171
|
+
document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]').forEach((root) => {
|
|
11172
|
+
const placement = getLogoPlacement(root);
|
|
11173
|
+
const desktop = resolveDesktopLogoSize(content, placement);
|
|
11174
|
+
const following = isMobileLogoSizeFollowing(content, placement);
|
|
11175
|
+
const mobile = following ? desktop : resolveMobileLogoSize(content, placement);
|
|
11176
|
+
setRootSizeVars(root, desktop, mobile, following);
|
|
11177
|
+
});
|
|
11178
|
+
}
|
|
11179
|
+
function applyLogoSizeToPlacement(placement, desktopPx, mobilePx, following) {
|
|
11180
|
+
document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]').forEach((root) => {
|
|
11181
|
+
if (getLogoPlacement(root) !== placement) return;
|
|
11182
|
+
setRootSizeVars(root, desktopPx, mobilePx, following);
|
|
11183
|
+
});
|
|
11184
|
+
}
|
|
11185
|
+
function logoHasUploadedImage(logoEl) {
|
|
11186
|
+
if (logoEl.hasAttribute("data-ohw-placeholder")) return false;
|
|
11187
|
+
const img = logoEl.querySelector('img[data-ohw-key="nav-logo-image"], img[data-ohw-key="footer-logo"], img[data-ohw-key="footer-logo-image"]') ?? logoEl.querySelector("img");
|
|
11188
|
+
if (!img) return false;
|
|
11189
|
+
const src = img.getAttribute("src")?.trim() ?? "";
|
|
11190
|
+
if (!src || src.startsWith("data:")) return false;
|
|
11191
|
+
if (img.style.display === "none") return false;
|
|
11192
|
+
return true;
|
|
11193
|
+
}
|
|
11194
|
+
function getLogoInteractionRect(logoEl) {
|
|
11195
|
+
if (logoHasUploadedImage(logoEl)) {
|
|
11196
|
+
const img = logoEl.querySelector('img[data-ohw-key="nav-logo-image"], img[data-ohw-key="footer-logo"], img[data-ohw-key="footer-logo-image"]') ?? logoEl.querySelector("img");
|
|
11197
|
+
if (img) {
|
|
11198
|
+
const r2 = img.getBoundingClientRect();
|
|
11199
|
+
if (r2.width > 0 && r2.height > 0) return r2;
|
|
11200
|
+
}
|
|
11201
|
+
}
|
|
11202
|
+
const text = logoEl.querySelector(
|
|
11203
|
+
'[data-ohw-key="nav-logo-text"], [data-ohw-key="footer-logo-text"]'
|
|
11204
|
+
);
|
|
11205
|
+
if (text) {
|
|
11206
|
+
const style = window.getComputedStyle(text);
|
|
11207
|
+
if (style.display !== "none" && style.visibility !== "hidden") {
|
|
11208
|
+
const r2 = text.getBoundingClientRect();
|
|
11209
|
+
if (r2.width > 0 && r2.height > 0) return r2;
|
|
11210
|
+
}
|
|
11211
|
+
}
|
|
11212
|
+
return logoEl.getBoundingClientRect();
|
|
11213
|
+
}
|
|
11214
|
+
function readLogoSizeState(content, placement) {
|
|
11215
|
+
const desktopPx = resolveDesktopLogoSize(content, placement);
|
|
11216
|
+
const mobileFollowing = isMobileLogoSizeFollowing(content, placement);
|
|
11217
|
+
const mobilePx = mobileFollowing ? desktopPx : resolveMobileLogoSize(content, placement);
|
|
11218
|
+
return { desktopPx, mobilePx, mobileFollowing };
|
|
11219
|
+
}
|
|
11220
|
+
|
|
11221
|
+
// src/lib/site-wide-scope.ts
|
|
11222
|
+
function getLogoElement(el) {
|
|
11223
|
+
const marked = el.closest('[data-ohw-role="logo"], [data-ohw-logo]');
|
|
11224
|
+
if (marked) return marked;
|
|
11225
|
+
if (el.closest('[data-ohw-editable="icon"]')) return null;
|
|
11226
|
+
const root = el.closest("nav, [data-ohw-nav-root], footer");
|
|
11227
|
+
if (!root) return null;
|
|
11228
|
+
const anchor = el.closest("a");
|
|
11229
|
+
if (anchor && root.contains(anchor) && !anchor.hasAttribute("data-ohw-href-key") && !anchor.closest("[data-ohw-nav-container]") && Boolean(anchor.querySelector("img") || anchor.matches("img"))) {
|
|
11230
|
+
return anchor;
|
|
11231
|
+
}
|
|
11232
|
+
const img = el.matches("img") ? el : null;
|
|
11233
|
+
if (img && !img.closest("[data-ohw-href-key]") && !img.closest("[data-ohw-nav-container]") && (img.closest("footer") || img.closest("nav, [data-ohw-nav-root]"))) {
|
|
11234
|
+
return img;
|
|
11235
|
+
}
|
|
11236
|
+
return null;
|
|
11237
|
+
}
|
|
11238
|
+
function isInFooter(el) {
|
|
11239
|
+
if (!el) return false;
|
|
11240
|
+
return Boolean(el.closest("footer") || el.closest('[data-ohw-section="footer"]'));
|
|
11241
|
+
}
|
|
11242
|
+
function isSiteWideElement(el) {
|
|
11243
|
+
if (!el) return false;
|
|
11244
|
+
if (getLogoElement(el)) return true;
|
|
11245
|
+
if (isInFooter(el)) return true;
|
|
11246
|
+
if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-nav-root")) {
|
|
11247
|
+
return true;
|
|
11248
|
+
}
|
|
11249
|
+
if (el.hasAttribute("data-ohw-href-key") && el.closest("nav, [data-ohw-nav-root], [data-ohw-nav-drawer], aside")) {
|
|
11250
|
+
return true;
|
|
11251
|
+
}
|
|
11252
|
+
if (el.closest('[data-ohw-role="navbar-button"]')) return true;
|
|
11253
|
+
return false;
|
|
11254
|
+
}
|
|
11255
|
+
function isSiteWideScopeActive(args) {
|
|
11256
|
+
return isSiteWideElement(args.selected) || isSiteWideElement(args.hoveredItem) || isSiteWideElement(args.hoveredNavContainer) || isSiteWideElement(args.active);
|
|
11257
|
+
}
|
|
11258
|
+
|
|
10299
11259
|
// src/lib/add-footer-column.ts
|
|
10300
11260
|
function buildFooterColumnEditContentPatch(result) {
|
|
10301
11261
|
return {
|
|
@@ -10328,37 +11288,406 @@ function addFooterColumnWithPersist({
|
|
|
10328
11288
|
return result;
|
|
10329
11289
|
}
|
|
10330
11290
|
|
|
10331
|
-
// src/
|
|
10332
|
-
|
|
10333
|
-
|
|
10334
|
-
|
|
10335
|
-
|
|
11291
|
+
// src/ui/FloatingPanel.tsx
|
|
11292
|
+
import {
|
|
11293
|
+
useCallback as useCallback5,
|
|
11294
|
+
useEffect as useEffect9,
|
|
11295
|
+
useLayoutEffect as useLayoutEffect3,
|
|
11296
|
+
useRef as useRef7,
|
|
11297
|
+
useState as useState8
|
|
11298
|
+
} from "react";
|
|
11299
|
+
import { X as X5 } from "lucide-react";
|
|
11300
|
+
import { jsx as jsx26, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
11301
|
+
var PANEL_WIDTH = 256;
|
|
11302
|
+
var EDGE_MARGIN = 16;
|
|
11303
|
+
function getVisibleClip(parentScroll) {
|
|
11304
|
+
const left = 0;
|
|
11305
|
+
const right = window.innerWidth;
|
|
11306
|
+
if (!parentScroll) {
|
|
11307
|
+
return { top: 0, bottom: window.innerHeight, left, right };
|
|
10336
11308
|
}
|
|
11309
|
+
const { iframeOffsetTop, headerH: visibleCanvasTop, canvasH } = parentScroll;
|
|
11310
|
+
const top = Math.max(0, visibleCanvasTop - iframeOffsetTop);
|
|
11311
|
+
const bottom = Math.min(window.innerHeight, visibleCanvasTop + canvasH - iframeOffsetTop);
|
|
11312
|
+
return { top, bottom: Math.max(top, bottom), left, right };
|
|
10337
11313
|
}
|
|
10338
|
-
function
|
|
10339
|
-
const
|
|
10340
|
-
|
|
10341
|
-
|
|
10342
|
-
|
|
10343
|
-
|
|
10344
|
-
|
|
10345
|
-
|
|
10346
|
-
|
|
10347
|
-
document.documentElement.setAttribute("data-ohw-item-dragging", "");
|
|
10348
|
-
clearTextSelection();
|
|
11314
|
+
function defaultFloatingPanelPosition(parentScroll, panelHeight = 280) {
|
|
11315
|
+
const clip = getVisibleClip(parentScroll);
|
|
11316
|
+
return {
|
|
11317
|
+
x: Math.max(EDGE_MARGIN, clip.right - PANEL_WIDTH - EDGE_MARGIN),
|
|
11318
|
+
y: Math.min(
|
|
11319
|
+
Math.max(clip.top + EDGE_MARGIN, EDGE_MARGIN),
|
|
11320
|
+
Math.max(clip.top + EDGE_MARGIN, clip.bottom - panelHeight - EDGE_MARGIN)
|
|
11321
|
+
)
|
|
11322
|
+
};
|
|
10349
11323
|
}
|
|
10350
|
-
function
|
|
10351
|
-
const
|
|
10352
|
-
|
|
10353
|
-
|
|
10354
|
-
|
|
11324
|
+
function clampPosition(pos, parentScroll, panelW, panelH) {
|
|
11325
|
+
const clip = getVisibleClip(parentScroll);
|
|
11326
|
+
const maxX = Math.max(clip.left + EDGE_MARGIN, clip.right - panelW - EDGE_MARGIN);
|
|
11327
|
+
const maxY = Math.max(clip.top + EDGE_MARGIN, clip.bottom - panelH - EDGE_MARGIN);
|
|
11328
|
+
return {
|
|
11329
|
+
x: Math.min(Math.max(pos.x, clip.left + EDGE_MARGIN), maxX),
|
|
11330
|
+
y: Math.min(Math.max(pos.y, clip.top + EDGE_MARGIN), maxY)
|
|
11331
|
+
};
|
|
10355
11332
|
}
|
|
10356
|
-
|
|
10357
|
-
|
|
10358
|
-
|
|
10359
|
-
|
|
10360
|
-
|
|
10361
|
-
|
|
11333
|
+
function FloatingPanel({
|
|
11334
|
+
open,
|
|
11335
|
+
title,
|
|
11336
|
+
context,
|
|
11337
|
+
icon,
|
|
11338
|
+
onClose,
|
|
11339
|
+
children,
|
|
11340
|
+
position,
|
|
11341
|
+
onPositionChange,
|
|
11342
|
+
parentScroll = null,
|
|
11343
|
+
className,
|
|
11344
|
+
bodyClassName
|
|
11345
|
+
}) {
|
|
11346
|
+
const panelRef = useRef7(null);
|
|
11347
|
+
const [measured, setMeasured] = useState8({ w: PANEL_WIDTH, h: 280 });
|
|
11348
|
+
const dragRef = useRef7(null);
|
|
11349
|
+
const resolved = position ?? defaultFloatingPanelPosition(parentScroll, measured.h);
|
|
11350
|
+
const clamped = clampPosition(resolved, parentScroll, measured.w, measured.h);
|
|
11351
|
+
useLayoutEffect3(() => {
|
|
11352
|
+
if (!open || !panelRef.current) return;
|
|
11353
|
+
const el = panelRef.current;
|
|
11354
|
+
const next = { w: el.offsetWidth || PANEL_WIDTH, h: el.offsetHeight || 280 };
|
|
11355
|
+
setMeasured((prev) => prev.w === next.w && prev.h === next.h ? prev : next);
|
|
11356
|
+
}, [open, children, title, context]);
|
|
11357
|
+
useEffect9(() => {
|
|
11358
|
+
if (!open || !position || !onPositionChange) return;
|
|
11359
|
+
const next = clampPosition(position, parentScroll, measured.w, measured.h);
|
|
11360
|
+
if (next.x !== position.x || next.y !== position.y) onPositionChange(next);
|
|
11361
|
+
}, [open, parentScroll, measured.w, measured.h, position, onPositionChange]);
|
|
11362
|
+
const onHeaderPointerDown = useCallback5(
|
|
11363
|
+
(e) => {
|
|
11364
|
+
if (e.button !== 0) return;
|
|
11365
|
+
if (e.target.closest("[data-ohw-floating-panel-close]")) return;
|
|
11366
|
+
e.preventDefault();
|
|
11367
|
+
e.stopPropagation();
|
|
11368
|
+
const el = e.currentTarget;
|
|
11369
|
+
el.setPointerCapture(e.pointerId);
|
|
11370
|
+
document.documentElement.setAttribute("data-ohw-panel-dragging", "");
|
|
11371
|
+
dragRef.current = {
|
|
11372
|
+
pointerId: e.pointerId,
|
|
11373
|
+
startX: e.clientX,
|
|
11374
|
+
startY: e.clientY,
|
|
11375
|
+
originX: clamped.x,
|
|
11376
|
+
originY: clamped.y
|
|
11377
|
+
};
|
|
11378
|
+
},
|
|
11379
|
+
[clamped.x, clamped.y]
|
|
11380
|
+
);
|
|
11381
|
+
const onHeaderPointerMove = useCallback5(
|
|
11382
|
+
(e) => {
|
|
11383
|
+
const drag = dragRef.current;
|
|
11384
|
+
if (!drag || drag.pointerId !== e.pointerId) return;
|
|
11385
|
+
e.preventDefault();
|
|
11386
|
+
const next = clampPosition(
|
|
11387
|
+
{
|
|
11388
|
+
x: drag.originX + (e.clientX - drag.startX),
|
|
11389
|
+
y: drag.originY + (e.clientY - drag.startY)
|
|
11390
|
+
},
|
|
11391
|
+
parentScroll,
|
|
11392
|
+
measured.w,
|
|
11393
|
+
measured.h
|
|
11394
|
+
);
|
|
11395
|
+
onPositionChange?.(next);
|
|
11396
|
+
},
|
|
11397
|
+
[measured.h, measured.w, onPositionChange, parentScroll]
|
|
11398
|
+
);
|
|
11399
|
+
const endDrag = useCallback5((e) => {
|
|
11400
|
+
const drag = dragRef.current;
|
|
11401
|
+
if (!drag || drag.pointerId !== e.pointerId) return;
|
|
11402
|
+
dragRef.current = null;
|
|
11403
|
+
document.documentElement.removeAttribute("data-ohw-panel-dragging");
|
|
11404
|
+
try {
|
|
11405
|
+
e.currentTarget.releasePointerCapture(e.pointerId);
|
|
11406
|
+
} catch {
|
|
11407
|
+
}
|
|
11408
|
+
}, []);
|
|
11409
|
+
useEffect9(() => {
|
|
11410
|
+
if (open) return;
|
|
11411
|
+
document.documentElement.removeAttribute("data-ohw-panel-dragging");
|
|
11412
|
+
}, [open]);
|
|
11413
|
+
useEffect9(() => () => document.documentElement.removeAttribute("data-ohw-panel-dragging"), []);
|
|
11414
|
+
if (!open) return null;
|
|
11415
|
+
return /* @__PURE__ */ jsxs16(
|
|
11416
|
+
"div",
|
|
11417
|
+
{
|
|
11418
|
+
ref: panelRef,
|
|
11419
|
+
"data-ohw-floating-panel": "",
|
|
11420
|
+
role: "dialog",
|
|
11421
|
+
"aria-label": title,
|
|
11422
|
+
className: cn(
|
|
11423
|
+
// Above MediaOverlay / item chrome (2147483646); link-modal content shares this tier.
|
|
11424
|
+
"fixed z-[2147483647] flex w-64 flex-col overflow-hidden rounded-xl border border-border bg-background font-sans shadow-lg outline-none",
|
|
11425
|
+
className
|
|
11426
|
+
),
|
|
11427
|
+
style: { left: clamped.x, top: clamped.y },
|
|
11428
|
+
onMouseDown: (e) => e.stopPropagation(),
|
|
11429
|
+
onPointerDown: (e) => e.stopPropagation(),
|
|
11430
|
+
onClick: (e) => e.stopPropagation(),
|
|
11431
|
+
children: [
|
|
11432
|
+
/* @__PURE__ */ jsxs16(
|
|
11433
|
+
"div",
|
|
11434
|
+
{
|
|
11435
|
+
"data-ohw-floating-panel-header": "",
|
|
11436
|
+
className: "relative flex cursor-grab items-start gap-2 border-b border-border py-5 pl-5 pr-11 active:cursor-grabbing",
|
|
11437
|
+
onPointerDown: onHeaderPointerDown,
|
|
11438
|
+
onPointerMove: onHeaderPointerMove,
|
|
11439
|
+
onPointerUp: endDrag,
|
|
11440
|
+
onPointerCancel: endDrag,
|
|
11441
|
+
children: [
|
|
11442
|
+
/* @__PURE__ */ jsxs16("div", { className: "flex min-w-0 flex-1 flex-col gap-1.5", children: [
|
|
11443
|
+
/* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-2", children: [
|
|
11444
|
+
icon ? /* @__PURE__ */ jsx26("span", { className: "shrink-0 text-foreground", children: icon }) : null,
|
|
11445
|
+
/* @__PURE__ */ jsx26("p", { className: "min-w-0 flex-1 text-lg font-semibold leading-7 text-foreground", children: title })
|
|
11446
|
+
] }),
|
|
11447
|
+
context ? /* @__PURE__ */ jsx26("p", { className: "w-full text-sm leading-5 text-muted-foreground", children: context }) : null
|
|
11448
|
+
] }),
|
|
11449
|
+
/* @__PURE__ */ jsx26(
|
|
11450
|
+
"button",
|
|
11451
|
+
{
|
|
11452
|
+
type: "button",
|
|
11453
|
+
"data-ohw-floating-panel-close": "",
|
|
11454
|
+
"aria-label": "Close",
|
|
11455
|
+
className: "absolute right-2.5 top-2.5 rounded-sm p-1.5 text-foreground hover:bg-muted/50",
|
|
11456
|
+
onClick: (e) => {
|
|
11457
|
+
e.stopPropagation();
|
|
11458
|
+
onClose();
|
|
11459
|
+
},
|
|
11460
|
+
onPointerDown: (e) => e.stopPropagation(),
|
|
11461
|
+
children: /* @__PURE__ */ jsx26(X5, { size: 16, "aria-hidden": true })
|
|
11462
|
+
}
|
|
11463
|
+
)
|
|
11464
|
+
]
|
|
11465
|
+
}
|
|
11466
|
+
),
|
|
11467
|
+
/* @__PURE__ */ jsx26(
|
|
11468
|
+
"div",
|
|
11469
|
+
{
|
|
11470
|
+
"data-ohw-floating-panel-body": "",
|
|
11471
|
+
className: cn("flex w-full flex-col gap-4 p-5", bodyClassName),
|
|
11472
|
+
children
|
|
11473
|
+
}
|
|
11474
|
+
)
|
|
11475
|
+
]
|
|
11476
|
+
}
|
|
11477
|
+
);
|
|
11478
|
+
}
|
|
11479
|
+
|
|
11480
|
+
// src/ui/logo-size-panel.tsx
|
|
11481
|
+
import { ArrowUpRight, Link as Link2 } from "lucide-react";
|
|
11482
|
+
import { jsx as jsx27, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
11483
|
+
function SizeSlider({
|
|
11484
|
+
value,
|
|
11485
|
+
onChange
|
|
11486
|
+
}) {
|
|
11487
|
+
const pct = (value - LOGO_SIZE_MIN) / (LOGO_SIZE_MAX - LOGO_SIZE_MIN) * 100;
|
|
11488
|
+
return /* @__PURE__ */ jsxs17("div", { className: "flex w-full flex-col gap-3", children: [
|
|
11489
|
+
/* @__PURE__ */ jsxs17("div", { className: "flex w-full items-center gap-2 text-sm font-medium leading-5", children: [
|
|
11490
|
+
/* @__PURE__ */ jsx27("span", { className: "min-w-0 flex-1 text-foreground", children: "Size" }),
|
|
11491
|
+
/* @__PURE__ */ jsxs17("span", { className: "shrink-0 whitespace-nowrap text-muted-foreground", children: [
|
|
11492
|
+
value,
|
|
11493
|
+
" px"
|
|
11494
|
+
] })
|
|
11495
|
+
] }),
|
|
11496
|
+
/* @__PURE__ */ jsxs17("div", { className: "relative h-2 w-full rounded-full bg-primary-50", children: [
|
|
11497
|
+
/* @__PURE__ */ jsx27(
|
|
11498
|
+
"div",
|
|
11499
|
+
{
|
|
11500
|
+
className: "absolute inset-y-0 left-0 rounded-full bg-primary",
|
|
11501
|
+
style: { width: `${pct}%` }
|
|
11502
|
+
}
|
|
11503
|
+
),
|
|
11504
|
+
/* @__PURE__ */ jsx27(
|
|
11505
|
+
"input",
|
|
11506
|
+
{
|
|
11507
|
+
type: "range",
|
|
11508
|
+
min: LOGO_SIZE_MIN,
|
|
11509
|
+
max: LOGO_SIZE_MAX,
|
|
11510
|
+
step: 1,
|
|
11511
|
+
value,
|
|
11512
|
+
"aria-label": "Logo size",
|
|
11513
|
+
className: cn(
|
|
11514
|
+
"absolute inset-0 h-full w-full cursor-pointer appearance-none bg-transparent",
|
|
11515
|
+
"[&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:size-5",
|
|
11516
|
+
"[&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:border-2",
|
|
11517
|
+
"[&::-webkit-slider-thumb]:border-primary [&::-webkit-slider-thumb]:bg-background",
|
|
11518
|
+
"[&::-moz-range-thumb]:size-5 [&::-moz-range-thumb]:rounded-full",
|
|
11519
|
+
"[&::-moz-range-thumb]:border-2 [&::-moz-range-thumb]:border-primary",
|
|
11520
|
+
"[&::-moz-range-thumb]:bg-background"
|
|
11521
|
+
),
|
|
11522
|
+
onChange: (e) => onChange(Number(e.target.value))
|
|
11523
|
+
}
|
|
11524
|
+
)
|
|
11525
|
+
] })
|
|
11526
|
+
] });
|
|
11527
|
+
}
|
|
11528
|
+
function LogoSizePanel({
|
|
11529
|
+
viewport,
|
|
11530
|
+
sizePx,
|
|
11531
|
+
mobileFollowing = true,
|
|
11532
|
+
onSizeChange,
|
|
11533
|
+
onCustomizeMobile,
|
|
11534
|
+
onResetMobile,
|
|
11535
|
+
onUpdateEverywhere,
|
|
11536
|
+
className
|
|
11537
|
+
}) {
|
|
11538
|
+
const showFollowing = viewport === "mobile" && mobileFollowing;
|
|
11539
|
+
const showMobileSlider = viewport === "mobile" && !mobileFollowing;
|
|
11540
|
+
const showDesktopSlider = viewport === "desktop";
|
|
11541
|
+
return /* @__PURE__ */ jsxs17("div", { className: cn("flex w-full flex-col gap-4", className), children: [
|
|
11542
|
+
showFollowing ? /* @__PURE__ */ jsxs17("div", { className: "flex w-full flex-col gap-2", children: [
|
|
11543
|
+
/* @__PURE__ */ jsxs17("div", { className: "flex items-start gap-1", children: [
|
|
11544
|
+
/* @__PURE__ */ jsx27(Link2, { size: 16, className: "mt-0.5 shrink-0 text-foreground", "aria-hidden": true }),
|
|
11545
|
+
/* @__PURE__ */ jsx27("p", { className: "text-sm font-semibold leading-5 text-foreground", children: "Following desktop size" })
|
|
11546
|
+
] }),
|
|
11547
|
+
/* @__PURE__ */ jsx27("p", { className: "text-sm leading-5 text-muted-foreground", children: "Mobile uses the desktop size until you customize it. Change the desktop size and it follows automatically." }),
|
|
11548
|
+
/* @__PURE__ */ jsx27(
|
|
11549
|
+
Button,
|
|
11550
|
+
{
|
|
11551
|
+
type: "button",
|
|
11552
|
+
variant: "outline",
|
|
11553
|
+
size: "sm",
|
|
11554
|
+
className: "h-9 w-full min-w-0 cursor-pointer",
|
|
11555
|
+
onClick: onCustomizeMobile,
|
|
11556
|
+
children: "Customize for mobile"
|
|
11557
|
+
}
|
|
11558
|
+
)
|
|
11559
|
+
] }) : null,
|
|
11560
|
+
showDesktopSlider || showMobileSlider ? /* @__PURE__ */ jsx27(SizeSlider, { value: sizePx, onChange: onSizeChange }) : null,
|
|
11561
|
+
showMobileSlider ? /* @__PURE__ */ jsx27(
|
|
11562
|
+
Button,
|
|
11563
|
+
{
|
|
11564
|
+
type: "button",
|
|
11565
|
+
variant: "outline",
|
|
11566
|
+
size: "sm",
|
|
11567
|
+
className: "h-9 w-full min-w-0 cursor-pointer",
|
|
11568
|
+
onClick: onResetMobile,
|
|
11569
|
+
children: "Reset to desktop size"
|
|
11570
|
+
}
|
|
11571
|
+
) : null,
|
|
11572
|
+
/* @__PURE__ */ jsx27("div", { className: "h-px w-full bg-border", role: "separator" }),
|
|
11573
|
+
/* @__PURE__ */ jsxs17(
|
|
11574
|
+
Button,
|
|
11575
|
+
{
|
|
11576
|
+
type: "button",
|
|
11577
|
+
variant: "outline",
|
|
11578
|
+
size: "sm",
|
|
11579
|
+
className: "h-9 w-full min-w-0 cursor-pointer gap-1",
|
|
11580
|
+
onClick: onUpdateEverywhere,
|
|
11581
|
+
children: [
|
|
11582
|
+
"Update logo everywhere",
|
|
11583
|
+
/* @__PURE__ */ jsx27(ArrowUpRight, { size: 16, "aria-hidden": true })
|
|
11584
|
+
]
|
|
11585
|
+
}
|
|
11586
|
+
),
|
|
11587
|
+
/* @__PURE__ */ jsx27("p", { className: "text-sm leading-5 text-muted-foreground", children: "Matches the right version to your background." })
|
|
11588
|
+
] });
|
|
11589
|
+
}
|
|
11590
|
+
|
|
11591
|
+
// src/ui/socials-display-panel.tsx
|
|
11592
|
+
import { jsx as jsx28, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
11593
|
+
function DisplaySwitch({
|
|
11594
|
+
label,
|
|
11595
|
+
checked,
|
|
11596
|
+
disabled,
|
|
11597
|
+
onChange
|
|
11598
|
+
}) {
|
|
11599
|
+
return /* @__PURE__ */ jsxs18("div", { className: "flex w-full items-center gap-2", children: [
|
|
11600
|
+
/* @__PURE__ */ jsx28(
|
|
11601
|
+
"span",
|
|
11602
|
+
{
|
|
11603
|
+
className: cn(
|
|
11604
|
+
"min-w-0 flex-1 text-sm font-medium leading-5",
|
|
11605
|
+
disabled ? "text-muted-foreground" : "text-foreground"
|
|
11606
|
+
),
|
|
11607
|
+
children: label
|
|
11608
|
+
}
|
|
11609
|
+
),
|
|
11610
|
+
/* @__PURE__ */ jsx28(
|
|
11611
|
+
"button",
|
|
11612
|
+
{
|
|
11613
|
+
type: "button",
|
|
11614
|
+
role: "switch",
|
|
11615
|
+
"aria-checked": checked,
|
|
11616
|
+
"aria-label": label,
|
|
11617
|
+
disabled,
|
|
11618
|
+
onClick: () => onChange(!checked),
|
|
11619
|
+
className: cn(
|
|
11620
|
+
"relative h-5 w-9 shrink-0 rounded-full transition-colors",
|
|
11621
|
+
checked ? "bg-primary" : "bg-primary-50",
|
|
11622
|
+
disabled ? "cursor-default opacity-50" : "cursor-pointer"
|
|
11623
|
+
),
|
|
11624
|
+
children: /* @__PURE__ */ jsx28(
|
|
11625
|
+
"span",
|
|
11626
|
+
{
|
|
11627
|
+
className: cn(
|
|
11628
|
+
"absolute top-0.5 h-4 w-4 rounded-full bg-white transition-all",
|
|
11629
|
+
checked ? "left-[1.125rem]" : "left-0.5"
|
|
11630
|
+
)
|
|
11631
|
+
}
|
|
11632
|
+
)
|
|
11633
|
+
}
|
|
11634
|
+
)
|
|
11635
|
+
] });
|
|
11636
|
+
}
|
|
11637
|
+
function SocialsDisplayPanel({ display, onChange, className }) {
|
|
11638
|
+
return /* @__PURE__ */ jsxs18("div", { className: cn("flex w-full flex-col gap-3", className), children: [
|
|
11639
|
+
/* @__PURE__ */ jsx28(
|
|
11640
|
+
DisplaySwitch,
|
|
11641
|
+
{
|
|
11642
|
+
label: "Text",
|
|
11643
|
+
checked: display.text,
|
|
11644
|
+
disabled: display.text && !display.icon,
|
|
11645
|
+
onChange: (text) => onChange({ ...display, text })
|
|
11646
|
+
}
|
|
11647
|
+
),
|
|
11648
|
+
/* @__PURE__ */ jsx28(
|
|
11649
|
+
DisplaySwitch,
|
|
11650
|
+
{
|
|
11651
|
+
label: "Icon",
|
|
11652
|
+
checked: display.icon,
|
|
11653
|
+
disabled: display.icon && !display.text,
|
|
11654
|
+
onChange: (icon) => onChange({ ...display, icon })
|
|
11655
|
+
}
|
|
11656
|
+
)
|
|
11657
|
+
] });
|
|
11658
|
+
}
|
|
11659
|
+
|
|
11660
|
+
// src/lib/item-drag-interaction.ts
|
|
11661
|
+
function disableNativeHrefDrag(el) {
|
|
11662
|
+
if (el.draggable) el.draggable = false;
|
|
11663
|
+
if (el.getAttribute("draggable") !== "false") {
|
|
11664
|
+
el.setAttribute("draggable", "false");
|
|
11665
|
+
}
|
|
11666
|
+
}
|
|
11667
|
+
function clearTextSelection() {
|
|
11668
|
+
const sel = window.getSelection();
|
|
11669
|
+
if (sel && !sel.isCollapsed) sel.removeAllRanges();
|
|
11670
|
+
}
|
|
11671
|
+
function armItemPressDrag() {
|
|
11672
|
+
document.documentElement.setAttribute("data-ohw-footer-press-drag", "");
|
|
11673
|
+
}
|
|
11674
|
+
function lockItemDuringDrag() {
|
|
11675
|
+
document.documentElement.removeAttribute("data-ohw-footer-press-drag");
|
|
11676
|
+
document.documentElement.setAttribute("data-ohw-item-dragging", "");
|
|
11677
|
+
clearTextSelection();
|
|
11678
|
+
}
|
|
11679
|
+
function unlockItemDragInteraction() {
|
|
11680
|
+
const wasDragging = document.documentElement.hasAttribute("data-ohw-item-dragging");
|
|
11681
|
+
document.documentElement.removeAttribute("data-ohw-footer-press-drag");
|
|
11682
|
+
document.documentElement.removeAttribute("data-ohw-item-dragging");
|
|
11683
|
+
if (wasDragging) clearTextSelection();
|
|
11684
|
+
}
|
|
11685
|
+
var armFooterPressDrag = armItemPressDrag;
|
|
11686
|
+
var lockFooterDuringDrag = lockItemDuringDrag;
|
|
11687
|
+
var unlockFooterDragInteraction = unlockItemDragInteraction;
|
|
11688
|
+
|
|
11689
|
+
// src/lib/nav-dnd.ts
|
|
11690
|
+
function listReorderableNavItems() {
|
|
10362
11691
|
return listNavbarItems().filter((el) => {
|
|
10363
11692
|
const key = el.getAttribute("data-ohw-href-key");
|
|
10364
11693
|
return isNavbarHrefKey(key) && !isNestedNavChild(el);
|
|
@@ -10526,7 +11855,7 @@ function hitTestNavDropSlot(clientX, clientY, draggedHrefKey) {
|
|
|
10526
11855
|
}
|
|
10527
11856
|
|
|
10528
11857
|
// src/useNavItemDrag.ts
|
|
10529
|
-
import { useCallback as
|
|
11858
|
+
import { useCallback as useCallback6, useEffect as useEffect10, useRef as useRef8, useState as useState9 } from "react";
|
|
10530
11859
|
function useNavItemDrag({
|
|
10531
11860
|
isEditMode,
|
|
10532
11861
|
editContentRef,
|
|
@@ -10550,11 +11879,11 @@ function useNavItemDrag({
|
|
|
10550
11879
|
getNavigationItemAnchor: getNavigationItemAnchor2,
|
|
10551
11880
|
isDragHandleDisabled: isDragHandleDisabled2
|
|
10552
11881
|
}) {
|
|
10553
|
-
const navDragRef =
|
|
10554
|
-
const [navDropSlots, setNavDropSlots] =
|
|
10555
|
-
const [activeNavDropIndex, setActiveNavDropIndex] =
|
|
10556
|
-
const navPointerDragRef =
|
|
10557
|
-
const clearNavDragVisuals =
|
|
11882
|
+
const navDragRef = useRef8(null);
|
|
11883
|
+
const [navDropSlots, setNavDropSlots] = useState9([]);
|
|
11884
|
+
const [activeNavDropIndex, setActiveNavDropIndex] = useState9(null);
|
|
11885
|
+
const navPointerDragRef = useRef8(null);
|
|
11886
|
+
const clearNavDragVisuals = useCallback6(() => {
|
|
10558
11887
|
const session = navDragRef.current;
|
|
10559
11888
|
const keepOpenEl = session?.draggedEl?.closest("[data-ohw-nav-children]") != null ? session.draggedEl : null;
|
|
10560
11889
|
navDragRef.current = null;
|
|
@@ -10571,7 +11900,7 @@ function useNavItemDrag({
|
|
|
10571
11900
|
document.documentElement.removeAttribute("data-ohw-nav-dragging-root");
|
|
10572
11901
|
unlockItemDragInteraction();
|
|
10573
11902
|
}, [setDraggedItemRect, setIsItemDragging, setSiblingHintRects]);
|
|
10574
|
-
const refreshNavDragVisuals =
|
|
11903
|
+
const refreshNavDragVisuals = useCallback6(
|
|
10575
11904
|
(session, activeSlot, clientX, clientY) => {
|
|
10576
11905
|
setDraggedItemRect(session.draggedEl.getBoundingClientRect());
|
|
10577
11906
|
if (typeof clientX === "number" && typeof clientY === "number") {
|
|
@@ -10589,13 +11918,13 @@ function useNavItemDrag({
|
|
|
10589
11918
|
},
|
|
10590
11919
|
[setDraggedItemRect, setSiblingHintRects]
|
|
10591
11920
|
);
|
|
10592
|
-
const refreshNavDragVisualsRef =
|
|
11921
|
+
const refreshNavDragVisualsRef = useRef8(refreshNavDragVisuals);
|
|
10593
11922
|
refreshNavDragVisualsRef.current = refreshNavDragVisuals;
|
|
10594
|
-
const commitNavDragRef =
|
|
11923
|
+
const commitNavDragRef = useRef8(() => {
|
|
10595
11924
|
});
|
|
10596
|
-
const beginNavDragRef =
|
|
11925
|
+
const beginNavDragRef = useRef8(() => {
|
|
10597
11926
|
});
|
|
10598
|
-
const beginNavDrag =
|
|
11927
|
+
const beginNavDrag = useCallback6(
|
|
10599
11928
|
(session) => {
|
|
10600
11929
|
const rect = session.draggedEl.getBoundingClientRect();
|
|
10601
11930
|
session.lastClientX = session.lastClientX || rect.left + rect.width / 2;
|
|
@@ -10629,7 +11958,7 @@ function useNavItemDrag({
|
|
|
10629
11958
|
]
|
|
10630
11959
|
);
|
|
10631
11960
|
beginNavDragRef.current = beginNavDrag;
|
|
10632
|
-
const commitNavDrag =
|
|
11961
|
+
const commitNavDrag = useCallback6(
|
|
10633
11962
|
(clientX, clientY) => {
|
|
10634
11963
|
const session = navDragRef.current;
|
|
10635
11964
|
if (!session) {
|
|
@@ -10690,7 +12019,7 @@ function useNavItemDrag({
|
|
|
10690
12019
|
[clearNavDragVisuals, deselectRef, editContentRef, postToParentRef, selectRef]
|
|
10691
12020
|
);
|
|
10692
12021
|
commitNavDragRef.current = commitNavDrag;
|
|
10693
|
-
const startNavLinkDrag =
|
|
12022
|
+
const startNavLinkDrag = useCallback6(
|
|
10694
12023
|
(anchor, clientX, clientY, wasSelected) => {
|
|
10695
12024
|
if (footerDragRef.current) return false;
|
|
10696
12025
|
const hrefKey = anchor.getAttribute("data-ohw-href-key");
|
|
@@ -10708,7 +12037,7 @@ function useNavItemDrag({
|
|
|
10708
12037
|
},
|
|
10709
12038
|
[beginNavDrag, footerDragRef, isDragHandleDisabled2, isCtaButton]
|
|
10710
12039
|
);
|
|
10711
|
-
const onNavDragOver =
|
|
12040
|
+
const onNavDragOver = useCallback6(
|
|
10712
12041
|
(e) => {
|
|
10713
12042
|
const session = navDragRef.current;
|
|
10714
12043
|
if (!session) return false;
|
|
@@ -10720,7 +12049,7 @@ function useNavItemDrag({
|
|
|
10720
12049
|
},
|
|
10721
12050
|
[]
|
|
10722
12051
|
);
|
|
10723
|
-
|
|
12052
|
+
useEffect10(() => {
|
|
10724
12053
|
if (!isEditMode) return;
|
|
10725
12054
|
const THRESHOLD = 10;
|
|
10726
12055
|
const resolveWasSelected = (el) => {
|
|
@@ -10845,7 +12174,7 @@ function useNavItemDrag({
|
|
|
10845
12174
|
setLinkPopover,
|
|
10846
12175
|
suppressNextClickRef
|
|
10847
12176
|
]);
|
|
10848
|
-
const armNavPressFromChrome =
|
|
12177
|
+
const armNavPressFromChrome = useCallback6(
|
|
10849
12178
|
(selected, clientX, clientY, pointerId) => {
|
|
10850
12179
|
const hrefKey = selected.getAttribute("data-ohw-href-key");
|
|
10851
12180
|
if (!hrefKey || !isNavbarHrefKey(hrefKey)) return false;
|
|
@@ -10877,7 +12206,7 @@ function useNavItemDrag({
|
|
|
10877
12206
|
|
|
10878
12207
|
// src/ui/footer-container-chrome.tsx
|
|
10879
12208
|
import { Plus as Plus2 } from "lucide-react";
|
|
10880
|
-
import { jsx as
|
|
12209
|
+
import { jsx as jsx29, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
10881
12210
|
function FooterContainerChrome({
|
|
10882
12211
|
rect,
|
|
10883
12212
|
onAdd,
|
|
@@ -10885,7 +12214,7 @@ function FooterContainerChrome({
|
|
|
10885
12214
|
}) {
|
|
10886
12215
|
const chromeGap = 6;
|
|
10887
12216
|
const buttonMargin = 7;
|
|
10888
|
-
return /* @__PURE__ */
|
|
12217
|
+
return /* @__PURE__ */ jsx29(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ jsx29(
|
|
10889
12218
|
"div",
|
|
10890
12219
|
{
|
|
10891
12220
|
"data-ohw-footer-container-chrome": "",
|
|
@@ -10897,8 +12226,8 @@ function FooterContainerChrome({
|
|
|
10897
12226
|
width: rect.width + chromeGap * 2,
|
|
10898
12227
|
height: rect.height + chromeGap * 2
|
|
10899
12228
|
},
|
|
10900
|
-
children: /* @__PURE__ */
|
|
10901
|
-
/* @__PURE__ */
|
|
12229
|
+
children: /* @__PURE__ */ jsxs19(Tooltip, { children: [
|
|
12230
|
+
/* @__PURE__ */ jsx29(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx29(
|
|
10902
12231
|
"button",
|
|
10903
12232
|
{
|
|
10904
12233
|
type: "button",
|
|
@@ -10917,17 +12246,17 @@ function FooterContainerChrome({
|
|
|
10917
12246
|
if (addDisabled) return;
|
|
10918
12247
|
onAdd();
|
|
10919
12248
|
},
|
|
10920
|
-
children: /* @__PURE__ */
|
|
12249
|
+
children: /* @__PURE__ */ jsx29(Plus2, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
|
|
10921
12250
|
}
|
|
10922
12251
|
) }),
|
|
10923
|
-
/* @__PURE__ */
|
|
12252
|
+
/* @__PURE__ */ jsx29(TooltipContent, { side: "bottom", sideOffset: 9, children: addDisabled ? "Maximum columns reached" : "Add item" })
|
|
10924
12253
|
] })
|
|
10925
12254
|
}
|
|
10926
12255
|
) });
|
|
10927
12256
|
}
|
|
10928
12257
|
|
|
10929
12258
|
// src/lib/carousel.ts
|
|
10930
|
-
import { useEffect as
|
|
12259
|
+
import { useEffect as useEffect11, useState as useState10 } from "react";
|
|
10931
12260
|
var CAROUSEL_ATTR = "data-ohw-carousel";
|
|
10932
12261
|
var CAROUSEL_VALUE_ATTR = "data-ohw-carousel-value";
|
|
10933
12262
|
var CAROUSEL_SLIDE_ATTR = "data-ohw-carousel-slide";
|
|
@@ -10989,8 +12318,8 @@ function applyCarouselNode(key, val) {
|
|
|
10989
12318
|
return true;
|
|
10990
12319
|
}
|
|
10991
12320
|
function useOhwCarousel(key, initial) {
|
|
10992
|
-
const [images, setImages] =
|
|
10993
|
-
|
|
12321
|
+
const [images, setImages] = useState10(initial);
|
|
12322
|
+
useEffect11(() => {
|
|
10994
12323
|
const el = document.querySelector(
|
|
10995
12324
|
`[${CAROUSEL_ATTR}][data-ohw-key="${CSS.escape(key)}"]`
|
|
10996
12325
|
);
|
|
@@ -11103,6 +12432,18 @@ function collectEditableNodes(extraContent, root = document) {
|
|
|
11103
12432
|
}
|
|
11104
12433
|
if (extraContent && !isScoped) {
|
|
11105
12434
|
applyNavFooterDeleteOverrides(byKey, extraContent);
|
|
12435
|
+
for (const key of LOGO_IMAGE_KEYS) {
|
|
12436
|
+
if (!(key in extraContent)) continue;
|
|
12437
|
+
byKey.set(key, { key, type: "image", text: extraContent[key] ?? "" });
|
|
12438
|
+
}
|
|
12439
|
+
for (const key of [LOGO_PLACEHOLDER_KEY, LOGO_ALT_KEY]) {
|
|
12440
|
+
if (!(key in extraContent)) continue;
|
|
12441
|
+
byKey.set(key, { key, type: "meta", text: extraContent[key] ?? "" });
|
|
12442
|
+
}
|
|
12443
|
+
for (const key of LOGO_SIZE_KEYS) {
|
|
12444
|
+
if (!(key in extraContent)) continue;
|
|
12445
|
+
byKey.set(key, { key, type: "meta", text: extraContent[key] ?? "" });
|
|
12446
|
+
}
|
|
11106
12447
|
}
|
|
11107
12448
|
return Array.from(byKey.values());
|
|
11108
12449
|
}
|
|
@@ -11205,7 +12546,7 @@ function isNavbarLinksContainer(el) {
|
|
|
11205
12546
|
function isNavigationItem(el) {
|
|
11206
12547
|
const anchor = el.matches("[data-ohw-href-key]") ? el : el.closest("[data-ohw-href-key]");
|
|
11207
12548
|
if (!anchor) return false;
|
|
11208
|
-
return Boolean(anchor.querySelector('[data-ohw-editable="text"]'));
|
|
12549
|
+
return Boolean(anchor.querySelector('[data-ohw-editable="text"]')) || Boolean(getSocialItem(anchor));
|
|
11209
12550
|
}
|
|
11210
12551
|
function findFooterItemGroup(item) {
|
|
11211
12552
|
const explicit = item.closest("[data-ohw-footer-col], [data-ohw-footer-column]");
|
|
@@ -11226,8 +12567,9 @@ function isInferredFooterGroup(el) {
|
|
|
11226
12567
|
const footer = el.closest("footer");
|
|
11227
12568
|
if (!footer || el === footer) return false;
|
|
11228
12569
|
if (el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column")) return true;
|
|
12570
|
+
if (isSocialsRow(el)) return false;
|
|
11229
12571
|
const count = Array.from(el.querySelectorAll("[data-ohw-href-key]")).filter(
|
|
11230
|
-
isNavigationItem
|
|
12572
|
+
(item) => isNavigationItem(item) && !getSocialItem(item)
|
|
11231
12573
|
).length;
|
|
11232
12574
|
return count >= 2;
|
|
11233
12575
|
}
|
|
@@ -11271,7 +12613,8 @@ function deleteSelectedNavFooterItem(deps) {
|
|
|
11271
12613
|
if (key.endsWith("-href")) applyLinkByKey2(key, text);
|
|
11272
12614
|
else {
|
|
11273
12615
|
document.querySelectorAll(`[data-ohw-key="${CSS.escape(key)}"]`).forEach((el) => {
|
|
11274
|
-
el.
|
|
12616
|
+
if (el.getAttribute("data-ohw-editable") === "icon") applyIconMarkup(el, text);
|
|
12617
|
+
else el.textContent = text;
|
|
11275
12618
|
});
|
|
11276
12619
|
}
|
|
11277
12620
|
}
|
|
@@ -11333,6 +12676,21 @@ function deleteSelectedNavFooterItem(deps) {
|
|
|
11333
12676
|
});
|
|
11334
12677
|
return true;
|
|
11335
12678
|
}
|
|
12679
|
+
const social = getSocialItem(selected);
|
|
12680
|
+
if (social) {
|
|
12681
|
+
const result = removeSocialItem(social, getEditContent());
|
|
12682
|
+
if (!result) return false;
|
|
12683
|
+
finishDelete({
|
|
12684
|
+
toastTitle: "Social deleted",
|
|
12685
|
+
removedKeys: result.removedKeys,
|
|
12686
|
+
previousContent: result.previousContent,
|
|
12687
|
+
orderKey: SOCIALS_ORDER_KEY,
|
|
12688
|
+
orderJson: JSON.stringify(result.order),
|
|
12689
|
+
previousOrderJson: JSON.stringify(result.previousOrder),
|
|
12690
|
+
undoDom: result.undo
|
|
12691
|
+
});
|
|
12692
|
+
return true;
|
|
12693
|
+
}
|
|
11336
12694
|
if (isFooterHrefKey(hrefKey)) {
|
|
11337
12695
|
const result = deleteFooterItem(selected);
|
|
11338
12696
|
if (!result) return false;
|
|
@@ -11352,13 +12710,13 @@ function deleteSelectedNavFooterItem(deps) {
|
|
|
11352
12710
|
|
|
11353
12711
|
// src/ui/navbar-container-chrome.tsx
|
|
11354
12712
|
import { Plus as Plus3 } from "lucide-react";
|
|
11355
|
-
import { jsx as
|
|
12713
|
+
import { jsx as jsx30 } from "react/jsx-runtime";
|
|
11356
12714
|
function NavbarContainerChrome({
|
|
11357
12715
|
rect,
|
|
11358
12716
|
onAdd
|
|
11359
12717
|
}) {
|
|
11360
12718
|
const chromeGap = 6;
|
|
11361
|
-
return /* @__PURE__ */
|
|
12719
|
+
return /* @__PURE__ */ jsx30(
|
|
11362
12720
|
"div",
|
|
11363
12721
|
{
|
|
11364
12722
|
"data-ohw-navbar-container-chrome": "",
|
|
@@ -11370,7 +12728,7 @@ function NavbarContainerChrome({
|
|
|
11370
12728
|
width: rect.width + chromeGap * 2,
|
|
11371
12729
|
height: rect.height + chromeGap * 2
|
|
11372
12730
|
},
|
|
11373
|
-
children: /* @__PURE__ */
|
|
12731
|
+
children: /* @__PURE__ */ jsx30(
|
|
11374
12732
|
"button",
|
|
11375
12733
|
{
|
|
11376
12734
|
type: "button",
|
|
@@ -11387,7 +12745,7 @@ function NavbarContainerChrome({
|
|
|
11387
12745
|
e.stopPropagation();
|
|
11388
12746
|
onAdd();
|
|
11389
12747
|
},
|
|
11390
|
-
children: /* @__PURE__ */
|
|
12748
|
+
children: /* @__PURE__ */ jsx30(Plus3, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
|
|
11391
12749
|
}
|
|
11392
12750
|
)
|
|
11393
12751
|
}
|
|
@@ -11396,7 +12754,7 @@ function NavbarContainerChrome({
|
|
|
11396
12754
|
|
|
11397
12755
|
// src/ui/drop-indicator.tsx
|
|
11398
12756
|
import * as React10 from "react";
|
|
11399
|
-
import { jsx as
|
|
12757
|
+
import { jsx as jsx31 } from "react/jsx-runtime";
|
|
11400
12758
|
var dropIndicatorVariants = cva(
|
|
11401
12759
|
"ov-gap-line pointer-events-none shrink-0 transition-opacity duration-150",
|
|
11402
12760
|
{
|
|
@@ -11420,7 +12778,7 @@ var dropIndicatorVariants = cva(
|
|
|
11420
12778
|
);
|
|
11421
12779
|
var DropIndicator = React10.forwardRef(
|
|
11422
12780
|
({ className, direction, state, ...props }, ref) => {
|
|
11423
|
-
return /* @__PURE__ */
|
|
12781
|
+
return /* @__PURE__ */ jsx31(
|
|
11424
12782
|
"div",
|
|
11425
12783
|
{
|
|
11426
12784
|
ref,
|
|
@@ -11437,7 +12795,7 @@ var DropIndicator = React10.forwardRef(
|
|
|
11437
12795
|
DropIndicator.displayName = "DropIndicator";
|
|
11438
12796
|
|
|
11439
12797
|
// src/ui/badge.tsx
|
|
11440
|
-
import { jsx as
|
|
12798
|
+
import { jsx as jsx32 } from "react/jsx-runtime";
|
|
11441
12799
|
var badgeVariants = cva(
|
|
11442
12800
|
"inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
|
|
11443
12801
|
{
|
|
@@ -11455,12 +12813,12 @@ var badgeVariants = cva(
|
|
|
11455
12813
|
}
|
|
11456
12814
|
);
|
|
11457
12815
|
function Badge({ className, variant, ...props }) {
|
|
11458
|
-
return /* @__PURE__ */
|
|
12816
|
+
return /* @__PURE__ */ jsx32("div", { className: cn(badgeVariants({ variant }), className), ...props });
|
|
11459
12817
|
}
|
|
11460
12818
|
|
|
11461
12819
|
// src/OhhwellsBridge.tsx
|
|
11462
|
-
import { Link as
|
|
11463
|
-
import { Fragment as Fragment8, jsx as
|
|
12820
|
+
import { Link as Link3 } from "lucide-react";
|
|
12821
|
+
import { Fragment as Fragment8, jsx as jsx33, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
11464
12822
|
var PRIMARY3 = "#0885FE";
|
|
11465
12823
|
var IMAGE_FADE_MS = 300;
|
|
11466
12824
|
function runOpacityFade(el, onDone) {
|
|
@@ -11554,21 +12912,10 @@ function parseSchedulingInsertAfter(insertAfter) {
|
|
|
11554
12912
|
insertBefore: insertAfter.slice(idx + INSERT_BEFORE_MARKER.length)
|
|
11555
12913
|
};
|
|
11556
12914
|
}
|
|
11557
|
-
function
|
|
11558
|
-
|
|
11559
|
-
const
|
|
11560
|
-
|
|
11561
|
-
return { effectiveInsertAfter, insertBefore };
|
|
11562
|
-
}
|
|
11563
|
-
function getSchedulingMountPoint(insertAfter) {
|
|
11564
|
-
const { anchor } = parseSchedulingInsertAfter(insertAfter);
|
|
11565
|
-
let anchorEl = document.querySelector(`[data-ohw-section="${anchor}"]`);
|
|
11566
|
-
if (!anchorEl && anchor === "scheduling") {
|
|
11567
|
-
const widgets = Array.from(document.querySelectorAll('[data-ohw-section^="scheduling-"]'));
|
|
11568
|
-
anchorEl = widgets.at(-1) ?? null;
|
|
11569
|
-
}
|
|
11570
|
-
if (!anchorEl) return null;
|
|
11571
|
-
return anchorEl.closest('[data-ohw-section-container="scheduling"]') ?? anchorEl;
|
|
12915
|
+
function resolveEntryAnchor(entry) {
|
|
12916
|
+
if (entry.anchorId !== void 0) return { anchorId: entry.anchorId, beforeId: entry.beforeId ?? null };
|
|
12917
|
+
const parsed = parseSchedulingInsertAfter(entry.insertAfter);
|
|
12918
|
+
return { anchorId: parsed.anchor, beforeId: parsed.insertBefore };
|
|
11572
12919
|
}
|
|
11573
12920
|
function schedulingMountDepth(insertAfter) {
|
|
11574
12921
|
if (!insertAfter.includes(INSERT_BEFORE_MARKER)) return 0;
|
|
@@ -11585,8 +12932,7 @@ function getPageSchedulingEntries(raw) {
|
|
|
11585
12932
|
}
|
|
11586
12933
|
}
|
|
11587
12934
|
function isSchedulingWidgetMissing(entry) {
|
|
11588
|
-
|
|
11589
|
-
return !document.querySelector(`[data-ohw-section="${schedulingSectionId(effectiveInsertAfter)}"]`);
|
|
12935
|
+
return !document.querySelector(`[data-ohw-section="${schedulingSectionId(entry.insertAfter)}"]`);
|
|
11590
12936
|
}
|
|
11591
12937
|
function hasMissingSchedulingWidgets(entries) {
|
|
11592
12938
|
return entries.some(isSchedulingWidgetMissing);
|
|
@@ -11616,16 +12962,17 @@ function initSectionsFromContent(content, removeExisting = false) {
|
|
|
11616
12962
|
} catch {
|
|
11617
12963
|
}
|
|
11618
12964
|
}
|
|
11619
|
-
function mountSchedulingWidget(
|
|
11620
|
-
const
|
|
11621
|
-
const sectionId = schedulingSectionId(
|
|
12965
|
+
function mountSchedulingWidget(anchorId, notifyOnConnect = false, scheduleId, beforeId, existingWidgetId) {
|
|
12966
|
+
const widgetId = existingWidgetId ?? (beforeId ? `${anchorId}${INSERT_BEFORE_MARKER}${beforeId}` : anchorId);
|
|
12967
|
+
const sectionId = schedulingSectionId(widgetId);
|
|
11622
12968
|
if (document.querySelector(`[data-ohw-section="${sectionId}"]`)) return false;
|
|
11623
|
-
const
|
|
11624
|
-
if (!
|
|
12969
|
+
const anchorEl = document.querySelector(`[data-ohw-section="${anchorId}"]`);
|
|
12970
|
+
if (!anchorEl) return false;
|
|
12971
|
+
const mountPoint = anchorEl.closest('[data-ohw-section-container="scheduling"]') ?? anchorEl;
|
|
11625
12972
|
const container = document.createElement("div");
|
|
11626
12973
|
container.dataset.ohwSectionContainer = "scheduling";
|
|
11627
|
-
if (
|
|
11628
|
-
const beforeAnchor = document.querySelector(`[data-ohw-section="${
|
|
12974
|
+
if (beforeId) {
|
|
12975
|
+
const beforeAnchor = document.querySelector(`[data-ohw-section="${beforeId}"]`);
|
|
11629
12976
|
const beforePoint = beforeAnchor?.closest('[data-ohw-section-container="scheduling"]') ?? beforeAnchor;
|
|
11630
12977
|
if (!beforePoint) return false;
|
|
11631
12978
|
beforePoint.insertAdjacentElement("beforebegin", container);
|
|
@@ -11636,19 +12983,25 @@ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId,
|
|
|
11636
12983
|
}
|
|
11637
12984
|
tail.insertAdjacentElement("afterend", container);
|
|
11638
12985
|
}
|
|
11639
|
-
|
|
11640
|
-
|
|
11641
|
-
|
|
11642
|
-
|
|
11643
|
-
|
|
11644
|
-
|
|
11645
|
-
|
|
11646
|
-
|
|
11647
|
-
|
|
11648
|
-
|
|
11649
|
-
|
|
11650
|
-
|
|
11651
|
-
|
|
12986
|
+
try {
|
|
12987
|
+
const root = createRoot2(container);
|
|
12988
|
+
flushSync2(() => {
|
|
12989
|
+
root.render(
|
|
12990
|
+
/* @__PURE__ */ jsx33(
|
|
12991
|
+
SchedulingWidget,
|
|
12992
|
+
{
|
|
12993
|
+
notifyOnConnect,
|
|
12994
|
+
initialScheduleId: scheduleId,
|
|
12995
|
+
insertAfter: widgetId
|
|
12996
|
+
}
|
|
12997
|
+
)
|
|
12998
|
+
);
|
|
12999
|
+
});
|
|
13000
|
+
} catch (err) {
|
|
13001
|
+
console.error("[ow:scheduling] render threw", err);
|
|
13002
|
+
container.remove();
|
|
13003
|
+
return false;
|
|
13004
|
+
}
|
|
11652
13005
|
const tracker = getSectionsTracker();
|
|
11653
13006
|
let sections = [];
|
|
11654
13007
|
try {
|
|
@@ -11656,10 +13009,12 @@ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId,
|
|
|
11656
13009
|
} catch {
|
|
11657
13010
|
}
|
|
11658
13011
|
const inEditor = typeof window !== "undefined" && window.self !== window.top;
|
|
11659
|
-
if (inEditor && !sections.find((s) => s.type === "scheduling" && s.insertAfter ===
|
|
13012
|
+
if (inEditor && !sections.find((s) => s.type === "scheduling" && s.insertAfter === widgetId)) {
|
|
11660
13013
|
sections.push({
|
|
11661
13014
|
type: "scheduling",
|
|
11662
|
-
insertAfter:
|
|
13015
|
+
insertAfter: widgetId,
|
|
13016
|
+
anchorId,
|
|
13017
|
+
beforeId: beforeId ?? null,
|
|
11663
13018
|
pagePath: window.location.pathname,
|
|
11664
13019
|
...scheduleId ? { scheduleId } : {}
|
|
11665
13020
|
});
|
|
@@ -11673,7 +13028,8 @@ function mountSchedulingEntries(entries, notifyOnConnect = false) {
|
|
|
11673
13028
|
for (let i = pending.length - 1; i >= 0; i--) {
|
|
11674
13029
|
const entry = pending[i];
|
|
11675
13030
|
const shouldNotify = typeof notifyOnConnect === "function" ? notifyOnConnect(entry) : notifyOnConnect;
|
|
11676
|
-
|
|
13031
|
+
const { anchorId, beforeId } = resolveEntryAnchor(entry);
|
|
13032
|
+
if (mountSchedulingWidget(anchorId, shouldNotify, entry.scheduleId ?? null, beforeId, entry.insertAfter)) {
|
|
11677
13033
|
pending.splice(i, 1);
|
|
11678
13034
|
}
|
|
11679
13035
|
}
|
|
@@ -11687,6 +13043,17 @@ function applyLinkHref(el, val) {
|
|
|
11687
13043
|
const anchor = el instanceof HTMLAnchorElement ? el : el.querySelector("a");
|
|
11688
13044
|
if (anchor) anchor.setAttribute("href", val);
|
|
11689
13045
|
}
|
|
13046
|
+
function currentIconRef(el) {
|
|
13047
|
+
const uploaded = el instanceof HTMLImageElement ? el : el.querySelector("img");
|
|
13048
|
+
if (uploaded?.getAttribute("src")) {
|
|
13049
|
+
return uploaded.getAttribute("src") ?? "";
|
|
13050
|
+
}
|
|
13051
|
+
const svg = el instanceof SVGElement ? el : el.querySelector("svg");
|
|
13052
|
+
const named = Array.from(svg?.classList ?? []).find(
|
|
13053
|
+
(c) => c.startsWith("lucide-") && c !== "lucide-icon"
|
|
13054
|
+
);
|
|
13055
|
+
return named ? `lucide:${named.slice("lucide-".length)}` : "";
|
|
13056
|
+
}
|
|
11690
13057
|
function getEditMeasureEl(editable) {
|
|
11691
13058
|
return editable.closest("[data-ohw-href-key]") ?? editable;
|
|
11692
13059
|
}
|
|
@@ -11731,8 +13098,11 @@ function isMediaEditable(el) {
|
|
|
11731
13098
|
const t = el.dataset.ohwEditable;
|
|
11732
13099
|
return t === "image" || t === "bg-image" || t === "video";
|
|
11733
13100
|
}
|
|
13101
|
+
function isIconEditable(el) {
|
|
13102
|
+
return el.dataset.ohwEditable === "icon";
|
|
13103
|
+
}
|
|
11734
13104
|
var MEDIA_SELECTOR = '[data-ohw-editable="image"], [data-ohw-editable="bg-image"], [data-ohw-editable="video"]';
|
|
11735
|
-
var NON_MEDIA_SELECTOR = '[data-ohw-editable]:not([data-ohw-editable="image"]):not([data-ohw-editable="bg-image"]):not([data-ohw-editable="video"])';
|
|
13105
|
+
var NON_MEDIA_SELECTOR = '[data-ohw-editable]:not([data-ohw-editable="image"]):not([data-ohw-editable="bg-image"]):not([data-ohw-editable="video"]):not([data-ohw-editable="icon"])';
|
|
11736
13106
|
function getVideoEl2(el) {
|
|
11737
13107
|
return el instanceof HTMLVideoElement ? el : el.querySelector("video");
|
|
11738
13108
|
}
|
|
@@ -11803,6 +13173,13 @@ function isInsideLinkEditor(target) {
|
|
|
11803
13173
|
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"]')
|
|
11804
13174
|
);
|
|
11805
13175
|
}
|
|
13176
|
+
function isInsideFloatingPanel(target) {
|
|
13177
|
+
return Boolean(target.closest("[data-ohw-floating-panel]"));
|
|
13178
|
+
}
|
|
13179
|
+
function isPointOverFloatingPanel(clientX, clientY) {
|
|
13180
|
+
const el = document.elementFromPoint(clientX, clientY);
|
|
13181
|
+
return Boolean(el instanceof Element && el.closest("[data-ohw-floating-panel]"));
|
|
13182
|
+
}
|
|
11806
13183
|
function getHrefKeyFromElement(el) {
|
|
11807
13184
|
if (!el) return null;
|
|
11808
13185
|
const anchor = el.closest("[data-ohw-href-key]");
|
|
@@ -11850,13 +13227,29 @@ function isNavItemPointerTarget(el) {
|
|
|
11850
13227
|
function getNavigationItemAnchor(el) {
|
|
11851
13228
|
const anchor = el.matches("[data-ohw-href-key]") ? el : el.closest("[data-ohw-href-key]");
|
|
11852
13229
|
if (!anchor) return null;
|
|
11853
|
-
if (!anchor.querySelector('[data-ohw-editable="text"]')) return null;
|
|
13230
|
+
if (!anchor.querySelector('[data-ohw-editable="text"]') && !getSocialItem(anchor)) return null;
|
|
11854
13231
|
if (!isNavItemPointerTarget(anchor)) return null;
|
|
11855
13232
|
return anchor;
|
|
11856
13233
|
}
|
|
11857
13234
|
function isNavigationItem2(el) {
|
|
11858
13235
|
return getNavigationItemAnchor(el) !== null;
|
|
11859
13236
|
}
|
|
13237
|
+
function requestSocialDialog(anchor, post, content) {
|
|
13238
|
+
const item = getSocialItem(anchor);
|
|
13239
|
+
if (!item) return false;
|
|
13240
|
+
const iconKey = item.querySelector('[data-ohw-editable="icon"]')?.dataset.ohwKey ?? "";
|
|
13241
|
+
post({
|
|
13242
|
+
type: "ow:social-pick",
|
|
13243
|
+
hrefKey: item.getAttribute("data-ohw-href-key") ?? "",
|
|
13244
|
+
iconKey,
|
|
13245
|
+
url: getLinkHref4(item),
|
|
13246
|
+
iconStyle: detectIconStyle(item),
|
|
13247
|
+
// What was chosen last time. Guessing from the address instead reads as "Website" for anything
|
|
13248
|
+
// unrecognised, and for an item with no address at all — so a deliberate choice looked lost.
|
|
13249
|
+
platformId: content[socialPlatformKey(iconKey)] ?? ""
|
|
13250
|
+
});
|
|
13251
|
+
return true;
|
|
13252
|
+
}
|
|
11860
13253
|
function listNavigationItems() {
|
|
11861
13254
|
return Array.from(
|
|
11862
13255
|
document.querySelectorAll("nav [data-ohw-href-key], footer [data-ohw-href-key]")
|
|
@@ -11891,7 +13284,7 @@ function getNavigationRoot(el) {
|
|
|
11891
13284
|
return el.closest("nav, footer, aside");
|
|
11892
13285
|
}
|
|
11893
13286
|
function countFooterNavItems(el) {
|
|
11894
|
-
return Array.from(el.querySelectorAll("[data-ohw-href-key]")).filter(isNavigationItem2).length;
|
|
13287
|
+
return Array.from(el.querySelectorAll("[data-ohw-href-key]")).filter((item) => isNavigationItem2(item) && !getSocialItem(item)).length;
|
|
11895
13288
|
}
|
|
11896
13289
|
function findFooterItemGroup2(item) {
|
|
11897
13290
|
const explicit = item.closest("[data-ohw-footer-col], [data-ohw-footer-column]");
|
|
@@ -11912,10 +13305,11 @@ function isInferredFooterGroup2(el) {
|
|
|
11912
13305
|
const footer = el.closest("footer");
|
|
11913
13306
|
if (!footer || el === footer) return false;
|
|
11914
13307
|
if (el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column")) return true;
|
|
13308
|
+
if (isSocialsRow(el)) return false;
|
|
11915
13309
|
return countFooterNavItems(el) >= 2;
|
|
11916
13310
|
}
|
|
11917
13311
|
function isNavigationContainer(el) {
|
|
11918
|
-
return el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-nav-drawer") || isFooterLinksContainer(el) || el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isNavigationRoot(el) || isInferredFooterGroup2(el);
|
|
13312
|
+
return el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-nav-drawer") || isFooterLinksContainer(el) || el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isNavigationRoot(el) || isSocialsRow(el) || isInferredFooterGroup2(el);
|
|
11919
13313
|
}
|
|
11920
13314
|
function isNavbarLinksContainer2(el) {
|
|
11921
13315
|
return el.hasAttribute("data-ohw-nav-container");
|
|
@@ -11923,6 +13317,11 @@ function isNavbarLinksContainer2(el) {
|
|
|
11923
13317
|
function getFooterColumn(el) {
|
|
11924
13318
|
return el.closest("[data-ohw-footer-col], [data-ohw-footer-column]");
|
|
11925
13319
|
}
|
|
13320
|
+
function isFooterAddItemDisabled(selected) {
|
|
13321
|
+
if (!selected) return false;
|
|
13322
|
+
const column = resolveFooterColumnForAdd(selected);
|
|
13323
|
+
return column ? !canAddFooterItem(column) : false;
|
|
13324
|
+
}
|
|
11926
13325
|
function resolveFooterColumnSelectionTarget(target, clientX, clientY) {
|
|
11927
13326
|
if (getNavigationItemAnchor(target)) return null;
|
|
11928
13327
|
const column = getFooterColumn(target);
|
|
@@ -11998,6 +13397,8 @@ function resolveNavContainerSelectionTarget(target, clientX, clientY) {
|
|
|
11998
13397
|
return null;
|
|
11999
13398
|
}
|
|
12000
13399
|
function getNavigationSelectionParent(el) {
|
|
13400
|
+
const socialsRow = findSocialsRow(el);
|
|
13401
|
+
if (socialsRow) return socialsRow;
|
|
12001
13402
|
if (isNavigationItem2(el)) {
|
|
12002
13403
|
const childrenRoot = el.closest("[data-ohw-nav-children]");
|
|
12003
13404
|
if (childrenRoot) {
|
|
@@ -12016,13 +13417,17 @@ function getNavigationSelectionParent(el) {
|
|
|
12016
13417
|
if (!isFooterLinksContainer(el) && (el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isInferredFooterGroup2(el))) {
|
|
12017
13418
|
return getFooterLinksContainer();
|
|
12018
13419
|
}
|
|
12019
|
-
if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-nav-drawer") || isFooterLinksContainer(el)) {
|
|
13420
|
+
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)) {
|
|
12020
13421
|
return getNavigationRoot(el);
|
|
12021
13422
|
}
|
|
12022
13423
|
return null;
|
|
12023
13424
|
}
|
|
12024
13425
|
function collectNavigationItemSiblingHintRects(selected) {
|
|
12025
13426
|
if (!isNavigationItem2(selected)) return [];
|
|
13427
|
+
const socialsRow = findSocialsRow(selected);
|
|
13428
|
+
if (socialsRow) {
|
|
13429
|
+
return listSocialItems(socialsRow).filter((item) => item !== selected).map((item) => item.getBoundingClientRect());
|
|
13430
|
+
}
|
|
12026
13431
|
const footerColumn = getFooterColumn(selected);
|
|
12027
13432
|
if (footerColumn) {
|
|
12028
13433
|
return listFooterLinksInColumn(footerColumn).filter((link) => link !== selected).map((link) => link.getBoundingClientRect());
|
|
@@ -12230,6 +13635,9 @@ var ICONS = {
|
|
|
12230
13635
|
var SELECTION_CHROME_GAP2 = 4;
|
|
12231
13636
|
var TOOLBAR_STROKE_GAP2 = 4;
|
|
12232
13637
|
var TOOLBAR_OFFSET_FROM_ELEMENT = SELECTION_CHROME_GAP2 + TOOLBAR_STROKE_GAP2;
|
|
13638
|
+
var HOVER_STROKE_WIDTH = 1.5;
|
|
13639
|
+
var TEXT_HOVER_SIDE_PAD = 4;
|
|
13640
|
+
var CHROME_PRIMARY = `var(--ohw-primary, ${PRIMARY3})`;
|
|
12233
13641
|
var TOOLBAR_GROUPS = [
|
|
12234
13642
|
[
|
|
12235
13643
|
{ cmd: "bold", title: "Bold" },
|
|
@@ -12255,7 +13663,7 @@ function EditGlowChrome({
|
|
|
12255
13663
|
hideHandle = false
|
|
12256
13664
|
}) {
|
|
12257
13665
|
const GAP = SELECTION_CHROME_GAP2;
|
|
12258
|
-
return /* @__PURE__ */
|
|
13666
|
+
return /* @__PURE__ */ jsxs20(
|
|
12259
13667
|
"div",
|
|
12260
13668
|
{
|
|
12261
13669
|
ref: elRef,
|
|
@@ -12270,7 +13678,7 @@ function EditGlowChrome({
|
|
|
12270
13678
|
zIndex: 2147483646
|
|
12271
13679
|
},
|
|
12272
13680
|
children: [
|
|
12273
|
-
/* @__PURE__ */
|
|
13681
|
+
/* @__PURE__ */ jsx33(
|
|
12274
13682
|
"div",
|
|
12275
13683
|
{
|
|
12276
13684
|
style: {
|
|
@@ -12283,7 +13691,7 @@ function EditGlowChrome({
|
|
|
12283
13691
|
}
|
|
12284
13692
|
}
|
|
12285
13693
|
),
|
|
12286
|
-
reorderHrefKey && !hideHandle && /* @__PURE__ */
|
|
13694
|
+
reorderHrefKey && !hideHandle && /* @__PURE__ */ jsx33(
|
|
12287
13695
|
"div",
|
|
12288
13696
|
{
|
|
12289
13697
|
"data-ohw-drag-handle-container": "",
|
|
@@ -12295,7 +13703,7 @@ function EditGlowChrome({
|
|
|
12295
13703
|
transform: "translate(calc(-100% - 7px), -50%)",
|
|
12296
13704
|
pointerEvents: dragDisabled ? "none" : "auto"
|
|
12297
13705
|
},
|
|
12298
|
-
children: /* @__PURE__ */
|
|
13706
|
+
children: /* @__PURE__ */ jsx33(
|
|
12299
13707
|
DragHandle,
|
|
12300
13708
|
{
|
|
12301
13709
|
"aria-label": `Reorder ${reorderHrefKey}`,
|
|
@@ -12505,7 +13913,7 @@ function FloatingToolbar({
|
|
|
12505
13913
|
return () => ro.disconnect();
|
|
12506
13914
|
}, [showEditLink, activeCommands]);
|
|
12507
13915
|
const { top, left, transform } = calcToolbarPos(rect, parentScroll, measuredW);
|
|
12508
|
-
return /* @__PURE__ */
|
|
13916
|
+
return /* @__PURE__ */ jsx33(
|
|
12509
13917
|
"div",
|
|
12510
13918
|
{
|
|
12511
13919
|
ref: setRefs,
|
|
@@ -12517,12 +13925,12 @@ function FloatingToolbar({
|
|
|
12517
13925
|
zIndex: 2147483647,
|
|
12518
13926
|
pointerEvents: "auto"
|
|
12519
13927
|
},
|
|
12520
|
-
children: /* @__PURE__ */
|
|
12521
|
-
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */
|
|
12522
|
-
gi > 0 && /* @__PURE__ */
|
|
13928
|
+
children: /* @__PURE__ */ jsxs20(CustomToolbar, { children: [
|
|
13929
|
+
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ jsxs20(React11.Fragment, { children: [
|
|
13930
|
+
gi > 0 && /* @__PURE__ */ jsx33(CustomToolbarDivider, {}),
|
|
12523
13931
|
btns.map((btn) => {
|
|
12524
13932
|
const isActive = activeCommands.has(btn.cmd);
|
|
12525
|
-
return /* @__PURE__ */
|
|
13933
|
+
return /* @__PURE__ */ jsx33(
|
|
12526
13934
|
CustomToolbarButton,
|
|
12527
13935
|
{
|
|
12528
13936
|
title: btn.title,
|
|
@@ -12531,7 +13939,7 @@ function FloatingToolbar({
|
|
|
12531
13939
|
e.preventDefault();
|
|
12532
13940
|
onCommand(btn.cmd);
|
|
12533
13941
|
},
|
|
12534
|
-
children: /* @__PURE__ */
|
|
13942
|
+
children: /* @__PURE__ */ jsx33(
|
|
12535
13943
|
"svg",
|
|
12536
13944
|
{
|
|
12537
13945
|
width: "16",
|
|
@@ -12552,7 +13960,7 @@ function FloatingToolbar({
|
|
|
12552
13960
|
);
|
|
12553
13961
|
})
|
|
12554
13962
|
] }, gi)),
|
|
12555
|
-
showEditLink ? /* @__PURE__ */
|
|
13963
|
+
showEditLink ? /* @__PURE__ */ jsx33(
|
|
12556
13964
|
CustomToolbarButton,
|
|
12557
13965
|
{
|
|
12558
13966
|
type: "button",
|
|
@@ -12566,7 +13974,7 @@ function FloatingToolbar({
|
|
|
12566
13974
|
e.preventDefault();
|
|
12567
13975
|
e.stopPropagation();
|
|
12568
13976
|
},
|
|
12569
|
-
children: /* @__PURE__ */
|
|
13977
|
+
children: /* @__PURE__ */ jsx33(Link3, { className: "size-4 shrink-0", "aria-hidden": true })
|
|
12570
13978
|
}
|
|
12571
13979
|
) : null
|
|
12572
13980
|
] })
|
|
@@ -12583,7 +13991,7 @@ function StateToggle({
|
|
|
12583
13991
|
states,
|
|
12584
13992
|
onStateChange
|
|
12585
13993
|
}) {
|
|
12586
|
-
return /* @__PURE__ */
|
|
13994
|
+
return /* @__PURE__ */ jsx33(
|
|
12587
13995
|
ToggleGroup,
|
|
12588
13996
|
{
|
|
12589
13997
|
"data-ohw-state-toggle": "",
|
|
@@ -12597,11 +14005,12 @@ function StateToggle({
|
|
|
12597
14005
|
left: rect.right - 8,
|
|
12598
14006
|
transform: "translateX(-100%)"
|
|
12599
14007
|
},
|
|
12600
|
-
children: states.map((state) => /* @__PURE__ */
|
|
14008
|
+
children: states.map((state) => /* @__PURE__ */ jsx33(ToggleGroupItem, { value: state, size: "sm", children: state }, state))
|
|
12601
14009
|
}
|
|
12602
14010
|
);
|
|
12603
14011
|
}
|
|
12604
14012
|
var contentCache = /* @__PURE__ */ new Map();
|
|
14013
|
+
var fetchedContentPaths = /* @__PURE__ */ new Set();
|
|
12605
14014
|
function resolveSubdomain(subdomainFromQuery) {
|
|
12606
14015
|
if (subdomainFromQuery) return subdomainFromQuery;
|
|
12607
14016
|
if (typeof window !== "undefined") {
|
|
@@ -12624,8 +14033,8 @@ function OhhwellsBridge() {
|
|
|
12624
14033
|
const router = useRouter3();
|
|
12625
14034
|
const searchParams = useSearchParams();
|
|
12626
14035
|
const isEditMode = isEditSessionActive();
|
|
12627
|
-
const [bridgeRoot, setBridgeRoot] =
|
|
12628
|
-
|
|
14036
|
+
const [bridgeRoot, setBridgeRoot] = useState11(null);
|
|
14037
|
+
useEffect12(() => {
|
|
12629
14038
|
const figtreeFontId = "ohw-figtree-font";
|
|
12630
14039
|
if (!document.getElementById(figtreeFontId)) {
|
|
12631
14040
|
const preconnect1 = Object.assign(document.createElement("link"), { rel: "preconnect", href: "https://fonts.googleapis.com" });
|
|
@@ -12654,110 +14063,159 @@ function OhhwellsBridge() {
|
|
|
12654
14063
|
const subdomain = resolveSubdomain(subdomainFromQuery);
|
|
12655
14064
|
useLinkHrefGuardian(pathname, subdomain, isEditMode);
|
|
12656
14065
|
useSavedLinkNavigation(isEditMode);
|
|
12657
|
-
const postToParent2 =
|
|
14066
|
+
const postToParent2 = useCallback7((data) => {
|
|
12658
14067
|
if (typeof window !== "undefined" && window.parent !== window) {
|
|
12659
14068
|
window.parent.postMessage(data, "*");
|
|
12660
14069
|
}
|
|
12661
14070
|
}, []);
|
|
12662
|
-
const [fetchState, setFetchState] =
|
|
12663
|
-
const autoSaveTimers =
|
|
12664
|
-
const activeElRef =
|
|
12665
|
-
const pointerHeldRef =
|
|
12666
|
-
const selectedElRef =
|
|
12667
|
-
const selectedHrefKeyRef =
|
|
12668
|
-
const selectedFooterColAttrRef =
|
|
12669
|
-
const originalContentRef =
|
|
12670
|
-
const activeStateElRef =
|
|
12671
|
-
const parentScrollRef =
|
|
12672
|
-
const visibleViewportRef =
|
|
12673
|
-
const [dialogPortalContainer, setDialogPortalContainer] =
|
|
12674
|
-
const attachVisibleViewport =
|
|
14071
|
+
const [fetchState, setFetchState] = useState11("idle");
|
|
14072
|
+
const autoSaveTimers = useRef9(/* @__PURE__ */ new Map());
|
|
14073
|
+
const activeElRef = useRef9(null);
|
|
14074
|
+
const pointerHeldRef = useRef9(false);
|
|
14075
|
+
const selectedElRef = useRef9(null);
|
|
14076
|
+
const selectedHrefKeyRef = useRef9(null);
|
|
14077
|
+
const selectedFooterColAttrRef = useRef9(null);
|
|
14078
|
+
const originalContentRef = useRef9(null);
|
|
14079
|
+
const activeStateElRef = useRef9(null);
|
|
14080
|
+
const parentScrollRef = useRef9(null);
|
|
14081
|
+
const visibleViewportRef = useRef9(null);
|
|
14082
|
+
const [dialogPortalContainer, setDialogPortalContainer] = useState11(null);
|
|
14083
|
+
const attachVisibleViewport = useCallback7((node) => {
|
|
12675
14084
|
visibleViewportRef.current = node;
|
|
12676
14085
|
setDialogPortalContainer(node);
|
|
12677
14086
|
if (node) applyVisibleViewport(node, parentScrollRef.current);
|
|
12678
14087
|
}, []);
|
|
12679
|
-
const toolbarElRef =
|
|
12680
|
-
const glowElRef =
|
|
12681
|
-
const hoveredImageRef =
|
|
12682
|
-
const hoveredImageHasTextOverlapRef =
|
|
12683
|
-
const dragOverElRef =
|
|
12684
|
-
const [mediaHover, setMediaHover] =
|
|
12685
|
-
const [carouselHover, setCarouselHover] =
|
|
12686
|
-
const [uploadingRects, setUploadingRects] =
|
|
12687
|
-
const hoveredGapRef =
|
|
12688
|
-
const imageUnhoverTimerRef =
|
|
12689
|
-
const imageShowTimerRef =
|
|
12690
|
-
const editStylesRef =
|
|
12691
|
-
const activateRef =
|
|
14088
|
+
const toolbarElRef = useRef9(null);
|
|
14089
|
+
const glowElRef = useRef9(null);
|
|
14090
|
+
const hoveredImageRef = useRef9(null);
|
|
14091
|
+
const hoveredImageHasTextOverlapRef = useRef9(false);
|
|
14092
|
+
const dragOverElRef = useRef9(null);
|
|
14093
|
+
const [mediaHover, setMediaHover] = useState11(null);
|
|
14094
|
+
const [carouselHover, setCarouselHover] = useState11(null);
|
|
14095
|
+
const [uploadingRects, setUploadingRects] = useState11({});
|
|
14096
|
+
const hoveredGapRef = useRef9(null);
|
|
14097
|
+
const imageUnhoverTimerRef = useRef9(null);
|
|
14098
|
+
const imageShowTimerRef = useRef9(null);
|
|
14099
|
+
const editStylesRef = useRef9(null);
|
|
14100
|
+
const activateRef = useRef9(() => {
|
|
14101
|
+
});
|
|
14102
|
+
const deactivateRef = useRef9(() => {
|
|
14103
|
+
});
|
|
14104
|
+
const selectRef = useRef9(() => {
|
|
14105
|
+
});
|
|
14106
|
+
const selectFrameRef = useRef9(() => {
|
|
12692
14107
|
});
|
|
12693
|
-
const
|
|
14108
|
+
const selectLogoRef = useRef9(() => {
|
|
12694
14109
|
});
|
|
12695
|
-
const
|
|
14110
|
+
const openLogoSizePanelRef = useRef9(() => {
|
|
12696
14111
|
});
|
|
12697
|
-
const
|
|
14112
|
+
const deselectRef = useRef9(() => {
|
|
12698
14113
|
});
|
|
12699
|
-
const
|
|
14114
|
+
const closeFloatingPanelOnlyRef = useRef9(() => {
|
|
12700
14115
|
});
|
|
12701
|
-
const reselectNavigationItemRef =
|
|
14116
|
+
const reselectNavigationItemRef = useRef9(() => {
|
|
12702
14117
|
});
|
|
12703
|
-
const commitNavigationTextEditRef =
|
|
14118
|
+
const commitNavigationTextEditRef = useRef9(() => {
|
|
12704
14119
|
});
|
|
12705
|
-
const handleDeleteSelectedRef =
|
|
12706
|
-
const runPendingDeleteUndoRef =
|
|
12707
|
-
const isFooterFrameSelectionRef =
|
|
12708
|
-
const refreshActiveCommandsRef =
|
|
14120
|
+
const handleDeleteSelectedRef = useRef9(() => false);
|
|
14121
|
+
const runPendingDeleteUndoRef = useRef9(() => false);
|
|
14122
|
+
const isFooterFrameSelectionRef = useRef9(false);
|
|
14123
|
+
const refreshActiveCommandsRef = useRef9(() => {
|
|
12709
14124
|
});
|
|
12710
|
-
const postToParentRef =
|
|
14125
|
+
const postToParentRef = useRef9(postToParent2);
|
|
12711
14126
|
postToParentRef.current = postToParent2;
|
|
12712
|
-
const aiSectionApiRef =
|
|
12713
|
-
const sectionsLoadedRef =
|
|
12714
|
-
const pendingScheduleConfigRequests =
|
|
12715
|
-
const [toolbarRect, setToolbarRect] =
|
|
12716
|
-
const [toolbarVariant, setToolbarVariant] =
|
|
12717
|
-
const toolbarVariantRef =
|
|
14127
|
+
const aiSectionApiRef = useRef9(null);
|
|
14128
|
+
const sectionsLoadedRef = useRef9(false);
|
|
14129
|
+
const pendingScheduleConfigRequests = useRef9([]);
|
|
14130
|
+
const [toolbarRect, setToolbarRect] = useState11(null);
|
|
14131
|
+
const [toolbarVariant, setToolbarVariant] = useState11("none");
|
|
14132
|
+
const toolbarVariantRef = useRef9("none");
|
|
12718
14133
|
toolbarVariantRef.current = toolbarVariant;
|
|
12719
|
-
const [selectedIsCta, setSelectedIsCta] =
|
|
12720
|
-
const [
|
|
12721
|
-
const [
|
|
12722
|
-
const [
|
|
12723
|
-
const [
|
|
12724
|
-
const [
|
|
12725
|
-
const [
|
|
12726
|
-
const [
|
|
12727
|
-
const
|
|
12728
|
-
const [
|
|
12729
|
-
const
|
|
12730
|
-
const [
|
|
12731
|
-
const
|
|
12732
|
-
const [
|
|
12733
|
-
const [
|
|
12734
|
-
|
|
12735
|
-
|
|
14134
|
+
const [selectedIsCta, setSelectedIsCta] = useState11(false);
|
|
14135
|
+
const [selectedIsSocial, setSelectedIsSocial] = useState11(false);
|
|
14136
|
+
const [selectedIsSocialsRow, setSelectedIsSocialsRow] = useState11(false);
|
|
14137
|
+
const [reorderHrefKey, setReorderHrefKey] = useState11(null);
|
|
14138
|
+
const [reorderDragDisabled, setReorderDragDisabled] = useState11(false);
|
|
14139
|
+
const [toggleState, setToggleState] = useState11(null);
|
|
14140
|
+
const [maxBadge, setMaxBadge] = useState11(null);
|
|
14141
|
+
const [activeCommands, setActiveCommands] = useState11(/* @__PURE__ */ new Set());
|
|
14142
|
+
const [sectionGap, setSectionGap] = useState11(null);
|
|
14143
|
+
const [toolbarShowEditLink, setToolbarShowEditLink] = useState11(false);
|
|
14144
|
+
const hoveredNavContainerRef = useRef9(null);
|
|
14145
|
+
const [hoveredNavContainerRect, setHoveredNavContainerRect] = useState11(null);
|
|
14146
|
+
const hoveredItemElRef = useRef9(null);
|
|
14147
|
+
const [hoveredItemRect, setHoveredItemRect] = useState11(null);
|
|
14148
|
+
const [hoveredTextRect, setHoveredTextRect] = useState11(null);
|
|
14149
|
+
useEffect12(() => {
|
|
14150
|
+
const sync = () => {
|
|
14151
|
+
const el = document.querySelector(
|
|
14152
|
+
"[data-ohw-hovered]:not([contenteditable]):not([data-ohw-href-key])"
|
|
14153
|
+
);
|
|
14154
|
+
const target = el && !el.closest("[data-ohw-href-key]") ? el : null;
|
|
14155
|
+
if (!target) {
|
|
14156
|
+
setHoveredTextRect(null);
|
|
14157
|
+
return;
|
|
14158
|
+
}
|
|
14159
|
+
const r2 = target.getBoundingClientRect();
|
|
14160
|
+
setHoveredTextRect(new DOMRect(r2.x - TEXT_HOVER_SIDE_PAD, r2.y, r2.width + TEXT_HOVER_SIDE_PAD * 2, r2.height));
|
|
14161
|
+
};
|
|
14162
|
+
const observer = new MutationObserver(sync);
|
|
14163
|
+
observer.observe(document.documentElement, {
|
|
14164
|
+
attributes: true,
|
|
14165
|
+
attributeFilter: ["data-ohw-hovered"],
|
|
14166
|
+
subtree: true
|
|
14167
|
+
});
|
|
14168
|
+
return () => observer.disconnect();
|
|
14169
|
+
}, []);
|
|
14170
|
+
const siblingHintElRef = useRef9(null);
|
|
14171
|
+
const [siblingHintRect, setSiblingHintRect] = useState11(null);
|
|
14172
|
+
const [siblingHintRects, setSiblingHintRects] = useState11([]);
|
|
14173
|
+
const [isItemDragging, setIsItemDragging] = useState11(false);
|
|
14174
|
+
const [isFooterFrameSelection, setIsFooterFrameSelection] = useState11(false);
|
|
12736
14175
|
isFooterFrameSelectionRef.current = isFooterFrameSelection;
|
|
12737
|
-
const [navDropdownPreviewOpen, setNavDropdownPreviewOpen] =
|
|
12738
|
-
const [footerHeadingVisible, setFooterHeadingVisible] =
|
|
12739
|
-
const footerDragRef =
|
|
12740
|
-
const [footerDropSlots, setFooterDropSlots] =
|
|
12741
|
-
const [activeFooterDropIndex, setActiveFooterDropIndex] =
|
|
12742
|
-
const [draggedItemRect, setDraggedItemRect] =
|
|
12743
|
-
const footerPointerDragRef =
|
|
12744
|
-
const suppressNextClickRef =
|
|
12745
|
-
const suppressClickUntilRef =
|
|
12746
|
-
const [linkPopover, setLinkPopover] =
|
|
12747
|
-
const linkPopoverSessionRef =
|
|
12748
|
-
const addNavAfterAnchorRef =
|
|
12749
|
-
const editContentRef =
|
|
12750
|
-
const aiSectionsRef =
|
|
12751
|
-
const
|
|
12752
|
-
const
|
|
12753
|
-
const [
|
|
12754
|
-
const
|
|
12755
|
-
const
|
|
12756
|
-
const
|
|
12757
|
-
const
|
|
12758
|
-
const
|
|
14176
|
+
const [navDropdownPreviewOpen, setNavDropdownPreviewOpen] = useState11(null);
|
|
14177
|
+
const [footerHeadingVisible, setFooterHeadingVisible] = useState11(null);
|
|
14178
|
+
const footerDragRef = useRef9(null);
|
|
14179
|
+
const [footerDropSlots, setFooterDropSlots] = useState11([]);
|
|
14180
|
+
const [activeFooterDropIndex, setActiveFooterDropIndex] = useState11(null);
|
|
14181
|
+
const [draggedItemRect, setDraggedItemRect] = useState11(null);
|
|
14182
|
+
const footerPointerDragRef = useRef9(null);
|
|
14183
|
+
const suppressNextClickRef = useRef9(false);
|
|
14184
|
+
const suppressClickUntilRef = useRef9(0);
|
|
14185
|
+
const [linkPopover, setLinkPopover] = useState11(null);
|
|
14186
|
+
const linkPopoverSessionRef = useRef9(null);
|
|
14187
|
+
const addNavAfterAnchorRef = useRef9(null);
|
|
14188
|
+
const editContentRef = useRef9({});
|
|
14189
|
+
const aiSectionsRef = useRef9("");
|
|
14190
|
+
const brandKitRef = useRef9("");
|
|
14191
|
+
const pendingDeleteUndoRef = useRef9(null);
|
|
14192
|
+
const [floatingPanel, setFloatingPanel] = useState11(null);
|
|
14193
|
+
const floatingPanelOpenRef = useRef9(false);
|
|
14194
|
+
const setFloatingPanelRef = useRef9(setFloatingPanel);
|
|
14195
|
+
const [floatingPanelPos, setFloatingPanelPos] = useState11(null);
|
|
14196
|
+
const [logoSizeDraft, setLogoSizeDraft] = useState11(null);
|
|
14197
|
+
const [editorViewport, setEditorViewport] = useState11("desktop");
|
|
14198
|
+
const [parentScrollSnap, setParentScrollSnap] = useState11(null);
|
|
14199
|
+
const [sitePages, setSitePages] = useState11([]);
|
|
14200
|
+
const [sectionsByPath, setSectionsByPath] = useState11({});
|
|
14201
|
+
const sectionsPrefetchGenRef = useRef9(0);
|
|
14202
|
+
const setLinkPopoverRef = useRef9(setLinkPopover);
|
|
14203
|
+
const linkPopoverPanelRef = useRef9(null);
|
|
14204
|
+
const linkPopoverOpenRef = useRef9(false);
|
|
14205
|
+
const linkPopoverGraceUntilRef = useRef9(0);
|
|
12759
14206
|
setLinkPopoverRef.current = setLinkPopover;
|
|
14207
|
+
setFloatingPanelRef.current = setFloatingPanel;
|
|
12760
14208
|
linkPopoverSessionRef.current = linkPopover;
|
|
14209
|
+
floatingPanelOpenRef.current = Boolean(floatingPanel);
|
|
14210
|
+
useEffect12(() => {
|
|
14211
|
+
const syncViewport = () => {
|
|
14212
|
+
const next = window.innerWidth <= 480 ? "mobile" : "desktop";
|
|
14213
|
+
setEditorViewport((prev) => prev === next ? prev : next);
|
|
14214
|
+
};
|
|
14215
|
+
syncViewport();
|
|
14216
|
+
window.addEventListener("resize", syncViewport);
|
|
14217
|
+
return () => window.removeEventListener("resize", syncViewport);
|
|
14218
|
+
}, []);
|
|
12761
14219
|
const {
|
|
12762
14220
|
navDragRef,
|
|
12763
14221
|
navDropSlots,
|
|
@@ -12793,7 +14251,7 @@ function OhhwellsBridge() {
|
|
|
12793
14251
|
const bumpLinkPopoverGrace = () => {
|
|
12794
14252
|
linkPopoverGraceUntilRef.current = Date.now() + 350;
|
|
12795
14253
|
};
|
|
12796
|
-
const runSectionsPrefetch =
|
|
14254
|
+
const runSectionsPrefetch = useCallback7((pages) => {
|
|
12797
14255
|
if (!isEditMode || shouldUseDevFixtures() || pages.length === 0) return;
|
|
12798
14256
|
const gen = ++sectionsPrefetchGenRef.current;
|
|
12799
14257
|
const paths = pages.map((p) => p.path);
|
|
@@ -12812,9 +14270,9 @@ function OhhwellsBridge() {
|
|
|
12812
14270
|
);
|
|
12813
14271
|
});
|
|
12814
14272
|
}, [isEditMode, pathname]);
|
|
12815
|
-
const runSectionsPrefetchRef =
|
|
14273
|
+
const runSectionsPrefetchRef = useRef9(runSectionsPrefetch);
|
|
12816
14274
|
runSectionsPrefetchRef.current = runSectionsPrefetch;
|
|
12817
|
-
|
|
14275
|
+
useEffect12(() => {
|
|
12818
14276
|
if (!linkPopover) {
|
|
12819
14277
|
document.documentElement.removeAttribute("data-ohw-link-popover-open");
|
|
12820
14278
|
return;
|
|
@@ -12842,7 +14300,7 @@ function OhhwellsBridge() {
|
|
|
12842
14300
|
document.documentElement.removeAttribute("data-ohw-link-popover-open");
|
|
12843
14301
|
};
|
|
12844
14302
|
}, [linkPopover, postToParent2]);
|
|
12845
|
-
|
|
14303
|
+
useEffect12(() => {
|
|
12846
14304
|
if (!isEditMode) return;
|
|
12847
14305
|
const useFixtures = shouldUseDevFixtures();
|
|
12848
14306
|
if (useFixtures) {
|
|
@@ -12866,14 +14324,14 @@ function OhhwellsBridge() {
|
|
|
12866
14324
|
if (!useFixtures) postToParent2({ type: "ow:request-site-pages" });
|
|
12867
14325
|
return () => window.removeEventListener("message", onSitePages);
|
|
12868
14326
|
}, [isEditMode, postToParent2]);
|
|
12869
|
-
|
|
14327
|
+
useEffect12(() => {
|
|
12870
14328
|
if (!isEditMode || shouldUseDevFixtures()) return;
|
|
12871
14329
|
void loadAllSectionsManifest().then((manifest) => {
|
|
12872
14330
|
if (Object.keys(manifest).length === 0) return;
|
|
12873
14331
|
setSectionsByPath((prev) => ({ ...manifest, ...prev }));
|
|
12874
14332
|
});
|
|
12875
14333
|
}, [isEditMode]);
|
|
12876
|
-
|
|
14334
|
+
useEffect12(() => {
|
|
12877
14335
|
const update = () => {
|
|
12878
14336
|
const el = activeElRef.current ?? selectedElRef.current;
|
|
12879
14337
|
if (el) setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
|
|
@@ -12897,10 +14355,10 @@ function OhhwellsBridge() {
|
|
|
12897
14355
|
vvp.removeEventListener("resize", update);
|
|
12898
14356
|
};
|
|
12899
14357
|
}, []);
|
|
12900
|
-
const refreshStateRules =
|
|
14358
|
+
const refreshStateRules = useCallback7(() => {
|
|
12901
14359
|
editStylesRef.current?.forceHover && (editStylesRef.current.forceHover.textContent = collectStateRules());
|
|
12902
14360
|
}, []);
|
|
12903
|
-
const processConfigRequest =
|
|
14361
|
+
const processConfigRequest = useCallback7((insertAfterVal) => {
|
|
12904
14362
|
const tracker = getSectionsTracker();
|
|
12905
14363
|
let entries = [];
|
|
12906
14364
|
try {
|
|
@@ -12923,7 +14381,7 @@ function OhhwellsBridge() {
|
|
|
12923
14381
|
}
|
|
12924
14382
|
window.postMessage({ type: "ow:schedule-config", insertAfter: insertAfterVal, scheduleId: null }, "*");
|
|
12925
14383
|
}, [isEditMode]);
|
|
12926
|
-
const deactivate =
|
|
14384
|
+
const deactivate = useCallback7(() => {
|
|
12927
14385
|
const el = activeElRef.current;
|
|
12928
14386
|
if (!el) return;
|
|
12929
14387
|
const key = el.dataset.ohwKey;
|
|
@@ -12956,17 +14414,19 @@ function OhhwellsBridge() {
|
|
|
12956
14414
|
setToolbarShowEditLink(false);
|
|
12957
14415
|
postToParent2({ type: "ow:exit-edit" });
|
|
12958
14416
|
}, [postToParent2]);
|
|
12959
|
-
const clearSelectedAttr =
|
|
14417
|
+
const clearSelectedAttr = useCallback7(() => {
|
|
12960
14418
|
document.querySelectorAll("[data-ohw-selected]").forEach((el) => {
|
|
12961
14419
|
el.removeAttribute("data-ohw-selected");
|
|
12962
14420
|
});
|
|
12963
14421
|
}, []);
|
|
12964
|
-
const deselect =
|
|
14422
|
+
const deselect = useCallback7(() => {
|
|
12965
14423
|
clearSelectedAttr();
|
|
12966
14424
|
selectedElRef.current = null;
|
|
12967
14425
|
selectedHrefKeyRef.current = null;
|
|
12968
14426
|
selectedFooterColAttrRef.current = null;
|
|
12969
14427
|
setSelectedIsCta(false);
|
|
14428
|
+
setSelectedIsSocial(false);
|
|
14429
|
+
setSelectedIsSocialsRow(false);
|
|
12970
14430
|
setReorderHrefKey(null);
|
|
12971
14431
|
setReorderDragDisabled(false);
|
|
12972
14432
|
setIsFooterFrameSelection(false);
|
|
@@ -12978,17 +14438,21 @@ function OhhwellsBridge() {
|
|
|
12978
14438
|
setIsItemDragging(false);
|
|
12979
14439
|
hoveredNavContainerRef.current = null;
|
|
12980
14440
|
setHoveredNavContainerRect(null);
|
|
14441
|
+
hoveredItemElRef.current = null;
|
|
14442
|
+
setHoveredItemRect(null);
|
|
14443
|
+
setFloatingPanel(null);
|
|
14444
|
+
setLogoSizeDraft(null);
|
|
12981
14445
|
if (!activeElRef.current) {
|
|
12982
14446
|
setNavGroupForceOpen(null, false);
|
|
12983
14447
|
setToolbarRect(null);
|
|
12984
14448
|
setToolbarVariant("none");
|
|
12985
14449
|
}
|
|
12986
14450
|
}, [clearSelectedAttr]);
|
|
12987
|
-
const markSelected =
|
|
14451
|
+
const markSelected = useCallback7((el) => {
|
|
12988
14452
|
clearSelectedAttr();
|
|
12989
14453
|
el.setAttribute("data-ohw-selected", "");
|
|
12990
14454
|
}, [clearSelectedAttr]);
|
|
12991
|
-
const resolveHrefKeyElement =
|
|
14455
|
+
const resolveHrefKeyElement = useCallback7((hrefKey) => {
|
|
12992
14456
|
if (isFooterHrefKey(hrefKey)) {
|
|
12993
14457
|
return document.querySelector(
|
|
12994
14458
|
`footer [data-ohw-href-key="${CSS.escape(hrefKey)}"]`
|
|
@@ -13003,7 +14467,7 @@ function OhhwellsBridge() {
|
|
|
13003
14467
|
`[data-ohw-href-key="${CSS.escape(hrefKey)}"]`
|
|
13004
14468
|
);
|
|
13005
14469
|
}, []);
|
|
13006
|
-
const resyncSelectedNavigationItem =
|
|
14470
|
+
const resyncSelectedNavigationItem = useCallback7(() => {
|
|
13007
14471
|
const hrefKey = selectedHrefKeyRef.current;
|
|
13008
14472
|
if (hrefKey) {
|
|
13009
14473
|
const link = resolveHrefKeyElement(hrefKey);
|
|
@@ -13041,12 +14505,14 @@ function OhhwellsBridge() {
|
|
|
13041
14505
|
);
|
|
13042
14506
|
}
|
|
13043
14507
|
}, [resolveHrefKeyElement]);
|
|
13044
|
-
const reselectNavigationItem =
|
|
14508
|
+
const reselectNavigationItem = useCallback7((navAnchor) => {
|
|
13045
14509
|
selectedElRef.current = navAnchor;
|
|
13046
14510
|
selectedHrefKeyRef.current = navAnchor.getAttribute("data-ohw-href-key");
|
|
13047
14511
|
selectedFooterColAttrRef.current = null;
|
|
13048
14512
|
markSelected(navAnchor);
|
|
13049
14513
|
setSelectedIsCta(isCtaButton(navAnchor));
|
|
14514
|
+
setSelectedIsSocial(Boolean(getSocialItem(navAnchor)));
|
|
14515
|
+
setSelectedIsSocialsRow(false);
|
|
13050
14516
|
const isDropdownTrigger = !isNestedNavChild(navAnchor) && (navItemHasDropdownChildren(navAnchor) || navItemOwnsDropdownPanel(navAnchor));
|
|
13051
14517
|
if (isNestedNavChild(navAnchor)) {
|
|
13052
14518
|
setNavGroupForceOpen(navAnchor, true);
|
|
@@ -13070,7 +14536,7 @@ function OhhwellsBridge() {
|
|
|
13070
14536
|
setToolbarShowEditLink(false);
|
|
13071
14537
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
13072
14538
|
}, [markSelected]);
|
|
13073
|
-
const commitNavigationTextEdit =
|
|
14539
|
+
const commitNavigationTextEdit = useCallback7((navAnchor) => {
|
|
13074
14540
|
const el = activeElRef.current;
|
|
13075
14541
|
if (!el) return;
|
|
13076
14542
|
const key = el.dataset.ohwKey;
|
|
@@ -13097,7 +14563,7 @@ function OhhwellsBridge() {
|
|
|
13097
14563
|
postToParent2({ type: "ow:exit-edit" });
|
|
13098
14564
|
reselectNavigationItem(navAnchor);
|
|
13099
14565
|
}, [postToParent2, reselectNavigationItem]);
|
|
13100
|
-
const handleAddTopLevelNavItem =
|
|
14566
|
+
const handleAddTopLevelNavItem = useCallback7(() => {
|
|
13101
14567
|
const items = listNavbarRootItems();
|
|
13102
14568
|
addNavAfterAnchorRef.current = items[items.length - 1] ?? null;
|
|
13103
14569
|
deselectRef.current();
|
|
@@ -13109,7 +14575,7 @@ function OhhwellsBridge() {
|
|
|
13109
14575
|
intent: "add-nav"
|
|
13110
14576
|
});
|
|
13111
14577
|
}, []);
|
|
13112
|
-
const maybeWarnNavLinkDropdownConflict =
|
|
14578
|
+
const maybeWarnNavLinkDropdownConflict = useCallback7(
|
|
13113
14579
|
(anchor) => {
|
|
13114
14580
|
if (!isNavbarHrefKey(anchor.getAttribute("data-ohw-href-key"))) return;
|
|
13115
14581
|
if (!navDropdownsOpenOnClick()) return;
|
|
@@ -13122,7 +14588,7 @@ function OhhwellsBridge() {
|
|
|
13122
14588
|
},
|
|
13123
14589
|
[postToParent2]
|
|
13124
14590
|
);
|
|
13125
|
-
const handleNavDropdownOpenChange =
|
|
14591
|
+
const handleNavDropdownOpenChange = useCallback7((open) => {
|
|
13126
14592
|
const selected = selectedElRef.current;
|
|
13127
14593
|
if (!selected || !isNavigationItem2(selected)) return;
|
|
13128
14594
|
setNavGroupForceOpen(selected, open);
|
|
@@ -13134,7 +14600,7 @@ function OhhwellsBridge() {
|
|
|
13134
14600
|
}
|
|
13135
14601
|
});
|
|
13136
14602
|
}, []);
|
|
13137
|
-
const handleFooterHeadingVisibleChange =
|
|
14603
|
+
const handleFooterHeadingVisibleChange = useCallback7(
|
|
13138
14604
|
(visible) => {
|
|
13139
14605
|
const selected = selectedElRef.current;
|
|
13140
14606
|
if (!selected || !isFooterFrameSelectionRef.current) return;
|
|
@@ -13158,7 +14624,7 @@ function OhhwellsBridge() {
|
|
|
13158
14624
|
},
|
|
13159
14625
|
[postToParent2]
|
|
13160
14626
|
);
|
|
13161
|
-
const enterEditOnNewItem =
|
|
14627
|
+
const enterEditOnNewItem = useCallback7((anchor) => {
|
|
13162
14628
|
const label = anchor.querySelector('[data-ohw-editable="text"]');
|
|
13163
14629
|
if (!label) {
|
|
13164
14630
|
selectRef.current(anchor);
|
|
@@ -13167,14 +14633,42 @@ function OhhwellsBridge() {
|
|
|
13167
14633
|
setNavGroupForceOpen(anchor, true);
|
|
13168
14634
|
activateRef.current(label);
|
|
13169
14635
|
}, []);
|
|
13170
|
-
const handleAddChildItem =
|
|
14636
|
+
const handleAddChildItem = useCallback7(() => {
|
|
13171
14637
|
const selected = selectedElRef.current;
|
|
13172
14638
|
if (!selected) return;
|
|
14639
|
+
const socialsRow = isSocialsRow(selected) ? selected : findSocialsRow(selected);
|
|
14640
|
+
if (socialsRow) {
|
|
14641
|
+
const after = getSocialItem(selected);
|
|
14642
|
+
const result2 = insertSocialItem(socialsRow, after, editContentRef.current);
|
|
14643
|
+
if (!result2) return;
|
|
14644
|
+
const orderJson = JSON.stringify(result2.order);
|
|
14645
|
+
applySocialsDisplayToRow(socialsRow, socialsDisplayFor(socialsRow, editContentRef.current));
|
|
14646
|
+
editContentRef.current = { ...editContentRef.current, [SOCIALS_ORDER_KEY]: orderJson };
|
|
14647
|
+
postToParent2({ type: "ow:change", nodes: [{ key: SOCIALS_ORDER_KEY, text: orderJson }] });
|
|
14648
|
+
postToParentRef.current({
|
|
14649
|
+
type: "ow:social-pick",
|
|
14650
|
+
hrefKey: result2.hrefKey,
|
|
14651
|
+
iconKey: result2.iconKey,
|
|
14652
|
+
url: "",
|
|
14653
|
+
iconStyle: detectIconStyle(result2.item),
|
|
14654
|
+
platformId: "",
|
|
14655
|
+
// Lets the editor undo the insert if the dialog is dismissed: an item that was never given
|
|
14656
|
+
// an address should not survive a Cancel.
|
|
14657
|
+
isNew: true
|
|
14658
|
+
});
|
|
14659
|
+
return;
|
|
14660
|
+
}
|
|
13173
14661
|
if (toolbarVariantRef.current === "select-frame" && isFooterFrameSelection) {
|
|
13174
|
-
|
|
13175
|
-
}
|
|
13176
|
-
const column = (selected.hasAttribute("data-ohw-footer-col") ? selected : null) ?? selected.closest("[data-ohw-footer-col]") ?? (listFooterColumns().includes(selected) ? selected : null);
|
|
14662
|
+
const column = resolveFooterColumnForAdd(selected);
|
|
13177
14663
|
if (!column) return;
|
|
14664
|
+
if (!canAddFooterItem(column)) {
|
|
14665
|
+
postToParent2({
|
|
14666
|
+
type: "ow:toast",
|
|
14667
|
+
title: `Maximum ${MAX_FOOTER_ITEMS_PER_COLUMN} items per column`,
|
|
14668
|
+
toastType: "error"
|
|
14669
|
+
});
|
|
14670
|
+
return;
|
|
14671
|
+
}
|
|
13178
14672
|
const result2 = insertFooterItem(column, "/", "New link", null);
|
|
13179
14673
|
applyLinkByKey(result2.hrefKey, result2.href);
|
|
13180
14674
|
document.querySelectorAll(`[data-ohw-key="${result2.labelKey}"]`).forEach((el) => {
|
|
@@ -13243,7 +14737,7 @@ function OhhwellsBridge() {
|
|
|
13243
14737
|
enterEditOnNewItem(result.anchor);
|
|
13244
14738
|
});
|
|
13245
14739
|
}, [enterEditOnNewItem, isFooterFrameSelection, maybeWarnNavLinkDropdownConflict, postToParent2]);
|
|
13246
|
-
const handleAddFooterColumn =
|
|
14740
|
+
const handleAddFooterColumn = useCallback7(() => {
|
|
13247
14741
|
if (!canAddFooterColumn()) {
|
|
13248
14742
|
postToParent2({
|
|
13249
14743
|
type: "ow:toast",
|
|
@@ -13264,7 +14758,7 @@ function OhhwellsBridge() {
|
|
|
13264
14758
|
selectRef.current(result.firstLink);
|
|
13265
14759
|
});
|
|
13266
14760
|
}, [postToParent2]);
|
|
13267
|
-
const clearFooterDragVisuals =
|
|
14761
|
+
const clearFooterDragVisuals = useCallback7(() => {
|
|
13268
14762
|
footerDragRef.current = null;
|
|
13269
14763
|
setSiblingHintRects([]);
|
|
13270
14764
|
setFooterDropSlots([]);
|
|
@@ -13273,7 +14767,7 @@ function OhhwellsBridge() {
|
|
|
13273
14767
|
setIsItemDragging(false);
|
|
13274
14768
|
unlockFooterDragInteraction();
|
|
13275
14769
|
}, []);
|
|
13276
|
-
const refreshFooterDragVisuals =
|
|
14770
|
+
const refreshFooterDragVisuals = useCallback7((session, activeSlot, clientX, clientY) => {
|
|
13277
14771
|
const dragged = session.draggedEl;
|
|
13278
14772
|
setDraggedItemRect(dragged.getBoundingClientRect());
|
|
13279
14773
|
if (typeof clientX === "number" && typeof clientY === "number") {
|
|
@@ -13282,6 +14776,13 @@ function OhhwellsBridge() {
|
|
|
13282
14776
|
}
|
|
13283
14777
|
session.activeSlot = activeSlot;
|
|
13284
14778
|
setSiblingHintRects([]);
|
|
14779
|
+
if (session.kind === "social") {
|
|
14780
|
+
const slots2 = session.hrefKey ? buildSocialDropSlotsForKey(session.hrefKey) : [];
|
|
14781
|
+
setFooterDropSlots(slots2);
|
|
14782
|
+
const activeIdx2 = activeSlot ? slots2.findIndex((s) => s.insertIndex === activeSlot.insertIndex) : -1;
|
|
14783
|
+
setActiveFooterDropIndex(activeIdx2 >= 0 ? activeIdx2 : null);
|
|
14784
|
+
return;
|
|
14785
|
+
}
|
|
13285
14786
|
if (session.kind === "link") {
|
|
13286
14787
|
const columns = listFooterColumns();
|
|
13287
14788
|
const slots2 = [];
|
|
@@ -13298,13 +14799,13 @@ function OhhwellsBridge() {
|
|
|
13298
14799
|
const activeIdx = activeSlot ? slots.findIndex((s) => s.insertIndex === activeSlot.insertIndex) : -1;
|
|
13299
14800
|
setActiveFooterDropIndex(activeIdx >= 0 ? activeIdx : null);
|
|
13300
14801
|
}, []);
|
|
13301
|
-
const refreshFooterDragVisualsRef =
|
|
14802
|
+
const refreshFooterDragVisualsRef = useRef9(refreshFooterDragVisuals);
|
|
13302
14803
|
refreshFooterDragVisualsRef.current = refreshFooterDragVisuals;
|
|
13303
|
-
const commitFooterDragRef =
|
|
14804
|
+
const commitFooterDragRef = useRef9(() => {
|
|
13304
14805
|
});
|
|
13305
|
-
const beginFooterDragRef =
|
|
14806
|
+
const beginFooterDragRef = useRef9(() => {
|
|
13306
14807
|
});
|
|
13307
|
-
const beginFooterDrag =
|
|
14808
|
+
const beginFooterDrag = useCallback7(
|
|
13308
14809
|
(session) => {
|
|
13309
14810
|
const rect = session.draggedEl.getBoundingClientRect();
|
|
13310
14811
|
session.lastClientX = session.lastClientX || rect.left + rect.width / 2;
|
|
@@ -13318,13 +14819,13 @@ function OhhwellsBridge() {
|
|
|
13318
14819
|
if (session.wasSelected && selectedElRef.current === session.draggedEl) {
|
|
13319
14820
|
setToolbarRect(rect);
|
|
13320
14821
|
}
|
|
13321
|
-
const initialSlot = session.kind === "link" && session.hrefKey ? hitTestLinkDropSlot(session.lastClientX, session.lastClientY, session.hrefKey) : hitTestColumnDropSlot(session.lastClientX, session.lastClientY);
|
|
14822
|
+
const initialSlot = session.kind === "social" && session.hrefKey ? hitTestSocialDropSlot(session.lastClientX, session.lastClientY, session.hrefKey) : session.kind === "link" && session.hrefKey ? hitTestLinkDropSlot(session.lastClientX, session.lastClientY, session.hrefKey) : hitTestColumnDropSlot(session.lastClientX, session.lastClientY);
|
|
13322
14823
|
refreshFooterDragVisuals(session, initialSlot, session.lastClientX, session.lastClientY);
|
|
13323
14824
|
},
|
|
13324
14825
|
[refreshFooterDragVisuals]
|
|
13325
14826
|
);
|
|
13326
14827
|
beginFooterDragRef.current = beginFooterDrag;
|
|
13327
|
-
const commitFooterDrag =
|
|
14828
|
+
const commitFooterDrag = useCallback7(
|
|
13328
14829
|
(clientX, clientY) => {
|
|
13329
14830
|
const session = footerDragRef.current;
|
|
13330
14831
|
if (!session) {
|
|
@@ -13334,8 +14835,11 @@ function OhhwellsBridge() {
|
|
|
13334
14835
|
const x = typeof clientX === "number" && (clientX !== 0 || clientY !== 0) ? clientX : session.lastClientX;
|
|
13335
14836
|
const y = typeof clientY === "number" && (clientX !== 0 || clientY !== 0) ? clientY : session.lastClientY;
|
|
13336
14837
|
let nextOrder = null;
|
|
13337
|
-
|
|
13338
|
-
|
|
14838
|
+
let nextSocialsOrder = null;
|
|
14839
|
+
const slot = session.activeSlot ?? (session.kind === "social" && session.hrefKey ? hitTestSocialDropSlot(x, y, session.hrefKey) : session.kind === "link" && session.hrefKey ? hitTestLinkDropSlot(x, y, session.hrefKey) : session.kind === "column" ? hitTestColumnDropSlot(x, y) : null);
|
|
14840
|
+
if (session.kind === "social" && session.hrefKey && slot) {
|
|
14841
|
+
nextSocialsOrder = planSocialMove(session.hrefKey, slot.insertIndex);
|
|
14842
|
+
} else if (session.kind === "link" && session.hrefKey && slot) {
|
|
13339
14843
|
nextOrder = planFooterLinkMove(session.hrefKey, slot.columnIndex, slot.insertIndex);
|
|
13340
14844
|
} else if (session.kind === "column" && slot) {
|
|
13341
14845
|
nextOrder = planFooterColumnMove(session.sourceColumnIndex, slot.insertIndex);
|
|
@@ -13393,6 +14897,27 @@ function OhhwellsBridge() {
|
|
|
13393
14897
|
}
|
|
13394
14898
|
deselectRef.current();
|
|
13395
14899
|
};
|
|
14900
|
+
if (nextSocialsOrder) {
|
|
14901
|
+
const orderJson = JSON.stringify(nextSocialsOrder);
|
|
14902
|
+
editContentRef.current = { ...editContentRef.current, [SOCIALS_ORDER_KEY]: orderJson };
|
|
14903
|
+
applySocialsOrder(nextSocialsOrder);
|
|
14904
|
+
postToParentRef.current({
|
|
14905
|
+
type: "ow:change",
|
|
14906
|
+
nodes: [{ key: SOCIALS_ORDER_KEY, text: orderJson }]
|
|
14907
|
+
});
|
|
14908
|
+
applySelectionAfterDrop();
|
|
14909
|
+
clearFooterDragVisuals();
|
|
14910
|
+
const reapply = nextSocialsOrder;
|
|
14911
|
+
requestAnimationFrame(() => {
|
|
14912
|
+
if (editContentRef.current[SOCIALS_ORDER_KEY] === orderJson) applySocialsOrder(reapply);
|
|
14913
|
+
applySelectionAfterDrop();
|
|
14914
|
+
requestAnimationFrame(() => {
|
|
14915
|
+
if (editContentRef.current[SOCIALS_ORDER_KEY] === orderJson) applySocialsOrder(reapply);
|
|
14916
|
+
resyncSelectedNavigationItem();
|
|
14917
|
+
});
|
|
14918
|
+
});
|
|
14919
|
+
return;
|
|
14920
|
+
}
|
|
13396
14921
|
if (nextOrder) {
|
|
13397
14922
|
const orderJson = JSON.stringify(nextOrder);
|
|
13398
14923
|
editContentRef.current = {
|
|
@@ -13428,10 +14953,25 @@ function OhhwellsBridge() {
|
|
|
13428
14953
|
[clearFooterDragVisuals, resolveHrefKeyElement, resyncSelectedNavigationItem]
|
|
13429
14954
|
);
|
|
13430
14955
|
commitFooterDragRef.current = commitFooterDrag;
|
|
13431
|
-
const startFooterLinkDrag =
|
|
14956
|
+
const startFooterLinkDrag = useCallback7(
|
|
13432
14957
|
(anchor, clientX, clientY, wasSelected) => {
|
|
13433
14958
|
const hrefKey = anchor.getAttribute("data-ohw-href-key");
|
|
13434
|
-
if (!hrefKey
|
|
14959
|
+
if (!hrefKey) return false;
|
|
14960
|
+
if (getSocialItem(anchor)) {
|
|
14961
|
+
beginFooterDrag({
|
|
14962
|
+
kind: "social",
|
|
14963
|
+
hrefKey,
|
|
14964
|
+
columnEl: null,
|
|
14965
|
+
sourceColumnIndex: 0,
|
|
14966
|
+
wasSelected,
|
|
14967
|
+
draggedEl: anchor,
|
|
14968
|
+
lastClientX: clientX,
|
|
14969
|
+
lastClientY: clientY,
|
|
14970
|
+
activeSlot: null
|
|
14971
|
+
});
|
|
14972
|
+
return true;
|
|
14973
|
+
}
|
|
14974
|
+
if (!isFooterHrefKey(hrefKey)) return false;
|
|
13435
14975
|
const column = findFooterColumnForLink(anchor);
|
|
13436
14976
|
const columns = listFooterColumns();
|
|
13437
14977
|
beginFooterDrag({
|
|
@@ -13449,7 +14989,7 @@ function OhhwellsBridge() {
|
|
|
13449
14989
|
},
|
|
13450
14990
|
[beginFooterDrag]
|
|
13451
14991
|
);
|
|
13452
|
-
const startFooterColumnDrag =
|
|
14992
|
+
const startFooterColumnDrag = useCallback7(
|
|
13453
14993
|
(columnEl, clientX, clientY, wasSelected) => {
|
|
13454
14994
|
const columns = listFooterColumns();
|
|
13455
14995
|
const idx = columns.indexOf(columnEl);
|
|
@@ -13469,7 +15009,7 @@ function OhhwellsBridge() {
|
|
|
13469
15009
|
},
|
|
13470
15010
|
[beginFooterDrag]
|
|
13471
15011
|
);
|
|
13472
|
-
const handleItemDragStart =
|
|
15012
|
+
const handleItemDragStart = useCallback7(
|
|
13473
15013
|
(e) => {
|
|
13474
15014
|
const selected = selectedElRef.current;
|
|
13475
15015
|
if (!selected) {
|
|
@@ -13489,7 +15029,7 @@ function OhhwellsBridge() {
|
|
|
13489
15029
|
},
|
|
13490
15030
|
[startFooterColumnDrag, startFooterLinkDrag, startNavLinkDrag]
|
|
13491
15031
|
);
|
|
13492
|
-
const handleItemDragEnd =
|
|
15032
|
+
const handleItemDragEnd = useCallback7(
|
|
13493
15033
|
(e) => {
|
|
13494
15034
|
if (footerDragRef.current) {
|
|
13495
15035
|
const x = e?.clientX;
|
|
@@ -13515,7 +15055,7 @@ function OhhwellsBridge() {
|
|
|
13515
15055
|
},
|
|
13516
15056
|
[commitFooterDrag, commitNavDrag, navDragRef]
|
|
13517
15057
|
);
|
|
13518
|
-
const handleItemChromePointerDown =
|
|
15058
|
+
const handleItemChromePointerDown = useCallback7((e) => {
|
|
13519
15059
|
if (e.button !== 0) return;
|
|
13520
15060
|
const selected = selectedElRef.current;
|
|
13521
15061
|
if (!selected) return;
|
|
@@ -13546,7 +15086,7 @@ function OhhwellsBridge() {
|
|
|
13546
15086
|
}
|
|
13547
15087
|
if (armNavPressFromChrome(selected, e.clientX, e.clientY, e.pointerId)) return;
|
|
13548
15088
|
}, [armNavPressFromChrome]);
|
|
13549
|
-
const handleItemChromeClick =
|
|
15089
|
+
const handleItemChromeClick = useCallback7((clientX, clientY) => {
|
|
13550
15090
|
if (suppressNextClickRef.current || Date.now() < suppressClickUntilRef.current) {
|
|
13551
15091
|
suppressNextClickRef.current = false;
|
|
13552
15092
|
return;
|
|
@@ -13559,7 +15099,7 @@ function OhhwellsBridge() {
|
|
|
13559
15099
|
}, []);
|
|
13560
15100
|
reselectNavigationItemRef.current = reselectNavigationItem;
|
|
13561
15101
|
commitNavigationTextEditRef.current = commitNavigationTextEdit;
|
|
13562
|
-
const select =
|
|
15102
|
+
const select = useCallback7((anchor) => {
|
|
13563
15103
|
if (!isNavigationItem2(anchor)) return;
|
|
13564
15104
|
if (activeElRef.current) deactivate();
|
|
13565
15105
|
aiSectionApiRef.current?.selectFromElement(anchor);
|
|
@@ -13568,6 +15108,8 @@ function OhhwellsBridge() {
|
|
|
13568
15108
|
selectedFooterColAttrRef.current = null;
|
|
13569
15109
|
markSelected(anchor);
|
|
13570
15110
|
setSelectedIsCta(isCtaButton(anchor));
|
|
15111
|
+
setSelectedIsSocial(Boolean(getSocialItem(anchor)));
|
|
15112
|
+
setSelectedIsSocialsRow(false);
|
|
13571
15113
|
clearHrefKeyHover(anchor);
|
|
13572
15114
|
const isDropdownTrigger = !isNestedNavChild(anchor) && (navItemHasDropdownChildren(anchor) || navItemOwnsDropdownPanel(anchor));
|
|
13573
15115
|
if (isNestedNavChild(anchor)) {
|
|
@@ -13597,8 +15139,10 @@ function OhhwellsBridge() {
|
|
|
13597
15139
|
setToolbarRect(anchor.getBoundingClientRect());
|
|
13598
15140
|
setToolbarShowEditLink(false);
|
|
13599
15141
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
15142
|
+
setFloatingPanel(null);
|
|
15143
|
+
setLogoSizeDraft(null);
|
|
13600
15144
|
}, [deactivate, markSelected]);
|
|
13601
|
-
const selectFrame =
|
|
15145
|
+
const selectFrame = useCallback7((el) => {
|
|
13602
15146
|
if (!isNavigationContainer(el)) return;
|
|
13603
15147
|
if (activeElRef.current) deactivate();
|
|
13604
15148
|
aiSectionApiRef.current?.selectFromElement(el);
|
|
@@ -13608,6 +15152,8 @@ function OhhwellsBridge() {
|
|
|
13608
15152
|
selectedFooterColAttrRef.current = isFooterColumn ? el.getAttribute("data-ohw-footer-col") ?? String(listFooterColumns().indexOf(el)) : null;
|
|
13609
15153
|
markSelected(el);
|
|
13610
15154
|
setSelectedIsCta(false);
|
|
15155
|
+
setSelectedIsSocial(false);
|
|
15156
|
+
setSelectedIsSocialsRow(isSocialsRow(el));
|
|
13611
15157
|
clearHrefKeyHover(el);
|
|
13612
15158
|
setNavGroupForceOpen(null, false);
|
|
13613
15159
|
hoveredNavContainerRef.current = null;
|
|
@@ -13636,22 +15182,153 @@ function OhhwellsBridge() {
|
|
|
13636
15182
|
nodes: [{ key: ensured.headingKey, text: ensured.text }]
|
|
13637
15183
|
});
|
|
13638
15184
|
}
|
|
13639
|
-
setFooterHeadingVisible(isFooterColumnHeadingVisible(el));
|
|
13640
|
-
} else {
|
|
13641
|
-
setFooterHeadingVisible(null);
|
|
13642
|
-
}
|
|
13643
|
-
setToolbarVariant("select-frame");
|
|
13644
|
-
setToolbarRect(el.getBoundingClientRect());
|
|
13645
|
-
setToolbarShowEditLink(false);
|
|
13646
|
-
setActiveCommands(/* @__PURE__ */ new Set());
|
|
13647
|
-
|
|
13648
|
-
|
|
15185
|
+
setFooterHeadingVisible(isFooterColumnHeadingVisible(el));
|
|
15186
|
+
} else {
|
|
15187
|
+
setFooterHeadingVisible(null);
|
|
15188
|
+
}
|
|
15189
|
+
setToolbarVariant("select-frame");
|
|
15190
|
+
setToolbarRect(el.getBoundingClientRect());
|
|
15191
|
+
setToolbarShowEditLink(false);
|
|
15192
|
+
setActiveCommands(/* @__PURE__ */ new Set());
|
|
15193
|
+
setFloatingPanel(null);
|
|
15194
|
+
setLogoSizeDraft(null);
|
|
15195
|
+
}, [deactivate, markSelected, postToParent2]);
|
|
15196
|
+
const selectLogo = useCallback7(
|
|
15197
|
+
(logoEl) => {
|
|
15198
|
+
if (activeElRef.current) deactivate();
|
|
15199
|
+
selectedElRef.current = logoEl;
|
|
15200
|
+
selectedHrefKeyRef.current = null;
|
|
15201
|
+
selectedFooterColAttrRef.current = null;
|
|
15202
|
+
markSelected(logoEl);
|
|
15203
|
+
setSelectedIsCta(false);
|
|
15204
|
+
setSelectedIsSocial(false);
|
|
15205
|
+
setSelectedIsSocialsRow(false);
|
|
15206
|
+
setSelectedIsSocialsRow(false);
|
|
15207
|
+
clearHrefKeyHover(logoEl);
|
|
15208
|
+
hoveredNavContainerRef.current = null;
|
|
15209
|
+
setHoveredNavContainerRect(null);
|
|
15210
|
+
setHoveredItemRect(null);
|
|
15211
|
+
hoveredItemElRef.current = null;
|
|
15212
|
+
siblingHintElRef.current = null;
|
|
15213
|
+
setSiblingHintRect(null);
|
|
15214
|
+
setSiblingHintRects([]);
|
|
15215
|
+
setIsItemDragging(false);
|
|
15216
|
+
setReorderHrefKey(null);
|
|
15217
|
+
setReorderDragDisabled(false);
|
|
15218
|
+
setIsFooterFrameSelection(false);
|
|
15219
|
+
setToolbarVariant("logo");
|
|
15220
|
+
setToolbarRect(getLogoInteractionRect(logoEl));
|
|
15221
|
+
setToolbarShowEditLink(false);
|
|
15222
|
+
setActiveCommands(/* @__PURE__ */ new Set());
|
|
15223
|
+
},
|
|
15224
|
+
[deactivate, markSelected]
|
|
15225
|
+
);
|
|
15226
|
+
const openLogoSizePanel = useCallback7((logoEl) => {
|
|
15227
|
+
const placement = getLogoPlacement(logoEl);
|
|
15228
|
+
const draft = readLogoSizeState(editContentRef.current, placement);
|
|
15229
|
+
setLogoSizeDraft(draft);
|
|
15230
|
+
setParentScrollSnap(parentScrollRef.current);
|
|
15231
|
+
setFloatingPanel({
|
|
15232
|
+
key: `logo-size:${placement}`,
|
|
15233
|
+
title: "Logo",
|
|
15234
|
+
context: placement === "navbar" ? "Navbar" : "Footer",
|
|
15235
|
+
kind: "logo-size",
|
|
15236
|
+
placement
|
|
15237
|
+
});
|
|
15238
|
+
}, []);
|
|
15239
|
+
const openSocialsDisplayPanel = useCallback7((row) => {
|
|
15240
|
+
setParentScrollSnap(parentScrollRef.current);
|
|
15241
|
+
setFloatingPanel({
|
|
15242
|
+
key: "socials-display",
|
|
15243
|
+
title: "Style",
|
|
15244
|
+
context: "Socials \xB7 Footer",
|
|
15245
|
+
kind: "socials-display",
|
|
15246
|
+
row
|
|
15247
|
+
});
|
|
15248
|
+
}, []);
|
|
15249
|
+
const changeSocialsDisplay = useCallback7(
|
|
15250
|
+
(row, next) => {
|
|
15251
|
+
if (next.icon) {
|
|
15252
|
+
const missing = socialsMissingIcons(row);
|
|
15253
|
+
listSocialItems(row).forEach((item) => ensureIconSlot(item));
|
|
15254
|
+
if (missing.length) {
|
|
15255
|
+
postToParentRef.current({ type: "ow:social-icons-needed", items: missing });
|
|
15256
|
+
}
|
|
15257
|
+
}
|
|
15258
|
+
applySocialsDisplayToRow(row, next);
|
|
15259
|
+
requestAnimationFrame(() => {
|
|
15260
|
+
if (selectedElRef.current === row && row.isConnected) setToolbarRect(row.getBoundingClientRect());
|
|
15261
|
+
});
|
|
15262
|
+
const displayJson = JSON.stringify(socialsDisplayWith(row, next, editContentRef.current));
|
|
15263
|
+
editContentRef.current = { ...editContentRef.current, [SOCIALS_DISPLAY_KEY]: displayJson };
|
|
15264
|
+
postToParentRef.current({
|
|
15265
|
+
type: "ow:change",
|
|
15266
|
+
nodes: [{ key: SOCIALS_DISPLAY_KEY, text: displayJson }],
|
|
15267
|
+
flush: true
|
|
15268
|
+
});
|
|
15269
|
+
},
|
|
15270
|
+
[]
|
|
15271
|
+
);
|
|
15272
|
+
const closeFloatingPanelOnly = useCallback7(() => {
|
|
15273
|
+
setFloatingPanel(null);
|
|
15274
|
+
setLogoSizeDraft(null);
|
|
15275
|
+
}, []);
|
|
15276
|
+
const closeFloatingPanelAndDeselect = useCallback7(() => {
|
|
15277
|
+
setFloatingPanel(null);
|
|
15278
|
+
setLogoSizeDraft(null);
|
|
15279
|
+
deselectRef.current();
|
|
15280
|
+
}, []);
|
|
15281
|
+
const persistLogoSizeDraft = useCallback7(
|
|
15282
|
+
(placement, draft) => {
|
|
15283
|
+
const desktopKey = LOGO_SIZE_DESKTOP_KEYS[placement];
|
|
15284
|
+
const mobileKey = LOGO_SIZE_MOBILE_KEYS[placement];
|
|
15285
|
+
const nodes = [
|
|
15286
|
+
{ key: desktopKey, text: String(draft.desktopPx) }
|
|
15287
|
+
];
|
|
15288
|
+
if (draft.mobileFollowing) {
|
|
15289
|
+
nodes.push({ key: mobileKey, text: "" });
|
|
15290
|
+
} else {
|
|
15291
|
+
nodes.push({ key: mobileKey, text: String(draft.mobilePx) });
|
|
15292
|
+
}
|
|
15293
|
+
editContentRef.current = {
|
|
15294
|
+
...editContentRef.current,
|
|
15295
|
+
[desktopKey]: String(draft.desktopPx),
|
|
15296
|
+
[mobileKey]: draft.mobileFollowing ? "" : String(draft.mobilePx)
|
|
15297
|
+
};
|
|
15298
|
+
applyLogoSizeToPlacement(
|
|
15299
|
+
placement,
|
|
15300
|
+
draft.desktopPx,
|
|
15301
|
+
draft.mobileFollowing ? draft.desktopPx : draft.mobilePx,
|
|
15302
|
+
draft.mobileFollowing
|
|
15303
|
+
);
|
|
15304
|
+
postToParent2({ type: "ow:change", nodes });
|
|
15305
|
+
requestAnimationFrame(() => {
|
|
15306
|
+
const selected = selectedElRef.current;
|
|
15307
|
+
if (!selected || toolbarVariantRef.current !== "logo") return;
|
|
15308
|
+
const rect = getLogoInteractionRect(selected);
|
|
15309
|
+
setToolbarRect(rect);
|
|
15310
|
+
if (glowElRef.current) {
|
|
15311
|
+
const GAP = SELECTION_CHROME_GAP2;
|
|
15312
|
+
glowElRef.current.style.top = `${rect.top - GAP}px`;
|
|
15313
|
+
glowElRef.current.style.left = `${rect.left - GAP}px`;
|
|
15314
|
+
glowElRef.current.style.width = `${rect.width + GAP * 2}px`;
|
|
15315
|
+
glowElRef.current.style.height = `${rect.height + GAP * 2}px`;
|
|
15316
|
+
}
|
|
15317
|
+
});
|
|
15318
|
+
},
|
|
15319
|
+
[postToParent2]
|
|
15320
|
+
);
|
|
15321
|
+
const activate = useCallback7((el, options) => {
|
|
13649
15322
|
if (activeElRef.current === el) return;
|
|
15323
|
+
if (isIconEditable(el)) return;
|
|
15324
|
+
if (el.hasAttribute("data-ohw-social-label")) return;
|
|
13650
15325
|
clearSelectedAttr();
|
|
13651
15326
|
selectedElRef.current = null;
|
|
13652
15327
|
selectedHrefKeyRef.current = null;
|
|
13653
15328
|
selectedFooterColAttrRef.current = null;
|
|
13654
15329
|
setSelectedIsCta(false);
|
|
15330
|
+
setSelectedIsSocial(false);
|
|
15331
|
+
setSelectedIsSocialsRow(false);
|
|
13655
15332
|
deactivate();
|
|
13656
15333
|
if (hoveredImageRef.current) {
|
|
13657
15334
|
hoveredImageRef.current = null;
|
|
@@ -13721,8 +15398,38 @@ function OhhwellsBridge() {
|
|
|
13721
15398
|
deactivateRef.current = deactivate;
|
|
13722
15399
|
selectRef.current = select;
|
|
13723
15400
|
selectFrameRef.current = selectFrame;
|
|
15401
|
+
selectLogoRef.current = selectLogo;
|
|
15402
|
+
openLogoSizePanelRef.current = openLogoSizePanel;
|
|
13724
15403
|
deselectRef.current = deselect;
|
|
13725
|
-
|
|
15404
|
+
closeFloatingPanelOnlyRef.current = closeFloatingPanelOnly;
|
|
15405
|
+
const lastSiteWideScopeRef = useRef9(null);
|
|
15406
|
+
useEffect12(() => {
|
|
15407
|
+
if (!isEditMode) {
|
|
15408
|
+
if (lastSiteWideScopeRef.current !== false) {
|
|
15409
|
+
lastSiteWideScopeRef.current = false;
|
|
15410
|
+
postToParent2({ type: "ow:site-wide-scope", active: false });
|
|
15411
|
+
}
|
|
15412
|
+
return;
|
|
15413
|
+
}
|
|
15414
|
+
const active = isSiteWideScopeActive({
|
|
15415
|
+
selected: selectedElRef.current,
|
|
15416
|
+
hoveredItem: hoveredItemElRef.current,
|
|
15417
|
+
hoveredNavContainer: hoveredNavContainerRef.current,
|
|
15418
|
+
active: activeElRef.current
|
|
15419
|
+
});
|
|
15420
|
+
if (lastSiteWideScopeRef.current === active) return;
|
|
15421
|
+
lastSiteWideScopeRef.current = active;
|
|
15422
|
+
postToParent2({ type: "ow:site-wide-scope", active });
|
|
15423
|
+
}, [
|
|
15424
|
+
isEditMode,
|
|
15425
|
+
hoveredItemRect,
|
|
15426
|
+
hoveredNavContainerRect,
|
|
15427
|
+
toolbarVariant,
|
|
15428
|
+
toolbarRect,
|
|
15429
|
+
isFooterFrameSelection,
|
|
15430
|
+
postToParent2
|
|
15431
|
+
]);
|
|
15432
|
+
useLayoutEffect4(() => {
|
|
13726
15433
|
if (!subdomain || isEditMode) {
|
|
13727
15434
|
setFetchState("done");
|
|
13728
15435
|
return;
|
|
@@ -13733,9 +15440,18 @@ function OhhwellsBridge() {
|
|
|
13733
15440
|
aiSectionsRef.current = content[AI_SECTIONS_KEY];
|
|
13734
15441
|
applyAiSectionsToDom(parseAiSectionsState(content[AI_SECTIONS_KEY]));
|
|
13735
15442
|
}
|
|
15443
|
+
if (typeof content[BRAND_KIT_KEY] === "string") {
|
|
15444
|
+
brandKitRef.current = content[BRAND_KIT_KEY];
|
|
15445
|
+
applyBrandToDom(parseBrandKit(content[BRAND_KIT_KEY]));
|
|
15446
|
+
}
|
|
15447
|
+
applyBrandChrome(content);
|
|
13736
15448
|
for (const [key, val] of Object.entries(content)) {
|
|
13737
15449
|
if (key === "__ohw_sections") continue;
|
|
13738
15450
|
if (key === AI_SECTIONS_KEY) continue;
|
|
15451
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
15452
|
+
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
15453
|
+
if (key === BRAND_KIT_KEY) continue;
|
|
15454
|
+
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
13739
15455
|
if (applyVideoSettingNode(key, val)) continue;
|
|
13740
15456
|
if (applyCarouselNode(key, val)) continue;
|
|
13741
15457
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
@@ -13762,14 +15478,20 @@ function OhhwellsBridge() {
|
|
|
13762
15478
|
}
|
|
13763
15479
|
} else if (el.dataset.ohwEditable === "link") {
|
|
13764
15480
|
applyLinkHref(el, val);
|
|
15481
|
+
} else if (el.dataset.ohwEditable === "icon") {
|
|
15482
|
+
applyIconMarkup(el, val);
|
|
13765
15483
|
} else if (el.innerHTML !== val) {
|
|
13766
15484
|
el.innerHTML = val;
|
|
13767
15485
|
}
|
|
13768
15486
|
});
|
|
13769
15487
|
applyLinkByKey(key, val);
|
|
13770
15488
|
}
|
|
15489
|
+
applyLogoFromContent(content);
|
|
15490
|
+
applyLogoSizes(content);
|
|
13771
15491
|
reconcileNavbarItemsFromContent(content);
|
|
13772
15492
|
reconcileFooterOrderFromContent(content);
|
|
15493
|
+
reconcileSocialsFromContent(content);
|
|
15494
|
+
applySocialsDisplayFromContent(content);
|
|
13773
15495
|
enforceLinkHrefs();
|
|
13774
15496
|
initSectionsFromContent(content, true);
|
|
13775
15497
|
sectionsLoadedRef.current = true;
|
|
@@ -13785,7 +15507,9 @@ function OhhwellsBridge() {
|
|
|
13785
15507
|
let cancelled = false;
|
|
13786
15508
|
setFetchState("loading");
|
|
13787
15509
|
const apiUrl = process.env.NEXT_PUBLIC_FLOWOPS_API_URL ?? "https://flowops-backend-staging-2yfdh7pwpq-as.a.run.app";
|
|
13788
|
-
|
|
15510
|
+
const initialPath = pathname;
|
|
15511
|
+
fetchedContentPaths.add(`${subdomain}::${initialPath}`);
|
|
15512
|
+
fetch(`${apiUrl}/api/public/sites/${subdomain}/content?path=${encodeURIComponent(initialPath)}`, { cache: "no-store" }).then((r2) => r2.ok ? r2.json() : null).then((data) => {
|
|
13789
15513
|
if (cancelled) return;
|
|
13790
15514
|
const content = data?.content ?? {};
|
|
13791
15515
|
contentCache.set(subdomain, content);
|
|
@@ -13798,7 +15522,7 @@ function OhhwellsBridge() {
|
|
|
13798
15522
|
cancelled = true;
|
|
13799
15523
|
};
|
|
13800
15524
|
}, [subdomain, isEditMode]);
|
|
13801
|
-
|
|
15525
|
+
useEffect12(() => {
|
|
13802
15526
|
if (!subdomain || isEditMode) return;
|
|
13803
15527
|
let debounceTimer = null;
|
|
13804
15528
|
let observer = null;
|
|
@@ -13808,8 +15532,16 @@ function OhhwellsBridge() {
|
|
|
13808
15532
|
retryMissingSchedulingMounts(getPageSchedulingEntries(content["__ohw_sections"]), false);
|
|
13809
15533
|
observer?.disconnect();
|
|
13810
15534
|
try {
|
|
15535
|
+
applyBrandChrome(content);
|
|
15536
|
+
if (typeof content[BRAND_KIT_KEY] === "string") {
|
|
15537
|
+
applyBrandToDom(parseBrandKit(content[BRAND_KIT_KEY]));
|
|
15538
|
+
}
|
|
13811
15539
|
for (const [key, val] of Object.entries(content)) {
|
|
13812
15540
|
if (key === "__ohw_sections") continue;
|
|
15541
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
15542
|
+
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
15543
|
+
if (key === BRAND_KIT_KEY) continue;
|
|
15544
|
+
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
13813
15545
|
if (applyVideoSettingNode(key, val)) continue;
|
|
13814
15546
|
if (applyCarouselNode(key, val)) continue;
|
|
13815
15547
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
@@ -13830,8 +15562,11 @@ function OhhwellsBridge() {
|
|
|
13830
15562
|
});
|
|
13831
15563
|
applyLinkByKey(key, val);
|
|
13832
15564
|
}
|
|
15565
|
+
applyLogoFromContent(content);
|
|
13833
15566
|
reconcileNavbarItemsFromContent(content);
|
|
13834
15567
|
reconcileFooterOrderFromContent(content);
|
|
15568
|
+
reconcileSocialsFromContent(content);
|
|
15569
|
+
applySocialsDisplayFromContent(content);
|
|
13835
15570
|
} finally {
|
|
13836
15571
|
observer?.observe(document.body, { childList: true, subtree: true });
|
|
13837
15572
|
}
|
|
@@ -13842,6 +15577,17 @@ function OhhwellsBridge() {
|
|
|
13842
15577
|
debounceTimer = setTimeout(applyFromCache, 150);
|
|
13843
15578
|
};
|
|
13844
15579
|
applyFromCache();
|
|
15580
|
+
const pathCacheKey = `${subdomain}::${pathname}`;
|
|
15581
|
+
if (!fetchedContentPaths.has(pathCacheKey)) {
|
|
15582
|
+
fetchedContentPaths.add(pathCacheKey);
|
|
15583
|
+
const apiUrl = process.env.NEXT_PUBLIC_FLOWOPS_API_URL ?? "https://flowops-backend-staging-2yfdh7pwpq-as.a.run.app";
|
|
15584
|
+
fetch(`${apiUrl}/api/public/sites/${subdomain}/content?path=${encodeURIComponent(pathname)}`, { cache: "no-store" }).then((r2) => r2.ok ? r2.json() : null).then((data) => {
|
|
15585
|
+
if (!data?.content) return;
|
|
15586
|
+
contentCache.set(subdomain, data.content);
|
|
15587
|
+
applyFromCache();
|
|
15588
|
+
}).catch(() => {
|
|
15589
|
+
});
|
|
15590
|
+
}
|
|
13845
15591
|
observer = new MutationObserver(scheduleApply);
|
|
13846
15592
|
observer.observe(document.body, { childList: true, subtree: true });
|
|
13847
15593
|
return () => {
|
|
@@ -13849,16 +15595,16 @@ function OhhwellsBridge() {
|
|
|
13849
15595
|
if (debounceTimer) clearTimeout(debounceTimer);
|
|
13850
15596
|
};
|
|
13851
15597
|
}, [subdomain, isEditMode, pathname]);
|
|
13852
|
-
|
|
15598
|
+
useLayoutEffect4(() => {
|
|
13853
15599
|
const el = document.getElementById("ohw-loader");
|
|
13854
15600
|
if (!el) return;
|
|
13855
15601
|
const visible = Boolean(subdomain) && fetchState !== "done";
|
|
13856
15602
|
el.style.display = visible ? "flex" : "none";
|
|
13857
15603
|
}, [subdomain, fetchState]);
|
|
13858
|
-
|
|
15604
|
+
useEffect12(() => {
|
|
13859
15605
|
postToParent2({ type: "ow:navigation", path: pathname });
|
|
13860
15606
|
}, [pathname, postToParent2]);
|
|
13861
|
-
|
|
15607
|
+
useEffect12(() => {
|
|
13862
15608
|
if (!isEditMode) return;
|
|
13863
15609
|
if (linkPopoverSessionRef.current?.intent === "add-nav") return;
|
|
13864
15610
|
if (document.querySelector("[data-ohw-section-picker]")) return;
|
|
@@ -13866,7 +15612,7 @@ function OhhwellsBridge() {
|
|
|
13866
15612
|
deselectRef.current();
|
|
13867
15613
|
deactivateRef.current();
|
|
13868
15614
|
}, [pathname, isEditMode]);
|
|
13869
|
-
|
|
15615
|
+
useEffect12(() => {
|
|
13870
15616
|
const contentForNav = () => {
|
|
13871
15617
|
if (isEditMode) return editContentRef.current;
|
|
13872
15618
|
if (!subdomain) return {};
|
|
@@ -13898,8 +15644,10 @@ function OhhwellsBridge() {
|
|
|
13898
15644
|
const content = contentForNav();
|
|
13899
15645
|
reconcileNavbarItemsFromContent(content);
|
|
13900
15646
|
reconcileFooterOrderFromContent(content);
|
|
15647
|
+
reconcileSocialsFromContent(content);
|
|
15648
|
+
applySocialsDisplayFromContent(content);
|
|
13901
15649
|
document.querySelectorAll("footer [data-ohw-href-key]").forEach((el) => {
|
|
13902
|
-
if (isFooterHrefKey(el.getAttribute("data-ohw-href-key"))) {
|
|
15650
|
+
if (isFooterHrefKey(el.getAttribute("data-ohw-href-key")) || getSocialItem(el)) {
|
|
13903
15651
|
disableNativeHrefDrag(el);
|
|
13904
15652
|
}
|
|
13905
15653
|
});
|
|
@@ -13931,31 +15679,36 @@ function OhhwellsBridge() {
|
|
|
13931
15679
|
observer?.disconnect();
|
|
13932
15680
|
};
|
|
13933
15681
|
}, [isEditMode, pathname, subdomain, fetchState, resyncSelectedNavigationItem]);
|
|
13934
|
-
|
|
15682
|
+
useEffect12(() => {
|
|
13935
15683
|
if (!isEditMode) return;
|
|
15684
|
+
let lastPosted = 0;
|
|
13936
15685
|
const measure = () => {
|
|
13937
15686
|
const h = document.body.scrollHeight;
|
|
13938
|
-
if (h > 50
|
|
15687
|
+
if (h > 50 && Math.abs(h - lastPosted) > 1) {
|
|
15688
|
+
lastPosted = h;
|
|
15689
|
+
postToParent2({ type: "ow:height", height: h });
|
|
15690
|
+
}
|
|
15691
|
+
};
|
|
15692
|
+
let raf = null;
|
|
15693
|
+
const schedule = () => {
|
|
15694
|
+
if (raf != null) return;
|
|
15695
|
+
raf = requestAnimationFrame(() => {
|
|
15696
|
+
raf = null;
|
|
15697
|
+
measure();
|
|
15698
|
+
});
|
|
13939
15699
|
};
|
|
13940
15700
|
const t1 = setTimeout(measure, 50);
|
|
13941
15701
|
const t2 = setTimeout(measure, 500);
|
|
13942
|
-
|
|
13943
|
-
|
|
13944
|
-
const handleResize = () => {
|
|
13945
|
-
if (window.innerWidth === lastWidth) return;
|
|
13946
|
-
lastWidth = window.innerWidth;
|
|
13947
|
-
if (resizeTimer) clearTimeout(resizeTimer);
|
|
13948
|
-
resizeTimer = setTimeout(measure, 150);
|
|
13949
|
-
};
|
|
13950
|
-
window.addEventListener("resize", handleResize);
|
|
15702
|
+
const ro = new ResizeObserver(schedule);
|
|
15703
|
+
ro.observe(document.body);
|
|
13951
15704
|
return () => {
|
|
13952
15705
|
clearTimeout(t1);
|
|
13953
15706
|
clearTimeout(t2);
|
|
13954
|
-
if (
|
|
13955
|
-
|
|
15707
|
+
if (raf != null) cancelAnimationFrame(raf);
|
|
15708
|
+
ro.disconnect();
|
|
13956
15709
|
};
|
|
13957
15710
|
}, [pathname, isEditMode, postToParent2]);
|
|
13958
|
-
|
|
15711
|
+
useEffect12(() => {
|
|
13959
15712
|
if (!subdomainFromQuery || isEditMode) return;
|
|
13960
15713
|
const handleClick = (e) => {
|
|
13961
15714
|
const anchor = e.target.closest("a");
|
|
@@ -13971,7 +15724,7 @@ function OhhwellsBridge() {
|
|
|
13971
15724
|
document.addEventListener("click", handleClick, true);
|
|
13972
15725
|
return () => document.removeEventListener("click", handleClick, true);
|
|
13973
15726
|
}, [subdomainFromQuery, isEditMode, router]);
|
|
13974
|
-
|
|
15727
|
+
useEffect12(() => {
|
|
13975
15728
|
if (!isEditMode) {
|
|
13976
15729
|
editStylesRef.current?.base.remove();
|
|
13977
15730
|
editStylesRef.current?.forceHover.remove();
|
|
@@ -14022,9 +15775,12 @@ function OhhwellsBridge() {
|
|
|
14022
15775
|
[data-ohw-editable="video"], [data-ohw-editable="video"] *,
|
|
14023
15776
|
[data-ohw-editable="bg-image"], [data-ohw-editable="bg-image"] * { cursor: pointer !important; }
|
|
14024
15777
|
[data-ohw-editable="link"], [data-ohw-editable="link"] * { cursor: pointer !important; }
|
|
15778
|
+
/* Text hover chrome is drawn by the overlay (see hoveredTextRect) \u2014 the CSS outline
|
|
15779
|
+
that used to draw it dashes denser than the overlay border, so identical specs
|
|
15780
|
+
still read as two different frames (OHH-695). The attribute stays: hover paths
|
|
15781
|
+
and suppression rules key off it. */
|
|
14025
15782
|
[data-ohw-hovered]:not([contenteditable]):not([data-ohw-href-key]) {
|
|
14026
|
-
outline:
|
|
14027
|
-
outline-offset: 4px;
|
|
15783
|
+
outline: none !important;
|
|
14028
15784
|
}
|
|
14029
15785
|
[data-ohw-href-key] [data-ohw-hovered],
|
|
14030
15786
|
[data-ohw-href-key][data-ohw-hovered],
|
|
@@ -14077,8 +15833,11 @@ function OhhwellsBridge() {
|
|
|
14077
15833
|
stateViews.textContent = `
|
|
14078
15834
|
[data-ohw-state-view]:not([data-ohw-state-view="default"]) { display: none; }
|
|
14079
15835
|
[data-ohw-state-view="default"] [data-ohw-editable] { pointer-events: auto !important; }
|
|
14080
|
-
[data-ohw-state-hovered] { outline:
|
|
15836
|
+
[data-ohw-state-hovered] { outline: ${HOVER_STROKE_WIDTH}px dashed ${CHROME_PRIMARY} !important; outline-offset: ${HOVER_CHROME_GAP}px; }
|
|
14081
15837
|
[data-ohw-state-hovered]:has([data-ohw-hovered]) { outline: none !important; }
|
|
15838
|
+
/* :has() only sees descendants \u2014 when the card itself is the hovered text, the overlay
|
|
15839
|
+
already frames it, and the card outline doubled it (OHH-695). */
|
|
15840
|
+
[data-ohw-state-hovered][data-ohw-hovered] { outline: none !important; }
|
|
14082
15841
|
`;
|
|
14083
15842
|
document.head.appendChild(base);
|
|
14084
15843
|
document.head.appendChild(forceHover);
|
|
@@ -14100,6 +15859,7 @@ function OhhwellsBridge() {
|
|
|
14100
15859
|
if (target.closest("[data-ohw-state-toggle]")) return;
|
|
14101
15860
|
if (target.closest("[data-ohw-max-badge]")) return;
|
|
14102
15861
|
if (isInsideLinkEditor(target)) return;
|
|
15862
|
+
if (isInsideFloatingPanel(target)) return;
|
|
14103
15863
|
if (target.closest('[data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
|
|
14104
15864
|
const beneath = document.elementsFromPoint(e.clientX, e.clientY).find(
|
|
14105
15865
|
(el) => el instanceof HTMLElement && !el.closest("[data-ohw-bridge-root]") && el.closest("[data-ohw-section]") != null
|
|
@@ -14163,6 +15923,21 @@ function OhhwellsBridge() {
|
|
|
14163
15923
|
return;
|
|
14164
15924
|
}
|
|
14165
15925
|
}
|
|
15926
|
+
const logoEl = getLogoElement(target);
|
|
15927
|
+
if (logoEl) {
|
|
15928
|
+
e.preventDefault();
|
|
15929
|
+
e.stopPropagation();
|
|
15930
|
+
if (!logoHasUploadedImage(logoEl)) {
|
|
15931
|
+
deselectRef.current();
|
|
15932
|
+
deactivateRef.current();
|
|
15933
|
+
const identity = readLogoIdentityFromDom();
|
|
15934
|
+
postToParentRef.current({ type: "ow:open-logo-settings", ...identity });
|
|
15935
|
+
return;
|
|
15936
|
+
}
|
|
15937
|
+
selectLogoRef.current(logoEl);
|
|
15938
|
+
openLogoSizePanelRef.current(logoEl);
|
|
15939
|
+
return;
|
|
15940
|
+
}
|
|
14166
15941
|
const editable = target.closest("[data-ohw-editable]");
|
|
14167
15942
|
if (editable) {
|
|
14168
15943
|
if (editable.dataset.ohwEditable === "link") {
|
|
@@ -14179,6 +15954,17 @@ function OhhwellsBridge() {
|
|
|
14179
15954
|
});
|
|
14180
15955
|
return;
|
|
14181
15956
|
}
|
|
15957
|
+
if (isIconEditable(editable) && !getSocialItem(editable)) {
|
|
15958
|
+
e.preventDefault();
|
|
15959
|
+
e.stopPropagation();
|
|
15960
|
+
aiSectionApiRef.current?.selectFromElement(editable);
|
|
15961
|
+
postToParentRef.current({
|
|
15962
|
+
type: "ow:icon-pick",
|
|
15963
|
+
key: editable.dataset.ohwKey ?? "",
|
|
15964
|
+
current: currentIconRef(editable)
|
|
15965
|
+
});
|
|
15966
|
+
return;
|
|
15967
|
+
}
|
|
14182
15968
|
if (isMediaEditable(editable)) {
|
|
14183
15969
|
e.preventDefault();
|
|
14184
15970
|
e.stopPropagation();
|
|
@@ -14193,6 +15979,7 @@ function OhhwellsBridge() {
|
|
|
14193
15979
|
e.stopPropagation();
|
|
14194
15980
|
if (selectedElRef.current === navAnchor) {
|
|
14195
15981
|
if (e.detail >= 2) return;
|
|
15982
|
+
if (requestSocialDialog(navAnchor, postToParentRef.current, editContentRef.current)) return;
|
|
14196
15983
|
activateRef.current(editable, { caretX: e.clientX, caretY: e.clientY });
|
|
14197
15984
|
return;
|
|
14198
15985
|
}
|
|
@@ -14209,6 +15996,7 @@ function OhhwellsBridge() {
|
|
|
14209
15996
|
e.preventDefault();
|
|
14210
15997
|
e.stopPropagation();
|
|
14211
15998
|
if (selectedElRef.current === hrefAnchor) {
|
|
15999
|
+
if (requestSocialDialog(hrefAnchor, postToParentRef.current, editContentRef.current)) return;
|
|
14212
16000
|
const textEditable = hrefAnchor.querySelector('[data-ohw-editable="text"]') ?? hrefAnchor.querySelector("[data-ohw-editable]");
|
|
14213
16001
|
if (textEditable) {
|
|
14214
16002
|
activateRef.current(textEditable, {
|
|
@@ -14247,6 +16035,13 @@ function OhhwellsBridge() {
|
|
|
14247
16035
|
selectFrameRef.current(navContainerToSelect);
|
|
14248
16036
|
return;
|
|
14249
16037
|
}
|
|
16038
|
+
const socialsRowToSelect = isSocialsRow(target) ? target : null;
|
|
16039
|
+
if (socialsRowToSelect && !getSocialItem(target)) {
|
|
16040
|
+
e.preventDefault();
|
|
16041
|
+
e.stopPropagation();
|
|
16042
|
+
selectFrameRef.current(socialsRowToSelect);
|
|
16043
|
+
return;
|
|
16044
|
+
}
|
|
14250
16045
|
const footerColumnToSelect = resolveFooterColumnSelectionTarget(target, e.clientX, e.clientY);
|
|
14251
16046
|
if (footerColumnToSelect) {
|
|
14252
16047
|
e.preventDefault();
|
|
@@ -14295,9 +16090,11 @@ function OhhwellsBridge() {
|
|
|
14295
16090
|
if (target.closest("[data-ohw-state-toggle]")) return;
|
|
14296
16091
|
if (target.closest("[data-ohw-max-badge]")) return;
|
|
14297
16092
|
if (isInsideLinkEditor(target)) return;
|
|
16093
|
+
if (isInsideFloatingPanel(target)) return;
|
|
14298
16094
|
if (target.closest('[data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
|
|
14299
16095
|
return;
|
|
14300
16096
|
}
|
|
16097
|
+
if (getSocialItem(target)) return;
|
|
14301
16098
|
const navLabel = getNavigationLabelEditable(target);
|
|
14302
16099
|
const editable = navLabel?.editable ?? target.closest('[data-ohw-editable="text"], [data-ohw-editable="plain"]');
|
|
14303
16100
|
if (!editable || isMediaEditable(editable) || editable.dataset.ohwEditable === "link") return;
|
|
@@ -14321,6 +16118,16 @@ function OhhwellsBridge() {
|
|
|
14321
16118
|
setHoveredNavContainerRect(null);
|
|
14322
16119
|
return;
|
|
14323
16120
|
}
|
|
16121
|
+
if (document.documentElement.hasAttribute("data-ohw-panel-dragging") || isInsideFloatingPanel(target) || isPointOverFloatingPanel(e.clientX, e.clientY)) {
|
|
16122
|
+
hoveredItemElRef.current = null;
|
|
16123
|
+
setHoveredItemRect(null);
|
|
16124
|
+
hoveredNavContainerRef.current = null;
|
|
16125
|
+
setHoveredNavContainerRect(null);
|
|
16126
|
+
siblingHintElRef.current = null;
|
|
16127
|
+
setSiblingHintRect(null);
|
|
16128
|
+
setSiblingHintRects([]);
|
|
16129
|
+
return;
|
|
16130
|
+
}
|
|
14324
16131
|
{
|
|
14325
16132
|
const selected2 = selectedElRef.current;
|
|
14326
16133
|
const selectedIsFooterColumn = Boolean(selected2) && !isFooterLinksContainer(selected2) && (selected2.hasAttribute("data-ohw-footer-col") || selected2.hasAttribute("data-ohw-footer-column") || Boolean(selected2.closest("footer") && isInferredFooterGroup2(selected2)));
|
|
@@ -14328,7 +16135,7 @@ function OhhwellsBridge() {
|
|
|
14328
16135
|
const allowFooterLinksHover = toolbarVariantRef.current !== "select-frame" || selectedIsFooterColumn;
|
|
14329
16136
|
if (allowNavContainerHover) {
|
|
14330
16137
|
const navContainer = target.closest("[data-ohw-nav-container]");
|
|
14331
|
-
if (navContainer && !getNavigationItemAnchor(target)) {
|
|
16138
|
+
if (navContainer && !getNavigationItemAnchor(target) && !getLogoElement(target)) {
|
|
14332
16139
|
hoveredNavContainerRef.current = navContainer;
|
|
14333
16140
|
setHoveredNavContainerRect(navContainer.getBoundingClientRect());
|
|
14334
16141
|
hoveredItemElRef.current = null;
|
|
@@ -14357,6 +16164,15 @@ function OhhwellsBridge() {
|
|
|
14357
16164
|
setHoveredNavContainerRect(null);
|
|
14358
16165
|
}
|
|
14359
16166
|
}
|
|
16167
|
+
const logoEl = getLogoElement(target);
|
|
16168
|
+
if (logoEl) {
|
|
16169
|
+
hoveredNavContainerRef.current = null;
|
|
16170
|
+
setHoveredNavContainerRect(null);
|
|
16171
|
+
if (selectedElRef.current === logoEl) return;
|
|
16172
|
+
hoveredItemElRef.current = logoEl;
|
|
16173
|
+
setHoveredItemRect(getLogoInteractionRect(logoEl));
|
|
16174
|
+
return;
|
|
16175
|
+
}
|
|
14360
16176
|
const navAnchor = getNavigationItemAnchor(target);
|
|
14361
16177
|
if (navAnchor) {
|
|
14362
16178
|
hoveredNavContainerRef.current = null;
|
|
@@ -14382,6 +16198,11 @@ function OhhwellsBridge() {
|
|
|
14382
16198
|
const selected = selectedElRef.current;
|
|
14383
16199
|
if (selected && (selected === editable || selected.contains(editable))) return;
|
|
14384
16200
|
if (!isMediaEditable(editable) && !editable.hasAttribute("contenteditable")) {
|
|
16201
|
+
if (isIconEditable(editable) && !getSocialItem(editable)) {
|
|
16202
|
+
hoveredItemElRef.current = editable;
|
|
16203
|
+
setHoveredItemRect(editable.getBoundingClientRect());
|
|
16204
|
+
return;
|
|
16205
|
+
}
|
|
14385
16206
|
const hoverTarget = editable.closest("[data-ohw-href-key]") ?? editable;
|
|
14386
16207
|
if (hoverTarget.hasAttribute("data-ohw-href-key")) {
|
|
14387
16208
|
clearHrefKeyHover(hoverTarget);
|
|
@@ -14389,6 +16210,11 @@ function OhhwellsBridge() {
|
|
|
14389
16210
|
setHoveredItemRect(hoverTarget.getBoundingClientRect());
|
|
14390
16211
|
} else if (!isInsideNavigationItem(editable)) {
|
|
14391
16212
|
hoverTarget.setAttribute("data-ohw-hovered", "");
|
|
16213
|
+
if (editable.closest("footer") || editable.closest('[data-ohw-section="footer"]')) {
|
|
16214
|
+
hoveredNavContainerRef.current = null;
|
|
16215
|
+
setHoveredNavContainerRect(null);
|
|
16216
|
+
hoveredItemElRef.current = editable;
|
|
16217
|
+
}
|
|
14392
16218
|
}
|
|
14393
16219
|
}
|
|
14394
16220
|
};
|
|
@@ -14424,11 +16250,30 @@ function OhhwellsBridge() {
|
|
|
14424
16250
|
}
|
|
14425
16251
|
return;
|
|
14426
16252
|
}
|
|
16253
|
+
const logoEl = getLogoElement(target);
|
|
16254
|
+
if (logoEl) {
|
|
16255
|
+
const related2 = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
16256
|
+
if (related2 && (logoEl === related2 || logoEl.contains(related2) || related2.closest?.('[data-ohw-role="logo"], [data-ohw-logo]'))) {
|
|
16257
|
+
return;
|
|
16258
|
+
}
|
|
16259
|
+
if (hoveredItemElRef.current === logoEl) {
|
|
16260
|
+
hoveredItemElRef.current = null;
|
|
16261
|
+
setHoveredItemRect(null);
|
|
16262
|
+
}
|
|
16263
|
+
return;
|
|
16264
|
+
}
|
|
14427
16265
|
const editable = target.closest("[data-ohw-editable]");
|
|
14428
16266
|
if (!editable) return;
|
|
14429
16267
|
const related = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
14430
16268
|
if (related?.closest("[data-ohw-drag-handle-container], [data-ohw-item-interaction]")) return;
|
|
14431
16269
|
if (!isMediaEditable(editable)) {
|
|
16270
|
+
if (isIconEditable(editable) && !getSocialItem(editable) && hoveredItemElRef.current === editable) {
|
|
16271
|
+
if (!related?.closest("[data-ohw-item-interaction]")) {
|
|
16272
|
+
hoveredItemElRef.current = null;
|
|
16273
|
+
setHoveredItemRect(null);
|
|
16274
|
+
}
|
|
16275
|
+
return;
|
|
16276
|
+
}
|
|
14432
16277
|
const hoverTarget = editable.closest("[data-ohw-href-key]") ?? editable;
|
|
14433
16278
|
if (hoverTarget.hasAttribute("data-ohw-href-key")) {
|
|
14434
16279
|
if (!related?.closest("[data-ohw-href-key]")) {
|
|
@@ -14437,6 +16282,13 @@ function OhhwellsBridge() {
|
|
|
14437
16282
|
}
|
|
14438
16283
|
} else {
|
|
14439
16284
|
hoverTarget.removeAttribute("data-ohw-hovered");
|
|
16285
|
+
if (hoveredItemElRef.current === editable) {
|
|
16286
|
+
const stillOnEditable = related instanceof Element && related.closest("[data-ohw-editable]") === editable;
|
|
16287
|
+
if (!stillOnEditable) {
|
|
16288
|
+
hoveredItemElRef.current = null;
|
|
16289
|
+
setHoveredItemRect(null);
|
|
16290
|
+
}
|
|
16291
|
+
}
|
|
14440
16292
|
}
|
|
14441
16293
|
}
|
|
14442
16294
|
};
|
|
@@ -14553,6 +16405,26 @@ function OhhwellsBridge() {
|
|
|
14553
16405
|
hoveredNavContainerRef.current = null;
|
|
14554
16406
|
setHoveredNavContainerRect(null);
|
|
14555
16407
|
}
|
|
16408
|
+
const logoCandidates = [
|
|
16409
|
+
...document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]'),
|
|
16410
|
+
...document.querySelectorAll("nav a:not([data-ohw-href-key]), [data-ohw-nav-root] a:not([data-ohw-href-key])"),
|
|
16411
|
+
...document.querySelectorAll("footer img")
|
|
16412
|
+
];
|
|
16413
|
+
const seenLogos = /* @__PURE__ */ new Set();
|
|
16414
|
+
for (const candidate of logoCandidates) {
|
|
16415
|
+
const logo = getLogoElement(candidate);
|
|
16416
|
+
if (!logo || seenLogos.has(logo)) continue;
|
|
16417
|
+
seenLogos.add(logo);
|
|
16418
|
+
const r2 = logo.getBoundingClientRect();
|
|
16419
|
+
if (x < r2.left || x > r2.right || y < r2.top || y > r2.bottom) continue;
|
|
16420
|
+
hoveredNavContainerRef.current = null;
|
|
16421
|
+
setHoveredNavContainerRect(null);
|
|
16422
|
+
if (selectedElRef.current !== logo) {
|
|
16423
|
+
hoveredItemElRef.current = logo;
|
|
16424
|
+
setHoveredItemRect(getLogoInteractionRect(logo));
|
|
16425
|
+
}
|
|
16426
|
+
return;
|
|
16427
|
+
}
|
|
14556
16428
|
const navContainers = Array.from(
|
|
14557
16429
|
document.querySelectorAll("[data-ohw-nav-container]")
|
|
14558
16430
|
);
|
|
@@ -14638,7 +16510,7 @@ function OhhwellsBridge() {
|
|
|
14638
16510
|
}
|
|
14639
16511
|
};
|
|
14640
16512
|
const probeImageAt = (clientX, clientY, isDragOver = false, fromParentViewport = false) => {
|
|
14641
|
-
if (linkPopoverOpenRef.current) {
|
|
16513
|
+
if (linkPopoverOpenRef.current || floatingPanelOpenRef.current && isPointOverFloatingPanel(clientX, clientY)) {
|
|
14642
16514
|
if (hoveredImageRef.current) {
|
|
14643
16515
|
hoveredImageRef.current = null;
|
|
14644
16516
|
hoveredImageHasTextOverlapRef.current = false;
|
|
@@ -14892,7 +16764,7 @@ function OhhwellsBridge() {
|
|
|
14892
16764
|
}
|
|
14893
16765
|
};
|
|
14894
16766
|
const probeHoverCardsAt = (clientX, clientY, fromParentViewport = false) => {
|
|
14895
|
-
if (linkPopoverOpenRef.current || document.documentElement.hasAttribute("data-ohw-section-picking")) {
|
|
16767
|
+
if (linkPopoverOpenRef.current || floatingPanelOpenRef.current && isPointOverFloatingPanel(clientX, clientY) || document.documentElement.hasAttribute("data-ohw-section-picking")) {
|
|
14896
16768
|
if (activeStateElRef.current) {
|
|
14897
16769
|
activeStateElRef.current.removeAttribute("data-ohw-state-hovered");
|
|
14898
16770
|
activeStateElRef.current = null;
|
|
@@ -14960,6 +16832,19 @@ function OhhwellsBridge() {
|
|
|
14960
16832
|
};
|
|
14961
16833
|
const handleMouseMove = (e) => {
|
|
14962
16834
|
const { clientX, clientY } = e;
|
|
16835
|
+
if (document.documentElement.hasAttribute("data-ohw-panel-dragging") || floatingPanelOpenRef.current && isPointOverFloatingPanel(clientX, clientY)) {
|
|
16836
|
+
hoveredItemElRef.current = null;
|
|
16837
|
+
setHoveredItemRect(null);
|
|
16838
|
+
hoveredNavContainerRef.current = null;
|
|
16839
|
+
setHoveredNavContainerRect(null);
|
|
16840
|
+
siblingHintElRef.current = null;
|
|
16841
|
+
setSiblingHintRect(null);
|
|
16842
|
+
setSiblingHintRects([]);
|
|
16843
|
+
dismissImageHover();
|
|
16844
|
+
clearImageHover();
|
|
16845
|
+
setSectionGap(null);
|
|
16846
|
+
return;
|
|
16847
|
+
}
|
|
14963
16848
|
probeSectionGapAt(clientX, clientY);
|
|
14964
16849
|
probeImageAt(clientX, clientY);
|
|
14965
16850
|
probeHoverCardsAt(clientX, clientY);
|
|
@@ -14968,6 +16853,11 @@ function OhhwellsBridge() {
|
|
|
14968
16853
|
if (e.data?.type !== "ow:pointer-sync") return;
|
|
14969
16854
|
const { clientX, clientY } = e.data;
|
|
14970
16855
|
if (typeof clientX !== "number" || typeof clientY !== "number") return;
|
|
16856
|
+
if (document.documentElement.hasAttribute("data-ohw-panel-dragging") || floatingPanelOpenRef.current && isPointOverFloatingPanel(clientX, clientY)) {
|
|
16857
|
+
dismissImageHover();
|
|
16858
|
+
clearImageHover();
|
|
16859
|
+
return;
|
|
16860
|
+
}
|
|
14971
16861
|
probeSectionGapAt(clientX, clientY);
|
|
14972
16862
|
probeImageAt(clientX, clientY);
|
|
14973
16863
|
probeHoverCardsAt(clientX, clientY);
|
|
@@ -14977,7 +16867,7 @@ function OhhwellsBridge() {
|
|
|
14977
16867
|
if (footerSession) {
|
|
14978
16868
|
e.preventDefault();
|
|
14979
16869
|
if (e.dataTransfer) e.dataTransfer.dropEffect = "move";
|
|
14980
|
-
const slot = footerSession.kind === "link" && footerSession.hrefKey ? hitTestLinkDropSlot(e.clientX, e.clientY, footerSession.hrefKey) : hitTestColumnDropSlot(e.clientX, e.clientY);
|
|
16870
|
+
const slot = footerSession.kind === "social" && footerSession.hrefKey ? hitTestSocialDropSlot(e.clientX, e.clientY, footerSession.hrefKey) : footerSession.kind === "link" && footerSession.hrefKey ? hitTestLinkDropSlot(e.clientX, e.clientY, footerSession.hrefKey) : hitTestColumnDropSlot(e.clientX, e.clientY);
|
|
14981
16871
|
refreshFooterDragVisualsRef.current(footerSession, slot, e.clientX, e.clientY);
|
|
14982
16872
|
return;
|
|
14983
16873
|
}
|
|
@@ -15029,6 +16919,62 @@ function OhhwellsBridge() {
|
|
|
15029
16919
|
resumeAnimTracks();
|
|
15030
16920
|
clearImageHover();
|
|
15031
16921
|
};
|
|
16922
|
+
const handleSocialCancel = (e) => {
|
|
16923
|
+
if (e.data?.type !== "ow:social-cancel") return;
|
|
16924
|
+
const { hrefKey } = e.data;
|
|
16925
|
+
const item = hrefKey ? findSocialByHrefKey(hrefKey) : null;
|
|
16926
|
+
if (!item) return;
|
|
16927
|
+
const removed = removeSocialItem(item, editContentRef.current);
|
|
16928
|
+
if (!removed) return;
|
|
16929
|
+
const orderJson = JSON.stringify(removed.order);
|
|
16930
|
+
editContentRef.current = { ...editContentRef.current, [SOCIALS_ORDER_KEY]: orderJson };
|
|
16931
|
+
postToParentRef.current({ type: "ow:change", nodes: [{ key: SOCIALS_ORDER_KEY, text: orderJson }] });
|
|
16932
|
+
deselectRef.current();
|
|
16933
|
+
};
|
|
16934
|
+
const handleSocialUpdate = (e) => {
|
|
16935
|
+
if (e.data?.type !== "ow:social-update") return;
|
|
16936
|
+
const updates = Array.isArray(e.data.items) ? e.data.items : [e.data];
|
|
16937
|
+
const nodes = [];
|
|
16938
|
+
for (const { hrefKey, iconKey, url, iconMarkup, platformId, label } of updates) {
|
|
16939
|
+
if (hrefKey) {
|
|
16940
|
+
document.querySelectorAll(`[data-ohw-href-key="${hrefKey}"]`).forEach((el) => applyLinkHref(el, url));
|
|
16941
|
+
nodes.push({ key: hrefKey, text: url });
|
|
16942
|
+
}
|
|
16943
|
+
if (iconKey && typeof iconMarkup === "string" && iconMarkup) {
|
|
16944
|
+
document.querySelectorAll(`[data-ohw-key="${iconKey}"][data-ohw-editable="icon"]`).forEach((el) => {
|
|
16945
|
+
applyIconMarkup(el, iconMarkup);
|
|
16946
|
+
});
|
|
16947
|
+
nodes.push({ key: iconKey, text: iconMarkup });
|
|
16948
|
+
}
|
|
16949
|
+
if (iconKey && platformId) nodes.push({ key: socialPlatformKey(iconKey), text: platformId });
|
|
16950
|
+
if (iconKey && label) {
|
|
16951
|
+
const labelKey = socialLabelKey(iconKey);
|
|
16952
|
+
document.querySelectorAll(`[data-ohw-key="${labelKey}"]`).forEach((el) => {
|
|
16953
|
+
el.textContent = label;
|
|
16954
|
+
});
|
|
16955
|
+
nodes.push({ key: labelKey, text: label });
|
|
16956
|
+
}
|
|
16957
|
+
}
|
|
16958
|
+
if (!nodes.length) return;
|
|
16959
|
+
editContentRef.current = {
|
|
16960
|
+
...editContentRef.current,
|
|
16961
|
+
...Object.fromEntries(nodes.map((node) => [node.key, node.text]))
|
|
16962
|
+
};
|
|
16963
|
+
postToParentRef.current({ type: "ow:change", nodes, flush: true });
|
|
16964
|
+
};
|
|
16965
|
+
const handleIconMarkup = (e) => {
|
|
16966
|
+
if (e.data?.type !== "ow:icon-markup") return;
|
|
16967
|
+
const { key, markup } = e.data;
|
|
16968
|
+
if (!key || typeof markup !== "string") return;
|
|
16969
|
+
const targets = document.querySelectorAll(
|
|
16970
|
+
`[data-ohw-key="${key}"][data-ohw-editable="icon"]`
|
|
16971
|
+
);
|
|
16972
|
+
if (!targets.length) return;
|
|
16973
|
+
targets.forEach((el) => {
|
|
16974
|
+
applyIconMarkup(el, markup);
|
|
16975
|
+
});
|
|
16976
|
+
postToParentRef.current({ type: "ow:change", nodes: [{ key, text: markup }], flush: true });
|
|
16977
|
+
};
|
|
15032
16978
|
const handleImageUrl = (e) => {
|
|
15033
16979
|
if (e.data?.type !== "ow:image-url") return;
|
|
15034
16980
|
const { key, url } = e.data;
|
|
@@ -15161,6 +17107,11 @@ function OhhwellsBridge() {
|
|
|
15161
17107
|
aiSectionsRef.current = content[AI_SECTIONS_KEY];
|
|
15162
17108
|
applyAiSectionsToDom(parseAiSectionsState(content[AI_SECTIONS_KEY]));
|
|
15163
17109
|
}
|
|
17110
|
+
if (typeof content[BRAND_KIT_KEY] === "string") {
|
|
17111
|
+
brandKitRef.current = content[BRAND_KIT_KEY];
|
|
17112
|
+
applyBrandToDom(parseBrandKit(content[BRAND_KIT_KEY]));
|
|
17113
|
+
}
|
|
17114
|
+
applyBrandChrome(content);
|
|
15164
17115
|
let sectionsJson = null;
|
|
15165
17116
|
for (const [key, val] of Object.entries(content)) {
|
|
15166
17117
|
if (key === "__ohw_sections") {
|
|
@@ -15168,6 +17119,10 @@ function OhhwellsBridge() {
|
|
|
15168
17119
|
continue;
|
|
15169
17120
|
}
|
|
15170
17121
|
if (key === AI_SECTIONS_KEY) continue;
|
|
17122
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
17123
|
+
if (LOGO_IMAGE_KEYS.includes(key) && !String(val ?? "").trim()) continue;
|
|
17124
|
+
if (key === BRAND_KIT_KEY) continue;
|
|
17125
|
+
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
15171
17126
|
if (applyVideoSettingNode(key, val)) continue;
|
|
15172
17127
|
if (applyCarouselNode(key, val)) continue;
|
|
15173
17128
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
@@ -15187,6 +17142,8 @@ function OhhwellsBridge() {
|
|
|
15187
17142
|
});
|
|
15188
17143
|
applyLinkByKey(key, val);
|
|
15189
17144
|
}
|
|
17145
|
+
applyLogoFromContent(content);
|
|
17146
|
+
applyLogoSizes(content);
|
|
15190
17147
|
if (sectionsJson) {
|
|
15191
17148
|
initSectionsFromContent({ __ohw_sections: sectionsJson }, true);
|
|
15192
17149
|
sectionsLoadedRef.current = true;
|
|
@@ -15201,6 +17158,58 @@ function OhhwellsBridge() {
|
|
|
15201
17158
|
if (hydratedHeight > 50) postToParentRef.current({ type: "ow:height", height: hydratedHeight });
|
|
15202
17159
|
postToParentRef.current({ type: "ow:hydrate-done" });
|
|
15203
17160
|
};
|
|
17161
|
+
const handleUpdateLogoIdentity = (e) => {
|
|
17162
|
+
if (e.data?.type !== "ow:update-logo-identity") return;
|
|
17163
|
+
const rawText = typeof e.data.text === "string" ? e.data.text : "";
|
|
17164
|
+
const alt = typeof e.data.alt === "string" ? e.data.alt : rawText;
|
|
17165
|
+
const href = typeof e.data.href === "string" ? e.data.href : void 0;
|
|
17166
|
+
const imageProvided = "image" in e.data;
|
|
17167
|
+
const imageUrl = imageProvided && typeof e.data.image === "string" && e.data.image.trim() ? e.data.image.trim() : imageProvided ? null : void 0;
|
|
17168
|
+
let isPlaceholder = e.data.isPlaceholder !== false;
|
|
17169
|
+
if (imageUrl) isPlaceholder = false;
|
|
17170
|
+
else if (imageProvided && imageUrl === null) {
|
|
17171
|
+
isPlaceholder = e.data.isPlaceholder === true || !rawText.trim() || resolveLogoDisplayText(rawText) === PLACEHOLDER_BUSINESS_NAME;
|
|
17172
|
+
}
|
|
17173
|
+
const display = applyLogoIdentity(rawText, isPlaceholder);
|
|
17174
|
+
const displayAlt = resolveLogoDisplayText(alt || display);
|
|
17175
|
+
if (imageUrl !== void 0) {
|
|
17176
|
+
applyLogoImage(imageUrl, displayAlt);
|
|
17177
|
+
} else {
|
|
17178
|
+
for (const key of LOGO_IMAGE_KEYS) {
|
|
17179
|
+
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
17180
|
+
const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
|
|
17181
|
+
if (img) img.alt = displayAlt;
|
|
17182
|
+
});
|
|
17183
|
+
}
|
|
17184
|
+
}
|
|
17185
|
+
if (href !== void 0) {
|
|
17186
|
+
applyLogoHref(href);
|
|
17187
|
+
applyLinkByKey("nav-logo-href", href);
|
|
17188
|
+
applyLinkByKey("footer-logo-href", href);
|
|
17189
|
+
applyLinkByKey("logo-href", href);
|
|
17190
|
+
}
|
|
17191
|
+
const nodes = [
|
|
17192
|
+
...LOGO_TEXT_KEYS.map((key) => ({ key, text: display })),
|
|
17193
|
+
{ key: LOGO_PLACEHOLDER_KEY, text: isPlaceholder ? "true" : "false" },
|
|
17194
|
+
{ key: LOGO_ALT_KEY, text: displayAlt }
|
|
17195
|
+
];
|
|
17196
|
+
if (imageUrl !== void 0) {
|
|
17197
|
+
if (imageUrl) {
|
|
17198
|
+
for (const key of LOGO_IMAGE_KEYS) nodes.push({ key, text: imageUrl });
|
|
17199
|
+
} else {
|
|
17200
|
+
for (const key of LOGO_IMAGE_KEYS) nodes.push({ key, text: "" });
|
|
17201
|
+
}
|
|
17202
|
+
}
|
|
17203
|
+
if (href !== void 0) {
|
|
17204
|
+
for (const key of LOGO_HREF_KEYS) nodes.push({ key, text: href.trim() || "/" });
|
|
17205
|
+
}
|
|
17206
|
+
editContentRef.current = {
|
|
17207
|
+
...editContentRef.current,
|
|
17208
|
+
...Object.fromEntries(nodes.map(({ key, text }) => [key, text]))
|
|
17209
|
+
};
|
|
17210
|
+
applyLogoSizes(editContentRef.current);
|
|
17211
|
+
postToParentRef.current({ type: "ow:change", nodes });
|
|
17212
|
+
};
|
|
15204
17213
|
window.addEventListener("message", handleHydrate);
|
|
15205
17214
|
const postAiSectionsChanged = () => {
|
|
15206
17215
|
postToParentRef.current({
|
|
@@ -15257,6 +17266,17 @@ function OhhwellsBridge() {
|
|
|
15257
17266
|
postAiSectionsChanged();
|
|
15258
17267
|
};
|
|
15259
17268
|
window.addEventListener("message", handleAiSetSections);
|
|
17269
|
+
const handleAiSetBrand = (e) => {
|
|
17270
|
+
if (e.data?.type !== "ow:ai-set-brand") return;
|
|
17271
|
+
const value = typeof e.data.value === "string" ? e.data.value : "";
|
|
17272
|
+
const previous = brandKitRef.current;
|
|
17273
|
+
brandKitRef.current = value;
|
|
17274
|
+
applyBrandToDom(parseBrandKit(value));
|
|
17275
|
+
if (aiSectionsRef.current) applyAiSectionsToDom(parseAiSectionsState(aiSectionsRef.current));
|
|
17276
|
+
postToParentRef.current({ type: "ow:change", nodes: [{ key: BRAND_KIT_KEY, text: value }] });
|
|
17277
|
+
postToParentRef.current({ type: "ow:ai-brand-applied", previous, value });
|
|
17278
|
+
};
|
|
17279
|
+
window.addEventListener("message", handleAiSetBrand);
|
|
15260
17280
|
const handleDeactivate = (e) => {
|
|
15261
17281
|
if (e.data?.type !== "ow:deactivate") return;
|
|
15262
17282
|
if (Date.now() < linkPopoverGraceUntilRef.current) return;
|
|
@@ -15265,6 +17285,12 @@ function OhhwellsBridge() {
|
|
|
15265
17285
|
closeLinkPopoverRef.current();
|
|
15266
17286
|
return;
|
|
15267
17287
|
}
|
|
17288
|
+
if (floatingPanelOpenRef.current) {
|
|
17289
|
+
setFloatingPanelRef.current(null);
|
|
17290
|
+
deselectRef.current();
|
|
17291
|
+
deactivateRef.current();
|
|
17292
|
+
return;
|
|
17293
|
+
}
|
|
15268
17294
|
deselectRef.current();
|
|
15269
17295
|
deactivateRef.current();
|
|
15270
17296
|
};
|
|
@@ -15284,6 +17310,10 @@ function OhhwellsBridge() {
|
|
|
15284
17310
|
closeLinkPopoverRef.current();
|
|
15285
17311
|
return;
|
|
15286
17312
|
}
|
|
17313
|
+
if (floatingPanelOpenRef.current) {
|
|
17314
|
+
closeFloatingPanelOnlyRef.current();
|
|
17315
|
+
return;
|
|
17316
|
+
}
|
|
15287
17317
|
if (activeElRef.current) {
|
|
15288
17318
|
const hrefCtx = getHrefKeyFromElement(activeElRef.current);
|
|
15289
17319
|
const navAnchor = hrefCtx ? getNavigationItemAnchor(hrefCtx.anchor) : null;
|
|
@@ -15314,6 +17344,10 @@ function OhhwellsBridge() {
|
|
|
15314
17344
|
return;
|
|
15315
17345
|
}
|
|
15316
17346
|
if (selectedElRef.current) {
|
|
17347
|
+
if (toolbarVariantRef.current === "logo") {
|
|
17348
|
+
deselectRef.current();
|
|
17349
|
+
return;
|
|
17350
|
+
}
|
|
15317
17351
|
if (toolbarVariantRef.current === "select-frame") {
|
|
15318
17352
|
const parent2 = getNavigationSelectionParent(selectedElRef.current);
|
|
15319
17353
|
if (parent2 && isNavigationContainer(parent2) && isFooterLinksContainer(parent2) && !isFooterLinksContainer(selectedElRef.current)) {
|
|
@@ -15347,7 +17381,16 @@ function OhhwellsBridge() {
|
|
|
15347
17381
|
closeLinkPopoverRef.current();
|
|
15348
17382
|
return;
|
|
15349
17383
|
}
|
|
17384
|
+
if (e.key === "Escape" && floatingPanelOpenRef.current) {
|
|
17385
|
+
e.preventDefault();
|
|
17386
|
+
closeFloatingPanelOnlyRef.current();
|
|
17387
|
+
return;
|
|
17388
|
+
}
|
|
15350
17389
|
if (e.key === "Escape" && selectedElRef.current && !activeElRef.current) {
|
|
17390
|
+
if (toolbarVariantRef.current === "logo") {
|
|
17391
|
+
deselectRef.current();
|
|
17392
|
+
return;
|
|
17393
|
+
}
|
|
15351
17394
|
if (toolbarVariantRef.current === "select-frame") {
|
|
15352
17395
|
const parent2 = getNavigationSelectionParent(selectedElRef.current);
|
|
15353
17396
|
if (parent2 && isNavigationContainer(parent2) && isFooterLinksContainer(parent2) && !isFooterLinksContainer(selectedElRef.current)) {
|
|
@@ -15425,7 +17468,8 @@ function OhhwellsBridge() {
|
|
|
15425
17468
|
const handleScroll = () => {
|
|
15426
17469
|
const focusEl = activeElRef.current ?? selectedElRef.current;
|
|
15427
17470
|
if (focusEl) {
|
|
15428
|
-
const
|
|
17471
|
+
const measureEl = activeElRef.current ? getEditMeasureEl(activeElRef.current) : toolbarVariantRef.current === "logo" ? null : focusEl;
|
|
17472
|
+
const r2 = measureEl ? measureEl.getBoundingClientRect() : toolbarVariantRef.current === "logo" ? getLogoInteractionRect(focusEl) : focusEl.getBoundingClientRect();
|
|
15429
17473
|
applyToolbarPos(r2);
|
|
15430
17474
|
setToolbarRect(r2);
|
|
15431
17475
|
setMaxBadge((prev) => prev && activeElRef.current ? { ...prev, rect: r2 } : prev);
|
|
@@ -15435,7 +17479,9 @@ function OhhwellsBridge() {
|
|
|
15435
17479
|
setToggleState((prev) => prev ? { ...prev, rect } : null);
|
|
15436
17480
|
}
|
|
15437
17481
|
if (hoveredItemElRef.current) {
|
|
15438
|
-
|
|
17482
|
+
const hoverEl = hoveredItemElRef.current;
|
|
17483
|
+
const logo = getLogoElement(hoverEl);
|
|
17484
|
+
setHoveredItemRect(logo ? getLogoInteractionRect(logo) : hoverEl.getBoundingClientRect());
|
|
15439
17485
|
}
|
|
15440
17486
|
if (hoveredNavContainerRef.current) {
|
|
15441
17487
|
setHoveredNavContainerRect(hoveredNavContainerRef.current.getBoundingClientRect());
|
|
@@ -15455,7 +17501,7 @@ function OhhwellsBridge() {
|
|
|
15455
17501
|
}
|
|
15456
17502
|
if (footerDragRef.current) {
|
|
15457
17503
|
const session = footerDragRef.current;
|
|
15458
|
-
const slot = session.kind === "link" && session.hrefKey ? hitTestLinkDropSlot(session.lastClientX, session.lastClientY, session.hrefKey) : hitTestColumnDropSlot(session.lastClientX, session.lastClientY);
|
|
17504
|
+
const slot = session.kind === "social" && session.hrefKey ? hitTestSocialDropSlot(session.lastClientX, session.lastClientY, session.hrefKey) : session.kind === "link" && session.hrefKey ? hitTestLinkDropSlot(session.lastClientX, session.lastClientY, session.hrefKey) : hitTestColumnDropSlot(session.lastClientX, session.lastClientY);
|
|
15459
17505
|
refreshFooterDragVisualsRef.current(session, slot, session.lastClientX, session.lastClientY);
|
|
15460
17506
|
}
|
|
15461
17507
|
if (navDragRef.current) {
|
|
@@ -15479,6 +17525,9 @@ function OhhwellsBridge() {
|
|
|
15479
17525
|
if (aiSectionsRef.current) {
|
|
15480
17526
|
nodes.push({ key: AI_SECTIONS_KEY, type: "sections", text: aiSectionsRef.current });
|
|
15481
17527
|
}
|
|
17528
|
+
if (brandKitRef.current) {
|
|
17529
|
+
nodes.push({ key: BRAND_KIT_KEY, type: "brand", text: brandKitRef.current });
|
|
17530
|
+
}
|
|
15482
17531
|
postToParentRef.current({ type: "ow:save-result", nodes });
|
|
15483
17532
|
};
|
|
15484
17533
|
const handleInsertSection = (e) => {
|
|
@@ -15489,8 +17538,12 @@ function OhhwellsBridge() {
|
|
|
15489
17538
|
if (inserted) {
|
|
15490
17539
|
const tracker = getSectionsTracker();
|
|
15491
17540
|
postToParentRef.current({ type: "ow:change", nodes: [{ key: "__ohw_sections", text: tracker.textContent ?? "[]" }] });
|
|
15492
|
-
const
|
|
15493
|
-
|
|
17541
|
+
const reportHeight = () => {
|
|
17542
|
+
const h = document.body.scrollHeight;
|
|
17543
|
+
if (h > 50) postToParentRef.current({ type: "ow:height", height: h });
|
|
17544
|
+
};
|
|
17545
|
+
reportHeight();
|
|
17546
|
+
setTimeout(reportHeight, 500);
|
|
15494
17547
|
}
|
|
15495
17548
|
};
|
|
15496
17549
|
const handleSwitchSchedule = (e) => {
|
|
@@ -15683,13 +17736,17 @@ function OhhwellsBridge() {
|
|
|
15683
17736
|
if (e.data?.type !== "ow:parent-scroll") return;
|
|
15684
17737
|
const { iframeOffsetTop, headerH, canvasH } = e.data;
|
|
15685
17738
|
parentScrollRef.current = { iframeOffsetTop, headerH, canvasH };
|
|
17739
|
+
if (floatingPanelOpenRef.current) {
|
|
17740
|
+
setParentScrollSnap({ iframeOffsetTop, headerH, canvasH });
|
|
17741
|
+
}
|
|
15686
17742
|
if (visibleViewportRef.current) {
|
|
15687
17743
|
applyVisibleViewport(visibleViewportRef.current, parentScrollRef.current);
|
|
15688
17744
|
}
|
|
15689
17745
|
const focusEl = activeElRef.current ?? selectedElRef.current;
|
|
15690
17746
|
if (focusEl) {
|
|
15691
|
-
const measureEl = activeElRef.current ? getEditMeasureEl(activeElRef.current) : focusEl;
|
|
15692
|
-
|
|
17747
|
+
const measureEl = activeElRef.current ? getEditMeasureEl(activeElRef.current) : toolbarVariantRef.current === "logo" ? null : focusEl;
|
|
17748
|
+
const r2 = measureEl ? measureEl.getBoundingClientRect() : toolbarVariantRef.current === "logo" ? getLogoInteractionRect(focusEl) : focusEl.getBoundingClientRect();
|
|
17749
|
+
applyToolbarPos(r2);
|
|
15693
17750
|
}
|
|
15694
17751
|
};
|
|
15695
17752
|
const handleClickAt = (e) => {
|
|
@@ -15714,6 +17771,25 @@ function OhhwellsBridge() {
|
|
|
15714
17771
|
postToParentRef.current({ type: "ow:image-pick", key: stateCardImage.dataset.ohwKey ?? "", elementType: stateCardImage.dataset.ohwEditable ?? "image" });
|
|
15715
17772
|
return;
|
|
15716
17773
|
}
|
|
17774
|
+
const logoAtPoint = Array.from(
|
|
17775
|
+
document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]')
|
|
17776
|
+
).map((el) => getLogoElement(el)).find((logo) => {
|
|
17777
|
+
if (!logo) return false;
|
|
17778
|
+
const r2 = logo.getBoundingClientRect();
|
|
17779
|
+
return clientX >= r2.left && clientX <= r2.right && clientY >= r2.top && clientY <= r2.bottom;
|
|
17780
|
+
});
|
|
17781
|
+
if (logoAtPoint) {
|
|
17782
|
+
if (!logoHasUploadedImage(logoAtPoint)) {
|
|
17783
|
+
deselectRef.current();
|
|
17784
|
+
deactivateRef.current();
|
|
17785
|
+
const identity = readLogoIdentityFromDom();
|
|
17786
|
+
postToParentRef.current({ type: "ow:open-logo-settings", ...identity });
|
|
17787
|
+
return;
|
|
17788
|
+
}
|
|
17789
|
+
selectLogoRef.current(logoAtPoint);
|
|
17790
|
+
openLogoSizePanelRef.current(logoAtPoint);
|
|
17791
|
+
return;
|
|
17792
|
+
}
|
|
15717
17793
|
const textEditable = Array.from(
|
|
15718
17794
|
document.querySelectorAll(NON_MEDIA_SELECTOR)
|
|
15719
17795
|
).find((el) => {
|
|
@@ -15775,6 +17851,9 @@ function OhhwellsBridge() {
|
|
|
15775
17851
|
window.addEventListener("message", handleClearSchedulingWidget);
|
|
15776
17852
|
window.addEventListener("message", handleRemoveSchedulingSection);
|
|
15777
17853
|
window.addEventListener("message", handleCollectSection);
|
|
17854
|
+
window.addEventListener("message", handleSocialCancel);
|
|
17855
|
+
window.addEventListener("message", handleSocialUpdate);
|
|
17856
|
+
window.addEventListener("message", handleIconMarkup);
|
|
15778
17857
|
window.addEventListener("message", handleImageUrl);
|
|
15779
17858
|
window.addEventListener("message", handleImageUploading);
|
|
15780
17859
|
window.addEventListener("message", handleCarouselChange);
|
|
@@ -15782,6 +17861,14 @@ function OhhwellsBridge() {
|
|
|
15782
17861
|
window.addEventListener("message", handleParentScroll);
|
|
15783
17862
|
window.addEventListener("message", handlePointerSync);
|
|
15784
17863
|
window.addEventListener("message", handleClickAt);
|
|
17864
|
+
window.addEventListener("message", handleUpdateLogoIdentity);
|
|
17865
|
+
const handleViewMode = (e) => {
|
|
17866
|
+
if (e.data?.type !== "ow:view-mode") return;
|
|
17867
|
+
const mode = e.data.mode === "Mobile" || e.data.mode === "mobile" ? "mobile" : "desktop";
|
|
17868
|
+
setEditorViewport(mode);
|
|
17869
|
+
applyLogoSizes(editContentRef.current);
|
|
17870
|
+
};
|
|
17871
|
+
window.addEventListener("message", handleViewMode);
|
|
15785
17872
|
const handleViewportResize = () => {
|
|
15786
17873
|
if (visibleViewportRef.current) {
|
|
15787
17874
|
applyVisibleViewport(visibleViewportRef.current, parentScrollRef.current);
|
|
@@ -15826,6 +17913,9 @@ function OhhwellsBridge() {
|
|
|
15826
17913
|
window.removeEventListener("message", handleClearSchedulingWidget);
|
|
15827
17914
|
window.removeEventListener("message", handleRemoveSchedulingSection);
|
|
15828
17915
|
window.removeEventListener("message", handleCollectSection);
|
|
17916
|
+
window.removeEventListener("message", handleSocialCancel);
|
|
17917
|
+
window.removeEventListener("message", handleSocialUpdate);
|
|
17918
|
+
window.removeEventListener("message", handleIconMarkup);
|
|
15829
17919
|
window.removeEventListener("message", handleImageUrl);
|
|
15830
17920
|
window.removeEventListener("message", handleImageUploading);
|
|
15831
17921
|
window.removeEventListener("message", handleCarouselChange);
|
|
@@ -15834,10 +17924,13 @@ function OhhwellsBridge() {
|
|
|
15834
17924
|
window.removeEventListener("resize", handleViewportResize);
|
|
15835
17925
|
window.removeEventListener("message", handlePointerSync);
|
|
15836
17926
|
window.removeEventListener("message", handleClickAt);
|
|
17927
|
+
window.removeEventListener("message", handleUpdateLogoIdentity);
|
|
17928
|
+
window.removeEventListener("message", handleViewMode);
|
|
15837
17929
|
window.removeEventListener("message", handleHydrate);
|
|
15838
17930
|
window.removeEventListener("message", handleAiApplyTree);
|
|
15839
17931
|
window.removeEventListener("message", handleAiDeleteSection);
|
|
15840
17932
|
window.removeEventListener("message", handleAiSetSections);
|
|
17933
|
+
window.removeEventListener("message", handleAiSetBrand);
|
|
15841
17934
|
window.removeEventListener("message", handleDeactivate);
|
|
15842
17935
|
window.removeEventListener("message", handleToastAction);
|
|
15843
17936
|
window.removeEventListener("message", handleUiEscape);
|
|
@@ -15847,7 +17940,7 @@ function OhhwellsBridge() {
|
|
|
15847
17940
|
if (imageShowTimerRef.current) clearTimeout(imageShowTimerRef.current);
|
|
15848
17941
|
};
|
|
15849
17942
|
}, [isEditMode, refreshStateRules]);
|
|
15850
|
-
|
|
17943
|
+
useEffect12(() => {
|
|
15851
17944
|
if (!isEditMode) return;
|
|
15852
17945
|
const THRESHOLD = 10;
|
|
15853
17946
|
const resolveWasSelected = (el) => {
|
|
@@ -15863,13 +17956,13 @@ function OhhwellsBridge() {
|
|
|
15863
17956
|
if (footerDragRef.current) return;
|
|
15864
17957
|
const target = e.target;
|
|
15865
17958
|
if (!target) return;
|
|
15866
|
-
if (target.closest('[data-ohw-drag-handle-container], [data-slot="drag-handle"], [data-ohw-toolbar], [data-ohw-item-toolbar-anchor], [data-ohw-link-popover-root]')) {
|
|
17959
|
+
if (target.closest('[data-ohw-drag-handle-container], [data-slot="drag-handle"], [data-ohw-toolbar], [data-ohw-item-toolbar-anchor], [data-ohw-link-popover-root], [data-ohw-floating-panel]')) {
|
|
15867
17960
|
return;
|
|
15868
17961
|
}
|
|
15869
17962
|
if (target.closest("[data-ohw-item-drag-surface]")) return;
|
|
15870
|
-
const anchor = getNavigationItemAnchor(target);
|
|
17963
|
+
const anchor = getNavigationItemAnchor(target) ?? (document.elementsFromPoint(e.clientX, e.clientY).map((el) => el instanceof HTMLElement ? getNavigationItemAnchor(el) : null).find((found) => found !== null) ?? null);
|
|
15871
17964
|
const hrefKey = anchor?.getAttribute("data-ohw-href-key") ?? null;
|
|
15872
|
-
if (anchor && isFooterHrefKey(hrefKey)) {
|
|
17965
|
+
if (anchor && (isFooterHrefKey(hrefKey) || getSocialItem(anchor))) {
|
|
15873
17966
|
footerPointerDragRef.current = {
|
|
15874
17967
|
el: anchor,
|
|
15875
17968
|
kind: "link",
|
|
@@ -15902,7 +17995,7 @@ function OhhwellsBridge() {
|
|
|
15902
17995
|
clearTextSelection();
|
|
15903
17996
|
const session = footerDragRef.current;
|
|
15904
17997
|
if (!session) return;
|
|
15905
|
-
const slot = session.kind === "link" && session.hrefKey ? hitTestLinkDropSlot(e.clientX, e.clientY, session.hrefKey) : hitTestColumnDropSlot(e.clientX, e.clientY);
|
|
17998
|
+
const slot = session.kind === "social" && session.hrefKey ? hitTestSocialDropSlot(e.clientX, e.clientY, session.hrefKey) : session.kind === "link" && session.hrefKey ? hitTestLinkDropSlot(e.clientX, e.clientY, session.hrefKey) : hitTestColumnDropSlot(e.clientX, e.clientY);
|
|
15906
17999
|
refreshFooterDragVisualsRef.current(session, slot, e.clientX, e.clientY);
|
|
15907
18000
|
return;
|
|
15908
18001
|
}
|
|
@@ -15929,7 +18022,7 @@ function OhhwellsBridge() {
|
|
|
15929
18022
|
const column = findFooterColumnForLink(pending.el);
|
|
15930
18023
|
const columns2 = listFooterColumns();
|
|
15931
18024
|
beginFooterDragRef.current({
|
|
15932
|
-
kind: "link",
|
|
18025
|
+
kind: getSocialItem(pending.el) ? "social" : "link",
|
|
15933
18026
|
hrefKey: key,
|
|
15934
18027
|
columnEl: column,
|
|
15935
18028
|
sourceColumnIndex: column ? columns2.indexOf(column) : 0,
|
|
@@ -16001,7 +18094,7 @@ function OhhwellsBridge() {
|
|
|
16001
18094
|
unlockFooterDragInteraction();
|
|
16002
18095
|
};
|
|
16003
18096
|
}, [isEditMode]);
|
|
16004
|
-
|
|
18097
|
+
useEffect12(() => {
|
|
16005
18098
|
const handler = (e) => {
|
|
16006
18099
|
if (e.data?.type !== "ow:request-schedule-config") return;
|
|
16007
18100
|
const insertAfterVal = e.data.insertAfter;
|
|
@@ -16017,7 +18110,7 @@ function OhhwellsBridge() {
|
|
|
16017
18110
|
window.addEventListener("message", handler);
|
|
16018
18111
|
return () => window.removeEventListener("message", handler);
|
|
16019
18112
|
}, [processConfigRequest]);
|
|
16020
|
-
|
|
18113
|
+
useEffect12(() => {
|
|
16021
18114
|
if (!isEditMode) return;
|
|
16022
18115
|
document.querySelectorAll("[data-ohw-active-state]").forEach((el) => {
|
|
16023
18116
|
el.removeAttribute("data-ohw-active-state");
|
|
@@ -16041,7 +18134,7 @@ function OhhwellsBridge() {
|
|
|
16041
18134
|
postToParent2({
|
|
16042
18135
|
type: "ow:ready",
|
|
16043
18136
|
version: "1",
|
|
16044
|
-
bridgeVersion: "0.1.
|
|
18137
|
+
bridgeVersion: "0.1.55",
|
|
16045
18138
|
path: pathname,
|
|
16046
18139
|
nodes: collectEditableNodes(editContentRef.current),
|
|
16047
18140
|
sections
|
|
@@ -16053,13 +18146,13 @@ function OhhwellsBridge() {
|
|
|
16053
18146
|
clearTimeout(timer);
|
|
16054
18147
|
};
|
|
16055
18148
|
}, [pathname, isEditMode, refreshStateRules, postToParent2]);
|
|
16056
|
-
|
|
18149
|
+
useEffect12(() => {
|
|
16057
18150
|
scrollToHashSectionWhenReady();
|
|
16058
18151
|
const onHashChange = () => scrollToHashSectionWhenReady();
|
|
16059
18152
|
window.addEventListener("hashchange", onHashChange);
|
|
16060
18153
|
return () => window.removeEventListener("hashchange", onHashChange);
|
|
16061
18154
|
}, [pathname]);
|
|
16062
|
-
const handleCommand =
|
|
18155
|
+
const handleCommand = useCallback7((cmd) => {
|
|
16063
18156
|
const el = activeElRef.current;
|
|
16064
18157
|
const selBefore = window.getSelection();
|
|
16065
18158
|
let savedOffsets = null;
|
|
@@ -16095,7 +18188,7 @@ function OhhwellsBridge() {
|
|
|
16095
18188
|
if (el) setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
|
|
16096
18189
|
refreshActiveCommandsRef.current();
|
|
16097
18190
|
}, []);
|
|
16098
|
-
const handleStateChange =
|
|
18191
|
+
const handleStateChange = useCallback7((state) => {
|
|
16099
18192
|
if (!activeStateElRef.current) return;
|
|
16100
18193
|
const el = activeStateElRef.current;
|
|
16101
18194
|
if (state === "Default") {
|
|
@@ -16108,7 +18201,7 @@ function OhhwellsBridge() {
|
|
|
16108
18201
|
}
|
|
16109
18202
|
setToggleState((prev) => prev ? { ...prev, activeState: state } : null);
|
|
16110
18203
|
}, [deactivate]);
|
|
16111
|
-
const reselectAfterLinkPopover =
|
|
18204
|
+
const reselectAfterLinkPopover = useCallback7(
|
|
16112
18205
|
(hrefKey) => {
|
|
16113
18206
|
requestAnimationFrame(() => {
|
|
16114
18207
|
const el = resolveHrefKeyElement(hrefKey);
|
|
@@ -16117,7 +18210,7 @@ function OhhwellsBridge() {
|
|
|
16117
18210
|
},
|
|
16118
18211
|
[resolveHrefKeyElement]
|
|
16119
18212
|
);
|
|
16120
|
-
const closeLinkPopover =
|
|
18213
|
+
const closeLinkPopover = useCallback7(() => {
|
|
16121
18214
|
const session = linkPopoverSessionRef.current;
|
|
16122
18215
|
addNavAfterAnchorRef.current = null;
|
|
16123
18216
|
setLinkPopover(null);
|
|
@@ -16125,9 +18218,9 @@ function OhhwellsBridge() {
|
|
|
16125
18218
|
reselectAfterLinkPopover(session.key);
|
|
16126
18219
|
}
|
|
16127
18220
|
}, [reselectAfterLinkPopover]);
|
|
16128
|
-
const closeLinkPopoverRef =
|
|
18221
|
+
const closeLinkPopoverRef = useRef9(closeLinkPopover);
|
|
16129
18222
|
closeLinkPopoverRef.current = closeLinkPopover;
|
|
16130
|
-
const openLinkPopoverForActive =
|
|
18223
|
+
const openLinkPopoverForActive = useCallback7(() => {
|
|
16131
18224
|
const hrefCtx = getHrefKeyFromElement(activeElRef.current);
|
|
16132
18225
|
if (!hrefCtx) return;
|
|
16133
18226
|
bumpLinkPopoverGrace();
|
|
@@ -16138,11 +18231,15 @@ function OhhwellsBridge() {
|
|
|
16138
18231
|
});
|
|
16139
18232
|
deactivate();
|
|
16140
18233
|
}, [deactivate]);
|
|
16141
|
-
const openLinkPopoverForSelected =
|
|
18234
|
+
const openLinkPopoverForSelected = useCallback7(() => {
|
|
16142
18235
|
const anchor = selectedElRef.current;
|
|
16143
18236
|
if (!anchor) return;
|
|
16144
18237
|
const key = anchor.getAttribute("data-ohw-href-key");
|
|
16145
18238
|
if (!key) return;
|
|
18239
|
+
if (requestSocialDialog(anchor, postToParentRef.current, editContentRef.current)) {
|
|
18240
|
+
deselect();
|
|
18241
|
+
return;
|
|
18242
|
+
}
|
|
16146
18243
|
bumpLinkPopoverGrace();
|
|
16147
18244
|
setLinkPopover({
|
|
16148
18245
|
key,
|
|
@@ -16151,7 +18248,7 @@ function OhhwellsBridge() {
|
|
|
16151
18248
|
});
|
|
16152
18249
|
deselect();
|
|
16153
18250
|
}, [deselect]);
|
|
16154
|
-
const handleSelectParent =
|
|
18251
|
+
const handleSelectParent = useCallback7(() => {
|
|
16155
18252
|
const selected = selectedElRef.current;
|
|
16156
18253
|
if (!selected) return;
|
|
16157
18254
|
if (toolbarVariantRef.current === "select-frame") {
|
|
@@ -16178,11 +18275,37 @@ function OhhwellsBridge() {
|
|
|
16178
18275
|
}
|
|
16179
18276
|
deselectRef.current();
|
|
16180
18277
|
}, []);
|
|
16181
|
-
const handleDuplicateSelected =
|
|
18278
|
+
const handleDuplicateSelected = useCallback7(() => {
|
|
16182
18279
|
const selected = selectedElRef.current;
|
|
16183
18280
|
if (!selected || !isNavigationItem2(selected)) return;
|
|
16184
18281
|
const hrefKey = selected.getAttribute("data-ohw-href-key");
|
|
16185
18282
|
if (!hrefKey) return;
|
|
18283
|
+
const social = getSocialItem(selected);
|
|
18284
|
+
if (social) {
|
|
18285
|
+
const result = duplicateSocialItem(social, editContentRef.current);
|
|
18286
|
+
if (!result) return;
|
|
18287
|
+
const orderJson = JSON.stringify(result.order);
|
|
18288
|
+
const carried = [
|
|
18289
|
+
{ from: result.copiedFrom?.href, to: result.hrefKey },
|
|
18290
|
+
{ from: result.copiedFrom?.icon, to: result.iconKey },
|
|
18291
|
+
{ from: result.copiedFrom?.icon ? socialPlatformKey(result.copiedFrom.icon) : null, to: socialPlatformKey(result.iconKey) }
|
|
18292
|
+
];
|
|
18293
|
+
const nodes = [{ key: SOCIALS_ORDER_KEY, text: orderJson }];
|
|
18294
|
+
for (const { from, to } of carried) {
|
|
18295
|
+
const value = from ? editContentRef.current[from] : void 0;
|
|
18296
|
+
if (value) nodes.push({ key: to, text: value });
|
|
18297
|
+
}
|
|
18298
|
+
editContentRef.current = {
|
|
18299
|
+
...editContentRef.current,
|
|
18300
|
+
...Object.fromEntries(nodes.map((node) => [node.key, node.text]))
|
|
18301
|
+
};
|
|
18302
|
+
postToParent2({ type: "ow:change", nodes });
|
|
18303
|
+
enforceLinkHrefs();
|
|
18304
|
+
const copyRow = findSocialsRow(result.item);
|
|
18305
|
+
if (copyRow) applySocialsDisplayToRow(copyRow, socialsDisplayFor(copyRow, editContentRef.current));
|
|
18306
|
+
requestAnimationFrame(() => selectRef.current(result.item));
|
|
18307
|
+
return;
|
|
18308
|
+
}
|
|
16186
18309
|
if (isNavbarHrefKey(hrefKey)) {
|
|
16187
18310
|
const result = duplicateNavbarItem(selected);
|
|
16188
18311
|
if (!result) return;
|
|
@@ -16268,7 +18391,7 @@ function OhhwellsBridge() {
|
|
|
16268
18391
|
});
|
|
16269
18392
|
}
|
|
16270
18393
|
}, [postToParent2]);
|
|
16271
|
-
const runPendingDeleteUndo =
|
|
18394
|
+
const runPendingDeleteUndo = useCallback7(() => {
|
|
16272
18395
|
const pending = pendingDeleteUndoRef.current;
|
|
16273
18396
|
if (!pending) return false;
|
|
16274
18397
|
pendingDeleteUndoRef.current = null;
|
|
@@ -16276,7 +18399,7 @@ function OhhwellsBridge() {
|
|
|
16276
18399
|
enforceLinkHrefs();
|
|
16277
18400
|
return true;
|
|
16278
18401
|
}, []);
|
|
16279
|
-
const handleDeleteSelected =
|
|
18402
|
+
const handleDeleteSelected = useCallback7(() => {
|
|
16280
18403
|
const selected = selectedElRef.current;
|
|
16281
18404
|
if (!selected) return false;
|
|
16282
18405
|
return deleteSelectedNavFooterItem({
|
|
@@ -16297,7 +18420,7 @@ function OhhwellsBridge() {
|
|
|
16297
18420
|
}, [postToParent2]);
|
|
16298
18421
|
handleDeleteSelectedRef.current = handleDeleteSelected;
|
|
16299
18422
|
runPendingDeleteUndoRef.current = runPendingDeleteUndo;
|
|
16300
|
-
const handleLinkPopoverSubmit =
|
|
18423
|
+
const handleLinkPopoverSubmit = useCallback7(
|
|
16301
18424
|
(target) => {
|
|
16302
18425
|
const session = linkPopoverSessionRef.current;
|
|
16303
18426
|
if (!session) return;
|
|
@@ -16363,19 +18486,19 @@ function OhhwellsBridge() {
|
|
|
16363
18486
|
const showEditLink = toolbarShowEditLink;
|
|
16364
18487
|
const currentSections = sectionsByPath[pathname] ?? [];
|
|
16365
18488
|
linkPopoverOpenRef.current = linkPopover !== null;
|
|
16366
|
-
const handleMediaReplace =
|
|
18489
|
+
const handleMediaReplace = useCallback7(
|
|
16367
18490
|
(key) => {
|
|
16368
18491
|
postToParent2({ type: "ow:image-pick", key, elementType: mediaHover?.elementType ?? "image" });
|
|
16369
18492
|
},
|
|
16370
18493
|
[postToParent2, mediaHover?.elementType]
|
|
16371
18494
|
);
|
|
16372
|
-
const handleEditCarousel =
|
|
18495
|
+
const handleEditCarousel = useCallback7(
|
|
16373
18496
|
(key) => {
|
|
16374
18497
|
postToParent2({ type: "ow:carousel-open", key, images: readCarouselValue(key) });
|
|
16375
18498
|
},
|
|
16376
18499
|
[postToParent2]
|
|
16377
18500
|
);
|
|
16378
|
-
const handleMediaFadeOutComplete =
|
|
18501
|
+
const handleMediaFadeOutComplete = useCallback7((key) => {
|
|
16379
18502
|
setUploadingRects((prev) => {
|
|
16380
18503
|
if (!(key in prev)) return prev;
|
|
16381
18504
|
const next = { ...prev };
|
|
@@ -16383,7 +18506,7 @@ function OhhwellsBridge() {
|
|
|
16383
18506
|
return next;
|
|
16384
18507
|
});
|
|
16385
18508
|
}, []);
|
|
16386
|
-
const handleVideoSettingsChange =
|
|
18509
|
+
const handleVideoSettingsChange = useCallback7(
|
|
16387
18510
|
(key, settings) => {
|
|
16388
18511
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
16389
18512
|
const video = getVideoEl2(el);
|
|
@@ -16406,10 +18529,10 @@ function OhhwellsBridge() {
|
|
|
16406
18529
|
[postToParent2]
|
|
16407
18530
|
);
|
|
16408
18531
|
return bridgeRoot ? createPortal2(
|
|
16409
|
-
/* @__PURE__ */
|
|
16410
|
-
/* @__PURE__ */
|
|
16411
|
-
isEditMode && /* @__PURE__ */
|
|
16412
|
-
Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */
|
|
18532
|
+
/* @__PURE__ */ jsxs20(Fragment8, { children: [
|
|
18533
|
+
/* @__PURE__ */ jsx33("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
|
|
18534
|
+
isEditMode && /* @__PURE__ */ jsx33(AiSectionOverlay, { postToParent: postToParent2, apiRef: aiSectionApiRef }),
|
|
18535
|
+
Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ jsx33(
|
|
16413
18536
|
MediaOverlay,
|
|
16414
18537
|
{
|
|
16415
18538
|
hover: { key, rect, elementType: "image", isDragOver: false, hasTextOverlap: false },
|
|
@@ -16420,7 +18543,7 @@ function OhhwellsBridge() {
|
|
|
16420
18543
|
},
|
|
16421
18544
|
`uploading-${key}`
|
|
16422
18545
|
)),
|
|
16423
|
-
mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */
|
|
18546
|
+
mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */ jsx33(
|
|
16424
18547
|
MediaOverlay,
|
|
16425
18548
|
{
|
|
16426
18549
|
hover: mediaHover,
|
|
@@ -16429,11 +18552,11 @@ function OhhwellsBridge() {
|
|
|
16429
18552
|
onVideoSettingsChange: handleVideoSettingsChange
|
|
16430
18553
|
}
|
|
16431
18554
|
),
|
|
16432
|
-
carouselHover && !linkPopover && !isItemDragging && /* @__PURE__ */
|
|
16433
|
-
siblingHintRect && !linkPopover && !isItemDragging && siblingHintRects.length === 0 && /* @__PURE__ */
|
|
16434
|
-
siblingHintRects.length > 0 && !linkPopover && !isItemDragging && siblingHintRects.map((rect, i) => /* @__PURE__ */
|
|
16435
|
-
isItemDragging && draggedItemRect && selectedElRef.current !== footerDragRef.current?.draggedEl && selectedElRef.current !== navDragRef.current?.draggedEl && /* @__PURE__ */
|
|
16436
|
-
isItemDragging && footerDropSlots.map((slot, i) => /* @__PURE__ */
|
|
18555
|
+
carouselHover && !linkPopover && !isItemDragging && /* @__PURE__ */ jsx33(CarouselOverlay, { hover: carouselHover, onEdit: handleEditCarousel }),
|
|
18556
|
+
siblingHintRect && !linkPopover && !isItemDragging && siblingHintRects.length === 0 && /* @__PURE__ */ jsx33(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
|
|
18557
|
+
siblingHintRects.length > 0 && !linkPopover && !isItemDragging && siblingHintRects.map((rect, i) => /* @__PURE__ */ jsx33(ItemInteractionLayer, { rect, state: "sibling-hint" }, `sibling-hint-${i}`)),
|
|
18558
|
+
isItemDragging && draggedItemRect && selectedElRef.current !== footerDragRef.current?.draggedEl && selectedElRef.current !== navDragRef.current?.draggedEl && /* @__PURE__ */ jsx33(ItemInteractionLayer, { rect: draggedItemRect, state: "dragging" }),
|
|
18559
|
+
isItemDragging && footerDropSlots.map((slot, i) => /* @__PURE__ */ jsx33(
|
|
16437
18560
|
"div",
|
|
16438
18561
|
{
|
|
16439
18562
|
className: "pointer-events-none fixed z-2147483646",
|
|
@@ -16443,7 +18566,7 @@ function OhhwellsBridge() {
|
|
|
16443
18566
|
width: slot.width,
|
|
16444
18567
|
height: slot.height
|
|
16445
18568
|
},
|
|
16446
|
-
children: /* @__PURE__ */
|
|
18569
|
+
children: /* @__PURE__ */ jsx33(
|
|
16447
18570
|
DropIndicator,
|
|
16448
18571
|
{
|
|
16449
18572
|
direction: slot.direction,
|
|
@@ -16454,7 +18577,7 @@ function OhhwellsBridge() {
|
|
|
16454
18577
|
},
|
|
16455
18578
|
`footer-drop-${slot.direction}-${slot.columnIndex}-${slot.insertIndex}-${i}`
|
|
16456
18579
|
)),
|
|
16457
|
-
isItemDragging && navDropSlots.map((slot, i) => /* @__PURE__ */
|
|
18580
|
+
isItemDragging && navDropSlots.map((slot, i) => /* @__PURE__ */ jsx33(
|
|
16458
18581
|
"div",
|
|
16459
18582
|
{
|
|
16460
18583
|
className: "pointer-events-none fixed z-2147483646",
|
|
@@ -16464,7 +18587,7 @@ function OhhwellsBridge() {
|
|
|
16464
18587
|
width: slot.width,
|
|
16465
18588
|
height: slot.height
|
|
16466
18589
|
},
|
|
16467
|
-
children: /* @__PURE__ */
|
|
18590
|
+
children: /* @__PURE__ */ jsx33(
|
|
16468
18591
|
DropIndicator,
|
|
16469
18592
|
{
|
|
16470
18593
|
direction: slot.direction,
|
|
@@ -16475,10 +18598,11 @@ function OhhwellsBridge() {
|
|
|
16475
18598
|
},
|
|
16476
18599
|
`nav-drop-${slot.direction}-${slot.parentId ?? "root"}-${slot.insertIndex}-${i}`
|
|
16477
18600
|
)),
|
|
16478
|
-
hoveredNavContainerRect && (toolbarVariant !== "select-frame" || isFooterFrameSelection) && !linkPopover && !isItemDragging && /* @__PURE__ */
|
|
16479
|
-
hoveredItemRect && !linkPopover && !hoveredNavContainerRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */
|
|
16480
|
-
|
|
16481
|
-
toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current &&
|
|
18601
|
+
hoveredNavContainerRect && (toolbarVariant !== "select-frame" || isFooterFrameSelection) && !linkPopover && !isItemDragging && /* @__PURE__ */ jsx33(ItemInteractionLayer, { rect: hoveredNavContainerRect, state: "hover" }),
|
|
18602
|
+
hoveredItemRect && !linkPopover && !hoveredNavContainerRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ jsx33(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
|
|
18603
|
+
hoveredTextRect && !isItemDragging && toolbarVariant !== "rich-text" && /* @__PURE__ */ jsx33(ItemInteractionLayer, { rect: hoveredTextRect, state: "hover" }),
|
|
18604
|
+
toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isNavbarLinksContainer2(selectedElRef.current) && /* @__PURE__ */ jsx33(NavbarContainerChrome, { rect: toolbarRect, onAdd: handleAddTopLevelNavItem }),
|
|
18605
|
+
toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isFooterLinksContainer(selectedElRef.current) && /* @__PURE__ */ jsx33(
|
|
16482
18606
|
FooterContainerChrome,
|
|
16483
18607
|
{
|
|
16484
18608
|
rect: toolbarRect,
|
|
@@ -16486,7 +18610,7 @@ function OhhwellsBridge() {
|
|
|
16486
18610
|
addDisabled: !canAddFooterColumn()
|
|
16487
18611
|
}
|
|
16488
18612
|
),
|
|
16489
|
-
toolbarRect && !linkPopover && (toolbarVariant === "link-action" || toolbarVariant === "select-frame") && /* @__PURE__ */
|
|
18613
|
+
toolbarRect && !linkPopover && (toolbarVariant === "link-action" || toolbarVariant === "select-frame" || toolbarVariant === "logo") && /* @__PURE__ */ jsx33(
|
|
16490
18614
|
ItemInteractionLayer,
|
|
16491
18615
|
{
|
|
16492
18616
|
rect: isItemDragging && draggedItemRect && (footerDragRef.current?.wasSelected || navDragRef.current?.wasSelected) ? draggedItemRect : toolbarRect,
|
|
@@ -16498,26 +18622,34 @@ function OhhwellsBridge() {
|
|
|
16498
18622
|
dragHandleLabel: reorderHrefKey ? `Reorder ${reorderHrefKey}` : "Reorder item",
|
|
16499
18623
|
onDragHandleDragStart: handleItemDragStart,
|
|
16500
18624
|
onDragHandleDragEnd: handleItemDragEnd,
|
|
16501
|
-
onItemPointerDown: handleItemChromePointerDown,
|
|
16502
|
-
onItemClick: handleItemChromeClick,
|
|
16503
|
-
itemDragSurface: !isFooterFrameSelection,
|
|
16504
|
-
toolbar: toolbarVariant === "link-action" && !isItemDragging || toolbarVariant === "select-frame" && isFooterFrameSelection && !isItemDragging ? /* @__PURE__ */
|
|
18625
|
+
onItemPointerDown: toolbarVariant === "logo" ? void 0 : handleItemChromePointerDown,
|
|
18626
|
+
onItemClick: toolbarVariant === "logo" ? void 0 : handleItemChromeClick,
|
|
18627
|
+
itemDragSurface: toolbarVariant !== "logo" && !isFooterFrameSelection,
|
|
18628
|
+
toolbar: toolbarVariant === "link-action" && !isItemDragging || toolbarVariant === "select-frame" && (isFooterFrameSelection || selectedIsSocialsRow) && !isItemDragging ? /* @__PURE__ */ jsx33(
|
|
16505
18629
|
ItemActionToolbar,
|
|
16506
18630
|
{
|
|
16507
18631
|
onEditLink: openLinkPopoverForSelected,
|
|
18632
|
+
onStyle: () => {
|
|
18633
|
+
const row = selectedElRef.current;
|
|
18634
|
+
if (!row) return;
|
|
18635
|
+
if (floatingPanel?.kind === "socials-display") closeFloatingPanelOnly();
|
|
18636
|
+
else openSocialsDisplayPanel(row);
|
|
18637
|
+
},
|
|
18638
|
+
showStyle: selectedIsSocialsRow,
|
|
18639
|
+
styleActive: floatingPanel?.kind === "socials-display",
|
|
16508
18640
|
onAddItem: handleAddChildItem,
|
|
16509
18641
|
onSelectParent: handleSelectParent,
|
|
16510
18642
|
onDuplicate: handleDuplicateSelected,
|
|
16511
18643
|
onDelete: handleDeleteSelected,
|
|
16512
|
-
addItemDisabled:
|
|
18644
|
+
addItemDisabled: isFooterFrameSelection && isFooterAddItemDisabled(selectedElRef.current),
|
|
16513
18645
|
editLinkDisabled: false,
|
|
16514
18646
|
moreDisabled: false,
|
|
16515
|
-
duplicateDisabled: isFooterFrameSelection,
|
|
16516
|
-
showEditLink: !isFooterFrameSelection && navDropdownPreviewOpen === null,
|
|
16517
|
-
showAddItem: isFooterFrameSelection || !selectedIsCta && Boolean(
|
|
18647
|
+
duplicateDisabled: isFooterFrameSelection || selectedIsSocialsRow,
|
|
18648
|
+
showEditLink: !isFooterFrameSelection && !selectedIsSocialsRow && navDropdownPreviewOpen === null,
|
|
18649
|
+
showAddItem: isFooterFrameSelection || selectedIsSocialsRow || !selectedIsCta && Boolean(
|
|
16518
18650
|
selectedElRef.current && isNavbarHrefKey(selectedElRef.current.getAttribute("data-ohw-href-key")) && !isNestedNavChild(selectedElRef.current)
|
|
16519
18651
|
),
|
|
16520
|
-
showMore: !selectedIsCta || isFooterFrameSelection,
|
|
18652
|
+
showMore: (!selectedIsCta || isFooterFrameSelection) && !selectedIsSocialsRow,
|
|
16521
18653
|
dropdownOpen: navDropdownPreviewOpen,
|
|
16522
18654
|
onDropdownOpenChange: handleNavDropdownOpenChange,
|
|
16523
18655
|
headingVisible: footerHeadingVisible,
|
|
@@ -16526,8 +18658,8 @@ function OhhwellsBridge() {
|
|
|
16526
18658
|
) : void 0
|
|
16527
18659
|
}
|
|
16528
18660
|
),
|
|
16529
|
-
toolbarRect && toolbarVariant === "rich-text" && !linkPopover && /* @__PURE__ */
|
|
16530
|
-
/* @__PURE__ */
|
|
18661
|
+
toolbarRect && toolbarVariant === "rich-text" && !linkPopover && /* @__PURE__ */ jsxs20(Fragment8, { children: [
|
|
18662
|
+
/* @__PURE__ */ jsx33(
|
|
16531
18663
|
EditGlowChrome,
|
|
16532
18664
|
{
|
|
16533
18665
|
rect: toolbarRect,
|
|
@@ -16537,7 +18669,7 @@ function OhhwellsBridge() {
|
|
|
16537
18669
|
hideHandle: isItemDragging
|
|
16538
18670
|
}
|
|
16539
18671
|
),
|
|
16540
|
-
/* @__PURE__ */
|
|
18672
|
+
/* @__PURE__ */ jsx33(
|
|
16541
18673
|
FloatingToolbar,
|
|
16542
18674
|
{
|
|
16543
18675
|
rect: toolbarRect,
|
|
@@ -16550,7 +18682,7 @@ function OhhwellsBridge() {
|
|
|
16550
18682
|
}
|
|
16551
18683
|
)
|
|
16552
18684
|
] }),
|
|
16553
|
-
maxBadge && /* @__PURE__ */
|
|
18685
|
+
maxBadge && /* @__PURE__ */ jsxs20(
|
|
16554
18686
|
"div",
|
|
16555
18687
|
{
|
|
16556
18688
|
"data-ohw-max-badge": "",
|
|
@@ -16576,7 +18708,7 @@ function OhhwellsBridge() {
|
|
|
16576
18708
|
]
|
|
16577
18709
|
}
|
|
16578
18710
|
),
|
|
16579
|
-
toggleState && !linkPopover && /* @__PURE__ */
|
|
18711
|
+
toggleState && !linkPopover && /* @__PURE__ */ jsx33(
|
|
16580
18712
|
StateToggle,
|
|
16581
18713
|
{
|
|
16582
18714
|
rect: toggleState.rect,
|
|
@@ -16585,15 +18717,15 @@ function OhhwellsBridge() {
|
|
|
16585
18717
|
onStateChange: handleStateChange
|
|
16586
18718
|
}
|
|
16587
18719
|
),
|
|
16588
|
-
sectionGap && !linkPopover && /* @__PURE__ */
|
|
18720
|
+
sectionGap && !linkPopover && /* @__PURE__ */ jsxs20(
|
|
16589
18721
|
"div",
|
|
16590
18722
|
{
|
|
16591
18723
|
"data-ohw-section-insert-line": "",
|
|
16592
18724
|
className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
|
|
16593
18725
|
style: { top: sectionGap.y, transform: "translateY(-50%)" },
|
|
16594
18726
|
children: [
|
|
16595
|
-
/* @__PURE__ */
|
|
16596
|
-
/* @__PURE__ */
|
|
18727
|
+
/* @__PURE__ */ jsx33("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
|
|
18728
|
+
/* @__PURE__ */ jsx33(
|
|
16597
18729
|
Badge,
|
|
16598
18730
|
{
|
|
16599
18731
|
className: "px-8 py-1 bg-primary hover:bg-primary text-primary-foreground text-xs font-medium shrink-0 rounded-full cursor-pointer pointer-events-auto",
|
|
@@ -16610,11 +18742,11 @@ function OhhwellsBridge() {
|
|
|
16610
18742
|
children: "Add Section"
|
|
16611
18743
|
}
|
|
16612
18744
|
),
|
|
16613
|
-
/* @__PURE__ */
|
|
18745
|
+
/* @__PURE__ */ jsx33("div", { className: "flex-1 bg-primary", style: { height: 3 } })
|
|
16614
18746
|
]
|
|
16615
18747
|
}
|
|
16616
18748
|
),
|
|
16617
|
-
linkPopover && dialogPortalContainer ? /* @__PURE__ */
|
|
18749
|
+
linkPopover && dialogPortalContainer ? /* @__PURE__ */ jsx33(
|
|
16618
18750
|
LinkPopover,
|
|
16619
18751
|
{
|
|
16620
18752
|
panelRef: linkPopoverPanelRef,
|
|
@@ -16630,11 +18762,137 @@ function OhhwellsBridge() {
|
|
|
16630
18762
|
onSubmit: handleLinkPopoverSubmit
|
|
16631
18763
|
},
|
|
16632
18764
|
linkPopover.key
|
|
18765
|
+
) : null,
|
|
18766
|
+
floatingPanel && floatingPanel.kind === "socials-display" ? /* @__PURE__ */ jsx33(
|
|
18767
|
+
FloatingPanel,
|
|
18768
|
+
{
|
|
18769
|
+
open: true,
|
|
18770
|
+
title: floatingPanel.title,
|
|
18771
|
+
context: floatingPanel.context,
|
|
18772
|
+
position: floatingPanelPos,
|
|
18773
|
+
onPositionChange: setFloatingPanelPos,
|
|
18774
|
+
parentScroll: parentScrollSnap ?? parentScrollRef.current,
|
|
18775
|
+
onClose: closeFloatingPanelOnly,
|
|
18776
|
+
children: /* @__PURE__ */ jsx33(
|
|
18777
|
+
SocialsDisplayPanel,
|
|
18778
|
+
{
|
|
18779
|
+
display: socialsDisplayFor(floatingPanel.row, editContentRef.current),
|
|
18780
|
+
onChange: (next) => {
|
|
18781
|
+
changeSocialsDisplay(floatingPanel.row, next);
|
|
18782
|
+
setFloatingPanel({ ...floatingPanel });
|
|
18783
|
+
}
|
|
18784
|
+
}
|
|
18785
|
+
)
|
|
18786
|
+
}
|
|
18787
|
+
) : null,
|
|
18788
|
+
floatingPanel && floatingPanel.kind === "logo-size" && logoSizeDraft ? /* @__PURE__ */ jsx33(
|
|
18789
|
+
FloatingPanel,
|
|
18790
|
+
{
|
|
18791
|
+
open: true,
|
|
18792
|
+
title: floatingPanel.title,
|
|
18793
|
+
context: floatingPanel.context,
|
|
18794
|
+
position: floatingPanelPos,
|
|
18795
|
+
onPositionChange: setFloatingPanelPos,
|
|
18796
|
+
parentScroll: parentScrollSnap ?? parentScrollRef.current,
|
|
18797
|
+
onClose: closeFloatingPanelAndDeselect,
|
|
18798
|
+
children: /* @__PURE__ */ jsx33(
|
|
18799
|
+
LogoSizePanel,
|
|
18800
|
+
{
|
|
18801
|
+
viewport: editorViewport,
|
|
18802
|
+
sizePx: editorViewport === "mobile" && !logoSizeDraft.mobileFollowing ? logoSizeDraft.mobilePx : logoSizeDraft.desktopPx,
|
|
18803
|
+
mobileFollowing: logoSizeDraft.mobileFollowing,
|
|
18804
|
+
onSizeChange: (px) => {
|
|
18805
|
+
const next = editorViewport === "mobile" ? { ...logoSizeDraft, mobilePx: px, mobileFollowing: false } : {
|
|
18806
|
+
...logoSizeDraft,
|
|
18807
|
+
desktopPx: px,
|
|
18808
|
+
mobilePx: logoSizeDraft.mobileFollowing ? px : logoSizeDraft.mobilePx
|
|
18809
|
+
};
|
|
18810
|
+
setLogoSizeDraft(next);
|
|
18811
|
+
persistLogoSizeDraft(floatingPanel.placement, next);
|
|
18812
|
+
},
|
|
18813
|
+
onCustomizeMobile: () => {
|
|
18814
|
+
const next = {
|
|
18815
|
+
...logoSizeDraft,
|
|
18816
|
+
mobileFollowing: false,
|
|
18817
|
+
mobilePx: logoSizeDraft.desktopPx
|
|
18818
|
+
};
|
|
18819
|
+
setLogoSizeDraft(next);
|
|
18820
|
+
persistLogoSizeDraft(floatingPanel.placement, next);
|
|
18821
|
+
},
|
|
18822
|
+
onResetMobile: () => {
|
|
18823
|
+
const next = {
|
|
18824
|
+
...logoSizeDraft,
|
|
18825
|
+
mobileFollowing: true,
|
|
18826
|
+
mobilePx: logoSizeDraft.desktopPx
|
|
18827
|
+
};
|
|
18828
|
+
setLogoSizeDraft(next);
|
|
18829
|
+
persistLogoSizeDraft(floatingPanel.placement, next);
|
|
18830
|
+
},
|
|
18831
|
+
onUpdateEverywhere: () => {
|
|
18832
|
+
const identity = readLogoIdentityFromDom();
|
|
18833
|
+
postToParent2({ type: "ow:open-logo-settings", ...identity });
|
|
18834
|
+
}
|
|
18835
|
+
}
|
|
18836
|
+
)
|
|
18837
|
+
}
|
|
16633
18838
|
) : null
|
|
16634
18839
|
] }),
|
|
16635
18840
|
bridgeRoot
|
|
16636
18841
|
) : null;
|
|
16637
18842
|
}
|
|
18843
|
+
|
|
18844
|
+
// src/ui/EmptySection.tsx
|
|
18845
|
+
import Link4 from "next/link";
|
|
18846
|
+
import { Fragment as Fragment9, jsx as jsx34, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
18847
|
+
function EmptySection({ title, homeHref = "/", eyebrowKey, titleKey, subtitleKey }) {
|
|
18848
|
+
return /* @__PURE__ */ jsxs21(Fragment9, { children: [
|
|
18849
|
+
/* @__PURE__ */ jsx34(
|
|
18850
|
+
"p",
|
|
18851
|
+
{
|
|
18852
|
+
style: {
|
|
18853
|
+
fontFamily: "var(--brand-font-body)",
|
|
18854
|
+
fontSize: "0.75rem",
|
|
18855
|
+
fontWeight: 500,
|
|
18856
|
+
letterSpacing: "0.15em",
|
|
18857
|
+
textTransform: "uppercase",
|
|
18858
|
+
color: "var(--brand-accent)",
|
|
18859
|
+
marginBottom: "1.5rem"
|
|
18860
|
+
},
|
|
18861
|
+
children: /* @__PURE__ */ jsx34(Link4, { href: homeHref, style: { color: "inherit" }, children: /* @__PURE__ */ jsx34("span", { ...eyebrowKey ? { "data-ohw-editable": "text", "data-ohw-key": eyebrowKey } : {}, children: "Home" }) })
|
|
18862
|
+
}
|
|
18863
|
+
),
|
|
18864
|
+
/* @__PURE__ */ jsx34(
|
|
18865
|
+
"h1",
|
|
18866
|
+
{
|
|
18867
|
+
style: {
|
|
18868
|
+
fontFamily: "var(--brand-font-heading)",
|
|
18869
|
+
fontSize: "clamp(2rem, 3.5vw, 2.75rem)",
|
|
18870
|
+
lineHeight: 1.1,
|
|
18871
|
+
letterSpacing: "-0.025em",
|
|
18872
|
+
color: "var(--brand-text)",
|
|
18873
|
+
marginBottom: "1rem"
|
|
18874
|
+
},
|
|
18875
|
+
...titleKey ? { "data-ohw-editable": "text", "data-ohw-key": titleKey, "data-ohw-max-length": 80 } : {},
|
|
18876
|
+
children: title
|
|
18877
|
+
}
|
|
18878
|
+
),
|
|
18879
|
+
/* @__PURE__ */ jsx34(
|
|
18880
|
+
"p",
|
|
18881
|
+
{
|
|
18882
|
+
style: {
|
|
18883
|
+
fontFamily: "var(--brand-font-body)",
|
|
18884
|
+
fontSize: "1rem",
|
|
18885
|
+
lineHeight: 1.7,
|
|
18886
|
+
fontWeight: 300,
|
|
18887
|
+
color: "var(--brand-text-muted)",
|
|
18888
|
+
maxWidth: "340px"
|
|
18889
|
+
},
|
|
18890
|
+
...subtitleKey ? { "data-ohw-editable": "text", "data-ohw-key": subtitleKey, "data-ohw-max-length": 160 } : {},
|
|
18891
|
+
children: "This page doesn't have any content yet."
|
|
18892
|
+
}
|
|
18893
|
+
)
|
|
18894
|
+
] });
|
|
18895
|
+
}
|
|
16638
18896
|
export {
|
|
16639
18897
|
AI_DEFAULT_BRAND,
|
|
16640
18898
|
AI_TREE_SCHEMA_VERSIONS,
|
|
@@ -16651,6 +18909,7 @@ export {
|
|
|
16651
18909
|
DropdownMenuItem,
|
|
16652
18910
|
DropdownMenuSeparator,
|
|
16653
18911
|
DropdownMenuTrigger,
|
|
18912
|
+
EmptySection,
|
|
16654
18913
|
ItemActionToolbar,
|
|
16655
18914
|
ItemInteractionLayer,
|
|
16656
18915
|
LinkEditorPanel,
|