@ohhwells/bridge 0.1.70-next.211 → 0.1.70-next.215
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 +528 -183
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.js +534 -189
- package/dist/index.js.map +1 -1
- package/dist/pages.cjs +1 -1
- package/dist/pages.cjs.map +1 -1
- package/dist/pages.js +1 -1
- package/dist/pages.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -6296,16 +6296,14 @@ var import_react6 = require("react");
|
|
|
6296
6296
|
var import_lucide_react3 = require("lucide-react");
|
|
6297
6297
|
|
|
6298
6298
|
// src/ui/dropdown-menu.tsx
|
|
6299
|
+
var React6 = __toESM(require("react"), 1);
|
|
6299
6300
|
var import_radix_ui3 = require("radix-ui");
|
|
6300
6301
|
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
6301
6302
|
function DropdownMenu({ ...props }) {
|
|
6302
6303
|
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_radix_ui3.DropdownMenu.Root, { "data-slot": "dropdown-menu", ...props });
|
|
6303
6304
|
}
|
|
6304
|
-
|
|
6305
|
-
|
|
6306
|
-
}) {
|
|
6307
|
-
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_radix_ui3.DropdownMenu.Trigger, { "data-slot": "dropdown-menu-trigger", ...props });
|
|
6308
|
-
}
|
|
6305
|
+
var DropdownMenuTrigger = React6.forwardRef((props, ref) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_radix_ui3.DropdownMenu.Trigger, { ref, "data-slot": "dropdown-menu-trigger", ...props }));
|
|
6306
|
+
DropdownMenuTrigger.displayName = "DropdownMenuTrigger";
|
|
6309
6307
|
function DropdownMenuGroup({
|
|
6310
6308
|
className,
|
|
6311
6309
|
...props
|
|
@@ -7558,11 +7556,11 @@ function FieldTypePicker({ onPick }) {
|
|
|
7558
7556
|
}
|
|
7559
7557
|
|
|
7560
7558
|
// src/ui/MediaOverlay.tsx
|
|
7561
|
-
var
|
|
7559
|
+
var React8 = __toESM(require("react"), 1);
|
|
7562
7560
|
var import_lucide_react5 = require("lucide-react");
|
|
7563
7561
|
|
|
7564
7562
|
// src/ui/button.tsx
|
|
7565
|
-
var
|
|
7563
|
+
var React7 = __toESM(require("react"), 1);
|
|
7566
7564
|
var import_radix_ui5 = require("radix-ui");
|
|
7567
7565
|
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
7568
7566
|
var buttonVariants = cva(
|
|
@@ -7585,7 +7583,7 @@ var buttonVariants = cva(
|
|
|
7585
7583
|
}
|
|
7586
7584
|
}
|
|
7587
7585
|
);
|
|
7588
|
-
var Button =
|
|
7586
|
+
var Button = React7.forwardRef(
|
|
7589
7587
|
({ className, variant, size, asChild = false, ...props }, ref) => {
|
|
7590
7588
|
const Comp = asChild ? import_radix_ui5.Slot.Root : "button";
|
|
7591
7589
|
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
@@ -7640,7 +7638,7 @@ function MediaOverlay({
|
|
|
7640
7638
|
onVideoSettingsChange
|
|
7641
7639
|
}) {
|
|
7642
7640
|
const { rect } = hover;
|
|
7643
|
-
const skeletonRef =
|
|
7641
|
+
const skeletonRef = React8.useRef(null);
|
|
7644
7642
|
const isVideo = hover.elementType === "video";
|
|
7645
7643
|
const showChrome = !selected || hovered;
|
|
7646
7644
|
const autoplay = hover.videoAutoplay ?? true;
|
|
@@ -7653,7 +7651,7 @@ function MediaOverlay({
|
|
|
7653
7651
|
height: rect.height,
|
|
7654
7652
|
zIndex: 2147483646
|
|
7655
7653
|
};
|
|
7656
|
-
|
|
7654
|
+
React8.useEffect(() => {
|
|
7657
7655
|
if (!isUploading || !fadingOut || !skeletonRef.current) return;
|
|
7658
7656
|
const anim = skeletonRef.current.animate([{ opacity: 1 }, { opacity: 0 }], {
|
|
7659
7657
|
duration: MEDIA_UPLOAD_FADE_MS,
|
|
@@ -7872,6 +7870,150 @@ function parseSectionsFromHtml(html) {
|
|
|
7872
7870
|
return parseSectionsFromRoot(doc);
|
|
7873
7871
|
}
|
|
7874
7872
|
|
|
7873
|
+
// src/lib/section-instances.ts
|
|
7874
|
+
var SECTION_ORDER_KEY = "__ohw_section_order";
|
|
7875
|
+
var REMOVED_ATTR2 = "data-ohw-section-removed";
|
|
7876
|
+
function isRemovedSection(el) {
|
|
7877
|
+
return el.hasAttribute(REMOVED_ATTR2);
|
|
7878
|
+
}
|
|
7879
|
+
function topLevelSections() {
|
|
7880
|
+
return Array.from(document.querySelectorAll("[data-ohw-section]")).filter(
|
|
7881
|
+
(el) => !el.parentElement?.closest("[data-ohw-section]") && !isChromeSection(el) && !isRemovedSection(el)
|
|
7882
|
+
);
|
|
7883
|
+
}
|
|
7884
|
+
function instanceIdOf(el) {
|
|
7885
|
+
return el.dataset.ohwInstance ?? el.dataset.ohwSection ?? "";
|
|
7886
|
+
}
|
|
7887
|
+
function planSectionMove(instanceId, targetIndex, currentPath) {
|
|
7888
|
+
const sections = topLevelSections();
|
|
7889
|
+
const index = sections.findIndex((el) => instanceIdOf(el) === instanceId);
|
|
7890
|
+
if (index === -1) return null;
|
|
7891
|
+
const dragged = sections[index];
|
|
7892
|
+
const others = sections.filter((_, i) => i !== index);
|
|
7893
|
+
const clamped = Math.max(0, Math.min(targetIndex, others.length));
|
|
7894
|
+
const reordered = [...others.slice(0, clamped), dragged, ...others.slice(clamped)];
|
|
7895
|
+
return reordered.map((el, order) => ({
|
|
7896
|
+
instanceId: instanceIdOf(el),
|
|
7897
|
+
type: el.getAttribute("data-ohw-section") ?? "",
|
|
7898
|
+
order,
|
|
7899
|
+
pagePath: currentPath
|
|
7900
|
+
}));
|
|
7901
|
+
}
|
|
7902
|
+
function moveSectionInstance(instanceId, direction, currentPath) {
|
|
7903
|
+
const sections = topLevelSections();
|
|
7904
|
+
const index = sections.findIndex((el) => instanceIdOf(el) === instanceId);
|
|
7905
|
+
if (index === -1) return null;
|
|
7906
|
+
const siblingIndex = direction === "up" ? index - 1 : index + 1;
|
|
7907
|
+
if (siblingIndex < 0 || siblingIndex >= sections.length) return null;
|
|
7908
|
+
const entries = planSectionMove(instanceId, siblingIndex, currentPath);
|
|
7909
|
+
if (!entries) return null;
|
|
7910
|
+
applyPersistedOrder(entries);
|
|
7911
|
+
return entries;
|
|
7912
|
+
}
|
|
7913
|
+
function syncRemovedFlags(entries) {
|
|
7914
|
+
const removedIds = new Set(entries.filter((e) => e.removed).map((e) => e.instanceId));
|
|
7915
|
+
document.querySelectorAll(`[${REMOVED_ATTR2}]`).forEach((el) => {
|
|
7916
|
+
if (!removedIds.has(instanceIdOf(el))) {
|
|
7917
|
+
el.style.removeProperty("display");
|
|
7918
|
+
el.removeAttribute(REMOVED_ATTR2);
|
|
7919
|
+
}
|
|
7920
|
+
});
|
|
7921
|
+
for (const id of removedIds) {
|
|
7922
|
+
const el = document.querySelector(`[data-ohw-instance="${CSS.escape(id)}"]`);
|
|
7923
|
+
if (el) {
|
|
7924
|
+
el.style.display = "none";
|
|
7925
|
+
el.setAttribute(REMOVED_ATTR2, "");
|
|
7926
|
+
}
|
|
7927
|
+
}
|
|
7928
|
+
}
|
|
7929
|
+
function applyPersistedOrder(entries) {
|
|
7930
|
+
syncRemovedFlags(entries);
|
|
7931
|
+
if (entries.length === 0) return;
|
|
7932
|
+
const sections = topLevelSections();
|
|
7933
|
+
if (sections.length === 0) return;
|
|
7934
|
+
const orderIndex = new Map(entries.map((e) => [e.instanceId, e.order]));
|
|
7935
|
+
const ordered = [...sections].sort((a, b) => {
|
|
7936
|
+
const aOrder = orderIndex.get(instanceIdOf(a));
|
|
7937
|
+
const bOrder = orderIndex.get(instanceIdOf(b));
|
|
7938
|
+
if (aOrder === void 0 && bOrder === void 0) return 0;
|
|
7939
|
+
if (aOrder === void 0) return 1;
|
|
7940
|
+
if (bOrder === void 0) return -1;
|
|
7941
|
+
return aOrder - bOrder;
|
|
7942
|
+
});
|
|
7943
|
+
let prev = null;
|
|
7944
|
+
for (const el of ordered) {
|
|
7945
|
+
if (prev) prev.after(el);
|
|
7946
|
+
prev = el;
|
|
7947
|
+
}
|
|
7948
|
+
}
|
|
7949
|
+
function setSectionRemoved(instanceId, currentPath, existingEntries, removed) {
|
|
7950
|
+
if (!document.querySelector(`[data-ohw-instance="${CSS.escape(instanceId)}"]`)) return null;
|
|
7951
|
+
const byId = new Map(existingEntries.map((e) => [e.instanceId, e]));
|
|
7952
|
+
const allSections = Array.from(document.querySelectorAll("[data-ohw-section]")).filter(
|
|
7953
|
+
(el) => !el.parentElement?.closest("[data-ohw-section]") && !isChromeSection(el)
|
|
7954
|
+
);
|
|
7955
|
+
allSections.forEach((el, order) => {
|
|
7956
|
+
const id = instanceIdOf(el);
|
|
7957
|
+
if (!byId.has(id)) {
|
|
7958
|
+
byId.set(id, { instanceId: id, type: el.getAttribute("data-ohw-section") ?? "", order, pagePath: currentPath });
|
|
7959
|
+
}
|
|
7960
|
+
});
|
|
7961
|
+
const target = byId.get(instanceId);
|
|
7962
|
+
if (!target) return null;
|
|
7963
|
+
byId.set(instanceId, { ...target, removed });
|
|
7964
|
+
const entries = Array.from(byId.values());
|
|
7965
|
+
applyPersistedOrder(entries);
|
|
7966
|
+
return entries;
|
|
7967
|
+
}
|
|
7968
|
+
function deleteSectionInstance(instanceId, currentPath, existingEntries) {
|
|
7969
|
+
return setSectionRemoved(instanceId, currentPath, existingEntries, true);
|
|
7970
|
+
}
|
|
7971
|
+
function restoreSectionInstance(instanceId, currentPath, existingEntries) {
|
|
7972
|
+
return setSectionRemoved(instanceId, currentPath, existingEntries, false);
|
|
7973
|
+
}
|
|
7974
|
+
function newInstanceId() {
|
|
7975
|
+
return typeof crypto !== "undefined" && "randomUUID" in crypto ? crypto.randomUUID() : `instance-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
7976
|
+
}
|
|
7977
|
+
function getPageSectionOrderEntries(raw, currentPath) {
|
|
7978
|
+
if (!raw) return [];
|
|
7979
|
+
try {
|
|
7980
|
+
const entries = JSON.parse(raw);
|
|
7981
|
+
return entries.filter((e) => !e.pagePath || e.pagePath === currentPath);
|
|
7982
|
+
} catch {
|
|
7983
|
+
return [];
|
|
7984
|
+
}
|
|
7985
|
+
}
|
|
7986
|
+
function rekeySectionSubtree(root, instanceId) {
|
|
7987
|
+
const suffix = `::${instanceId}`;
|
|
7988
|
+
const rekey = (el, attr) => {
|
|
7989
|
+
const current = el.getAttribute(attr);
|
|
7990
|
+
if (current) el.setAttribute(attr, `${current}${suffix}`);
|
|
7991
|
+
};
|
|
7992
|
+
if (root.hasAttribute("data-ohw-key")) rekey(root, "data-ohw-key");
|
|
7993
|
+
if (root.hasAttribute("data-ohw-href-key")) rekey(root, "data-ohw-href-key");
|
|
7994
|
+
root.querySelectorAll("[data-ohw-key]").forEach((el) => rekey(el, "data-ohw-key"));
|
|
7995
|
+
root.querySelectorAll("[data-ohw-href-key]").forEach((el) => rekey(el, "data-ohw-href-key"));
|
|
7996
|
+
}
|
|
7997
|
+
function initSectionInstancesFromContent(content, currentPath) {
|
|
7998
|
+
document.querySelectorAll("[data-ohw-section]:not([data-ohw-instance])").forEach((el) => {
|
|
7999
|
+
el.setAttribute("data-ohw-instance", el.getAttribute("data-ohw-section") ?? "");
|
|
8000
|
+
});
|
|
8001
|
+
const entries = getPageSectionOrderEntries(content[SECTION_ORDER_KEY], currentPath);
|
|
8002
|
+
for (const entry of entries) {
|
|
8003
|
+
if (entry.instanceId === entry.type) continue;
|
|
8004
|
+
if (document.querySelector(`[data-ohw-instance="${CSS.escape(entry.instanceId)}"]`)) continue;
|
|
8005
|
+
const original = document.querySelector(
|
|
8006
|
+
`[data-ohw-section="${CSS.escape(entry.type)}"][data-ohw-instance="${CSS.escape(entry.type)}"]`
|
|
8007
|
+
);
|
|
8008
|
+
if (!original) continue;
|
|
8009
|
+
const clone = original.cloneNode(true);
|
|
8010
|
+
clone.setAttribute("data-ohw-instance", entry.instanceId);
|
|
8011
|
+
rekeySectionSubtree(clone, entry.instanceId);
|
|
8012
|
+
original.insertAdjacentElement("afterend", clone);
|
|
8013
|
+
}
|
|
8014
|
+
applyPersistedOrder(entries);
|
|
8015
|
+
}
|
|
8016
|
+
|
|
7875
8017
|
// src/ui/ai-section/AiSectionOverlay.tsx
|
|
7876
8018
|
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
7877
8019
|
function findSectionElement(instanceId) {
|
|
@@ -7916,9 +8058,7 @@ function useLiveSectionRect(sectionId) {
|
|
|
7916
8058
|
return rect;
|
|
7917
8059
|
}
|
|
7918
8060
|
function computeSectionBoundaryFlags(instanceId) {
|
|
7919
|
-
const topLevel =
|
|
7920
|
-
(el) => !el.parentElement?.closest("[data-ohw-section]") && !isChromeSection(el)
|
|
7921
|
-
);
|
|
8061
|
+
const topLevel = topLevelSections();
|
|
7922
8062
|
const index = topLevel.findIndex((el) => (el.dataset.ohwInstance ?? el.dataset.ohwSection) === instanceId);
|
|
7923
8063
|
if (index === -1) return { isFirst: true, isLast: true };
|
|
7924
8064
|
return { isFirst: index === 0, isLast: index === topLevel.length - 1 };
|
|
@@ -8035,12 +8175,15 @@ function AiSectionOverlay({
|
|
|
8035
8175
|
selectFromElement(sectionEl);
|
|
8036
8176
|
return sectionEl != null;
|
|
8037
8177
|
},
|
|
8038
|
-
clear: () =>
|
|
8178
|
+
clear: () => {
|
|
8179
|
+
setSelectedId(null);
|
|
8180
|
+
report(null);
|
|
8181
|
+
}
|
|
8039
8182
|
};
|
|
8040
8183
|
return () => {
|
|
8041
8184
|
apiRef.current = null;
|
|
8042
8185
|
};
|
|
8043
|
-
}, [apiRef, selectFromElement]);
|
|
8186
|
+
}, [apiRef, selectFromElement, report]);
|
|
8044
8187
|
(0, import_react8.useEffect)(() => {
|
|
8045
8188
|
const onMessage = (e) => {
|
|
8046
8189
|
if (e.data?.type === "ow:ai-select" && e.data.sectionId === null) {
|
|
@@ -8215,101 +8358,6 @@ function AiSectionOverlay({
|
|
|
8215
8358
|
] });
|
|
8216
8359
|
}
|
|
8217
8360
|
|
|
8218
|
-
// src/lib/section-instances.ts
|
|
8219
|
-
var SECTION_ORDER_KEY = "__ohw_section_order";
|
|
8220
|
-
function topLevelSections() {
|
|
8221
|
-
return Array.from(document.querySelectorAll("[data-ohw-section]")).filter(
|
|
8222
|
-
(el) => !el.parentElement?.closest("[data-ohw-section]") && !isChromeSection(el)
|
|
8223
|
-
);
|
|
8224
|
-
}
|
|
8225
|
-
function instanceIdOf(el) {
|
|
8226
|
-
return el.dataset.ohwInstance ?? el.dataset.ohwSection ?? "";
|
|
8227
|
-
}
|
|
8228
|
-
function planSectionMove(instanceId, targetIndex, currentPath) {
|
|
8229
|
-
const sections = topLevelSections();
|
|
8230
|
-
const index = sections.findIndex((el) => instanceIdOf(el) === instanceId);
|
|
8231
|
-
if (index === -1) return null;
|
|
8232
|
-
const dragged = sections[index];
|
|
8233
|
-
const others = sections.filter((_, i) => i !== index);
|
|
8234
|
-
const clamped = Math.max(0, Math.min(targetIndex, others.length));
|
|
8235
|
-
const reordered = [...others.slice(0, clamped), dragged, ...others.slice(clamped)];
|
|
8236
|
-
return reordered.map((el, order) => ({
|
|
8237
|
-
instanceId: instanceIdOf(el),
|
|
8238
|
-
type: el.getAttribute("data-ohw-section") ?? "",
|
|
8239
|
-
order,
|
|
8240
|
-
pagePath: currentPath
|
|
8241
|
-
}));
|
|
8242
|
-
}
|
|
8243
|
-
function moveSectionInstance(instanceId, direction, currentPath) {
|
|
8244
|
-
const sections = topLevelSections();
|
|
8245
|
-
const index = sections.findIndex((el) => instanceIdOf(el) === instanceId);
|
|
8246
|
-
if (index === -1) return null;
|
|
8247
|
-
const siblingIndex = direction === "up" ? index - 1 : index + 1;
|
|
8248
|
-
if (siblingIndex < 0 || siblingIndex >= sections.length) return null;
|
|
8249
|
-
const entries = planSectionMove(instanceId, siblingIndex, currentPath);
|
|
8250
|
-
if (!entries) return null;
|
|
8251
|
-
applyPersistedOrder(entries);
|
|
8252
|
-
return entries;
|
|
8253
|
-
}
|
|
8254
|
-
function applyPersistedOrder(entries) {
|
|
8255
|
-
if (entries.length === 0) return;
|
|
8256
|
-
const sections = topLevelSections();
|
|
8257
|
-
if (sections.length === 0) return;
|
|
8258
|
-
const orderIndex = new Map(entries.map((e) => [e.instanceId, e.order]));
|
|
8259
|
-
const ordered = [...sections].sort((a, b) => {
|
|
8260
|
-
const aOrder = orderIndex.get(instanceIdOf(a));
|
|
8261
|
-
const bOrder = orderIndex.get(instanceIdOf(b));
|
|
8262
|
-
if (aOrder === void 0 && bOrder === void 0) return 0;
|
|
8263
|
-
if (aOrder === void 0) return 1;
|
|
8264
|
-
if (bOrder === void 0) return -1;
|
|
8265
|
-
return aOrder - bOrder;
|
|
8266
|
-
});
|
|
8267
|
-
let prev = null;
|
|
8268
|
-
for (const el of ordered) {
|
|
8269
|
-
if (prev) prev.after(el);
|
|
8270
|
-
prev = el;
|
|
8271
|
-
}
|
|
8272
|
-
}
|
|
8273
|
-
function getPageSectionOrderEntries(raw, currentPath) {
|
|
8274
|
-
if (!raw) return [];
|
|
8275
|
-
try {
|
|
8276
|
-
const entries = JSON.parse(raw);
|
|
8277
|
-
return entries.filter((e) => !e.pagePath || e.pagePath === currentPath);
|
|
8278
|
-
} catch {
|
|
8279
|
-
return [];
|
|
8280
|
-
}
|
|
8281
|
-
}
|
|
8282
|
-
function rekeySectionSubtree(root, instanceId) {
|
|
8283
|
-
const suffix = `::${instanceId}`;
|
|
8284
|
-
const rekey = (el, attr) => {
|
|
8285
|
-
const current = el.getAttribute(attr);
|
|
8286
|
-
if (current) el.setAttribute(attr, `${current}${suffix}`);
|
|
8287
|
-
};
|
|
8288
|
-
if (root.hasAttribute("data-ohw-key")) rekey(root, "data-ohw-key");
|
|
8289
|
-
if (root.hasAttribute("data-ohw-href-key")) rekey(root, "data-ohw-href-key");
|
|
8290
|
-
root.querySelectorAll("[data-ohw-key]").forEach((el) => rekey(el, "data-ohw-key"));
|
|
8291
|
-
root.querySelectorAll("[data-ohw-href-key]").forEach((el) => rekey(el, "data-ohw-href-key"));
|
|
8292
|
-
}
|
|
8293
|
-
function initSectionInstancesFromContent(content, currentPath) {
|
|
8294
|
-
document.querySelectorAll("[data-ohw-section]:not([data-ohw-instance])").forEach((el) => {
|
|
8295
|
-
el.setAttribute("data-ohw-instance", el.getAttribute("data-ohw-section") ?? "");
|
|
8296
|
-
});
|
|
8297
|
-
const entries = getPageSectionOrderEntries(content[SECTION_ORDER_KEY], currentPath);
|
|
8298
|
-
for (const entry of entries) {
|
|
8299
|
-
if (entry.instanceId === entry.type) continue;
|
|
8300
|
-
if (document.querySelector(`[data-ohw-instance="${CSS.escape(entry.instanceId)}"]`)) continue;
|
|
8301
|
-
const original = document.querySelector(
|
|
8302
|
-
`[data-ohw-section="${CSS.escape(entry.type)}"][data-ohw-instance="${CSS.escape(entry.type)}"]`
|
|
8303
|
-
);
|
|
8304
|
-
if (!original) continue;
|
|
8305
|
-
const clone = original.cloneNode(true);
|
|
8306
|
-
clone.setAttribute("data-ohw-instance", entry.instanceId);
|
|
8307
|
-
rekeySectionSubtree(clone, entry.instanceId);
|
|
8308
|
-
original.insertAdjacentElement("afterend", clone);
|
|
8309
|
-
}
|
|
8310
|
-
applyPersistedOrder(entries);
|
|
8311
|
-
}
|
|
8312
|
-
|
|
8313
8361
|
// src/OhhwellsBridge.tsx
|
|
8314
8362
|
var import_react_dom4 = require("react-dom");
|
|
8315
8363
|
var import_navigation3 = require("next/navigation");
|
|
@@ -8617,7 +8665,7 @@ function scrollToHashSectionWhenReady(behavior = "smooth") {
|
|
|
8617
8665
|
var import_react12 = require("react");
|
|
8618
8666
|
|
|
8619
8667
|
// src/ui/dialog.tsx
|
|
8620
|
-
var
|
|
8668
|
+
var React9 = __toESM(require("react"), 1);
|
|
8621
8669
|
var import_radix_ui6 = require("radix-ui");
|
|
8622
8670
|
var import_lucide_react8 = require("lucide-react");
|
|
8623
8671
|
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
@@ -8645,7 +8693,7 @@ function DialogOverlay({
|
|
|
8645
8693
|
}
|
|
8646
8694
|
);
|
|
8647
8695
|
}
|
|
8648
|
-
var DialogContent =
|
|
8696
|
+
var DialogContent = React9.forwardRef(
|
|
8649
8697
|
({ className, children, showCloseButton = true, container, ...props }, ref) => {
|
|
8650
8698
|
const positionMode = container ? "absolute" : "fixed";
|
|
8651
8699
|
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(DialogPortal, { container: container ?? void 0, children: [
|
|
@@ -8700,7 +8748,7 @@ function DialogFooter({
|
|
|
8700
8748
|
}
|
|
8701
8749
|
);
|
|
8702
8750
|
}
|
|
8703
|
-
var DialogTitle =
|
|
8751
|
+
var DialogTitle = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
8704
8752
|
import_radix_ui6.Dialog.Title,
|
|
8705
8753
|
{
|
|
8706
8754
|
ref,
|
|
@@ -8712,7 +8760,7 @@ var DialogTitle = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE
|
|
|
8712
8760
|
}
|
|
8713
8761
|
));
|
|
8714
8762
|
DialogTitle.displayName = import_radix_ui6.Dialog.Title.displayName;
|
|
8715
|
-
var DialogDescription =
|
|
8763
|
+
var DialogDescription = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
8716
8764
|
import_radix_ui6.Dialog.Description,
|
|
8717
8765
|
{
|
|
8718
8766
|
ref,
|
|
@@ -8817,9 +8865,9 @@ function SectionTreeItem({
|
|
|
8817
8865
|
var import_react9 = require("react");
|
|
8818
8866
|
|
|
8819
8867
|
// src/ui/input.tsx
|
|
8820
|
-
var
|
|
8868
|
+
var React10 = __toESM(require("react"), 1);
|
|
8821
8869
|
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
8822
|
-
var Input =
|
|
8870
|
+
var Input = React10.forwardRef(
|
|
8823
8871
|
({ className, type, ...props }, ref) => {
|
|
8824
8872
|
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
8825
8873
|
"input",
|
|
@@ -10851,7 +10899,9 @@ function deleteNavbarItem(sourceAnchor) {
|
|
|
10851
10899
|
var GLYPH_SELECTOR = "svg, img";
|
|
10852
10900
|
function referenceBox(slot) {
|
|
10853
10901
|
const row = slot.closest("[data-ohw-socials-row]") ?? slot.closest("a")?.parentElement ?? null;
|
|
10854
|
-
const neighbour = row ? Array.from(row.querySelectorAll('[data-ohw-editable="icon"]')).find(
|
|
10902
|
+
const neighbour = row ? Array.from(row.querySelectorAll('[data-ohw-editable="icon"]')).find(
|
|
10903
|
+
(el) => el !== slot && !el.hasAttribute("data-ohw-social-icon-placeholder")
|
|
10904
|
+
) : null;
|
|
10855
10905
|
if (neighbour) {
|
|
10856
10906
|
const box2 = neighbour.querySelector(GLYPH_SELECTOR)?.getBoundingClientRect();
|
|
10857
10907
|
if (box2?.width && box2.height) return box2;
|
|
@@ -10876,11 +10926,14 @@ function iconMarkupSizedFor(slot, markup) {
|
|
|
10876
10926
|
glyph.style.height = `${Math.round(box.height)}px`;
|
|
10877
10927
|
return holder.innerHTML;
|
|
10878
10928
|
}
|
|
10929
|
+
var ICON_SOURCE_ATTR = "data-ohw-icon-source";
|
|
10879
10930
|
function applyIconMarkup(slot, markup) {
|
|
10880
10931
|
if (!markup) return;
|
|
10932
|
+
if (slot.getAttribute(ICON_SOURCE_ATTR) === markup) return;
|
|
10881
10933
|
const coloured = iconMarkupInheritingColour(markup);
|
|
10882
10934
|
const sized = iconMarkupSizedFor(slot, coloured);
|
|
10883
10935
|
if (slot.innerHTML !== sized) slot.innerHTML = sized;
|
|
10936
|
+
slot.setAttribute(ICON_SOURCE_ATTR, markup);
|
|
10884
10937
|
if (sized === coloured) {
|
|
10885
10938
|
requestAnimationFrame(() => {
|
|
10886
10939
|
if (!slot.isConnected) return;
|
|
@@ -10915,7 +10968,7 @@ function iconMarkupInheritingColour(markup) {
|
|
|
10915
10968
|
|
|
10916
10969
|
// src/lib/socials-items.ts
|
|
10917
10970
|
var ICON_SELECTOR = '[data-ohw-editable="icon"]';
|
|
10918
|
-
var PLACEHOLDER_SOCIAL_ICON = '<svg xmlns="http://www.w3.org/2000/svg" width="
|
|
10971
|
+
var PLACEHOLDER_SOCIAL_ICON = '<svg xmlns="http://www.w3.org/2000/svg" width="1.5em" height="1.5em" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/><path d="M2 12h20"/></svg>';
|
|
10919
10972
|
var PLACEHOLDER_SOCIAL_LABEL = "Social";
|
|
10920
10973
|
var SOCIAL_KEY_RE = /(^|-)social(s)?(-|$)/i;
|
|
10921
10974
|
var SOCIAL_PLATFORM_KEY_RE = /(^|-)(instagram|facebook|fb|linkedin|twitter|tiktok|youtube|threads|whatsapp|telegram|pinterest|snapchat|discord|behance|dribbble|vimeo|spotify|github|reddit|medium|twitch)(-|$)/i;
|
|
@@ -10994,31 +11047,71 @@ function listSocialsRows(root = document) {
|
|
|
10994
11047
|
}
|
|
10995
11048
|
var rowTemplates = /* @__PURE__ */ new Map();
|
|
10996
11049
|
function markSocialsRows(root = document) {
|
|
10997
|
-
|
|
10998
|
-
item.removeAttribute(SOCIALS_ITEM_ATTR);
|
|
10999
|
-
});
|
|
11050
|
+
const stillInARow = /* @__PURE__ */ new Set();
|
|
11000
11051
|
listSocialsRows(root).forEach((row) => {
|
|
11001
|
-
row.setAttribute(SOCIALS_ROW_ATTR, "");
|
|
11052
|
+
if (row.getAttribute(SOCIALS_ROW_ATTR) === null) row.setAttribute(SOCIALS_ROW_ATTR, "");
|
|
11053
|
+
queueMicrotask(
|
|
11054
|
+
() => markEmptySocialLabels(row.ownerDocument, row.ownerDocument.activeElement)
|
|
11055
|
+
);
|
|
11002
11056
|
allowRowToWrap(row);
|
|
11003
11057
|
const items = listSocialItems(row);
|
|
11004
11058
|
const firstUnit = items[0] ? socialRowUnit(items[0], row) : null;
|
|
11005
11059
|
if (firstUnit) rowTemplates.set(rowKeyOf(row), firstUnit.outerHTML);
|
|
11006
11060
|
items.forEach((item, index) => {
|
|
11007
|
-
|
|
11008
|
-
|
|
11061
|
+
stillInARow.add(item);
|
|
11062
|
+
if (item.getAttribute(SOCIALS_ITEM_ATTR) !== String(index)) {
|
|
11063
|
+
item.setAttribute(SOCIALS_ITEM_ATTR, String(index));
|
|
11064
|
+
}
|
|
11065
|
+
const iconKey = socialIconKey(item) ?? socialHrefKey(item)?.replace(/-href$/, "");
|
|
11066
|
+
if (iconKey && !item.querySelector(ICON_SELECTOR)) {
|
|
11067
|
+
const drawn = item.querySelector("svg, img");
|
|
11068
|
+
if (drawn) adoptAsIconSlot(drawn, iconKey);
|
|
11069
|
+
}
|
|
11009
11070
|
if (iconKey) ensureLabelSlot(item, iconKey);
|
|
11010
11071
|
});
|
|
11011
11072
|
});
|
|
11073
|
+
root.querySelectorAll(`[${SOCIALS_ITEM_ATTR}]`).forEach((item) => {
|
|
11074
|
+
if (!stillInARow.has(item)) item.removeAttribute(SOCIALS_ITEM_ATTR);
|
|
11075
|
+
});
|
|
11012
11076
|
}
|
|
11013
11077
|
var SOCIALS_LABEL_ATTR = "data-ohw-social-label";
|
|
11078
|
+
var SOCIALS_ICON_PLACEHOLDER_ATTR = "data-ohw-social-icon-placeholder";
|
|
11079
|
+
var SOCIALS_EMPTY_LABEL_ATTR = "data-ohw-empty-label";
|
|
11080
|
+
var EMPTY_LABEL_WIDTH = "8ch";
|
|
11081
|
+
function markEmptySocialLabels(root = document, skip) {
|
|
11082
|
+
root.querySelectorAll(`[${SOCIALS_ROW_ATTR}]`).forEach((row) => {
|
|
11083
|
+
listSocialItems(row).forEach((item) => {
|
|
11084
|
+
const label = socialLabelElement(item);
|
|
11085
|
+
if (!label || label === skip) return;
|
|
11086
|
+
const empty = !label.textContent?.trim();
|
|
11087
|
+
if (empty === label.hasAttribute(SOCIALS_EMPTY_LABEL_ATTR)) return;
|
|
11088
|
+
if (empty) {
|
|
11089
|
+
label.setAttribute(SOCIALS_EMPTY_LABEL_ATTR, "");
|
|
11090
|
+
label.style.display = "inline-block";
|
|
11091
|
+
label.style.minWidth = EMPTY_LABEL_WIDTH;
|
|
11092
|
+
label.style.minHeight = "1.4em";
|
|
11093
|
+
} else {
|
|
11094
|
+
label.removeAttribute(SOCIALS_EMPTY_LABEL_ATTR);
|
|
11095
|
+
label.style.display = "";
|
|
11096
|
+
label.style.minWidth = "";
|
|
11097
|
+
label.style.minHeight = "";
|
|
11098
|
+
}
|
|
11099
|
+
});
|
|
11100
|
+
});
|
|
11101
|
+
}
|
|
11014
11102
|
function ensureLabelSlot(item, iconKey) {
|
|
11015
11103
|
if (socialLabelElement(item)) return;
|
|
11016
11104
|
const label = document.createElement("span");
|
|
11017
11105
|
label.setAttribute("data-ohw-key", `${iconKey}-label`);
|
|
11018
11106
|
label.setAttribute("data-ohw-editable", "text");
|
|
11019
11107
|
label.setAttribute(SOCIALS_LABEL_ATTR, "");
|
|
11020
|
-
|
|
11021
|
-
|
|
11108
|
+
const ownText = Array.from(item.childNodes).filter(
|
|
11109
|
+
(node) => node.nodeType === Node.TEXT_NODE && node.textContent?.trim()
|
|
11110
|
+
);
|
|
11111
|
+
const carried = ownText.map((node) => node.textContent?.trim()).join(" ");
|
|
11112
|
+
ownText.forEach((node) => node.remove());
|
|
11113
|
+
label.textContent = carried || item.getAttribute("aria-label") || "";
|
|
11114
|
+
label.style.display = carried ? "" : "none";
|
|
11022
11115
|
item.appendChild(label);
|
|
11023
11116
|
}
|
|
11024
11117
|
function socialLabelElement(item) {
|
|
@@ -11029,17 +11122,26 @@ function socialLabelElement(item) {
|
|
|
11029
11122
|
function socialLabelKey(iconKey) {
|
|
11030
11123
|
return `${iconKey}-label`;
|
|
11031
11124
|
}
|
|
11125
|
+
function isEmptyLabelValue(value) {
|
|
11126
|
+
return !value.replace(/<br\s*\/?>/gi, "").replace(/ /gi, " ").trim();
|
|
11127
|
+
}
|
|
11032
11128
|
function applyStoredValues(item, content) {
|
|
11033
11129
|
const hrefKey = socialHrefKey(item);
|
|
11034
11130
|
const iconKey = socialIconKey(item);
|
|
11035
11131
|
if (hrefKey && content[hrefKey] !== void 0) item.setAttribute("href", content[hrefKey]);
|
|
11036
11132
|
if (iconKey) {
|
|
11037
11133
|
const glyph = item.querySelector(ICON_SELECTOR);
|
|
11038
|
-
if (glyph && content[iconKey])
|
|
11134
|
+
if (glyph && content[iconKey]) {
|
|
11135
|
+
applyIconMarkup(glyph, content[iconKey]);
|
|
11136
|
+
glyph.removeAttribute(SOCIALS_ICON_PLACEHOLDER_ATTR);
|
|
11137
|
+
}
|
|
11039
11138
|
const label = item.querySelector(`[${SOCIALS_LABEL_ATTR}]`);
|
|
11040
11139
|
label?.setAttribute("data-ohw-key", socialLabelKey(iconKey));
|
|
11041
11140
|
const stored = content[socialLabelKey(iconKey)];
|
|
11042
|
-
if (label && stored
|
|
11141
|
+
if (label && stored !== void 0) {
|
|
11142
|
+
const words = isEmptyLabelValue(stored) ? "" : stored;
|
|
11143
|
+
if (label.innerHTML !== words) label.innerHTML = words;
|
|
11144
|
+
}
|
|
11043
11145
|
}
|
|
11044
11146
|
}
|
|
11045
11147
|
function socialPlatformKey(iconKey) {
|
|
@@ -11076,7 +11178,7 @@ function getSocialsOrderFromDom(root = document) {
|
|
|
11076
11178
|
}
|
|
11077
11179
|
function hasStoredValue(content, hrefKey) {
|
|
11078
11180
|
const iconKey = hrefKey.replace(/-href$/, "");
|
|
11079
|
-
return Boolean(content[hrefKey]) || Boolean(content[iconKey]);
|
|
11181
|
+
return Boolean(content[hrefKey]) || Boolean(content[iconKey]) || Boolean(content[socialLabelKey(iconKey)]);
|
|
11080
11182
|
}
|
|
11081
11183
|
function parseSocialsOrder(raw) {
|
|
11082
11184
|
if (!raw) return null;
|
|
@@ -11087,24 +11189,24 @@ function parseSocialsOrder(raw) {
|
|
|
11087
11189
|
return null;
|
|
11088
11190
|
}
|
|
11089
11191
|
}
|
|
11090
|
-
function nextSocialIndex(row, rowKey, content) {
|
|
11091
|
-
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));
|
|
11192
|
+
function nextSocialIndex(row, rowKey, content, reserved = []) {
|
|
11193
|
+
const used = listSocialItems(row).map((item) => socialHrefKey(item)).concat(Object.keys(content)).concat(reserved).map((key) => key?.match(new RegExp(`^${rowKey}-(\\d+)`))?.[1]).map((digits) => digits === void 0 ? -1 : Number(digits));
|
|
11092
11194
|
return Math.max(-1, ...used) + 1;
|
|
11093
11195
|
}
|
|
11094
|
-
function planSocialInsert(row, content = {}) {
|
|
11196
|
+
function planSocialInsert(row, content = {}, reserved = []) {
|
|
11095
11197
|
if (!canAddSocialItem(row)) return null;
|
|
11096
11198
|
const rowKey = rowKeyOf(row);
|
|
11097
|
-
const iconKey = `${rowKey}-${nextSocialIndex(row, rowKey, content)}`;
|
|
11199
|
+
const iconKey = `${rowKey}-${nextSocialIndex(row, rowKey, content, reserved)}`;
|
|
11098
11200
|
return { hrefKey: `${iconKey}-href`, iconKey };
|
|
11099
11201
|
}
|
|
11100
|
-
function insertSocialItem(row, after, content = {}, { placeholder = true } = {}) {
|
|
11202
|
+
function insertSocialItem(row, after, content = {}, { placeholder = true, keys } = {}) {
|
|
11101
11203
|
const rowKey = rowKeyOf(row);
|
|
11102
11204
|
const template = listSocialItems(row)[0];
|
|
11103
11205
|
const remembered = rowTemplates.get(rowKey);
|
|
11104
11206
|
if (!template && !remembered) return null;
|
|
11105
|
-
const
|
|
11106
|
-
const iconKey = `${rowKey}-${
|
|
11107
|
-
const hrefKey = `${iconKey}-href`;
|
|
11207
|
+
const display = socialsDisplayFor(row, content);
|
|
11208
|
+
const iconKey = keys?.iconKey ?? `${rowKey}-${nextSocialIndex(row, rowKey, content)}`;
|
|
11209
|
+
const hrefKey = keys?.hrefKey ?? `${iconKey}-href`;
|
|
11108
11210
|
const templateUnit = template ? socialRowUnit(template) : null;
|
|
11109
11211
|
const unit = templateUnit ? templateUnit.cloneNode(true) : fromMarkup(remembered);
|
|
11110
11212
|
const item = unit && (unit.matches("a") ? unit : unit.querySelector("a"));
|
|
@@ -11119,6 +11221,7 @@ function insertSocialItem(row, after, content = {}, { placeholder = true } = {})
|
|
|
11119
11221
|
const icon = item.querySelector(ICON_SELECTOR);
|
|
11120
11222
|
icon?.setAttribute("data-ohw-key", iconKey);
|
|
11121
11223
|
if (placeholder && icon) icon.innerHTML = PLACEHOLDER_SOCIAL_ICON;
|
|
11224
|
+
socialLabelElement(item)?.setAttribute("data-ohw-key", socialLabelKey(iconKey));
|
|
11122
11225
|
item.querySelector(`[${SOCIALS_LABEL_ATTR}]`)?.remove();
|
|
11123
11226
|
const afterUnit = after ? socialRowUnit(after) : null;
|
|
11124
11227
|
if (afterUnit && afterUnit.parentElement === row) afterUnit.insertAdjacentElement("afterend", unit);
|
|
@@ -11128,7 +11231,7 @@ function insertSocialItem(row, after, content = {}, { placeholder = true } = {})
|
|
|
11128
11231
|
const label = socialLabelElement(item);
|
|
11129
11232
|
if (label) label.textContent = PLACEHOLDER_SOCIAL_LABEL;
|
|
11130
11233
|
}
|
|
11131
|
-
applySocialsDisplayToRow(row,
|
|
11234
|
+
applySocialsDisplayToRow(row, display);
|
|
11132
11235
|
return { item, hrefKey, iconKey, order: getSocialsOrderFromDom(row.ownerDocument) };
|
|
11133
11236
|
}
|
|
11134
11237
|
function duplicateSocialItem(item, content) {
|
|
@@ -11145,9 +11248,9 @@ function duplicateSocialItem(item, content) {
|
|
|
11145
11248
|
const slot = link.querySelector(ICON_SELECTOR);
|
|
11146
11249
|
if (slot) slot.innerHTML = glyph;
|
|
11147
11250
|
}
|
|
11148
|
-
const sourceLabel = socialLabelElement(item)
|
|
11251
|
+
const sourceLabel = socialLabelElement(item);
|
|
11149
11252
|
const copyLabel = socialLabelElement(link);
|
|
11150
|
-
if (copyLabel && sourceLabel) copyLabel.
|
|
11253
|
+
if (copyLabel && sourceLabel) copyLabel.innerHTML = sourceLabel.innerHTML;
|
|
11151
11254
|
if (row) applySocialsDisplayToRow(row, socialsDisplayFor(row, content));
|
|
11152
11255
|
return {
|
|
11153
11256
|
...created,
|
|
@@ -11188,17 +11291,32 @@ function applySocialsOrder(order, root = document) {
|
|
|
11188
11291
|
const wanted = order[rowKeyOf(row)];
|
|
11189
11292
|
if (!wanted) return;
|
|
11190
11293
|
const byKey = new Map(listSocialItems(row).map((item) => [socialHrefKey(item), item]));
|
|
11191
|
-
wanted.
|
|
11192
|
-
|
|
11193
|
-
|
|
11194
|
-
|
|
11195
|
-
|
|
11196
|
-
});
|
|
11294
|
+
const units = wanted.map((key) => byKey.get(key)).filter((item) => Boolean(item)).map((item) => socialRowUnit(item, row)).filter((unit) => Boolean(unit));
|
|
11295
|
+
const tail = Array.from(row.children).slice(-units.length);
|
|
11296
|
+
const inPlace = units.length > 0 && tail.length === units.length && units.every((unit, i) => tail[i] === unit);
|
|
11297
|
+
if (inPlace) return;
|
|
11298
|
+
units.forEach((unit) => row.appendChild(unit));
|
|
11197
11299
|
});
|
|
11198
11300
|
markSocialsRows(root);
|
|
11199
11301
|
}
|
|
11200
11302
|
function reconcileSocialsFromContent(content, root = document) {
|
|
11201
11303
|
markSocialsRows(root);
|
|
11304
|
+
listSocialsRows(root).forEach((row) => {
|
|
11305
|
+
const rowDisplay = socialsDisplayFor(row, content);
|
|
11306
|
+
listSocialItems(row).forEach((item) => {
|
|
11307
|
+
const key = socialIconKey(item) ?? socialHrefKey(item)?.replace(/-href$/, "");
|
|
11308
|
+
const stored2 = key ? content[key] : void 0;
|
|
11309
|
+
if (!stored2?.trim()) return;
|
|
11310
|
+
const existing = item.querySelector(ICON_SELECTOR);
|
|
11311
|
+
if (existing && existing.innerHTML.trim() && !existing.hasAttribute(SOCIALS_ICON_PLACEHOLDER_ATTR)) return;
|
|
11312
|
+
ensureIconSlot(item);
|
|
11313
|
+
const slot = item.querySelector(ICON_SELECTOR);
|
|
11314
|
+
if (!slot) return;
|
|
11315
|
+
applyIconMarkup(slot, stored2);
|
|
11316
|
+
slot.removeAttribute(SOCIALS_ICON_PLACEHOLDER_ATTR);
|
|
11317
|
+
if (!rowDisplay.icon) slot.style.display = "none";
|
|
11318
|
+
});
|
|
11319
|
+
});
|
|
11202
11320
|
const stored = parseSocialsOrder(content[SOCIALS_ORDER_KEY]);
|
|
11203
11321
|
if (!stored) return;
|
|
11204
11322
|
listSocialsRows(root).forEach((row) => {
|
|
@@ -11208,12 +11326,11 @@ function reconcileSocialsFromContent(content, root = document) {
|
|
|
11208
11326
|
wanted.forEach((key) => {
|
|
11209
11327
|
if (listSocialItems(row).some((item) => socialHrefKey(item) === key)) return;
|
|
11210
11328
|
if (!hasStoredValue(content, key)) return;
|
|
11211
|
-
const created = insertSocialItem(row, null, content
|
|
11212
|
-
|
|
11213
|
-
|
|
11214
|
-
|
|
11215
|
-
|
|
11216
|
-
}
|
|
11329
|
+
const created = insertSocialItem(row, null, content, {
|
|
11330
|
+
placeholder: false,
|
|
11331
|
+
keys: { hrefKey: key, iconKey: key.replace(/-href$/, "") }
|
|
11332
|
+
});
|
|
11333
|
+
if (created) applyStoredValues(created.item, content);
|
|
11217
11334
|
});
|
|
11218
11335
|
const present = listSocialItems(row);
|
|
11219
11336
|
const surviving = present.filter((item) => {
|
|
@@ -11288,9 +11405,10 @@ var SOCIALS_DISPLAY_KEY = "__ohw_socials_display";
|
|
|
11288
11405
|
function readSocialsDisplay(row) {
|
|
11289
11406
|
const items = listSocialItems(row);
|
|
11290
11407
|
const visible = (el) => Boolean(el) && el.style.display !== "none" && el.getAttribute("data-ohw-hidden") === null;
|
|
11408
|
+
const drawn = (el) => Boolean(el && visible(el) && el.innerHTML.trim());
|
|
11291
11409
|
return {
|
|
11292
11410
|
text: items.some((item) => visible(socialLabelElement(item))),
|
|
11293
|
-
icon: items.some((item) =>
|
|
11411
|
+
icon: items.some((item) => drawn(item.querySelector(ICON_SELECTOR)))
|
|
11294
11412
|
};
|
|
11295
11413
|
}
|
|
11296
11414
|
function parseSocialsDisplay(raw) {
|
|
@@ -11338,6 +11456,20 @@ function allowRowToWrap(row) {
|
|
|
11338
11456
|
const display = row.ownerDocument.defaultView?.getComputedStyle(row).display ?? "";
|
|
11339
11457
|
if (display === "flex" || display === "inline-flex") row.style.flexWrap = "wrap";
|
|
11340
11458
|
}
|
|
11459
|
+
function applySocialsLabelsFromContent(content, root = document, { fillEmptyOnly = false } = {}) {
|
|
11460
|
+
const focused = root.activeElement ?? document.activeElement;
|
|
11461
|
+
listSocialsRows(root).forEach((row) => {
|
|
11462
|
+
listSocialItems(row).forEach((item) => {
|
|
11463
|
+
const label = socialLabelElement(item);
|
|
11464
|
+
const key = label?.getAttribute("data-ohw-key");
|
|
11465
|
+
const stored = key ? content[key] : void 0;
|
|
11466
|
+
if (!label || !stored || label === focused) return;
|
|
11467
|
+
if (fillEmptyOnly && label.textContent?.trim()) return;
|
|
11468
|
+
if (!stored.replace(/<br\s*\/?>/gi, "").trim()) return;
|
|
11469
|
+
if (label.innerHTML !== stored) label.innerHTML = stored;
|
|
11470
|
+
});
|
|
11471
|
+
});
|
|
11472
|
+
}
|
|
11341
11473
|
function applySocialsDisplayFromContent(content, root = document) {
|
|
11342
11474
|
const stored = parseSocialsDisplay(content[SOCIALS_DISPLAY_KEY]);
|
|
11343
11475
|
if (!stored) return;
|
|
@@ -11357,8 +11489,27 @@ function applySocialsDisplayFromContent(content, root = document) {
|
|
|
11357
11489
|
function socialsMissingIcons(row) {
|
|
11358
11490
|
return listSocialItems(row).filter((item) => {
|
|
11359
11491
|
const slot = item.querySelector(ICON_SELECTOR);
|
|
11360
|
-
return !slot || !slot.firstElementChild;
|
|
11361
|
-
}).map((item) => ({
|
|
11492
|
+
return !slot || !slot.firstElementChild || slot.hasAttribute(SOCIALS_ICON_PLACEHOLDER_ATTR);
|
|
11493
|
+
}).map((item) => ({
|
|
11494
|
+
hrefKey: socialHrefKey(item) ?? "",
|
|
11495
|
+
url: item.getAttribute("href") ?? "",
|
|
11496
|
+
// Templates ship placeholder addresses — serene-oasis writes "[INSTAGRAM URL]" — and then the
|
|
11497
|
+
// words are the only thing naming the network.
|
|
11498
|
+
label: (socialLabelElement(item)?.textContent ?? item.getAttribute("aria-label") ?? "").trim()
|
|
11499
|
+
})).filter((entry) => Boolean(entry.hrefKey));
|
|
11500
|
+
}
|
|
11501
|
+
function adoptAsIconSlot(drawn, base) {
|
|
11502
|
+
const parent = drawn.parentElement;
|
|
11503
|
+
if (!parent) return null;
|
|
11504
|
+
const taken = drawn.ownerDocument.querySelector(`[data-ohw-key="${base}"]`);
|
|
11505
|
+
const iconKey = taken ? `${base}-icon` : base;
|
|
11506
|
+
const slot = drawn.ownerDocument.createElement("span");
|
|
11507
|
+
slot.setAttribute("data-ohw-key", iconKey);
|
|
11508
|
+
slot.setAttribute("data-ohw-editable", "icon");
|
|
11509
|
+
slot.style.display = "inline-flex";
|
|
11510
|
+
parent.insertBefore(slot, drawn);
|
|
11511
|
+
slot.appendChild(drawn);
|
|
11512
|
+
return iconKey;
|
|
11362
11513
|
}
|
|
11363
11514
|
function ensureIconSlot(item) {
|
|
11364
11515
|
const existing = item.querySelector(ICON_SELECTOR);
|
|
@@ -11366,12 +11517,19 @@ function ensureIconSlot(item) {
|
|
|
11366
11517
|
const hrefKey = socialHrefKey(item);
|
|
11367
11518
|
if (!hrefKey) return null;
|
|
11368
11519
|
const base = hrefKey.replace(/-href$/, "");
|
|
11520
|
+
const drawn = item.querySelector("svg, img");
|
|
11521
|
+
if (drawn) {
|
|
11522
|
+
const adopted = adoptAsIconSlot(drawn, base);
|
|
11523
|
+
if (adopted) return adopted;
|
|
11524
|
+
}
|
|
11369
11525
|
const taken = document.querySelector(`[data-ohw-key="${base}"]`);
|
|
11370
11526
|
const iconKey = taken && taken !== item ? `${base}-icon` : base;
|
|
11371
11527
|
const slot = document.createElement("span");
|
|
11372
11528
|
slot.setAttribute("data-ohw-key", iconKey);
|
|
11373
11529
|
slot.setAttribute("data-ohw-editable", "icon");
|
|
11374
11530
|
slot.style.display = "inline-flex";
|
|
11531
|
+
slot.innerHTML = PLACEHOLDER_SOCIAL_ICON;
|
|
11532
|
+
slot.setAttribute(SOCIALS_ICON_PLACEHOLDER_ATTR, "");
|
|
11375
11533
|
item.prepend(slot);
|
|
11376
11534
|
return iconKey;
|
|
11377
11535
|
}
|
|
@@ -13945,12 +14103,27 @@ function collectEditableNodes(extraContent, root = document) {
|
|
|
13945
14103
|
nodes.push({ key, type: "link", text: href });
|
|
13946
14104
|
}
|
|
13947
14105
|
if (extraContent) {
|
|
13948
|
-
for (const key of [
|
|
14106
|
+
for (const key of [
|
|
14107
|
+
NAV_ORDER_KEY,
|
|
14108
|
+
FOOTER_ORDER_KEY,
|
|
14109
|
+
NAV_COUNT_KEY,
|
|
14110
|
+
SECTION_ORDER_KEY,
|
|
14111
|
+
// A socials row's order and its icons-vs-words setting live under keys no element carries,
|
|
14112
|
+
// so collecting the DOM alone left them behind: the draft knew the row was showing icons and
|
|
14113
|
+
// had gained an item, and the published page went back to the template's own (OHH-736).
|
|
14114
|
+
SOCIALS_ORDER_KEY,
|
|
14115
|
+
SOCIALS_DISPLAY_KEY
|
|
14116
|
+
]) {
|
|
13949
14117
|
const text = extraContent[key];
|
|
13950
14118
|
if (typeof text === "string" && text.length > 0) {
|
|
13951
14119
|
nodes.push({ key, type: "meta", text });
|
|
13952
14120
|
}
|
|
13953
14121
|
}
|
|
14122
|
+
for (const [key, text] of Object.entries(extraContent)) {
|
|
14123
|
+
if (key.endsWith("-platform") && typeof text === "string" && text.length > 0) {
|
|
14124
|
+
nodes.push({ key, type: "meta", text });
|
|
14125
|
+
}
|
|
14126
|
+
}
|
|
13954
14127
|
}
|
|
13955
14128
|
if (!isScoped) {
|
|
13956
14129
|
document.querySelectorAll('[data-ohw-editable="video"]').forEach((el) => {
|
|
@@ -14303,7 +14476,7 @@ function NavbarContainerChrome({
|
|
|
14303
14476
|
}
|
|
14304
14477
|
|
|
14305
14478
|
// src/ui/drop-indicator.tsx
|
|
14306
|
-
var
|
|
14479
|
+
var React11 = __toESM(require("react"), 1);
|
|
14307
14480
|
var import_jsx_runtime31 = require("react/jsx-runtime");
|
|
14308
14481
|
var dropIndicatorVariants = cva(
|
|
14309
14482
|
"ov-gap-line pointer-events-none shrink-0 transition-opacity duration-150",
|
|
@@ -14326,7 +14499,7 @@ var dropIndicatorVariants = cva(
|
|
|
14326
14499
|
}
|
|
14327
14500
|
}
|
|
14328
14501
|
);
|
|
14329
|
-
var DropIndicator =
|
|
14502
|
+
var DropIndicator = React11.forwardRef(
|
|
14330
14503
|
({ className, direction, state, ...props }, ref) => {
|
|
14331
14504
|
return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
14332
14505
|
"div",
|
|
@@ -14940,6 +15113,15 @@ function isPointOverNavItem(container, x, y) {
|
|
|
14940
15113
|
return x >= itemRect.left && x <= itemRect.right && y >= itemRect.top && y <= itemRect.bottom;
|
|
14941
15114
|
});
|
|
14942
15115
|
}
|
|
15116
|
+
function socialsRowAtPoint(x, y) {
|
|
15117
|
+
const inside = (el) => {
|
|
15118
|
+
const r2 = el.getBoundingClientRect();
|
|
15119
|
+
return x >= r2.left && x <= r2.right && y >= r2.top && y <= r2.bottom;
|
|
15120
|
+
};
|
|
15121
|
+
return Array.from(document.querySelectorAll(`[${SOCIALS_ROW_ATTR}]`)).find(
|
|
15122
|
+
(row) => inside(row) && !listSocialItems(row).some(inside)
|
|
15123
|
+
) ?? null;
|
|
15124
|
+
}
|
|
14943
15125
|
function isPointOverFooterColumn(x, y) {
|
|
14944
15126
|
return listFooterColumns().some((col) => {
|
|
14945
15127
|
const r2 = col.getBoundingClientRect();
|
|
@@ -16256,7 +16438,7 @@ function OhhwellsBridge() {
|
|
|
16256
16438
|
const original = originalContentRef.current ?? "";
|
|
16257
16439
|
if (html !== sanitizeHtml(original)) {
|
|
16258
16440
|
postToParentRef.current({ type: "ow:change", nodes: [{ key, text: html }] });
|
|
16259
|
-
const h = document.
|
|
16441
|
+
const h = document.body.scrollHeight;
|
|
16260
16442
|
if (h > 50) postToParentRef.current({ type: "ow:height", height: h });
|
|
16261
16443
|
}
|
|
16262
16444
|
}
|
|
@@ -16418,7 +16600,7 @@ function OhhwellsBridge() {
|
|
|
16418
16600
|
const original = originalContentRef.current ?? "";
|
|
16419
16601
|
if (html !== sanitizeHtml(original)) {
|
|
16420
16602
|
postToParent2({ type: "ow:change", nodes: [{ key, text: html }] });
|
|
16421
|
-
const h = document.
|
|
16603
|
+
const h = document.body.scrollHeight;
|
|
16422
16604
|
if (h > 50) postToParent2({ type: "ow:height", height: h });
|
|
16423
16605
|
}
|
|
16424
16606
|
}
|
|
@@ -16522,7 +16704,8 @@ function OhhwellsBridge() {
|
|
|
16522
16704
|
return;
|
|
16523
16705
|
}
|
|
16524
16706
|
const after = getSocialItem(selected);
|
|
16525
|
-
const
|
|
16707
|
+
const stillPromised = pendingSocialAddRef.current ? [pendingSocialAddRef.current.iconKey] : [];
|
|
16708
|
+
const planned = planSocialInsert(socialsRow, editContentRef.current, stillPromised);
|
|
16526
16709
|
if (!planned) return;
|
|
16527
16710
|
pendingSocialAddRef.current = { row: socialsRow, after, ...planned };
|
|
16528
16711
|
postToParentRef.current({
|
|
@@ -16782,7 +16965,8 @@ function OhhwellsBridge() {
|
|
|
16782
16965
|
applySocialsOrder(nextSocialsOrder);
|
|
16783
16966
|
postToParentRef.current({
|
|
16784
16967
|
type: "ow:change",
|
|
16785
|
-
nodes: [{ key: SOCIALS_ORDER_KEY, text: orderJson }]
|
|
16968
|
+
nodes: [{ key: SOCIALS_ORDER_KEY, text: orderJson }],
|
|
16969
|
+
flush: true
|
|
16786
16970
|
});
|
|
16787
16971
|
applySelectionAfterDrop();
|
|
16788
16972
|
clearFooterDragVisuals();
|
|
@@ -16972,7 +17156,7 @@ function OhhwellsBridge() {
|
|
|
16972
17156
|
}
|
|
16973
17157
|
const selected = selectedElRef.current;
|
|
16974
17158
|
if (!selected || !isNavigationItem2(selected)) return;
|
|
16975
|
-
const editable = selected.querySelector('[data-ohw-editable="text"]') ?? selected.querySelector(
|
|
17159
|
+
const editable = selected.querySelector('[data-ohw-editable="text"], [data-ohw-editable="plain"]') ?? selected.querySelector('[data-ohw-editable]:not([data-ohw-editable="icon"])');
|
|
16976
17160
|
if (!editable) return;
|
|
16977
17161
|
activateRef.current(editable, { caretX: clientX, caretY: clientY });
|
|
16978
17162
|
}, []);
|
|
@@ -17127,13 +17311,16 @@ function OhhwellsBridge() {
|
|
|
17127
17311
|
const isEditModeRef = (0, import_react17.useRef)(false);
|
|
17128
17312
|
const requestMissingSocialIconsRef = (0, import_react17.useRef)(() => {
|
|
17129
17313
|
});
|
|
17314
|
+
const askedSocialIconsRef = (0, import_react17.useRef)(/* @__PURE__ */ new Set());
|
|
17130
17315
|
const requestMissingSocialIcons = (0, import_react17.useCallback)(() => {
|
|
17131
17316
|
const items = Array.from(document.querySelectorAll(`[${SOCIALS_ROW_ATTR}]`)).filter((row) => socialsDisplayFor(row, editContentRef.current).icon).flatMap((row) => {
|
|
17132
17317
|
const missing = socialsMissingIcons(row);
|
|
17133
17318
|
listSocialItems(row).forEach((item) => ensureIconSlot(item));
|
|
17134
17319
|
return missing;
|
|
17135
17320
|
});
|
|
17136
|
-
|
|
17321
|
+
const fresh = items.filter((item) => !askedSocialIconsRef.current.has(`${item.hrefKey}|${item.url}`));
|
|
17322
|
+
fresh.forEach((item) => askedSocialIconsRef.current.add(`${item.hrefKey}|${item.url}`));
|
|
17323
|
+
if (fresh.length) postToParentRef.current({ type: "ow:social-icons-needed", items: fresh });
|
|
17137
17324
|
}, []);
|
|
17138
17325
|
requestMissingSocialIconsRef.current = requestMissingSocialIcons;
|
|
17139
17326
|
isEditModeRef.current = isEditMode;
|
|
@@ -17142,6 +17329,7 @@ function OhhwellsBridge() {
|
|
|
17142
17329
|
if (next.icon) {
|
|
17143
17330
|
const missing = socialsMissingIcons(row);
|
|
17144
17331
|
listSocialItems(row).forEach((item) => ensureIconSlot(item));
|
|
17332
|
+
missing.forEach((item) => askedSocialIconsRef.current.delete(`${item.hrefKey}|${item.url}`));
|
|
17145
17333
|
if (missing.length) {
|
|
17146
17334
|
postToParentRef.current({ type: "ow:social-icons-needed", items: missing });
|
|
17147
17335
|
}
|
|
@@ -17231,7 +17419,15 @@ function OhhwellsBridge() {
|
|
|
17231
17419
|
);
|
|
17232
17420
|
const activate = (0, import_react17.useCallback)((el, options) => {
|
|
17233
17421
|
if (activeElRef.current === el) return;
|
|
17234
|
-
if (isIconEditable(el))
|
|
17422
|
+
if (isIconEditable(el)) {
|
|
17423
|
+
const social = getSocialItem(el);
|
|
17424
|
+
const words = social ? social.querySelector('[data-ohw-editable="text"], [data-ohw-editable="plain"]') : null;
|
|
17425
|
+
if (words && words.offsetParent !== null) {
|
|
17426
|
+
if (social && selectedElRef.current !== social) selectRef.current(social);
|
|
17427
|
+
activateRef.current(words, options);
|
|
17428
|
+
}
|
|
17429
|
+
return;
|
|
17430
|
+
}
|
|
17235
17431
|
if (el.hasAttribute("data-ohw-social-label") && el.offsetParent === null) return;
|
|
17236
17432
|
clearSelectedAttr();
|
|
17237
17433
|
selectedElRef.current = null;
|
|
@@ -17410,6 +17606,7 @@ function OhhwellsBridge() {
|
|
|
17410
17606
|
reconcileFooterOrderFromContent(content);
|
|
17411
17607
|
reconcileSocialsFromContent(content);
|
|
17412
17608
|
applySocialsDisplayFromContent(content);
|
|
17609
|
+
applySocialsLabelsFromContent(content, document, { fillEmptyOnly: isEditModeRef.current });
|
|
17413
17610
|
if (isEditModeRef.current) requestMissingSocialIconsRef.current();
|
|
17414
17611
|
enforceLinkHrefs();
|
|
17415
17612
|
initSectionsFromContent(content, true);
|
|
@@ -17595,6 +17792,7 @@ function OhhwellsBridge() {
|
|
|
17595
17792
|
reconcileFooterOrderFromContent(content);
|
|
17596
17793
|
reconcileSocialsFromContent(content);
|
|
17597
17794
|
applySocialsDisplayFromContent(content);
|
|
17795
|
+
applySocialsLabelsFromContent(content, document, { fillEmptyOnly: isEditModeRef.current });
|
|
17598
17796
|
if (isEditModeRef.current) requestMissingSocialIconsRef.current();
|
|
17599
17797
|
document.querySelectorAll('[data-ohw-editable="form"]').forEach((form) => {
|
|
17600
17798
|
if (!form.querySelector("[data-ohw-form-success]")) {
|
|
@@ -17681,6 +17879,7 @@ function OhhwellsBridge() {
|
|
|
17681
17879
|
reconcileFooterOrderFromContent(content);
|
|
17682
17880
|
reconcileSocialsFromContent(content);
|
|
17683
17881
|
applySocialsDisplayFromContent(content);
|
|
17882
|
+
applySocialsLabelsFromContent(content, document, { fillEmptyOnly: isEditModeRef.current });
|
|
17684
17883
|
if (isEditModeRef.current) requestMissingSocialIconsRef.current();
|
|
17685
17884
|
document.querySelectorAll("footer [data-ohw-href-key]").forEach((el) => {
|
|
17686
17885
|
if (isFooterHrefKey(el.getAttribute("data-ohw-href-key")) || getSocialItem(el)) {
|
|
@@ -17785,6 +17984,66 @@ function OhhwellsBridge() {
|
|
|
17785
17984
|
[style*="100vh"] { min-height: ${initialVh}px !important; height: ${initialVh}px !important; }
|
|
17786
17985
|
[style*="100svh"] { min-height: ${initialVh}px !important; height: ${initialVh}px !important; }
|
|
17787
17986
|
[style*="100dvh"] { min-height: ${initialVh}px !important; height: ${initialVh}px !important; }
|
|
17987
|
+
/* Emptied text keeps somewhere to click. A label typed down to nothing collapses to a
|
|
17988
|
+
couple of pixels, and getting back into it meant hunting for the caret with the mouse.
|
|
17989
|
+
Edit mode only \u2014 the published page shows nothing where there is nothing (OHH-736). */
|
|
17990
|
+
[data-ohw-editable="text"]:empty,
|
|
17991
|
+
[data-ohw-editable="plain"]:empty,
|
|
17992
|
+
[data-ohw-editable="text"]:has(> br:only-child),
|
|
17993
|
+
[data-ohw-editable="plain"]:has(> br:only-child) {
|
|
17994
|
+
min-width: 8ch;
|
|
17995
|
+
min-height: 1.4em;
|
|
17996
|
+
padding: 0 4px;
|
|
17997
|
+
}
|
|
17998
|
+
/* A social left deliberately wordless is a choice, not a mistake, so its empty label takes no
|
|
17999
|
+
room at rest \u2014 the row stays as tight as the site draws it. The box appears only while that
|
|
18000
|
+
row is being worked on: pointer over it, or the item selected (OHH-736). */
|
|
18001
|
+
/* The room itself is kept by the element in both modes \u2014 see markEmptySocialLabels. Left
|
|
18002
|
+
here is only what belongs to editing: something to aim at inside that room. */
|
|
18003
|
+
[data-ohw-socials-row] [data-ohw-empty-label] {
|
|
18004
|
+
padding: 0 4px;
|
|
18005
|
+
}
|
|
18006
|
+
[data-ohw-editable="text"]:empty::before,
|
|
18007
|
+
[data-ohw-editable="plain"]:empty::before {
|
|
18008
|
+
content: '';
|
|
18009
|
+
display: inline-block;
|
|
18010
|
+
width: 100%;
|
|
18011
|
+
height: 1.4em;
|
|
18012
|
+
}
|
|
18013
|
+
/* Not inside a socials row. A stand-in the width of its container is right for a paragraph
|
|
18014
|
+
that has been emptied, but beside an icon it opened a gap as wide as the row would allow:
|
|
18015
|
+
the editor showed the icons strewn across three lines while the published page \u2014 which
|
|
18016
|
+
carries no editing chrome at all \u2014 packed them together, and the two looked nothing alike
|
|
18017
|
+
(OHH-736). The box is given its width on hover and selection instead, which is when it is
|
|
18018
|
+
there to be clicked into. */
|
|
18019
|
+
[data-ohw-socials-row] [data-ohw-editable="text"]:empty::before,
|
|
18020
|
+
[data-ohw-socials-row] [data-ohw-editable="plain"]:empty::before {
|
|
18021
|
+
width: 0;
|
|
18022
|
+
}
|
|
18023
|
+
/* Room inside a socials row so the row itself can be clicked. Without it the items fill their
|
|
18024
|
+
own frame edge to edge and the only way to the row was through an icon and Select parent. */
|
|
18025
|
+
[data-ohw-socials-row] {
|
|
18026
|
+
padding: 6px;
|
|
18027
|
+
}
|
|
18028
|
+
/* A row of socials stays a row. The blanket block above is for body text; applied to the
|
|
18029
|
+
words inside a social it stacked every item on its own line, so instead of wrapping the
|
|
18030
|
+
row grew downwards and pushed the footer with it (OHH-736). */
|
|
18031
|
+
[data-ohw-socials-row] [data-ohw-editable="text"],
|
|
18032
|
+
[data-ohw-socials-row] [data-ohw-editable="plain"] {
|
|
18033
|
+
display: inline-block;
|
|
18034
|
+
}
|
|
18035
|
+
/* The glyph too, and this one mattered most: as a block it filled the whole width of its
|
|
18036
|
+
link and sat over the words, so every click meant for the text landed on the icon. */
|
|
18037
|
+
[data-ohw-socials-row] [data-ohw-editable="icon"] {
|
|
18038
|
+
display: inline-flex;
|
|
18039
|
+
flex: 0 0 auto;
|
|
18040
|
+
align-items: center;
|
|
18041
|
+
}
|
|
18042
|
+
[data-ohw-socials-row] a {
|
|
18043
|
+
display: inline-flex;
|
|
18044
|
+
align-items: center;
|
|
18045
|
+
gap: 6px;
|
|
18046
|
+
}
|
|
17788
18047
|
/* Not the form: it is a layout container (flex/grid with gaps), and forcing block
|
|
17789
18048
|
crushed its fields together (OHH-490). */
|
|
17790
18049
|
[data-ohw-editable]:not([data-ohw-editable="form"]) {
|
|
@@ -18037,6 +18296,13 @@ function OhhwellsBridge() {
|
|
|
18037
18296
|
return;
|
|
18038
18297
|
}
|
|
18039
18298
|
}
|
|
18299
|
+
const socialsRowUnderPoint = socialsRowAtPoint(e.clientX, e.clientY);
|
|
18300
|
+
if (socialsRowUnderPoint) {
|
|
18301
|
+
e.preventDefault();
|
|
18302
|
+
e.stopPropagation();
|
|
18303
|
+
selectFrameRef.current(socialsRowUnderPoint);
|
|
18304
|
+
return;
|
|
18305
|
+
}
|
|
18040
18306
|
const logoEl = getLogoElement(target);
|
|
18041
18307
|
if (logoEl) {
|
|
18042
18308
|
e.preventDefault();
|
|
@@ -18091,6 +18357,19 @@ function OhhwellsBridge() {
|
|
|
18091
18357
|
}
|
|
18092
18358
|
return;
|
|
18093
18359
|
}
|
|
18360
|
+
const socialItem = getSocialItem(editable);
|
|
18361
|
+
const isVisibleWords = (editable.dataset.ohwEditable === "text" || editable.dataset.ohwEditable === "plain") && editable.offsetParent !== null;
|
|
18362
|
+
if (socialItem && isVisibleWords) {
|
|
18363
|
+
e.preventDefault();
|
|
18364
|
+
e.stopPropagation();
|
|
18365
|
+
if (activeElRef.current === editable) return;
|
|
18366
|
+
if (selectedElRef.current === socialItem) {
|
|
18367
|
+
activateRef.current(editable, { caretX: e.clientX, caretY: e.clientY });
|
|
18368
|
+
return;
|
|
18369
|
+
}
|
|
18370
|
+
selectRef.current(socialItem);
|
|
18371
|
+
return;
|
|
18372
|
+
}
|
|
18094
18373
|
const hrefLookupTarget = buttonOnMedia ? clickedButton : editable;
|
|
18095
18374
|
const hrefCtx = getHrefKeyFromElement(hrefLookupTarget);
|
|
18096
18375
|
const navAnchor = hrefCtx ? getNavigationItemAnchor(hrefCtx.anchor) : null;
|
|
@@ -18160,7 +18439,7 @@ function OhhwellsBridge() {
|
|
|
18160
18439
|
selectFrameRef.current(navContainerToSelect);
|
|
18161
18440
|
return;
|
|
18162
18441
|
}
|
|
18163
|
-
const socialsRowToSelect = isSocialsRow(target) ? target :
|
|
18442
|
+
const socialsRowToSelect = isSocialsRow(target) ? target : findSocialsRow(target);
|
|
18164
18443
|
if (socialsRowToSelect && !getSocialItem(target)) {
|
|
18165
18444
|
e.preventDefault();
|
|
18166
18445
|
e.stopPropagation();
|
|
@@ -19162,15 +19441,25 @@ function OhhwellsBridge() {
|
|
|
19162
19441
|
if (pending && updates.some((update) => update.hrefKey === pending.hrefKey)) {
|
|
19163
19442
|
pendingSocialAddRef.current = null;
|
|
19164
19443
|
if (pending.row.isConnected) {
|
|
19165
|
-
const created = insertSocialItem(pending.row, pending.after, editContentRef.current
|
|
19444
|
+
const created = insertSocialItem(pending.row, pending.after, editContentRef.current, {
|
|
19445
|
+
keys: { hrefKey: pending.hrefKey, iconKey: pending.iconKey }
|
|
19446
|
+
});
|
|
19166
19447
|
if (created) {
|
|
19167
19448
|
const orderJson = JSON.stringify(created.order);
|
|
19168
19449
|
editContentRef.current = { ...editContentRef.current, [SOCIALS_ORDER_KEY]: orderJson };
|
|
19169
19450
|
nodes.push({ key: SOCIALS_ORDER_KEY, text: orderJson });
|
|
19451
|
+
const words = created.item.querySelector(
|
|
19452
|
+
'[data-ohw-social-label], [data-ohw-editable="text"], [data-ohw-editable="plain"]'
|
|
19453
|
+
);
|
|
19454
|
+
const labelKey = words?.getAttribute("data-ohw-key");
|
|
19455
|
+
const labelText = words?.textContent?.trim();
|
|
19456
|
+
if (labelKey && labelText && !editContentRef.current[labelKey]) {
|
|
19457
|
+
nodes.push({ key: labelKey, text: labelText });
|
|
19458
|
+
}
|
|
19170
19459
|
}
|
|
19171
19460
|
}
|
|
19172
19461
|
}
|
|
19173
|
-
for (const { hrefKey, iconKey: requestedIconKey, url, iconMarkup, platformId, label } of updates) {
|
|
19462
|
+
for (const { hrefKey, iconKey: requestedIconKey, url, iconMarkup, platformId, label, keepLabel } of updates) {
|
|
19174
19463
|
if (hrefKey) {
|
|
19175
19464
|
document.querySelectorAll(`[data-ohw-href-key="${hrefKey}"]`).forEach((el) => applyLinkHref(el, url));
|
|
19176
19465
|
nodes.push({ key: hrefKey, text: url });
|
|
@@ -19182,6 +19471,7 @@ function OhhwellsBridge() {
|
|
|
19182
19471
|
if (iconKey && typeof iconMarkup === "string" && iconMarkup) {
|
|
19183
19472
|
document.querySelectorAll(`[data-ohw-key="${iconKey}"][data-ohw-editable="icon"]`).forEach((el) => {
|
|
19184
19473
|
applyIconMarkup(el, iconMarkup);
|
|
19474
|
+
el.removeAttribute(SOCIALS_ICON_PLACEHOLDER_ATTR);
|
|
19185
19475
|
});
|
|
19186
19476
|
nodes.push({ key: iconKey, text: iconMarkup });
|
|
19187
19477
|
}
|
|
@@ -19189,9 +19479,10 @@ function OhhwellsBridge() {
|
|
|
19189
19479
|
if (iconKey && label) {
|
|
19190
19480
|
const labelKey = socialLabelKey(iconKey);
|
|
19191
19481
|
document.querySelectorAll(`[data-ohw-key="${labelKey}"]`).forEach((el) => {
|
|
19482
|
+
if (keepLabel && el.textContent?.trim()) return;
|
|
19192
19483
|
el.textContent = label;
|
|
19193
19484
|
});
|
|
19194
|
-
nodes.push({ key: labelKey, text: label });
|
|
19485
|
+
if (!keepLabel) nodes.push({ key: labelKey, text: label });
|
|
19195
19486
|
}
|
|
19196
19487
|
}
|
|
19197
19488
|
if (!nodes.length) return;
|
|
@@ -19324,8 +19615,11 @@ function OhhwellsBridge() {
|
|
|
19324
19615
|
}
|
|
19325
19616
|
setMaxBadge({ rect: el.getBoundingClientRect(), current: Math.min(current, maxLen), max: maxLen });
|
|
19326
19617
|
}
|
|
19618
|
+
if (el.closest(`[${SOCIALS_ROW_ATTR}]`)) markEmptySocialLabels(document, el);
|
|
19327
19619
|
const html = sanitizeHtml(el.innerHTML);
|
|
19328
|
-
|
|
19620
|
+
editContentRef.current = { ...editContentRef.current, [key]: html };
|
|
19621
|
+
const sharing = document.querySelectorAll(`[data-ohw-key="${key}"]`);
|
|
19622
|
+
sharing.forEach((sibling) => {
|
|
19329
19623
|
if (sibling !== el) sibling.innerHTML = html;
|
|
19330
19624
|
});
|
|
19331
19625
|
const timers = autoSaveTimers.current;
|
|
@@ -19334,7 +19628,7 @@ function OhhwellsBridge() {
|
|
|
19334
19628
|
timers.set(key, setTimeout(() => {
|
|
19335
19629
|
timers.delete(key);
|
|
19336
19630
|
postToParentRef.current({ type: "ow:change", nodes: [{ key, text: html }] });
|
|
19337
|
-
const h = document.
|
|
19631
|
+
const h = document.body.scrollHeight;
|
|
19338
19632
|
if (h > 50) postToParentRef.current({ type: "ow:height", height: h });
|
|
19339
19633
|
}, 400));
|
|
19340
19634
|
};
|
|
@@ -19402,7 +19696,7 @@ function OhhwellsBridge() {
|
|
|
19402
19696
|
reconcileFooterOrderFromContent(editContentRef.current);
|
|
19403
19697
|
syncNavigationDragCursorAttrs();
|
|
19404
19698
|
enforceLinkHrefs();
|
|
19405
|
-
const hydratedHeight = document.
|
|
19699
|
+
const hydratedHeight = document.body.scrollHeight;
|
|
19406
19700
|
if (hydratedHeight > 50) postToParentRef.current({ type: "ow:height", height: hydratedHeight });
|
|
19407
19701
|
postToParentRef.current({ type: "ow:hydrate-done" });
|
|
19408
19702
|
};
|
|
@@ -19484,7 +19778,7 @@ function OhhwellsBridge() {
|
|
|
19484
19778
|
const nextValue = serializeAiSectionsState(nextState);
|
|
19485
19779
|
aiSectionsRef.current = nextValue;
|
|
19486
19780
|
applyAiSectionsToDom(nextState);
|
|
19487
|
-
const newHeight = document.
|
|
19781
|
+
const newHeight = document.body.scrollHeight;
|
|
19488
19782
|
if (newHeight > 50) postToParentRef.current({ type: "ow:height", height: newHeight });
|
|
19489
19783
|
postToParentRef.current({ type: "ow:change", nodes: [{ key: AI_SECTIONS_KEY, text: nextValue }] });
|
|
19490
19784
|
const appliedEl = document.querySelector(`[data-ohw-section="${CSS.escape(payload.id)}"]`);
|
|
@@ -19506,7 +19800,7 @@ function OhhwellsBridge() {
|
|
|
19506
19800
|
const nextValue = serializeAiSectionsState(nextState);
|
|
19507
19801
|
aiSectionsRef.current = nextValue;
|
|
19508
19802
|
applyAiSectionsToDom(nextState);
|
|
19509
|
-
const newHeight = document.
|
|
19803
|
+
const newHeight = document.body.scrollHeight;
|
|
19510
19804
|
if (newHeight > 50) postToParentRef.current({ type: "ow:height", height: newHeight });
|
|
19511
19805
|
postToParentRef.current({ type: "ow:change", nodes: [{ key: AI_SECTIONS_KEY, text: nextValue }] });
|
|
19512
19806
|
postToParentRef.current({ type: "ow:ai-section-deleted", sectionId, previous, value: nextValue });
|
|
@@ -19520,7 +19814,7 @@ function OhhwellsBridge() {
|
|
|
19520
19814
|
aiSectionsRef.current = value;
|
|
19521
19815
|
applyAiSectionsToDom(parseAiSectionsState(value));
|
|
19522
19816
|
applyStylesToDom(parseStyleStore(stylesRef.current));
|
|
19523
|
-
const restoredHeight = document.
|
|
19817
|
+
const restoredHeight = document.body.scrollHeight;
|
|
19524
19818
|
if (restoredHeight > 50) postToParentRef.current({ type: "ow:height", height: restoredHeight });
|
|
19525
19819
|
postToParentRef.current({ type: "ow:change", nodes: [{ key: AI_SECTIONS_KEY, text: value }] });
|
|
19526
19820
|
postAiSectionsChanged();
|
|
@@ -19574,6 +19868,48 @@ function OhhwellsBridge() {
|
|
|
19574
19868
|
else document.documentElement.removeAttribute("data-ohw-panel-dragging");
|
|
19575
19869
|
};
|
|
19576
19870
|
window.addEventListener("message", handlePanelDragging);
|
|
19871
|
+
const handleDeleteSection = (e) => {
|
|
19872
|
+
if (e.data?.type !== "ow:delete-section") return;
|
|
19873
|
+
const instanceId = typeof e.data.instanceId === "string" ? e.data.instanceId : "";
|
|
19874
|
+
if (!instanceId) return;
|
|
19875
|
+
const currentEntries = getPageSectionOrderEntries(editContentRef.current[SECTION_ORDER_KEY], window.location.pathname);
|
|
19876
|
+
const entries = deleteSectionInstance(instanceId, window.location.pathname, currentEntries);
|
|
19877
|
+
if (!entries) return;
|
|
19878
|
+
const orderJson = JSON.stringify(entries);
|
|
19879
|
+
editContentRef.current = { ...editContentRef.current, [SECTION_ORDER_KEY]: orderJson };
|
|
19880
|
+
postToParentRef.current({ type: "ow:change", nodes: [{ key: SECTION_ORDER_KEY, text: orderJson }] });
|
|
19881
|
+
aiSectionApiRef.current?.clear();
|
|
19882
|
+
window.dispatchEvent(new Event("resize"));
|
|
19883
|
+
const deleteHeight = document.body.scrollHeight;
|
|
19884
|
+
if (deleteHeight > 50) postToParentRef.current({ type: "ow:height", height: deleteHeight });
|
|
19885
|
+
const actionId = newInstanceId();
|
|
19886
|
+
pendingDeleteUndoRef.current = {
|
|
19887
|
+
actionId,
|
|
19888
|
+
restore: () => {
|
|
19889
|
+
const restoredEntries = getPageSectionOrderEntries(
|
|
19890
|
+
editContentRef.current[SECTION_ORDER_KEY],
|
|
19891
|
+
window.location.pathname
|
|
19892
|
+
);
|
|
19893
|
+
const restored = restoreSectionInstance(instanceId, window.location.pathname, restoredEntries);
|
|
19894
|
+
if (!restored) return;
|
|
19895
|
+
const restoredJson = JSON.stringify(restored);
|
|
19896
|
+
editContentRef.current = { ...editContentRef.current, [SECTION_ORDER_KEY]: restoredJson };
|
|
19897
|
+
postToParentRef.current({ type: "ow:change", nodes: [{ key: SECTION_ORDER_KEY, text: restoredJson }] });
|
|
19898
|
+
window.dispatchEvent(new Event("resize"));
|
|
19899
|
+
const restoreHeight = document.body.scrollHeight;
|
|
19900
|
+
if (restoreHeight > 50) postToParentRef.current({ type: "ow:height", height: restoreHeight });
|
|
19901
|
+
}
|
|
19902
|
+
};
|
|
19903
|
+
postToParentRef.current({
|
|
19904
|
+
type: "ow:toast",
|
|
19905
|
+
title: "Section deleted",
|
|
19906
|
+
toastType: "success",
|
|
19907
|
+
actionLabel: "Undo",
|
|
19908
|
+
actionId,
|
|
19909
|
+
duration: 6e3
|
|
19910
|
+
});
|
|
19911
|
+
};
|
|
19912
|
+
window.addEventListener("message", handleDeleteSection);
|
|
19577
19913
|
const handleDeactivate = (e) => {
|
|
19578
19914
|
if (e.data?.type !== "ow:deactivate") return;
|
|
19579
19915
|
if (document.documentElement.hasAttribute("data-ohw-panel-dragging")) return;
|
|
@@ -19909,7 +20245,7 @@ function OhhwellsBridge() {
|
|
|
19909
20245
|
const updated = sections.filter((s) => !(s.type === "scheduling" && s.pagePath === currentPath));
|
|
19910
20246
|
tracker.textContent = JSON.stringify(updated);
|
|
19911
20247
|
postToParentRef.current({ type: "ow:change", nodes: [{ key: "__ohw_sections", text: tracker.textContent }] });
|
|
19912
|
-
const h = document.
|
|
20248
|
+
const h = document.body.scrollHeight;
|
|
19913
20249
|
if (h > 50) postToParentRef.current({ type: "ow:height", height: h });
|
|
19914
20250
|
};
|
|
19915
20251
|
const handleCollectSection = (e) => {
|
|
@@ -20260,6 +20596,7 @@ function OhhwellsBridge() {
|
|
|
20260
20596
|
window.removeEventListener("message", handleAiSetStyles);
|
|
20261
20597
|
window.removeEventListener("message", handleGetBrand);
|
|
20262
20598
|
window.removeEventListener("message", handlePanelDragging);
|
|
20599
|
+
window.removeEventListener("message", handleDeleteSection);
|
|
20263
20600
|
window.removeEventListener("message", handleDeactivate);
|
|
20264
20601
|
window.removeEventListener("message", handleToastAction);
|
|
20265
20602
|
window.removeEventListener("message", handleFormCount);
|
|
@@ -20665,15 +21002,23 @@ function OhhwellsBridge() {
|
|
|
20665
21002
|
const result = duplicateSocialItem(social, editContentRef.current);
|
|
20666
21003
|
if (!result) return;
|
|
20667
21004
|
const orderJson = JSON.stringify(result.order);
|
|
21005
|
+
const copyIcon = result.item.querySelector('[data-ohw-editable="icon"]');
|
|
21006
|
+
const copyLabel = result.item.querySelector(
|
|
21007
|
+
'[data-ohw-social-label], [data-ohw-editable="text"], [data-ohw-editable="plain"]'
|
|
21008
|
+
);
|
|
21009
|
+
const storedOf = (key) => key ? editContentRef.current[key] : void 0;
|
|
20668
21010
|
const carried = [
|
|
20669
|
-
{
|
|
20670
|
-
{
|
|
20671
|
-
{
|
|
21011
|
+
{ key: result.hrefKey, text: storedOf(result.copiedFrom?.href) ?? result.item.getAttribute("href") },
|
|
21012
|
+
{ key: result.iconKey, text: storedOf(result.copiedFrom?.icon) ?? copyIcon?.innerHTML },
|
|
21013
|
+
{
|
|
21014
|
+
key: socialPlatformKey(result.iconKey),
|
|
21015
|
+
text: storedOf(result.copiedFrom?.icon ? socialPlatformKey(result.copiedFrom.icon) : null)
|
|
21016
|
+
},
|
|
21017
|
+
{ key: copyLabel?.getAttribute("data-ohw-key"), text: copyLabel?.textContent?.trim() }
|
|
20672
21018
|
];
|
|
20673
21019
|
const nodes = [{ key: SOCIALS_ORDER_KEY, text: orderJson }];
|
|
20674
|
-
for (const {
|
|
20675
|
-
|
|
20676
|
-
if (value) nodes.push({ key: to, text: value });
|
|
21020
|
+
for (const { key, text } of carried) {
|
|
21021
|
+
if (key && text) nodes.push({ key, text });
|
|
20677
21022
|
}
|
|
20678
21023
|
editContentRef.current = {
|
|
20679
21024
|
...editContentRef.current,
|
|
@@ -21200,7 +21545,7 @@ function OhhwellsBridge() {
|
|
|
21200
21545
|
onDragHandleDragEnd: handleItemDragEnd,
|
|
21201
21546
|
onItemPointerDown: toolbarVariant === "logo" ? void 0 : handleItemChromePointerDown,
|
|
21202
21547
|
onItemClick: toolbarVariant === "logo" ? void 0 : handleItemChromeClick,
|
|
21203
|
-
itemDragSurface: toolbarVariant !== "logo" && !isFooterFrameSelection,
|
|
21548
|
+
itemDragSurface: toolbarVariant !== "logo" && !isFooterFrameSelection && !selectedIsSocialsRow,
|
|
21204
21549
|
toolbar: toolbarVariant === "link-action" && !isItemDragging || toolbarVariant === "select-frame" && (isFooterFrameSelection || selectedIsSocialsRow) && !isItemDragging ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
21205
21550
|
ItemActionToolbar,
|
|
21206
21551
|
{
|