@ohhwells/bridge 0.1.38-next.68 → 0.1.38
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/README.md +1 -13
- package/dist/index.cjs +682 -3006
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -98
- package/dist/index.d.ts +6 -98
- package/dist/index.js +691 -3012
- package/dist/index.js.map +1 -1
- package/dist/styles.css +34 -169
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -35,7 +35,6 @@ __export(index_exports, {
|
|
|
35
35
|
CustomToolbarButton: () => CustomToolbarButton,
|
|
36
36
|
CustomToolbarDivider: () => CustomToolbarDivider,
|
|
37
37
|
DragHandle: () => DragHandle,
|
|
38
|
-
DropIndicator: () => DropIndicator,
|
|
39
38
|
ItemActionToolbar: () => ItemActionToolbar,
|
|
40
39
|
ItemInteractionLayer: () => ItemInteractionLayer,
|
|
41
40
|
LinkEditorPanel: () => LinkEditorPanel,
|
|
@@ -50,31 +49,26 @@ __export(index_exports, {
|
|
|
50
49
|
TooltipProvider: () => TooltipProvider,
|
|
51
50
|
TooltipTrigger: () => TooltipTrigger,
|
|
52
51
|
buildTarget: () => buildTarget,
|
|
53
|
-
dropIndicatorVariants: () => dropIndicatorVariants,
|
|
54
52
|
filterAvailablePages: () => filterAvailablePages,
|
|
55
53
|
getEditModeInitialState: () => getEditModeInitialState,
|
|
56
54
|
isEditSessionActive: () => isEditSessionActive,
|
|
57
55
|
isValidUrl: () => isValidUrl,
|
|
58
56
|
parseTarget: () => parseTarget,
|
|
59
57
|
toggleVariants: () => toggleVariants,
|
|
60
|
-
useOhwCarousel: () => useOhwCarousel,
|
|
61
58
|
validateUrlInput: () => validateUrlInput
|
|
62
59
|
});
|
|
63
60
|
module.exports = __toCommonJS(index_exports);
|
|
64
61
|
|
|
65
62
|
// src/OhhwellsBridge.tsx
|
|
66
|
-
var
|
|
63
|
+
var import_react6 = __toESM(require("react"), 1);
|
|
67
64
|
var import_client = require("react-dom/client");
|
|
68
|
-
var
|
|
65
|
+
var import_react_dom = require("react-dom");
|
|
69
66
|
|
|
70
67
|
// src/linkHrefStore.ts
|
|
71
68
|
var linkHrefStore = /* @__PURE__ */ new Map();
|
|
72
69
|
function setStoredLinkHref(key, href) {
|
|
73
70
|
linkHrefStore.set(key, href);
|
|
74
71
|
}
|
|
75
|
-
function getStoredLinkHref(key) {
|
|
76
|
-
return linkHrefStore.get(key);
|
|
77
|
-
}
|
|
78
72
|
function enforceLinkHrefs() {
|
|
79
73
|
document.querySelectorAll("[data-ohw-href-key]").forEach((el) => {
|
|
80
74
|
const key = el.getAttribute("data-ohw-href-key") ?? "";
|
|
@@ -116,7 +110,6 @@ var import_react3 = require("react");
|
|
|
116
110
|
var import_react2 = require("react");
|
|
117
111
|
var import_radix_ui = require("radix-ui");
|
|
118
112
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
119
|
-
var isValidEmail = (value) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value);
|
|
120
113
|
function Spinner() {
|
|
121
114
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
122
115
|
"svg",
|
|
@@ -150,17 +143,12 @@ function EmailCaptureModal({ title, subtitle, onSubmit, onClose }) {
|
|
|
150
143
|
const [error, setError] = (0, import_react2.useState)(null);
|
|
151
144
|
const isBook = title === "Confirm your spot";
|
|
152
145
|
const handleSubmit = async () => {
|
|
153
|
-
|
|
154
|
-
if (!trimmed) return;
|
|
155
|
-
if (!isValidEmail(trimmed)) {
|
|
156
|
-
setError("Please enter a valid email address.");
|
|
157
|
-
return;
|
|
158
|
-
}
|
|
146
|
+
if (!email.trim()) return;
|
|
159
147
|
setLoading(true);
|
|
160
148
|
setError(null);
|
|
161
149
|
try {
|
|
162
|
-
await onSubmit(
|
|
163
|
-
setSubmittedEmail(
|
|
150
|
+
await onSubmit(email.trim());
|
|
151
|
+
setSubmittedEmail(email.trim());
|
|
164
152
|
setSuccess(true);
|
|
165
153
|
} catch (e) {
|
|
166
154
|
setError(e instanceof Error ? e.message : "Something went wrong. Please try again.");
|
|
@@ -235,10 +223,7 @@ function EmailCaptureModal({ title, subtitle, onSubmit, onClose }) {
|
|
|
235
223
|
{
|
|
236
224
|
type: "email",
|
|
237
225
|
value: email,
|
|
238
|
-
onChange: (e) =>
|
|
239
|
-
setEmail(e.target.value);
|
|
240
|
-
if (error) setError(null);
|
|
241
|
-
},
|
|
226
|
+
onChange: (e) => setEmail(e.target.value),
|
|
242
227
|
onKeyDown: handleKeyDown,
|
|
243
228
|
placeholder: "hello@gmail.com",
|
|
244
229
|
autoFocus: true,
|
|
@@ -295,20 +280,12 @@ function formatClassTime(cls) {
|
|
|
295
280
|
const em = endTotal % 60;
|
|
296
281
|
return `${h}:${cls.startTime.minutes}-${eh}:${String(em).padStart(2, "0")}`;
|
|
297
282
|
}
|
|
298
|
-
function formatBookingLabel(cls) {
|
|
299
|
-
const price = cls.price;
|
|
300
|
-
const isFree = price === null || price === void 0 || `${price}` === "" || `${price}` === "0";
|
|
301
|
-
return isFree ? "Book for free" : `Book for ${cls.currency ?? ""} ${price}`.trim();
|
|
302
|
-
}
|
|
303
283
|
function getBookingsOnDate(cls, date) {
|
|
304
284
|
if (!cls.bookings?.length) return 0;
|
|
305
|
-
const
|
|
306
|
-
target.setHours(0, 0, 0, 0);
|
|
285
|
+
const ds = date.toISOString().split("T")[0];
|
|
307
286
|
return cls.bookings.filter((b) => {
|
|
308
287
|
try {
|
|
309
|
-
|
|
310
|
-
bookingDate.setHours(0, 0, 0, 0);
|
|
311
|
-
return bookingDate.getTime() === target.getTime();
|
|
288
|
+
return new Date(b.classDate).toISOString().split("T")[0] === ds;
|
|
312
289
|
} catch {
|
|
313
290
|
return false;
|
|
314
291
|
}
|
|
@@ -573,7 +550,7 @@ function ScheduleView({ schedule, dates, selectedIdx, onSelectDate, onOpenModal
|
|
|
573
550
|
}
|
|
574
551
|
)
|
|
575
552
|
] }),
|
|
576
|
-
|
|
553
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "sm:hidden flex flex-col gap-px", children: isFull ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "font-body text-sm text-(--color-dark,#200C02) opacity-80", children: "Full" }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
577
554
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "font-body text-sm text-(--color-dark,#200C02) opacity-80", children: [
|
|
578
555
|
available,
|
|
579
556
|
"/",
|
|
@@ -585,10 +562,9 @@ function ScheduleView({ schedule, dates, selectedIdx, onSelectDate, onOpenModal
|
|
|
585
562
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex flex-1 flex-col gap-2 min-w-0 sm:contents", children: [
|
|
586
563
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex-1 flex flex-col gap-2 min-w-0", children: [
|
|
587
564
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "font-body text-base font-bold text-(--color-dark,#200C02) block truncate", children: cls.name }),
|
|
588
|
-
cls.hostName && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "font-body text-base font-normal text-(--color-dark,#200C02) opacity-80 block truncate", children: cls.hostName })
|
|
589
|
-
cls.description && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "font-body text-sm font-normal text-(--color-dark,#200C02) opacity-70 block truncate", children: cls.description })
|
|
565
|
+
cls.hostName && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "font-body text-base font-normal text-(--color-dark,#200C02) opacity-80 block truncate", children: cls.hostName })
|
|
590
566
|
] }),
|
|
591
|
-
|
|
567
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "hidden sm:flex w-14 shrink-0 flex-col gap-px", children: isFull ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "font-body text-sm text-(--color-dark,#200C02) opacity-80", children: "Full" }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
592
568
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "font-body text-sm text-(--color-dark,#200C02) opacity-80", children: [
|
|
593
569
|
available,
|
|
594
570
|
"/",
|
|
@@ -613,7 +589,7 @@ function ScheduleView({ schedule, dates, selectedIdx, onSelectDate, onOpenModal
|
|
|
613
589
|
if (!cls.id) return;
|
|
614
590
|
onOpenModal?.(isFull ? "waitlist" : "book", cls.id, selectedDate);
|
|
615
591
|
},
|
|
616
|
-
children: isFull ? "Join Waitlist" :
|
|
592
|
+
children: isFull ? "Join Waitlist" : "Book Now"
|
|
617
593
|
}
|
|
618
594
|
)
|
|
619
595
|
] })
|
|
@@ -655,17 +631,6 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
655
631
|
const [isHovered, setIsHovered] = (0, import_react3.useState)(false);
|
|
656
632
|
const [modalState, setModalState] = (0, import_react3.useState)(null);
|
|
657
633
|
const switchScheduleIdRef = (0, import_react3.useRef)(null);
|
|
658
|
-
const liveScheduleIdRef = (0, import_react3.useRef)(null);
|
|
659
|
-
const refetchLiveSchedule = (0, import_react3.useCallback)(async () => {
|
|
660
|
-
const id = liveScheduleIdRef.current;
|
|
661
|
-
if (!id) return;
|
|
662
|
-
try {
|
|
663
|
-
const res = await fetch(`${API_URL}/api/schedule/id/${id}`);
|
|
664
|
-
const data = await res.json();
|
|
665
|
-
if (data?.id) setSchedule(data);
|
|
666
|
-
} catch {
|
|
667
|
-
}
|
|
668
|
-
}, []);
|
|
669
634
|
const dates = (0, import_react3.useMemo)(() => {
|
|
670
635
|
const today = /* @__PURE__ */ new Date();
|
|
671
636
|
today.setHours(0, 0, 0, 0);
|
|
@@ -685,18 +650,6 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
685
650
|
}
|
|
686
651
|
}
|
|
687
652
|
}, [schedule, dates]);
|
|
688
|
-
(0, import_react3.useEffect)(() => {
|
|
689
|
-
if (typeof window === "undefined") return;
|
|
690
|
-
const onVisible = () => {
|
|
691
|
-
if (!document.hidden) void refetchLiveSchedule();
|
|
692
|
-
};
|
|
693
|
-
window.addEventListener("focus", refetchLiveSchedule);
|
|
694
|
-
document.addEventListener("visibilitychange", onVisible);
|
|
695
|
-
return () => {
|
|
696
|
-
window.removeEventListener("focus", refetchLiveSchedule);
|
|
697
|
-
document.removeEventListener("visibilitychange", onVisible);
|
|
698
|
-
};
|
|
699
|
-
}, [refetchLiveSchedule]);
|
|
700
653
|
(0, import_react3.useEffect)(() => {
|
|
701
654
|
if (typeof window === "undefined") return;
|
|
702
655
|
const isInEditor = window.self !== window.top;
|
|
@@ -758,7 +711,7 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
758
711
|
setLoading(false);
|
|
759
712
|
return;
|
|
760
713
|
}
|
|
761
|
-
|
|
714
|
+
;
|
|
762
715
|
(async () => {
|
|
763
716
|
try {
|
|
764
717
|
const res = await fetch(`${API_URL}/api/schedule/id/${effectiveId}`);
|
|
@@ -815,14 +768,18 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
815
768
|
const data = await res.json().catch(() => ({}));
|
|
816
769
|
throw new Error(data?.message ?? "Something went wrong. Please try again.");
|
|
817
770
|
}
|
|
818
|
-
await refetchLiveSchedule();
|
|
819
771
|
};
|
|
820
772
|
const handleReplaceSchedule = () => {
|
|
821
773
|
setIsHovered(false);
|
|
822
|
-
|
|
823
|
-
{
|
|
824
|
-
|
|
825
|
-
|
|
774
|
+
if (schedule) {
|
|
775
|
+
window.parent.postMessage({
|
|
776
|
+
type: "ow:schedule-connected",
|
|
777
|
+
schedule: { id: schedule.id, name: schedule.name },
|
|
778
|
+
insertAfter
|
|
779
|
+
}, "*");
|
|
780
|
+
} else {
|
|
781
|
+
window.parent.postMessage({ type: "ow:scheduling-not-connected", insertAfter }, "*");
|
|
782
|
+
}
|
|
826
783
|
};
|
|
827
784
|
if (!inEditor && !loading && !schedule) return null;
|
|
828
785
|
const sectionId = `scheduling-${insertAfter}`;
|
|
@@ -865,19 +822,7 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
865
822
|
),
|
|
866
823
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "max-w-[1280px] mx-auto flex flex-col items-center gap-16", children: [
|
|
867
824
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex flex-col items-center gap-4", children: [
|
|
868
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
869
|
-
"h2",
|
|
870
|
-
{
|
|
871
|
-
className: "font-display text-center m-0 text-(--color-dark,#200C02)",
|
|
872
|
-
style: {
|
|
873
|
-
fontSize: "var(--fs-section-h2, clamp(40px, 4.4vw, 64px))",
|
|
874
|
-
fontWeight: "var(--font-weight-heading, 400)",
|
|
875
|
-
lineHeight: 1.05,
|
|
876
|
-
letterSpacing: "-0.02em"
|
|
877
|
-
},
|
|
878
|
-
children: schedule?.name ?? "Book an appointment"
|
|
879
|
-
}
|
|
880
|
-
),
|
|
825
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h2", { className: "font-display text-4xl sm:text-5xl font-bold text-center m-0 text-(--color-dark,#200C02)", children: schedule?.name ?? "Book an appointment" }),
|
|
881
826
|
schedule?.description && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "font-body text-body text-center m-0 text-(--color-accent,#A89B83)", children: schedule.description })
|
|
882
827
|
] }),
|
|
883
828
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "w-full flex flex-col items-end gap-3", children: [
|
|
@@ -4463,7 +4408,6 @@ function ItemActionToolbar({
|
|
|
4463
4408
|
onEditLink,
|
|
4464
4409
|
onAddItem,
|
|
4465
4410
|
onMore,
|
|
4466
|
-
editLinkDisabled = false,
|
|
4467
4411
|
addItemDisabled = true,
|
|
4468
4412
|
moreDisabled = true,
|
|
4469
4413
|
tooltipSide = "bottom"
|
|
@@ -4472,12 +4416,10 @@ function ItemActionToolbar({
|
|
|
4472
4416
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
4473
4417
|
ToolbarActionTooltip,
|
|
4474
4418
|
{
|
|
4475
|
-
label: "
|
|
4419
|
+
label: "Add link",
|
|
4476
4420
|
side: tooltipSide,
|
|
4477
|
-
disabled: editLinkDisabled,
|
|
4478
4421
|
buttonProps: {
|
|
4479
4422
|
onMouseDown: (e) => {
|
|
4480
|
-
if (editLinkDisabled) return;
|
|
4481
4423
|
e.preventDefault();
|
|
4482
4424
|
e.stopPropagation();
|
|
4483
4425
|
onEditLink?.();
|
|
@@ -4555,7 +4497,7 @@ function getChromeStyle(state) {
|
|
|
4555
4497
|
case "dragging":
|
|
4556
4498
|
return {
|
|
4557
4499
|
border: `2px solid ${PRIMARY}`,
|
|
4558
|
-
boxShadow:
|
|
4500
|
+
boxShadow: DRAG_SHADOW
|
|
4559
4501
|
};
|
|
4560
4502
|
default:
|
|
4561
4503
|
return {};
|
|
@@ -4571,8 +4513,6 @@ function ItemInteractionLayer({
|
|
|
4571
4513
|
dragHandleLabel = "Reorder item",
|
|
4572
4514
|
onDragHandleDragStart,
|
|
4573
4515
|
onDragHandleDragEnd,
|
|
4574
|
-
onItemPointerDown,
|
|
4575
|
-
onItemClick,
|
|
4576
4516
|
chromeGap = 6,
|
|
4577
4517
|
className
|
|
4578
4518
|
}) {
|
|
@@ -4580,8 +4520,7 @@ function ItemInteractionLayer({
|
|
|
4580
4520
|
const isActive = state === "active-top" || state === "active-bottom";
|
|
4581
4521
|
const isDragging = state === "dragging";
|
|
4582
4522
|
const showToolbar = isActive && toolbar;
|
|
4583
|
-
const showDragHandle =
|
|
4584
|
-
const itemDragEnabled = isActive && showHandle && !isDragging && !dragDisabled;
|
|
4523
|
+
const showDragHandle = isActive && showHandle && !isDragging;
|
|
4585
4524
|
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
4586
4525
|
"div",
|
|
4587
4526
|
{
|
|
@@ -4606,28 +4545,11 @@ function ItemInteractionLayer({
|
|
|
4606
4545
|
style: getChromeStyle(state)
|
|
4607
4546
|
}
|
|
4608
4547
|
),
|
|
4609
|
-
itemDragEnabled && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
4610
|
-
"div",
|
|
4611
|
-
{
|
|
4612
|
-
"data-ohw-item-drag-surface": "",
|
|
4613
|
-
className: "pointer-events-auto absolute inset-0 cursor-grab rounded-lg active:cursor-grabbing",
|
|
4614
|
-
onPointerDown: (e) => {
|
|
4615
|
-
if (e.button !== 0) return;
|
|
4616
|
-
onItemPointerDown?.(e);
|
|
4617
|
-
},
|
|
4618
|
-
onClick: (e) => {
|
|
4619
|
-
e.preventDefault();
|
|
4620
|
-
e.stopPropagation();
|
|
4621
|
-
onItemClick?.(e.clientX, e.clientY);
|
|
4622
|
-
}
|
|
4623
|
-
}
|
|
4624
|
-
),
|
|
4625
4548
|
showDragHandle && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
4626
4549
|
"div",
|
|
4627
4550
|
{
|
|
4628
4551
|
"data-ohw-drag-handle-container": "",
|
|
4629
|
-
className: "pointer-events-auto absolute left-0 top-1/2
|
|
4630
|
-
style: isDragging ? { visibility: "hidden" } : void 0,
|
|
4552
|
+
className: "pointer-events-auto absolute left-0 top-1/2 -translate-x-[calc(100%+7px)] -translate-y-1/2",
|
|
4631
4553
|
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
4632
4554
|
DragHandle,
|
|
4633
4555
|
{
|
|
@@ -4850,12 +4772,15 @@ function MediaOverlay({
|
|
|
4850
4772
|
className: "flex items-center justify-center cursor-pointer",
|
|
4851
4773
|
style: {
|
|
4852
4774
|
...box,
|
|
4853
|
-
//
|
|
4854
|
-
//
|
|
4855
|
-
|
|
4775
|
+
// When text overlays this media, let clicks fall THROUGH to the text underneath. In the
|
|
4776
|
+
// parent this needed a whole `ow:click-at` round-trip to re-hit-test inside the iframe;
|
|
4777
|
+
// in-document, pointer-events does it natively. The button below opts back in, so
|
|
4778
|
+
// Replace still works.
|
|
4779
|
+
pointerEvents: hover.hasTextOverlap ? "none" : "auto",
|
|
4856
4780
|
boxShadow: "inset 0 0 0 1.5px var(--color-primary)",
|
|
4857
4781
|
background: "color-mix(in srgb, var(--color-primary) 20%, transparent)"
|
|
4858
4782
|
},
|
|
4783
|
+
onClick: () => onReplace(hover.key),
|
|
4859
4784
|
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
4860
4785
|
Button,
|
|
4861
4786
|
{
|
|
@@ -4880,64 +4805,9 @@ function MediaOverlay({
|
|
|
4880
4805
|
] });
|
|
4881
4806
|
}
|
|
4882
4807
|
|
|
4883
|
-
// src/ui/CarouselOverlay.tsx
|
|
4884
|
-
var import_lucide_react4 = require("lucide-react");
|
|
4885
|
-
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
4886
|
-
var OVERLAY_BUTTON_STYLE2 = {
|
|
4887
|
-
pointerEvents: "auto",
|
|
4888
|
-
fontFamily: "Inter, sans-serif",
|
|
4889
|
-
fontSize: 12,
|
|
4890
|
-
color: "#000"
|
|
4891
|
-
};
|
|
4892
|
-
function CarouselOverlay({
|
|
4893
|
-
hover,
|
|
4894
|
-
onEdit
|
|
4895
|
-
}) {
|
|
4896
|
-
const { rect } = hover;
|
|
4897
|
-
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
4898
|
-
"div",
|
|
4899
|
-
{
|
|
4900
|
-
"data-ohw-bridge": "",
|
|
4901
|
-
"data-ohw-carousel-overlay": "",
|
|
4902
|
-
className: "flex cursor-pointer items-center justify-center",
|
|
4903
|
-
style: {
|
|
4904
|
-
position: "fixed",
|
|
4905
|
-
top: rect.top,
|
|
4906
|
-
left: rect.left,
|
|
4907
|
-
width: rect.width,
|
|
4908
|
-
height: rect.height,
|
|
4909
|
-
zIndex: 2147483646,
|
|
4910
|
-
pointerEvents: "auto",
|
|
4911
|
-
boxShadow: "inset 0 0 0 1.5px var(--color-primary)",
|
|
4912
|
-
background: "color-mix(in srgb, var(--color-primary) 20%, transparent)"
|
|
4913
|
-
},
|
|
4914
|
-
onClick: () => onEdit(hover.key),
|
|
4915
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
4916
|
-
Button,
|
|
4917
|
-
{
|
|
4918
|
-
"data-ohw-carousel-overlay": "",
|
|
4919
|
-
variant: "outline",
|
|
4920
|
-
size: "sm",
|
|
4921
|
-
className: "cursor-pointer gap-1.5 hover:bg-background",
|
|
4922
|
-
style: OVERLAY_BUTTON_STYLE2,
|
|
4923
|
-
onMouseDown: (e) => e.preventDefault(),
|
|
4924
|
-
onClick: (e) => {
|
|
4925
|
-
e.stopPropagation();
|
|
4926
|
-
onEdit(hover.key);
|
|
4927
|
-
},
|
|
4928
|
-
children: [
|
|
4929
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react4.GalleryHorizontal, { size: 14 }),
|
|
4930
|
-
"Edit gallery"
|
|
4931
|
-
]
|
|
4932
|
-
}
|
|
4933
|
-
)
|
|
4934
|
-
}
|
|
4935
|
-
);
|
|
4936
|
-
}
|
|
4937
|
-
|
|
4938
4808
|
// src/OhhwellsBridge.tsx
|
|
4939
|
-
var
|
|
4940
|
-
var
|
|
4809
|
+
var import_react_dom2 = require("react-dom");
|
|
4810
|
+
var import_navigation = require("next/navigation");
|
|
4941
4811
|
|
|
4942
4812
|
// src/lib/session-search.ts
|
|
4943
4813
|
var STORAGE_KEY = "ohw-preserved-search";
|
|
@@ -4967,7 +4837,6 @@ function parseSectionsFromRoot(root) {
|
|
|
4967
4837
|
for (const el of root.querySelectorAll("[data-ohw-section]")) {
|
|
4968
4838
|
const id = el.getAttribute("data-ohw-section") ?? "";
|
|
4969
4839
|
if (!id || seen.has(id)) continue;
|
|
4970
|
-
if (el.parentElement?.closest("[data-ohw-section]")) continue;
|
|
4971
4840
|
seen.add(id);
|
|
4972
4841
|
const label = el.getAttribute("data-ohw-section-label") ?? titleCaseSectionId(id);
|
|
4973
4842
|
sections.push({ id, label });
|
|
@@ -5214,22 +5083,54 @@ function scrollToHashSectionWhenReady(behavior = "smooth") {
|
|
|
5214
5083
|
tick();
|
|
5215
5084
|
}
|
|
5216
5085
|
|
|
5217
|
-
// src/ui/link-modal/LinkPopover.tsx
|
|
5218
|
-
var import_react7 = require("react");
|
|
5219
|
-
|
|
5220
5086
|
// src/ui/dialog.tsx
|
|
5221
5087
|
var React7 = __toESM(require("react"), 1);
|
|
5222
5088
|
var import_radix_ui5 = require("radix-ui");
|
|
5223
|
-
|
|
5089
|
+
|
|
5090
|
+
// src/ui/icons.tsx
|
|
5091
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
5092
|
+
function IconX({ className, ...props }) {
|
|
5093
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
5094
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M18 6 6 18" }),
|
|
5095
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "m6 6 12 12" })
|
|
5096
|
+
] });
|
|
5097
|
+
}
|
|
5098
|
+
function IconChevronDown({ className, ...props }) {
|
|
5099
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "m6 9 6 6 6-6" }) });
|
|
5100
|
+
}
|
|
5101
|
+
function IconFile({ className, ...props }) {
|
|
5102
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
5103
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z" }),
|
|
5104
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M14 2v4a2 2 0 0 0 2 2h4" })
|
|
5105
|
+
] });
|
|
5106
|
+
}
|
|
5107
|
+
function IconInfo({ className, ...props }) {
|
|
5108
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
5109
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("circle", { cx: "12", cy: "12", r: "10" }),
|
|
5110
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M12 16v-4" }),
|
|
5111
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M12 8h.01" })
|
|
5112
|
+
] });
|
|
5113
|
+
}
|
|
5114
|
+
function IconArrowRight({ className, ...props }) {
|
|
5115
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
5116
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M5 12h14" }),
|
|
5117
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "m12 5 7 7-7 7" })
|
|
5118
|
+
] });
|
|
5119
|
+
}
|
|
5120
|
+
function IconSection({ className, ...props }) {
|
|
5121
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
5122
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("rect", { width: "18", height: "7", x: "3", y: "3", rx: "1" }),
|
|
5123
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("rect", { width: "9", height: "7", x: "3", y: "14", rx: "1" }),
|
|
5124
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("rect", { width: "5", height: "7", x: "16", y: "14", rx: "1" })
|
|
5125
|
+
] });
|
|
5126
|
+
}
|
|
5127
|
+
|
|
5128
|
+
// src/ui/dialog.tsx
|
|
5224
5129
|
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
5225
|
-
function Dialog2({
|
|
5226
|
-
...props
|
|
5227
|
-
}) {
|
|
5130
|
+
function Dialog2({ ...props }) {
|
|
5228
5131
|
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_radix_ui5.Dialog.Root, { "data-slot": "dialog", ...props });
|
|
5229
5132
|
}
|
|
5230
|
-
function DialogPortal({
|
|
5231
|
-
...props
|
|
5232
|
-
}) {
|
|
5133
|
+
function DialogPortal({ ...props }) {
|
|
5233
5134
|
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_radix_ui5.Dialog.Portal, { ...props });
|
|
5234
5135
|
}
|
|
5235
5136
|
function DialogOverlay({
|
|
@@ -5246,69 +5147,52 @@ function DialogOverlay({
|
|
|
5246
5147
|
}
|
|
5247
5148
|
);
|
|
5248
5149
|
}
|
|
5249
|
-
var DialogContent = React7.forwardRef(
|
|
5250
|
-
|
|
5251
|
-
|
|
5252
|
-
|
|
5253
|
-
|
|
5254
|
-
|
|
5255
|
-
|
|
5256
|
-
|
|
5257
|
-
|
|
5258
|
-
|
|
5259
|
-
|
|
5260
|
-
|
|
5261
|
-
|
|
5262
|
-
|
|
5263
|
-
|
|
5264
|
-
|
|
5265
|
-
|
|
5266
|
-
|
|
5267
|
-
|
|
5268
|
-
children
|
|
5269
|
-
|
|
5270
|
-
|
|
5271
|
-
|
|
5272
|
-
|
|
5273
|
-
|
|
5274
|
-
|
|
5275
|
-
|
|
5276
|
-
|
|
5277
|
-
|
|
5278
|
-
|
|
5279
|
-
|
|
5280
|
-
|
|
5281
|
-
|
|
5282
|
-
|
|
5283
|
-
}
|
|
5284
|
-
);
|
|
5150
|
+
var DialogContent = React7.forwardRef(({ className, children, showCloseButton = true, container, ...props }, ref) => {
|
|
5151
|
+
const positionMode = container ? "absolute" : "fixed";
|
|
5152
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(DialogPortal, { container: container ?? void 0, children: [
|
|
5153
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(DialogOverlay, { className: cn(positionMode, "inset-0") }),
|
|
5154
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
5155
|
+
import_radix_ui5.Dialog.Content,
|
|
5156
|
+
{
|
|
5157
|
+
ref,
|
|
5158
|
+
"data-slot": "dialog-content",
|
|
5159
|
+
className: cn(
|
|
5160
|
+
positionMode,
|
|
5161
|
+
"left-1/2 top-1/2 z-[2147483647] flex w-full max-w-[483px] -translate-x-1/2 -translate-y-1/2 flex-col overflow-hidden",
|
|
5162
|
+
"rounded-xl border border-border bg-background font-sans shadow-lg outline-none",
|
|
5163
|
+
container ? "max-h-[calc(100%-32px)] max-w-[calc(100%-16px)]" : "max-h-[calc(100vh-32px)] max-w-[calc(100vw-16px)]",
|
|
5164
|
+
className
|
|
5165
|
+
),
|
|
5166
|
+
onMouseDown: (e) => e.stopPropagation(),
|
|
5167
|
+
...props,
|
|
5168
|
+
children: [
|
|
5169
|
+
children,
|
|
5170
|
+
showCloseButton ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
5171
|
+
import_radix_ui5.Dialog.Close,
|
|
5172
|
+
{
|
|
5173
|
+
type: "button",
|
|
5174
|
+
className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50",
|
|
5175
|
+
"aria-label": "Close",
|
|
5176
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(IconX, { "aria-hidden": true })
|
|
5177
|
+
}
|
|
5178
|
+
) : null
|
|
5179
|
+
]
|
|
5180
|
+
}
|
|
5181
|
+
)
|
|
5182
|
+
] });
|
|
5183
|
+
});
|
|
5285
5184
|
DialogContent.displayName = import_radix_ui5.Dialog.Content.displayName;
|
|
5286
|
-
function DialogHeader({
|
|
5287
|
-
className,
|
|
5288
|
-
...props
|
|
5289
|
-
}) {
|
|
5185
|
+
function DialogHeader({ className, ...props }) {
|
|
5290
5186
|
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: cn("flex flex-col gap-1.5", className), ...props });
|
|
5291
5187
|
}
|
|
5292
|
-
function DialogFooter({
|
|
5293
|
-
className,
|
|
5294
|
-
...props
|
|
5295
|
-
}) {
|
|
5296
|
-
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
5297
|
-
"div",
|
|
5298
|
-
{
|
|
5299
|
-
className: cn("flex items-center justify-end gap-2", className),
|
|
5300
|
-
...props
|
|
5301
|
-
}
|
|
5302
|
-
);
|
|
5188
|
+
function DialogFooter({ className, ...props }) {
|
|
5189
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: cn("flex items-center justify-end gap-2", className), ...props });
|
|
5303
5190
|
}
|
|
5304
5191
|
var DialogTitle = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
5305
5192
|
import_radix_ui5.Dialog.Title,
|
|
5306
5193
|
{
|
|
5307
5194
|
ref,
|
|
5308
|
-
className: cn(
|
|
5309
|
-
"text-lg font-semibold leading-none tracking-tight text-card-foreground",
|
|
5310
|
-
className
|
|
5311
|
-
),
|
|
5195
|
+
className: cn("text-lg font-semibold leading-none tracking-tight text-card-foreground", className),
|
|
5312
5196
|
...props
|
|
5313
5197
|
}
|
|
5314
5198
|
));
|
|
@@ -5324,40 +5208,19 @@ var DialogDescription = React7.forwardRef(({ className, ...props }, ref) => /* @
|
|
|
5324
5208
|
DialogDescription.displayName = import_radix_ui5.Dialog.Description.displayName;
|
|
5325
5209
|
var DialogClose = import_radix_ui5.Dialog.Close;
|
|
5326
5210
|
|
|
5327
|
-
// src/ui/link-modal/LinkEditorPanel.tsx
|
|
5328
|
-
var import_lucide_react9 = require("lucide-react");
|
|
5329
|
-
|
|
5330
5211
|
// src/ui/link-modal/DestinationBreadcrumb.tsx
|
|
5331
|
-
var import_lucide_react6 = require("lucide-react");
|
|
5332
5212
|
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
5333
|
-
function DestinationBreadcrumb({
|
|
5334
|
-
pageTitle,
|
|
5335
|
-
sectionLabel
|
|
5336
|
-
}) {
|
|
5213
|
+
function DestinationBreadcrumb({ pageTitle, sectionLabel }) {
|
|
5337
5214
|
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex w-full flex-col gap-2", children: [
|
|
5338
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "text-sm font-medium
|
|
5215
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "text-sm font-medium text-foreground", children: "Destination" }),
|
|
5339
5216
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center gap-3", children: [
|
|
5340
5217
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
5341
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
5342
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "text-sm font-medium leading-none text-foreground
|
|
5218
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(IconFile, { className: "shrink-0 text-foreground", "aria-hidden": true }),
|
|
5219
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "text-sm font-medium leading-none text-foreground", children: pageTitle })
|
|
5343
5220
|
] }),
|
|
5344
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
5345
|
-
import_lucide_react6.ArrowRight,
|
|
5346
|
-
{
|
|
5347
|
-
size: 16,
|
|
5348
|
-
className: "shrink-0 text-muted-foreground",
|
|
5349
|
-
"aria-hidden": true
|
|
5350
|
-
}
|
|
5351
|
-
),
|
|
5221
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(IconArrowRight, { className: "shrink-0 text-muted-foreground", "aria-hidden": true }),
|
|
5352
5222
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
|
|
5353
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
5354
|
-
import_lucide_react6.GalleryVertical,
|
|
5355
|
-
{
|
|
5356
|
-
size: 16,
|
|
5357
|
-
className: "shrink-0 text-foreground",
|
|
5358
|
-
"aria-hidden": true
|
|
5359
|
-
}
|
|
5360
|
-
),
|
|
5223
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(IconSection, { className: "shrink-0 text-foreground", "aria-hidden": true }),
|
|
5361
5224
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "truncate text-sm font-medium leading-none text-foreground", children: sectionLabel })
|
|
5362
5225
|
] })
|
|
5363
5226
|
] })
|
|
@@ -5365,13 +5228,8 @@ function DestinationBreadcrumb({
|
|
|
5365
5228
|
}
|
|
5366
5229
|
|
|
5367
5230
|
// src/ui/link-modal/SectionTreeItem.tsx
|
|
5368
|
-
var import_lucide_react7 = require("lucide-react");
|
|
5369
5231
|
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
5370
|
-
function SectionTreeItem({
|
|
5371
|
-
section,
|
|
5372
|
-
onSelect,
|
|
5373
|
-
selected
|
|
5374
|
-
}) {
|
|
5232
|
+
function SectionTreeItem({ section, onSelect, selected }) {
|
|
5375
5233
|
const interactive = Boolean(onSelect);
|
|
5376
5234
|
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex h-9 w-full items-end pl-3", children: [
|
|
5377
5235
|
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
@@ -5399,20 +5257,22 @@ function SectionTreeItem({
|
|
|
5399
5257
|
interactive && selected && "border-primary"
|
|
5400
5258
|
),
|
|
5401
5259
|
children: [
|
|
5402
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
5403
|
-
import_lucide_react7.GalleryVertical,
|
|
5404
|
-
{
|
|
5405
|
-
size: 16,
|
|
5406
|
-
className: "shrink-0 text-foreground",
|
|
5407
|
-
"aria-hidden": true
|
|
5408
|
-
}
|
|
5409
|
-
),
|
|
5260
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(IconSection, { className: "shrink-0 text-foreground", "aria-hidden": true }),
|
|
5410
5261
|
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "truncate text-sm font-normal leading-5 text-foreground", children: section.label })
|
|
5411
5262
|
]
|
|
5412
5263
|
}
|
|
5413
5264
|
)
|
|
5414
5265
|
] });
|
|
5415
5266
|
}
|
|
5267
|
+
function SectionPickerList({ sections, onSelect }) {
|
|
5268
|
+
if (sections.length === 0) {
|
|
5269
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "text-sm text-muted-foreground", children: "No sections found on this page." });
|
|
5270
|
+
}
|
|
5271
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
5272
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "text-sm text-muted-foreground", children: "Pick a section this link should scroll to." }),
|
|
5273
|
+
sections.map((section) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(SectionTreeItem, { section, onSelect }, section.id))
|
|
5274
|
+
] });
|
|
5275
|
+
}
|
|
5416
5276
|
|
|
5417
5277
|
// src/ui/link-modal/UrlOrPageInput.tsx
|
|
5418
5278
|
var import_react4 = require("react");
|
|
@@ -5454,11 +5314,8 @@ function Label({ className, ...props }) {
|
|
|
5454
5314
|
}
|
|
5455
5315
|
|
|
5456
5316
|
// src/ui/link-modal/UrlOrPageInput.tsx
|
|
5457
|
-
var import_lucide_react8 = require("lucide-react");
|
|
5458
5317
|
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
5459
|
-
function FieldChevron({
|
|
5460
|
-
onClick
|
|
5461
|
-
}) {
|
|
5318
|
+
function FieldChevron({ onClick }) {
|
|
5462
5319
|
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5463
5320
|
"button",
|
|
5464
5321
|
{
|
|
@@ -5467,7 +5324,7 @@ function FieldChevron({
|
|
|
5467
5324
|
onClick,
|
|
5468
5325
|
"aria-label": "Open page list",
|
|
5469
5326
|
tabIndex: -1,
|
|
5470
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5327
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(IconChevronDown, {})
|
|
5471
5328
|
}
|
|
5472
5329
|
);
|
|
5473
5330
|
}
|
|
@@ -5485,29 +5342,7 @@ function UrlOrPageInput({
|
|
|
5485
5342
|
}) {
|
|
5486
5343
|
const inputId = (0, import_react4.useId)();
|
|
5487
5344
|
const inputRef = (0, import_react4.useRef)(null);
|
|
5488
|
-
const rootRef = (0, import_react4.useRef)(null);
|
|
5489
5345
|
const [isFocused, setIsFocused] = (0, import_react4.useState)(false);
|
|
5490
|
-
(0, import_react4.useEffect)(() => {
|
|
5491
|
-
if (!dropdownOpen) return;
|
|
5492
|
-
const isOutside = (e) => {
|
|
5493
|
-
const root = rootRef.current;
|
|
5494
|
-
if (!root) return true;
|
|
5495
|
-
const path = typeof e.composedPath === "function" ? e.composedPath() : [];
|
|
5496
|
-
if (path.includes(root)) return false;
|
|
5497
|
-
const target = e.target;
|
|
5498
|
-
return !(target instanceof Node && root.contains(target));
|
|
5499
|
-
};
|
|
5500
|
-
const closeIfOutside = (e) => {
|
|
5501
|
-
if (!isOutside(e)) return;
|
|
5502
|
-
onDropdownOpenChange(false);
|
|
5503
|
-
};
|
|
5504
|
-
document.addEventListener("pointerdown", closeIfOutside, true);
|
|
5505
|
-
document.addEventListener("mousedown", closeIfOutside, true);
|
|
5506
|
-
return () => {
|
|
5507
|
-
document.removeEventListener("pointerdown", closeIfOutside, true);
|
|
5508
|
-
document.removeEventListener("mousedown", closeIfOutside, true);
|
|
5509
|
-
};
|
|
5510
|
-
}, [dropdownOpen, onDropdownOpenChange]);
|
|
5511
5346
|
const openDropdown = () => {
|
|
5512
5347
|
if (readOnly || filteredPages.length === 0) return;
|
|
5513
5348
|
onDropdownOpenChange(true);
|
|
@@ -5525,21 +5360,14 @@ function UrlOrPageInput({
|
|
|
5525
5360
|
requestAnimationFrame(() => inputRef.current?.focus());
|
|
5526
5361
|
};
|
|
5527
5362
|
const fieldClassName = cn(
|
|
5528
|
-
"data-ohw-link-field flex h-
|
|
5363
|
+
"data-ohw-link-field flex h-10 w-full items-center overflow-hidden rounded-md border bg-background pl-3 pr-3 py-2 outline-none transition-[border-color,box-shadow]",
|
|
5529
5364
|
urlError ? "border-destructive shadow-[0_0_0_1px_var(--ohw-destructive)]" : isFocused ? "border-primary shadow-[0_0_0_1px_var(--ohw-primary)]" : "border-input"
|
|
5530
5365
|
);
|
|
5531
5366
|
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex w-full flex-col gap-2 p-0", children: [
|
|
5532
5367
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Label, { htmlFor: inputId, className: cn(urlError && "text-destructive"), children: "Destination" }),
|
|
5533
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", {
|
|
5368
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "relative w-full", children: [
|
|
5534
5369
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { "data-ohw-link-field": true, className: fieldClassName, children: [
|
|
5535
|
-
selectedPage ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "flex shrink-0 items-center pr-2", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5536
|
-
import_lucide_react8.File,
|
|
5537
|
-
{
|
|
5538
|
-
size: 16,
|
|
5539
|
-
className: "shrink-0 text-foreground",
|
|
5540
|
-
"aria-hidden": true
|
|
5541
|
-
}
|
|
5542
|
-
) }) : null,
|
|
5370
|
+
selectedPage ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "flex shrink-0 items-center pr-2", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(IconFile, { className: "text-foreground", "aria-hidden": true }) }) : null,
|
|
5543
5371
|
readOnly ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "min-w-0 flex-1 truncate text-sm leading-5 text-foreground", children: selectedPage?.title ?? value }) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5544
5372
|
Input,
|
|
5545
5373
|
{
|
|
@@ -5551,14 +5379,7 @@ function UrlOrPageInput({
|
|
|
5551
5379
|
setIsFocused(true);
|
|
5552
5380
|
if (!selectedPage) openDropdown();
|
|
5553
5381
|
},
|
|
5554
|
-
onBlur: () =>
|
|
5555
|
-
setIsFocused(false);
|
|
5556
|
-
requestAnimationFrame(() => {
|
|
5557
|
-
if (!rootRef.current?.contains(document.activeElement)) {
|
|
5558
|
-
onDropdownOpenChange(false);
|
|
5559
|
-
}
|
|
5560
|
-
});
|
|
5561
|
-
},
|
|
5382
|
+
onBlur: () => setIsFocused(false),
|
|
5562
5383
|
placeholder,
|
|
5563
5384
|
className: cn(
|
|
5564
5385
|
"min-w-0 flex-1 truncate border-0 bg-transparent p-0 text-sm font-normal leading-5 shadow-none outline-none ring-0 caret-foreground",
|
|
@@ -5574,7 +5395,7 @@ function UrlOrPageInput({
|
|
|
5574
5395
|
onMouseDown: clearSelection,
|
|
5575
5396
|
"aria-label": "Clear selected page",
|
|
5576
5397
|
tabIndex: -1,
|
|
5577
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5398
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(IconX, { "aria-hidden": true })
|
|
5578
5399
|
}
|
|
5579
5400
|
) : null,
|
|
5580
5401
|
!readOnly ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(FieldChevron, { onClick: toggleDropdown }) : null
|
|
@@ -5583,7 +5404,7 @@ function UrlOrPageInput({
|
|
|
5583
5404
|
"div",
|
|
5584
5405
|
{
|
|
5585
5406
|
"data-ohw-link-page-dropdown": "",
|
|
5586
|
-
className: "absolute left-0 right-0 top-[calc(100%+4px)] z-
|
|
5407
|
+
className: "absolute left-0 right-0 h-20 top-[calc(100%+4px)] z-10 max-h-48 overflow-auto rounded-lg border border-border bg-popover py-1 shadow-lg",
|
|
5587
5408
|
onMouseDown: (e) => e.preventDefault(),
|
|
5588
5409
|
children: filteredPages.map((page) => /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
5589
5410
|
"button",
|
|
@@ -5592,7 +5413,7 @@ function UrlOrPageInput({
|
|
|
5592
5413
|
className: "flex h-9 w-full items-center gap-2 border-0 bg-transparent px-3 text-left text-sm leading-5 text-foreground outline-none hover:bg-muted",
|
|
5593
5414
|
onClick: () => onPageSelect(page),
|
|
5594
5415
|
children: [
|
|
5595
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5416
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(IconFile, { className: "shrink-0", "aria-hidden": true }),
|
|
5596
5417
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "truncate", children: page.title })
|
|
5597
5418
|
]
|
|
5598
5419
|
},
|
|
@@ -5605,439 +5426,8 @@ function UrlOrPageInput({
|
|
|
5605
5426
|
] });
|
|
5606
5427
|
}
|
|
5607
5428
|
|
|
5608
|
-
// src/ui/link-modal/
|
|
5609
|
-
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
5610
|
-
function LinkEditorPanel({ state, onClose }) {
|
|
5611
|
-
const isCancel = state.secondaryLabel === "Cancel" || state.secondaryLabel === "Back to sections";
|
|
5612
|
-
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
|
|
5613
|
-
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(DialogClose, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5614
|
-
"button",
|
|
5615
|
-
{
|
|
5616
|
-
type: "button",
|
|
5617
|
-
className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50 h-7",
|
|
5618
|
-
"aria-label": "Close",
|
|
5619
|
-
onClick: onClose,
|
|
5620
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react9.X, { size: 16, "aria-hidden": true })
|
|
5621
|
-
}
|
|
5622
|
-
) }),
|
|
5623
|
-
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(DialogHeader, { className: "w-full gap-1.5 p-6 pr-12", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(DialogTitle, { className: "m-0 w-full break-words", children: state.title }) }),
|
|
5624
|
-
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex w-full flex-col gap-3 px-6 pb-8 pt-1", children: [
|
|
5625
|
-
state.showBreadcrumb && state.selectedPage && state.selectedSection ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5626
|
-
DestinationBreadcrumb,
|
|
5627
|
-
{
|
|
5628
|
-
pageTitle: state.selectedPage.title,
|
|
5629
|
-
sectionLabel: state.selectedSection.label
|
|
5630
|
-
}
|
|
5631
|
-
) : /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5632
|
-
UrlOrPageInput,
|
|
5633
|
-
{
|
|
5634
|
-
value: state.searchValue,
|
|
5635
|
-
selectedPage: state.selectedPage,
|
|
5636
|
-
dropdownOpen: state.dropdownOpen,
|
|
5637
|
-
onDropdownOpenChange: state.setDropdownOpen,
|
|
5638
|
-
filteredPages: state.filteredPages,
|
|
5639
|
-
onInputChange: state.handleInputChange,
|
|
5640
|
-
onPageSelect: state.handlePageSelect,
|
|
5641
|
-
urlError: state.urlError
|
|
5642
|
-
}
|
|
5643
|
-
),
|
|
5644
|
-
state.showChooseSection ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex flex-col justify-center gap-2", children: [
|
|
5645
|
-
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5646
|
-
Button,
|
|
5647
|
-
{
|
|
5648
|
-
type: "button",
|
|
5649
|
-
variant: "outline",
|
|
5650
|
-
className: "w-fit cursor-pointer",
|
|
5651
|
-
size: "sm",
|
|
5652
|
-
onClick: state.handleChooseSection,
|
|
5653
|
-
children: "Choose a section"
|
|
5654
|
-
}
|
|
5655
|
-
),
|
|
5656
|
-
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex items-center gap-1 text-sm text-muted-foreground", children: [
|
|
5657
|
-
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react9.Info, { size: 16, className: "shrink-0", "aria-hidden": true }),
|
|
5658
|
-
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { children: "Pick a section this link should scroll to." })
|
|
5659
|
-
] })
|
|
5660
|
-
] }) : null,
|
|
5661
|
-
state.showSectionRow && state.selectedSection ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(SectionTreeItem, { section: state.selectedSection, selected: true }) : null
|
|
5662
|
-
] }),
|
|
5663
|
-
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(DialogFooter, { className: "w-full px-6 pb-6", children: [
|
|
5664
|
-
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5665
|
-
Button,
|
|
5666
|
-
{
|
|
5667
|
-
type: "button",
|
|
5668
|
-
variant: isCancel ? "outline" : "ghost",
|
|
5669
|
-
className: "leading-6 shadow-none cursor-pointer",
|
|
5670
|
-
style: isCancel ? {
|
|
5671
|
-
backgroundColor: "var(--ohw-background)",
|
|
5672
|
-
borderColor: "var(--ohw-border)",
|
|
5673
|
-
color: "var(--ohw-foreground)"
|
|
5674
|
-
} : void 0,
|
|
5675
|
-
onClick: state.handleSecondary,
|
|
5676
|
-
children: state.secondaryLabel
|
|
5677
|
-
}
|
|
5678
|
-
),
|
|
5679
|
-
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5680
|
-
Button,
|
|
5681
|
-
{
|
|
5682
|
-
type: "button",
|
|
5683
|
-
className: "border-0 leading-6 shadow-none hover:opacity-90 disabled:opacity-50 cursor-pointer",
|
|
5684
|
-
style: {
|
|
5685
|
-
backgroundColor: "var(--ohw-primary)",
|
|
5686
|
-
color: "var(--ohw-primary-foreground)"
|
|
5687
|
-
},
|
|
5688
|
-
disabled: !state.isValid,
|
|
5689
|
-
onClick: state.handleSubmit,
|
|
5690
|
-
children: state.submitLabel
|
|
5691
|
-
}
|
|
5692
|
-
)
|
|
5693
|
-
] })
|
|
5694
|
-
] });
|
|
5695
|
-
}
|
|
5696
|
-
|
|
5697
|
-
// src/ui/link-modal/SectionPickerOverlay.tsx
|
|
5429
|
+
// src/ui/link-modal/useLinkModalState.ts
|
|
5698
5430
|
var import_react5 = require("react");
|
|
5699
|
-
var import_react_dom = require("react-dom");
|
|
5700
|
-
var import_lucide_react10 = require("lucide-react");
|
|
5701
|
-
var import_navigation = require("next/navigation");
|
|
5702
|
-
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
5703
|
-
var DIM_OVERLAY = "rgba(0, 0, 0, 0.45)";
|
|
5704
|
-
function rectsEqual(a, b) {
|
|
5705
|
-
if (a.size !== b.size) return false;
|
|
5706
|
-
for (const [id, rect] of a) {
|
|
5707
|
-
const other = b.get(id);
|
|
5708
|
-
if (!other || rect.top !== other.top || rect.left !== other.left || rect.width !== other.width || rect.height !== other.height) {
|
|
5709
|
-
return false;
|
|
5710
|
-
}
|
|
5711
|
-
}
|
|
5712
|
-
return true;
|
|
5713
|
-
}
|
|
5714
|
-
function readSectionRects(sectionIds) {
|
|
5715
|
-
const next = /* @__PURE__ */ new Map();
|
|
5716
|
-
for (const id of sectionIds) {
|
|
5717
|
-
const el = document.querySelector(
|
|
5718
|
-
`[data-ohw-section="${CSS.escape(id)}"]`
|
|
5719
|
-
);
|
|
5720
|
-
if (el) next.set(id, el.getBoundingClientRect());
|
|
5721
|
-
}
|
|
5722
|
-
return next;
|
|
5723
|
-
}
|
|
5724
|
-
function hitTestSectionId(x, y, sectionIds, rects) {
|
|
5725
|
-
for (const id of sectionIds) {
|
|
5726
|
-
const rect = rects.get(id);
|
|
5727
|
-
if (!rect || rect.width <= 0 || rect.height <= 0) continue;
|
|
5728
|
-
if (x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom) {
|
|
5729
|
-
return id;
|
|
5730
|
-
}
|
|
5731
|
-
}
|
|
5732
|
-
return null;
|
|
5733
|
-
}
|
|
5734
|
-
function useSectionRects(sectionIdsKey, enabled) {
|
|
5735
|
-
const [rects, setRects] = (0, import_react5.useState)(/* @__PURE__ */ new Map());
|
|
5736
|
-
const sectionIds = (0, import_react5.useMemo)(
|
|
5737
|
-
() => sectionIdsKey ? sectionIdsKey.split("\0") : [],
|
|
5738
|
-
[sectionIdsKey]
|
|
5739
|
-
);
|
|
5740
|
-
(0, import_react5.useEffect)(() => {
|
|
5741
|
-
if (!enabled || sectionIds.length === 0) {
|
|
5742
|
-
setRects((prev) => prev.size === 0 ? prev : /* @__PURE__ */ new Map());
|
|
5743
|
-
return;
|
|
5744
|
-
}
|
|
5745
|
-
const update = () => {
|
|
5746
|
-
const next = readSectionRects(sectionIds);
|
|
5747
|
-
setRects((prev) => rectsEqual(prev, next) ? prev : next);
|
|
5748
|
-
};
|
|
5749
|
-
update();
|
|
5750
|
-
const opts = { capture: true, passive: true };
|
|
5751
|
-
window.addEventListener("scroll", update, opts);
|
|
5752
|
-
window.addEventListener("resize", update);
|
|
5753
|
-
const vv = window.visualViewport;
|
|
5754
|
-
vv?.addEventListener("resize", update);
|
|
5755
|
-
vv?.addEventListener("scroll", update);
|
|
5756
|
-
const ro = new ResizeObserver(update);
|
|
5757
|
-
for (const id of sectionIds) {
|
|
5758
|
-
const el = document.querySelector(
|
|
5759
|
-
`[data-ohw-section="${CSS.escape(id)}"]`
|
|
5760
|
-
);
|
|
5761
|
-
if (el) ro.observe(el);
|
|
5762
|
-
}
|
|
5763
|
-
return () => {
|
|
5764
|
-
window.removeEventListener("scroll", update, opts);
|
|
5765
|
-
window.removeEventListener("resize", update);
|
|
5766
|
-
vv?.removeEventListener("resize", update);
|
|
5767
|
-
vv?.removeEventListener("scroll", update);
|
|
5768
|
-
ro.disconnect();
|
|
5769
|
-
};
|
|
5770
|
-
}, [sectionIds, enabled]);
|
|
5771
|
-
return rects;
|
|
5772
|
-
}
|
|
5773
|
-
function SectionPickerOverlay({
|
|
5774
|
-
pagePath,
|
|
5775
|
-
sections,
|
|
5776
|
-
onBack,
|
|
5777
|
-
onSelect
|
|
5778
|
-
}) {
|
|
5779
|
-
const router = (0, import_navigation.useRouter)();
|
|
5780
|
-
const pathname = (0, import_navigation.usePathname)();
|
|
5781
|
-
const [selectedId, setSelectedId] = (0, import_react5.useState)(null);
|
|
5782
|
-
const [hoveredId, setHoveredId] = (0, import_react5.useState)(null);
|
|
5783
|
-
const pointerRef = (0, import_react5.useRef)(null);
|
|
5784
|
-
const pointerScreenRef = (0, import_react5.useRef)(null);
|
|
5785
|
-
const iframeOffsetTopRef = (0, import_react5.useRef)(null);
|
|
5786
|
-
const sectionIdsRef = (0, import_react5.useRef)([]);
|
|
5787
|
-
const [chromeClip, setChromeClip] = (0, import_react5.useState)(
|
|
5788
|
-
() => ({
|
|
5789
|
-
top: 0,
|
|
5790
|
-
bottom: typeof window !== "undefined" ? window.innerHeight : 0
|
|
5791
|
-
})
|
|
5792
|
-
);
|
|
5793
|
-
const normalizedTarget = normalizePath(pagePath);
|
|
5794
|
-
const isOnTargetPage = normalizePath(pathname) === normalizedTarget;
|
|
5795
|
-
(0, import_react5.useEffect)(() => {
|
|
5796
|
-
if (isOnTargetPage) return;
|
|
5797
|
-
const search = readPreservedSearch();
|
|
5798
|
-
router.push(`${normalizedTarget}${search}`);
|
|
5799
|
-
}, [isOnTargetPage, normalizedTarget, router]);
|
|
5800
|
-
(0, import_react5.useEffect)(() => {
|
|
5801
|
-
document.documentElement.setAttribute("data-ohw-section-picking", "");
|
|
5802
|
-
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => {
|
|
5803
|
-
el.removeAttribute("data-ohw-hovered");
|
|
5804
|
-
});
|
|
5805
|
-
document.querySelectorAll("[data-ohw-state-hovered]").forEach((el) => {
|
|
5806
|
-
el.removeAttribute("data-ohw-state-hovered");
|
|
5807
|
-
});
|
|
5808
|
-
return () => {
|
|
5809
|
-
document.documentElement.removeAttribute("data-ohw-section-picking");
|
|
5810
|
-
};
|
|
5811
|
-
}, []);
|
|
5812
|
-
const liveSections = (0, import_react5.useMemo)(() => {
|
|
5813
|
-
if (!isOnTargetPage) return sections;
|
|
5814
|
-
const live = collectSectionsFromDom();
|
|
5815
|
-
if (live.length === 0) return sections;
|
|
5816
|
-
const labels = new Map(sections.map((s) => [s.id, s.label]));
|
|
5817
|
-
return live.map((s) => ({ id: s.id, label: labels.get(s.id) ?? s.label }));
|
|
5818
|
-
}, [isOnTargetPage, sections, pathname]);
|
|
5819
|
-
const sectionIdsKey = (0, import_react5.useMemo)(
|
|
5820
|
-
() => liveSections.map((s) => s.id).join("\0"),
|
|
5821
|
-
[liveSections]
|
|
5822
|
-
);
|
|
5823
|
-
const sectionIds = (0, import_react5.useMemo)(
|
|
5824
|
-
() => liveSections.map((s) => s.id),
|
|
5825
|
-
[liveSections]
|
|
5826
|
-
);
|
|
5827
|
-
sectionIdsRef.current = sectionIds;
|
|
5828
|
-
const rects = useSectionRects(sectionIdsKey, isOnTargetPage);
|
|
5829
|
-
const applyHoverAt = (0, import_react5.useCallback)(
|
|
5830
|
-
(x, y, liveRects) => {
|
|
5831
|
-
const ids = sectionIdsRef.current;
|
|
5832
|
-
const map = liveRects ?? readSectionRects(ids);
|
|
5833
|
-
const next = hitTestSectionId(x, y, ids, map);
|
|
5834
|
-
setHoveredId((prev) => prev === next ? prev : next);
|
|
5835
|
-
},
|
|
5836
|
-
[]
|
|
5837
|
-
);
|
|
5838
|
-
(0, import_react5.useEffect)(() => {
|
|
5839
|
-
const applyClip = (iframeOffsetTop, visibleCanvasTop, canvasH) => {
|
|
5840
|
-
const top = Math.max(0, visibleCanvasTop - iframeOffsetTop);
|
|
5841
|
-
const bottom = Math.min(
|
|
5842
|
-
window.innerHeight,
|
|
5843
|
-
visibleCanvasTop + canvasH - iframeOffsetTop
|
|
5844
|
-
);
|
|
5845
|
-
setChromeClip(
|
|
5846
|
-
(prev) => prev.top === top && prev.bottom === bottom ? prev : { top, bottom: Math.max(top, bottom) }
|
|
5847
|
-
);
|
|
5848
|
-
};
|
|
5849
|
-
const onParentScroll = (e) => {
|
|
5850
|
-
if (e.data?.type !== "ow:parent-scroll") return;
|
|
5851
|
-
const { iframeOffsetTop, headerH, canvasH } = e.data;
|
|
5852
|
-
applyClip(iframeOffsetTop, headerH, canvasH);
|
|
5853
|
-
iframeOffsetTopRef.current = iframeOffsetTop;
|
|
5854
|
-
if (!pointerScreenRef.current && pointerRef.current) {
|
|
5855
|
-
pointerScreenRef.current = {
|
|
5856
|
-
x: pointerRef.current.x,
|
|
5857
|
-
y: pointerRef.current.y + iframeOffsetTop
|
|
5858
|
-
};
|
|
5859
|
-
}
|
|
5860
|
-
const screen = pointerScreenRef.current;
|
|
5861
|
-
if (screen) {
|
|
5862
|
-
const next = { x: screen.x, y: screen.y - iframeOffsetTop };
|
|
5863
|
-
pointerRef.current = next;
|
|
5864
|
-
applyHoverAt(next.x, next.y);
|
|
5865
|
-
}
|
|
5866
|
-
};
|
|
5867
|
-
const onResize = () => {
|
|
5868
|
-
setChromeClip((prev) => {
|
|
5869
|
-
const bottom = Math.max(prev.top, window.innerHeight);
|
|
5870
|
-
return prev.bottom === bottom ? prev : { ...prev, bottom };
|
|
5871
|
-
});
|
|
5872
|
-
};
|
|
5873
|
-
window.addEventListener("message", onParentScroll);
|
|
5874
|
-
window.addEventListener("resize", onResize);
|
|
5875
|
-
return () => {
|
|
5876
|
-
window.removeEventListener("message", onParentScroll);
|
|
5877
|
-
window.removeEventListener("resize", onResize);
|
|
5878
|
-
};
|
|
5879
|
-
}, [applyHoverAt]);
|
|
5880
|
-
(0, import_react5.useEffect)(() => {
|
|
5881
|
-
const ptr = pointerRef.current;
|
|
5882
|
-
if (!ptr) return;
|
|
5883
|
-
applyHoverAt(ptr.x, ptr.y, rects);
|
|
5884
|
-
}, [rects, applyHoverAt]);
|
|
5885
|
-
(0, import_react5.useEffect)(() => {
|
|
5886
|
-
const rememberPointer = (clientX, clientY) => {
|
|
5887
|
-
pointerRef.current = { x: clientX, y: clientY };
|
|
5888
|
-
const top = iframeOffsetTopRef.current;
|
|
5889
|
-
if (top != null) {
|
|
5890
|
-
pointerScreenRef.current = { x: clientX, y: clientY + top };
|
|
5891
|
-
}
|
|
5892
|
-
applyHoverAt(clientX, clientY, rects);
|
|
5893
|
-
};
|
|
5894
|
-
const onPointerMove = (e) => {
|
|
5895
|
-
rememberPointer(e.clientX, e.clientY);
|
|
5896
|
-
};
|
|
5897
|
-
const onPointerSync = (e) => {
|
|
5898
|
-
if (e.data?.type !== "ow:pointer-sync") return;
|
|
5899
|
-
const { clientX, clientY } = e.data;
|
|
5900
|
-
rememberPointer(clientX, clientY);
|
|
5901
|
-
};
|
|
5902
|
-
window.addEventListener("pointermove", onPointerMove, { passive: true });
|
|
5903
|
-
window.addEventListener("message", onPointerSync);
|
|
5904
|
-
return () => {
|
|
5905
|
-
window.removeEventListener("pointermove", onPointerMove);
|
|
5906
|
-
window.removeEventListener("message", onPointerSync);
|
|
5907
|
-
};
|
|
5908
|
-
}, [rects, applyHoverAt]);
|
|
5909
|
-
const handleSelect = (0, import_react5.useCallback)(
|
|
5910
|
-
(section) => {
|
|
5911
|
-
if (selectedId) return;
|
|
5912
|
-
setSelectedId(section.id);
|
|
5913
|
-
onSelect(section);
|
|
5914
|
-
},
|
|
5915
|
-
[selectedId, onSelect]
|
|
5916
|
-
);
|
|
5917
|
-
(0, import_react5.useEffect)(() => {
|
|
5918
|
-
const onKeyDown = (e) => {
|
|
5919
|
-
if (e.key === "Escape") {
|
|
5920
|
-
e.preventDefault();
|
|
5921
|
-
e.stopPropagation();
|
|
5922
|
-
onBack();
|
|
5923
|
-
}
|
|
5924
|
-
};
|
|
5925
|
-
window.addEventListener("keydown", onKeyDown, true);
|
|
5926
|
-
return () => window.removeEventListener("keydown", onKeyDown, true);
|
|
5927
|
-
}, [onBack]);
|
|
5928
|
-
const portalRoot = typeof document !== "undefined" ? document.querySelector("[data-ohw-bridge-root]") ?? document.body : null;
|
|
5929
|
-
if (!portalRoot) return null;
|
|
5930
|
-
return (0, import_react_dom.createPortal)(
|
|
5931
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
5932
|
-
"div",
|
|
5933
|
-
{
|
|
5934
|
-
"data-ohw-section-picker": "",
|
|
5935
|
-
"data-ohw-bridge": "",
|
|
5936
|
-
className: `pointer-events-none fixed inset-0 z-[2147483647] transition-opacity duration-200 ${"opacity-100"}`,
|
|
5937
|
-
"aria-modal": true,
|
|
5938
|
-
role: "dialog",
|
|
5939
|
-
"aria-label": "Choose a section",
|
|
5940
|
-
children: [
|
|
5941
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5942
|
-
"div",
|
|
5943
|
-
{
|
|
5944
|
-
className: "pointer-events-auto fixed left-5 z-[2]",
|
|
5945
|
-
style: { top: chromeClip.top + 20 },
|
|
5946
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
5947
|
-
Button,
|
|
5948
|
-
{
|
|
5949
|
-
type: "button",
|
|
5950
|
-
variant: "outline",
|
|
5951
|
-
size: "sm",
|
|
5952
|
-
className: "h-8 min-w-0 gap-1 border-border bg-background px-2 py-1.5 shadow-sm hover:bg-muted cursor-pointer",
|
|
5953
|
-
onClick: onBack,
|
|
5954
|
-
children: [
|
|
5955
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react10.ArrowLeft, { className: "size-4 shrink-0", "aria-hidden": true }),
|
|
5956
|
-
"Back"
|
|
5957
|
-
]
|
|
5958
|
-
}
|
|
5959
|
-
)
|
|
5960
|
-
}
|
|
5961
|
-
),
|
|
5962
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5963
|
-
"div",
|
|
5964
|
-
{
|
|
5965
|
-
className: "pointer-events-none fixed left-1/2 z-[2] rounded-lg px-4 py-3 text-xs leading-4 tracking-[0.18px] text-white shadow-md",
|
|
5966
|
-
style: {
|
|
5967
|
-
top: chromeClip.bottom - 20,
|
|
5968
|
-
transform: "translate(-50%, -100%)",
|
|
5969
|
-
backgroundColor: "var(--ohw-popover-foreground, #0c0a09)"
|
|
5970
|
-
},
|
|
5971
|
-
"data-ohw-section-picker-hint": "",
|
|
5972
|
-
children: "Click on section to select"
|
|
5973
|
-
}
|
|
5974
|
-
),
|
|
5975
|
-
!isOnTargetPage ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5976
|
-
"div",
|
|
5977
|
-
{
|
|
5978
|
-
className: "pointer-events-none fixed left-1/2 z-[1] -translate-x-1/2 rounded-md bg-background/90 px-3 py-2 text-sm text-muted-foreground shadow-sm",
|
|
5979
|
-
style: { top: chromeClip.top + 64 },
|
|
5980
|
-
children: "Loading page preview\u2026"
|
|
5981
|
-
}
|
|
5982
|
-
) : null,
|
|
5983
|
-
isOnTargetPage && liveSections.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "pointer-events-auto fixed inset-0 z-[1] flex items-center justify-center bg-muted/40", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { className: "text-sm text-muted-foreground", children: "No sections found on this page." }) }) : null,
|
|
5984
|
-
isOnTargetPage ? liveSections.map((section) => {
|
|
5985
|
-
const rect = rects.get(section.id);
|
|
5986
|
-
if (!rect || rect.width <= 0 || rect.height <= 0) return null;
|
|
5987
|
-
const isSelected = selectedId === section.id;
|
|
5988
|
-
const isHovered = hoveredId === section.id;
|
|
5989
|
-
const isLit = isSelected || isHovered;
|
|
5990
|
-
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
5991
|
-
"button",
|
|
5992
|
-
{
|
|
5993
|
-
type: "button",
|
|
5994
|
-
className: "pointer-events-auto fixed z-[1] cursor-pointer border-0 bg-transparent p-0 transition-[background-color] duration-150",
|
|
5995
|
-
style: {
|
|
5996
|
-
top: rect.top,
|
|
5997
|
-
left: rect.left,
|
|
5998
|
-
width: rect.width,
|
|
5999
|
-
height: rect.height,
|
|
6000
|
-
backgroundColor: isLit ? "transparent" : DIM_OVERLAY
|
|
6001
|
-
},
|
|
6002
|
-
"aria-label": `Select section ${section.label}`,
|
|
6003
|
-
onClick: () => handleSelect(section),
|
|
6004
|
-
children: [
|
|
6005
|
-
isLit ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
6006
|
-
"span",
|
|
6007
|
-
{
|
|
6008
|
-
className: "pointer-events-none absolute",
|
|
6009
|
-
style: {
|
|
6010
|
-
inset: 4,
|
|
6011
|
-
borderRadius: "var(--radius, 6px)",
|
|
6012
|
-
border: "1.5px dashed var(--primary, #0885FE)",
|
|
6013
|
-
boxSizing: "border-box"
|
|
6014
|
-
},
|
|
6015
|
-
"aria-hidden": true
|
|
6016
|
-
}
|
|
6017
|
-
) : null,
|
|
6018
|
-
isSelected ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
6019
|
-
"span",
|
|
6020
|
-
{
|
|
6021
|
-
className: "absolute right-3 top-3 flex size-8 items-center justify-center rounded-full text-white",
|
|
6022
|
-
style: { backgroundColor: "var(--ohw-primary, #0885fe)" },
|
|
6023
|
-
"aria-hidden": true,
|
|
6024
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react10.Check, { className: "size-5" })
|
|
6025
|
-
}
|
|
6026
|
-
) : null
|
|
6027
|
-
]
|
|
6028
|
-
},
|
|
6029
|
-
section.id
|
|
6030
|
-
);
|
|
6031
|
-
}) : null
|
|
6032
|
-
]
|
|
6033
|
-
}
|
|
6034
|
-
),
|
|
6035
|
-
portalRoot
|
|
6036
|
-
);
|
|
6037
|
-
}
|
|
6038
|
-
|
|
6039
|
-
// src/ui/link-modal/useLinkModalState.ts
|
|
6040
|
-
var import_react6 = require("react");
|
|
6041
5431
|
function useLinkModalState({
|
|
6042
5432
|
open,
|
|
6043
5433
|
mode,
|
|
@@ -6045,18 +5435,21 @@ function useLinkModalState({
|
|
|
6045
5435
|
sections: _sections,
|
|
6046
5436
|
sectionsByPath,
|
|
6047
5437
|
initialTarget,
|
|
6048
|
-
existingTargets
|
|
5438
|
+
existingTargets,
|
|
6049
5439
|
onClose,
|
|
6050
5440
|
onSubmit
|
|
6051
5441
|
}) {
|
|
6052
|
-
const availablePages = (0,
|
|
6053
|
-
|
|
6054
|
-
|
|
6055
|
-
|
|
6056
|
-
const [
|
|
6057
|
-
const [
|
|
6058
|
-
const [
|
|
6059
|
-
const
|
|
5442
|
+
const availablePages = (0, import_react5.useMemo)(
|
|
5443
|
+
() => mode === "create" ? filterAvailablePages(pages, existingTargets) : pages,
|
|
5444
|
+
[mode, pages, existingTargets]
|
|
5445
|
+
);
|
|
5446
|
+
const [searchValue, setSearchValue] = (0, import_react5.useState)("");
|
|
5447
|
+
const [selectedPage, setSelectedPage] = (0, import_react5.useState)(null);
|
|
5448
|
+
const [selectedSection, setSelectedSection] = (0, import_react5.useState)(null);
|
|
5449
|
+
const [step, setStep] = (0, import_react5.useState)("input");
|
|
5450
|
+
const [dropdownOpen, setDropdownOpen] = (0, import_react5.useState)(false);
|
|
5451
|
+
const [urlError, setUrlError] = (0, import_react5.useState)("");
|
|
5452
|
+
const reset = (0, import_react5.useCallback)(() => {
|
|
6060
5453
|
setSearchValue("");
|
|
6061
5454
|
setSelectedPage(null);
|
|
6062
5455
|
setSelectedSection(null);
|
|
@@ -6064,7 +5457,7 @@ function useLinkModalState({
|
|
|
6064
5457
|
setDropdownOpen(false);
|
|
6065
5458
|
setUrlError("");
|
|
6066
5459
|
}, []);
|
|
6067
|
-
(0,
|
|
5460
|
+
(0, import_react5.useEffect)(() => {
|
|
6068
5461
|
if (!open) return;
|
|
6069
5462
|
if (mode === "edit" && initialTarget) {
|
|
6070
5463
|
const { pageRoute } = parseTarget(initialTarget);
|
|
@@ -6079,12 +5472,12 @@ function useLinkModalState({
|
|
|
6079
5472
|
}
|
|
6080
5473
|
setDropdownOpen(false);
|
|
6081
5474
|
setUrlError("");
|
|
6082
|
-
}, [open, mode, initialTarget, reset]);
|
|
6083
|
-
const filteredPages = (0,
|
|
5475
|
+
}, [open, mode, initialTarget, pages, sectionsByPath, reset]);
|
|
5476
|
+
const filteredPages = (0, import_react5.useMemo)(() => {
|
|
6084
5477
|
if (!searchValue.trim()) return availablePages;
|
|
6085
5478
|
return availablePages.filter((p) => p.title.toLowerCase().startsWith(searchValue.toLowerCase()));
|
|
6086
5479
|
}, [availablePages, searchValue]);
|
|
6087
|
-
const activeSections = (0,
|
|
5480
|
+
const activeSections = (0, import_react5.useMemo)(() => {
|
|
6088
5481
|
if (!selectedPage) return [];
|
|
6089
5482
|
return getSectionsForPath(sectionsByPath, selectedPage.path);
|
|
6090
5483
|
}, [selectedPage, sectionsByPath]);
|
|
@@ -6126,14 +5519,11 @@ function useLinkModalState({
|
|
|
6126
5519
|
const handleBackToSections = () => {
|
|
6127
5520
|
setStep("sectionPicker");
|
|
6128
5521
|
};
|
|
6129
|
-
const handleSectionPickerBack = () => {
|
|
6130
|
-
setStep("input");
|
|
6131
|
-
};
|
|
6132
5522
|
const handleClose = () => {
|
|
6133
5523
|
reset();
|
|
6134
5524
|
onClose();
|
|
6135
5525
|
};
|
|
6136
|
-
const isValid = (0,
|
|
5526
|
+
const isValid = (0, import_react5.useMemo)(() => {
|
|
6137
5527
|
if (urlError) return false;
|
|
6138
5528
|
if (showBreadcrumb) return true;
|
|
6139
5529
|
if (selectedPage) return true;
|
|
@@ -6166,7 +5556,7 @@ function useLinkModalState({
|
|
|
6166
5556
|
onSubmit(normalizeUrl(searchValue));
|
|
6167
5557
|
handleClose();
|
|
6168
5558
|
};
|
|
6169
|
-
const submitLabel =
|
|
5559
|
+
const submitLabel = mode === "edit" ? "Save" : "Create";
|
|
6170
5560
|
const title = mode === "edit" ? "Edit navigation item" : "Create navigation item";
|
|
6171
5561
|
const secondaryLabel = showBreadcrumb ? "Back to sections" : "Cancel";
|
|
6172
5562
|
const handleSecondary = showBreadcrumb ? handleBackToSections : handleClose;
|
|
@@ -6193,29 +5583,23 @@ function useLinkModalState({
|
|
|
6193
5583
|
handleChooseSection,
|
|
6194
5584
|
handleSectionSelect,
|
|
6195
5585
|
handleBackToSections,
|
|
6196
|
-
handleSectionPickerBack,
|
|
6197
5586
|
handleClose,
|
|
6198
5587
|
handleSecondary,
|
|
6199
5588
|
handleSubmit
|
|
6200
5589
|
};
|
|
6201
5590
|
}
|
|
6202
5591
|
|
|
6203
|
-
// src/ui/link-modal/
|
|
6204
|
-
var
|
|
6205
|
-
function
|
|
6206
|
-
window.parent?.postMessage(data, "*");
|
|
6207
|
-
}
|
|
6208
|
-
function LinkPopover({
|
|
5592
|
+
// src/ui/link-modal/LinkEditorPanel.tsx
|
|
5593
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
5594
|
+
function LinkEditorPanel({
|
|
6209
5595
|
open = true,
|
|
6210
|
-
panelRef,
|
|
6211
|
-
portalContainer,
|
|
6212
|
-
onClose,
|
|
6213
5596
|
mode = "create",
|
|
6214
5597
|
pages,
|
|
6215
5598
|
sections = [],
|
|
6216
5599
|
sectionsByPath,
|
|
6217
5600
|
initialTarget,
|
|
6218
5601
|
existingTargets = [],
|
|
5602
|
+
onClose,
|
|
6219
5603
|
onSubmit
|
|
6220
5604
|
}) {
|
|
6221
5605
|
const state = useLinkModalState({
|
|
@@ -6229,109 +5613,115 @@ function LinkPopover({
|
|
|
6229
5613
|
onClose,
|
|
6230
5614
|
onSubmit
|
|
6231
5615
|
});
|
|
6232
|
-
const
|
|
6233
|
-
(0,
|
|
6234
|
-
|
|
6235
|
-
|
|
6236
|
-
postToParent({ type: "ui:unlock" });
|
|
6237
|
-
postToParent({ type: "ow:section-picker", active: true });
|
|
6238
|
-
document.documentElement.style.overflow = "";
|
|
6239
|
-
document.body.style.overflow = "";
|
|
6240
|
-
return () => {
|
|
6241
|
-
postToParent({ type: "ow:section-picker", active: false });
|
|
6242
|
-
};
|
|
6243
|
-
}
|
|
6244
|
-
postToParent({ type: "ow:section-picker", active: false });
|
|
6245
|
-
postToParent({ type: "ui:lock" });
|
|
6246
|
-
const html = document.documentElement;
|
|
6247
|
-
const body = document.body;
|
|
6248
|
-
const prevHtmlOverflow = html.style.overflow;
|
|
6249
|
-
const prevBodyOverflow = body.style.overflow;
|
|
6250
|
-
const prevHtmlOverscroll = html.style.overscrollBehavior;
|
|
6251
|
-
const prevBodyOverscroll = body.style.overscrollBehavior;
|
|
6252
|
-
html.style.overflow = "hidden";
|
|
6253
|
-
body.style.overflow = "hidden";
|
|
6254
|
-
html.style.overscrollBehavior = "none";
|
|
6255
|
-
body.style.overscrollBehavior = "none";
|
|
6256
|
-
const canScrollElement = (el, deltaY) => {
|
|
6257
|
-
const { overflowY } = getComputedStyle(el);
|
|
6258
|
-
if (overflowY !== "auto" && overflowY !== "scroll") return false;
|
|
6259
|
-
if (el.scrollHeight <= el.clientHeight + 1) return false;
|
|
6260
|
-
if (deltaY < 0) return el.scrollTop > 0;
|
|
6261
|
-
if (deltaY > 0)
|
|
6262
|
-
return el.scrollTop + el.clientHeight < el.scrollHeight - 1;
|
|
6263
|
-
return true;
|
|
6264
|
-
};
|
|
6265
|
-
const allowsInternalScroll = (e) => {
|
|
6266
|
-
const target = e.target;
|
|
6267
|
-
if (!(target instanceof Element)) return false;
|
|
6268
|
-
const scrollRoot = target.closest(
|
|
6269
|
-
"[data-ohw-link-page-dropdown], [data-ohw-allow-scroll]"
|
|
6270
|
-
);
|
|
6271
|
-
if (!scrollRoot) return false;
|
|
6272
|
-
const deltaY = e instanceof WheelEvent ? e.deltaY : 0;
|
|
6273
|
-
return canScrollElement(scrollRoot, deltaY);
|
|
6274
|
-
};
|
|
6275
|
-
const preventBackgroundScroll = (e) => {
|
|
6276
|
-
if (allowsInternalScroll(e)) return;
|
|
6277
|
-
e.preventDefault();
|
|
6278
|
-
};
|
|
6279
|
-
const scrollOpts = { passive: false, capture: true };
|
|
6280
|
-
document.addEventListener("wheel", preventBackgroundScroll, scrollOpts);
|
|
6281
|
-
document.addEventListener("touchmove", preventBackgroundScroll, scrollOpts);
|
|
6282
|
-
return () => {
|
|
6283
|
-
postToParent({ type: "ui:unlock" });
|
|
6284
|
-
html.style.overflow = prevHtmlOverflow;
|
|
6285
|
-
body.style.overflow = prevBodyOverflow;
|
|
6286
|
-
html.style.overscrollBehavior = prevHtmlOverscroll;
|
|
6287
|
-
body.style.overscrollBehavior = prevBodyOverscroll;
|
|
6288
|
-
document.removeEventListener(
|
|
6289
|
-
"wheel",
|
|
6290
|
-
preventBackgroundScroll,
|
|
6291
|
-
scrollOpts
|
|
6292
|
-
);
|
|
6293
|
-
document.removeEventListener(
|
|
6294
|
-
"touchmove",
|
|
6295
|
-
preventBackgroundScroll,
|
|
6296
|
-
scrollOpts
|
|
6297
|
-
);
|
|
6298
|
-
};
|
|
6299
|
-
}, [open, sectionPickerActive]);
|
|
6300
|
-
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
|
|
6301
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
6302
|
-
Dialog2,
|
|
6303
|
-
{
|
|
6304
|
-
open: open && !sectionPickerActive,
|
|
6305
|
-
onOpenChange: (next) => {
|
|
6306
|
-
if (!next) onClose?.();
|
|
6307
|
-
},
|
|
6308
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
6309
|
-
DialogContent,
|
|
6310
|
-
{
|
|
6311
|
-
ref: panelRef,
|
|
6312
|
-
container: portalContainer,
|
|
6313
|
-
"data-ohw-link-popover-root": "",
|
|
6314
|
-
"data-ohw-link-modal-root": "",
|
|
6315
|
-
"data-ohw-bridge": "",
|
|
6316
|
-
showCloseButton: false,
|
|
6317
|
-
className: "gap-0 p-0 w-full max-w-[448px] pointer-events-auto z-[2147483646] overflow-visible",
|
|
6318
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(LinkEditorPanel, { state, onClose })
|
|
6319
|
-
}
|
|
6320
|
-
)
|
|
6321
|
-
}
|
|
6322
|
-
),
|
|
6323
|
-
sectionPickerActive && state.selectedPage ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
6324
|
-
SectionPickerOverlay,
|
|
5616
|
+
const isCancel = state.secondaryLabel === "Cancel";
|
|
5617
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
|
|
5618
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(DialogClose, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5619
|
+
"button",
|
|
6325
5620
|
{
|
|
6326
|
-
|
|
6327
|
-
|
|
6328
|
-
|
|
6329
|
-
|
|
5621
|
+
type: "button",
|
|
5622
|
+
className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50",
|
|
5623
|
+
"aria-label": "Close",
|
|
5624
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(IconX, { "aria-hidden": true })
|
|
6330
5625
|
}
|
|
6331
|
-
)
|
|
5626
|
+
) }),
|
|
5627
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(DialogHeader, { className: "w-full gap-1.5 p-6 pr-12", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(DialogTitle, { className: "m-0 w-full break-words", children: state.title }) }),
|
|
5628
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex w-full flex-col gap-3 px-6 pb-8 pt-1", children: [
|
|
5629
|
+
state.showBreadcrumb && state.selectedPage && state.selectedSection ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5630
|
+
DestinationBreadcrumb,
|
|
5631
|
+
{
|
|
5632
|
+
pageTitle: state.selectedPage.title,
|
|
5633
|
+
sectionLabel: state.selectedSection.label
|
|
5634
|
+
}
|
|
5635
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5636
|
+
UrlOrPageInput,
|
|
5637
|
+
{
|
|
5638
|
+
value: state.searchValue,
|
|
5639
|
+
selectedPage: state.selectedPage,
|
|
5640
|
+
dropdownOpen: state.dropdownOpen,
|
|
5641
|
+
onDropdownOpenChange: state.setDropdownOpen,
|
|
5642
|
+
filteredPages: state.filteredPages,
|
|
5643
|
+
onInputChange: state.handleInputChange,
|
|
5644
|
+
onPageSelect: state.handlePageSelect,
|
|
5645
|
+
urlError: state.urlError
|
|
5646
|
+
}
|
|
5647
|
+
),
|
|
5648
|
+
state.showChooseSection ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex flex-col justify-center gap-2", children: [
|
|
5649
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Button, { type: "button", variant: "outline", className: "w-fit cursor-pointer", size: "sm", onClick: state.handleChooseSection, children: "Choose a section" }),
|
|
5650
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex items-center gap-1 text-sm text-muted-foreground", children: [
|
|
5651
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(IconInfo, { className: "shrink-0", "aria-hidden": true }),
|
|
5652
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { children: "Pick a section this link should scroll to." })
|
|
5653
|
+
] })
|
|
5654
|
+
] }) : null,
|
|
5655
|
+
state.showSectionPicker ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(SectionPickerList, { sections: state.activeSections, onSelect: state.handleSectionSelect }) : null,
|
|
5656
|
+
state.showSectionRow && state.selectedSection ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(SectionTreeItem, { section: state.selectedSection, selected: true }) : null
|
|
5657
|
+
] }),
|
|
5658
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(DialogFooter, { className: "w-full px-6 pb-6", children: [
|
|
5659
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5660
|
+
Button,
|
|
5661
|
+
{
|
|
5662
|
+
type: "button",
|
|
5663
|
+
variant: isCancel ? "outline" : "ghost",
|
|
5664
|
+
className: "leading-6 shadow-none cursor-pointer",
|
|
5665
|
+
style: isCancel ? {
|
|
5666
|
+
backgroundColor: "var(--ohw-background)",
|
|
5667
|
+
borderColor: "var(--ohw-border)",
|
|
5668
|
+
color: "var(--ohw-foreground)"
|
|
5669
|
+
} : void 0,
|
|
5670
|
+
onClick: state.handleSecondary,
|
|
5671
|
+
children: state.secondaryLabel
|
|
5672
|
+
}
|
|
5673
|
+
),
|
|
5674
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5675
|
+
Button,
|
|
5676
|
+
{
|
|
5677
|
+
type: "button",
|
|
5678
|
+
className: "border-0 leading-6 shadow-none hover:opacity-90 disabled:opacity-50 cursor-pointer",
|
|
5679
|
+
style: {
|
|
5680
|
+
backgroundColor: "var(--ohw-primary)",
|
|
5681
|
+
color: "var(--ohw-primary-foreground)"
|
|
5682
|
+
},
|
|
5683
|
+
disabled: !state.isValid,
|
|
5684
|
+
onClick: state.handleSubmit,
|
|
5685
|
+
children: state.submitLabel
|
|
5686
|
+
}
|
|
5687
|
+
)
|
|
5688
|
+
] })
|
|
6332
5689
|
] });
|
|
6333
5690
|
}
|
|
6334
5691
|
|
|
5692
|
+
// src/ui/link-modal/LinkPopover.tsx
|
|
5693
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
5694
|
+
function LinkPopover({
|
|
5695
|
+
open = true,
|
|
5696
|
+
panelRef,
|
|
5697
|
+
portalContainer,
|
|
5698
|
+
onClose,
|
|
5699
|
+
...editorProps
|
|
5700
|
+
}) {
|
|
5701
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5702
|
+
Dialog2,
|
|
5703
|
+
{
|
|
5704
|
+
open,
|
|
5705
|
+
onOpenChange: (next) => {
|
|
5706
|
+
if (!next) onClose?.();
|
|
5707
|
+
},
|
|
5708
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5709
|
+
DialogContent,
|
|
5710
|
+
{
|
|
5711
|
+
ref: panelRef,
|
|
5712
|
+
container: portalContainer,
|
|
5713
|
+
"data-ohw-link-popover-root": "",
|
|
5714
|
+
"data-ohw-link-modal-root": "",
|
|
5715
|
+
"data-ohw-bridge": "",
|
|
5716
|
+
showCloseButton: false,
|
|
5717
|
+
className: "gap-0 p-0 w-full md:w-md pointer-events-auto",
|
|
5718
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(LinkEditorPanel, { ...editorProps, open, onClose })
|
|
5719
|
+
}
|
|
5720
|
+
)
|
|
5721
|
+
}
|
|
5722
|
+
);
|
|
5723
|
+
}
|
|
5724
|
+
|
|
6335
5725
|
// src/ui/link-modal/devFixtures.ts
|
|
6336
5726
|
var DEV_SITE_PAGES = [
|
|
6337
5727
|
{ path: "/", title: "Home" },
|
|
@@ -6351,766 +5741,47 @@ var DEV_SECTIONS_BY_PATH = {
|
|
|
6351
5741
|
{ id: "founder-teaser", label: "Founder" },
|
|
6352
5742
|
{ id: "plan-form", label: "Plan Form" },
|
|
6353
5743
|
{ id: "testimonials", label: "Testimonials" },
|
|
6354
|
-
{ id: "wordmark", label: "Wordmark" }
|
|
6355
|
-
{ id: "footer", label: "Footer" }
|
|
5744
|
+
{ id: "wordmark", label: "Wordmark" }
|
|
6356
5745
|
],
|
|
6357
5746
|
"/about": [
|
|
6358
|
-
{ id: "manifesto", label: "Manifesto" },
|
|
6359
|
-
{ id: "story-letter", label: "Our Story" },
|
|
6360
|
-
{ id: "lagree-explainer", label: "Lagree Explainer" },
|
|
6361
|
-
{ id: "waitlist-cta", label: "Waitlist" },
|
|
6362
|
-
{ id: "personal-training", label: "Personal training" }
|
|
6363
|
-
|
|
6364
|
-
],
|
|
6365
|
-
"/
|
|
6366
|
-
{ id: "
|
|
6367
|
-
{ id: "
|
|
6368
|
-
|
|
6369
|
-
|
|
6370
|
-
{ id: "
|
|
6371
|
-
{ id: "
|
|
6372
|
-
{ id: "
|
|
6373
|
-
|
|
6374
|
-
|
|
6375
|
-
{ id: "
|
|
6376
|
-
{ id: "
|
|
6377
|
-
{ id: "
|
|
6378
|
-
|
|
6379
|
-
|
|
6380
|
-
|
|
6381
|
-
|
|
6382
|
-
{ id: "
|
|
6383
|
-
{ id: "
|
|
6384
|
-
{ id: "
|
|
6385
|
-
]
|
|
6386
|
-
|
|
6387
|
-
|
|
6388
|
-
|
|
6389
|
-
|
|
6390
|
-
"
|
|
6391
|
-
|
|
6392
|
-
{ id: "contact-form", label: "Contact Form" },
|
|
6393
|
-
{ id: "faq", label: "FAQ" },
|
|
6394
|
-
{ id: "footer", label: "Footer" }
|
|
6395
|
-
]
|
|
6396
|
-
};
|
|
6397
|
-
function shouldUseDevFixtures() {
|
|
6398
|
-
if (typeof window === "undefined") return false;
|
|
6399
|
-
const raw = readPreservedSearch();
|
|
6400
|
-
const q = raw.startsWith("?") ? raw.slice(1) : raw;
|
|
6401
|
-
return new URLSearchParams(q).get("ohw-fixtures") === "1";
|
|
6402
|
-
}
|
|
6403
|
-
|
|
6404
|
-
// src/lib/nav-items.ts
|
|
6405
|
-
var NAV_COUNT_KEY = "__ohw_nav_count";
|
|
6406
|
-
var NAV_ORDER_KEY = "__ohw_nav_order";
|
|
6407
|
-
function getLinkHref(el) {
|
|
6408
|
-
const key = el.getAttribute("data-ohw-href-key");
|
|
6409
|
-
if (key) {
|
|
6410
|
-
const stored = getStoredLinkHref(key);
|
|
6411
|
-
if (stored !== void 0) return stored;
|
|
6412
|
-
}
|
|
6413
|
-
return el.getAttribute("href") ?? "";
|
|
6414
|
-
}
|
|
6415
|
-
function isNavbarButton(el) {
|
|
6416
|
-
return el.hasAttribute("data-ohw-role") && el.getAttribute("data-ohw-role") === "navbar-button";
|
|
6417
|
-
}
|
|
6418
|
-
function isNavbarLinkItem(el) {
|
|
6419
|
-
if (!el.matches("[data-ohw-href-key]")) return false;
|
|
6420
|
-
if (isNavbarButton(el)) return false;
|
|
6421
|
-
if (!el.querySelector('[data-ohw-editable="text"]')) return false;
|
|
6422
|
-
return Boolean(el.closest("nav, [data-ohw-nav-container], [data-ohw-nav-drawer]"));
|
|
6423
|
-
}
|
|
6424
|
-
function getNavbarDesktopContainer() {
|
|
6425
|
-
return document.querySelector("[data-ohw-nav-container]");
|
|
6426
|
-
}
|
|
6427
|
-
function getNavbarDrawerContainer() {
|
|
6428
|
-
return document.querySelector("[data-ohw-nav-drawer]");
|
|
6429
|
-
}
|
|
6430
|
-
function listNavbarItems() {
|
|
6431
|
-
const desktop = getNavbarDesktopContainer();
|
|
6432
|
-
if (desktop) {
|
|
6433
|
-
return Array.from(desktop.querySelectorAll("[data-ohw-href-key]")).filter(isNavbarLinkItem);
|
|
6434
|
-
}
|
|
6435
|
-
const drawer = getNavbarDrawerContainer();
|
|
6436
|
-
if (drawer) {
|
|
6437
|
-
return Array.from(drawer.querySelectorAll("[data-ohw-href-key]")).filter(isNavbarLinkItem);
|
|
6438
|
-
}
|
|
6439
|
-
return Array.from(document.querySelectorAll("nav [data-ohw-href-key]")).filter(isNavbarLinkItem);
|
|
6440
|
-
}
|
|
6441
|
-
function parseNavIndexFromKey(key) {
|
|
6442
|
-
if (!key) return null;
|
|
6443
|
-
const match = key.match(/^nav-(\d+)-href$/);
|
|
6444
|
-
if (!match) return null;
|
|
6445
|
-
return parseInt(match[1], 10);
|
|
6446
|
-
}
|
|
6447
|
-
function getNavbarIndicesInDom() {
|
|
6448
|
-
const indices = /* @__PURE__ */ new Set();
|
|
6449
|
-
for (const item of listNavbarItems()) {
|
|
6450
|
-
const idx = parseNavIndexFromKey(item.getAttribute("data-ohw-href-key"));
|
|
6451
|
-
if (idx !== null) indices.add(idx);
|
|
6452
|
-
}
|
|
6453
|
-
return [...indices].sort((a, b) => a - b);
|
|
6454
|
-
}
|
|
6455
|
-
function getNextNavbarIndex() {
|
|
6456
|
-
const indices = getNavbarIndicesInDom();
|
|
6457
|
-
if (indices.length === 0) return 0;
|
|
6458
|
-
return Math.max(...indices) + 1;
|
|
6459
|
-
}
|
|
6460
|
-
function getNavbarExistingTargets() {
|
|
6461
|
-
return listNavbarItems().map((el) => getLinkHref(el)).filter(Boolean);
|
|
6462
|
-
}
|
|
6463
|
-
function getNavOrderFromDom() {
|
|
6464
|
-
return listNavbarItems().map((el) => el.getAttribute("data-ohw-href-key")).filter((key) => Boolean(key));
|
|
6465
|
-
}
|
|
6466
|
-
function parseNavOrder(content) {
|
|
6467
|
-
const raw = content[NAV_ORDER_KEY];
|
|
6468
|
-
if (!raw) return null;
|
|
6469
|
-
try {
|
|
6470
|
-
const parsed = JSON.parse(raw);
|
|
6471
|
-
if (!Array.isArray(parsed)) return null;
|
|
6472
|
-
return parsed.filter((key) => typeof key === "string" && key.length > 0);
|
|
6473
|
-
} catch {
|
|
6474
|
-
return null;
|
|
6475
|
-
}
|
|
6476
|
-
}
|
|
6477
|
-
function findCounterpartByHrefKey(hrefKey, root) {
|
|
6478
|
-
return root.querySelector(`[data-ohw-href-key="${CSS.escape(hrefKey)}"]`);
|
|
6479
|
-
}
|
|
6480
|
-
function cloneNavLinkShell(template) {
|
|
6481
|
-
const anchor = document.createElement("a");
|
|
6482
|
-
if (template) {
|
|
6483
|
-
anchor.style.cssText = template.style.cssText;
|
|
6484
|
-
if (template.className) anchor.className = template.className;
|
|
6485
|
-
}
|
|
6486
|
-
anchor.style.cursor = "pointer";
|
|
6487
|
-
anchor.style.textDecoration = "none";
|
|
6488
|
-
return anchor;
|
|
6489
|
-
}
|
|
6490
|
-
function buildNavLink(index, href, label, template) {
|
|
6491
|
-
const anchor = cloneNavLinkShell(template);
|
|
6492
|
-
anchor.href = href;
|
|
6493
|
-
anchor.setAttribute("data-ohw-href-key", `nav-${index}-href`);
|
|
6494
|
-
const span = document.createElement("span");
|
|
6495
|
-
span.setAttribute("data-ohw-editable", "text");
|
|
6496
|
-
span.setAttribute("data-ohw-key", `nav-${index}-label`);
|
|
6497
|
-
span.textContent = label;
|
|
6498
|
-
anchor.appendChild(span);
|
|
6499
|
-
return anchor;
|
|
6500
|
-
}
|
|
6501
|
-
function insertNavLinkInContainer(container, anchor, afterHrefKey) {
|
|
6502
|
-
if (!afterHrefKey) {
|
|
6503
|
-
container.appendChild(anchor);
|
|
6504
|
-
return;
|
|
6505
|
-
}
|
|
6506
|
-
const afterEl = findCounterpartByHrefKey(afterHrefKey, container);
|
|
6507
|
-
if (afterEl?.parentElement === container) {
|
|
6508
|
-
afterEl.insertAdjacentElement("afterend", anchor);
|
|
6509
|
-
return;
|
|
6510
|
-
}
|
|
6511
|
-
container.appendChild(anchor);
|
|
6512
|
-
}
|
|
6513
|
-
function insertNavbarItemDom(index, href, label, afterAnchor) {
|
|
6514
|
-
const afterHrefKey = afterAnchor?.getAttribute("data-ohw-href-key") ?? null;
|
|
6515
|
-
const desktopItems = getNavbarDesktopContainer()?.querySelectorAll("[data-ohw-href-key]") ?? [];
|
|
6516
|
-
const drawerItems = getNavbarDrawerContainer()?.querySelectorAll("[data-ohw-href-key]") ?? [];
|
|
6517
|
-
const desktopTemplate = Array.from(desktopItems).find(isNavbarLinkItem) ?? null;
|
|
6518
|
-
const drawerTemplate = Array.from(drawerItems).find(isNavbarLinkItem) ?? null;
|
|
6519
|
-
let primary = null;
|
|
6520
|
-
const desktopContainer = getNavbarDesktopContainer();
|
|
6521
|
-
if (desktopContainer) {
|
|
6522
|
-
const desktopAnchor = buildNavLink(index, href, label, desktopTemplate);
|
|
6523
|
-
insertNavLinkInContainer(desktopContainer, desktopAnchor, afterHrefKey);
|
|
6524
|
-
primary = desktopAnchor;
|
|
6525
|
-
}
|
|
6526
|
-
const drawerContainer = getNavbarDrawerContainer();
|
|
6527
|
-
if (drawerContainer) {
|
|
6528
|
-
const drawerAnchor = buildNavLink(index, href, label, drawerTemplate);
|
|
6529
|
-
insertNavLinkInContainer(drawerContainer, drawerAnchor, afterHrefKey);
|
|
6530
|
-
if (!primary) primary = drawerAnchor;
|
|
6531
|
-
}
|
|
6532
|
-
if (!primary) {
|
|
6533
|
-
const fallback = buildNavLink(index, href, label, listNavbarItems()[0] ?? null);
|
|
6534
|
-
const nav = document.querySelector("nav");
|
|
6535
|
-
nav?.appendChild(fallback);
|
|
6536
|
-
primary = fallback;
|
|
6537
|
-
}
|
|
6538
|
-
return primary;
|
|
6539
|
-
}
|
|
6540
|
-
function applyNavOrderToContainer(container, order) {
|
|
6541
|
-
const seen = /* @__PURE__ */ new Set();
|
|
6542
|
-
for (const hrefKey of order) {
|
|
6543
|
-
if (seen.has(hrefKey)) continue;
|
|
6544
|
-
seen.add(hrefKey);
|
|
6545
|
-
const el = findCounterpartByHrefKey(hrefKey, container);
|
|
6546
|
-
if (el) container.appendChild(el);
|
|
6547
|
-
}
|
|
6548
|
-
for (const el of container.querySelectorAll("[data-ohw-href-key]")) {
|
|
6549
|
-
if (!isNavbarLinkItem(el)) continue;
|
|
6550
|
-
const key = el.getAttribute("data-ohw-href-key");
|
|
6551
|
-
if (!key || seen.has(key)) continue;
|
|
6552
|
-
container.appendChild(el);
|
|
6553
|
-
}
|
|
6554
|
-
}
|
|
6555
|
-
function applyNavOrder(order) {
|
|
6556
|
-
const desktop = getNavbarDesktopContainer();
|
|
6557
|
-
if (desktop) applyNavOrderToContainer(desktop, order);
|
|
6558
|
-
const drawer = getNavbarDrawerContainer();
|
|
6559
|
-
if (drawer) applyNavOrderToContainer(drawer, order);
|
|
6560
|
-
}
|
|
6561
|
-
function collectNavbarIndicesFromContent(content) {
|
|
6562
|
-
const indices = /* @__PURE__ */ new Set();
|
|
6563
|
-
for (const key of Object.keys(content)) {
|
|
6564
|
-
const idx = parseNavIndexFromKey(key);
|
|
6565
|
-
if (idx !== null) indices.add(idx);
|
|
6566
|
-
}
|
|
6567
|
-
const countRaw = content[NAV_COUNT_KEY];
|
|
6568
|
-
if (countRaw) {
|
|
6569
|
-
const count = parseInt(countRaw, 10);
|
|
6570
|
-
if (Number.isFinite(count) && count > 0) {
|
|
6571
|
-
for (let i = 0; i < count; i++) indices.add(i);
|
|
6572
|
-
}
|
|
6573
|
-
}
|
|
6574
|
-
return [...indices].sort((a, b) => a - b);
|
|
6575
|
-
}
|
|
6576
|
-
function navbarIndexExistsInDom(index) {
|
|
6577
|
-
return document.querySelector(`[data-ohw-href-key="nav-${index}-href"]`) !== null;
|
|
6578
|
-
}
|
|
6579
|
-
function reconcileNavbarItemsFromContent(content) {
|
|
6580
|
-
const indices = collectNavbarIndicesFromContent(content);
|
|
6581
|
-
for (const index of indices) {
|
|
6582
|
-
if (navbarIndexExistsInDom(index)) continue;
|
|
6583
|
-
const href = content[`nav-${index}-href`];
|
|
6584
|
-
const label = content[`nav-${index}-label`];
|
|
6585
|
-
if (!href && !label) continue;
|
|
6586
|
-
insertNavbarItemDom(index, href ?? "/", label ?? "Untitled", null);
|
|
6587
|
-
}
|
|
6588
|
-
const order = parseNavOrder(content);
|
|
6589
|
-
if (order?.length) applyNavOrder(order);
|
|
6590
|
-
}
|
|
6591
|
-
function buildNavOrderAfterInsert(afterAnchor, newHrefKey) {
|
|
6592
|
-
const order = getNavOrderFromDom();
|
|
6593
|
-
if (!afterAnchor) {
|
|
6594
|
-
if (!order.includes(newHrefKey)) order.push(newHrefKey);
|
|
6595
|
-
return order;
|
|
6596
|
-
}
|
|
6597
|
-
const afterKey = afterAnchor.getAttribute("data-ohw-href-key");
|
|
6598
|
-
if (!afterKey) {
|
|
6599
|
-
if (!order.includes(newHrefKey)) order.push(newHrefKey);
|
|
6600
|
-
return order;
|
|
6601
|
-
}
|
|
6602
|
-
const withoutNew = order.filter((key) => key !== newHrefKey);
|
|
6603
|
-
const pos = withoutNew.indexOf(afterKey);
|
|
6604
|
-
if (pos >= 0) {
|
|
6605
|
-
withoutNew.splice(pos + 1, 0, newHrefKey);
|
|
6606
|
-
return withoutNew;
|
|
6607
|
-
}
|
|
6608
|
-
withoutNew.push(newHrefKey);
|
|
6609
|
-
return withoutNew;
|
|
6610
|
-
}
|
|
6611
|
-
function insertNavbarItem(href, label, afterAnchor = null) {
|
|
6612
|
-
const index = getNextNavbarIndex();
|
|
6613
|
-
const anchor = insertNavbarItemDom(index, href, label, afterAnchor);
|
|
6614
|
-
if (!anchor) throw new Error("Failed to insert navbar item");
|
|
6615
|
-
const hrefKey = `nav-${index}-href`;
|
|
6616
|
-
const order = buildNavOrderAfterInsert(afterAnchor, hrefKey);
|
|
6617
|
-
applyNavOrder(order);
|
|
6618
|
-
return {
|
|
6619
|
-
anchor,
|
|
6620
|
-
index,
|
|
6621
|
-
hrefKey,
|
|
6622
|
-
labelKey: `nav-${index}-label`,
|
|
6623
|
-
href,
|
|
6624
|
-
label,
|
|
6625
|
-
order
|
|
6626
|
-
};
|
|
6627
|
-
}
|
|
6628
|
-
|
|
6629
|
-
// src/lib/footer-items.ts
|
|
6630
|
-
var FOOTER_ORDER_KEY = "__ohw_footer_order";
|
|
6631
|
-
var FOOTER_HREF_RE = /^footer-(\d+)-(\d+)-href$/;
|
|
6632
|
-
function parseFooterHrefKey(key) {
|
|
6633
|
-
if (!key) return null;
|
|
6634
|
-
const match = key.match(FOOTER_HREF_RE);
|
|
6635
|
-
if (!match) return null;
|
|
6636
|
-
return { col: parseInt(match[1], 10), item: parseInt(match[2], 10) };
|
|
6637
|
-
}
|
|
6638
|
-
function isFooterHrefKey(key) {
|
|
6639
|
-
return parseFooterHrefKey(key) !== null;
|
|
6640
|
-
}
|
|
6641
|
-
function getFooterRoot() {
|
|
6642
|
-
return document.querySelector('footer[data-ohw-section="footer"], footer');
|
|
6643
|
-
}
|
|
6644
|
-
function getFooterLinksContainer() {
|
|
6645
|
-
return document.querySelector("[data-ohw-footer-links]") ?? document.querySelector(".rb-footer-links");
|
|
6646
|
-
}
|
|
6647
|
-
function isFooterLinkAnchor(el) {
|
|
6648
|
-
if (!el.matches("[data-ohw-href-key]")) return false;
|
|
6649
|
-
if (!isFooterHrefKey(el.getAttribute("data-ohw-href-key"))) return false;
|
|
6650
|
-
return Boolean(el.querySelector('[data-ohw-editable="text"]'));
|
|
6651
|
-
}
|
|
6652
|
-
function listFooterColumns() {
|
|
6653
|
-
const root = getFooterLinksContainer() ?? getFooterRoot()?.querySelector(".rb-footer-links") ?? null;
|
|
6654
|
-
if (!root) return [];
|
|
6655
|
-
const explicit = Array.from(root.querySelectorAll(":scope > [data-ohw-footer-col]"));
|
|
6656
|
-
if (explicit.length > 0) return explicit;
|
|
6657
|
-
return Array.from(root.children).filter((el) => {
|
|
6658
|
-
if (!(el instanceof HTMLElement)) return false;
|
|
6659
|
-
return Array.from(el.querySelectorAll(":scope > [data-ohw-href-key]")).some(
|
|
6660
|
-
isFooterLinkAnchor
|
|
6661
|
-
);
|
|
6662
|
-
});
|
|
6663
|
-
}
|
|
6664
|
-
function listFooterLinksInColumn(column) {
|
|
6665
|
-
return Array.from(column.querySelectorAll(":scope > [data-ohw-href-key]")).filter(
|
|
6666
|
-
isFooterLinkAnchor
|
|
6667
|
-
);
|
|
6668
|
-
}
|
|
6669
|
-
function findFooterColumnForLink(anchor) {
|
|
6670
|
-
const columns = listFooterColumns();
|
|
6671
|
-
return columns.find((col) => col.contains(anchor)) ?? null;
|
|
6672
|
-
}
|
|
6673
|
-
function getFooterOrderFromDom() {
|
|
6674
|
-
return listFooterColumns().map(
|
|
6675
|
-
(col) => listFooterLinksInColumn(col).map((el) => el.getAttribute("data-ohw-href-key")).filter((key) => Boolean(key))
|
|
6676
|
-
);
|
|
6677
|
-
}
|
|
6678
|
-
function findFooterLinkByKey(hrefKey) {
|
|
6679
|
-
return document.querySelector(
|
|
6680
|
-
`footer [data-ohw-href-key="${CSS.escape(hrefKey)}"]`
|
|
6681
|
-
);
|
|
6682
|
-
}
|
|
6683
|
-
function syncFooterColumnIndices(columns) {
|
|
6684
|
-
columns.forEach((col, index) => {
|
|
6685
|
-
const next = String(index);
|
|
6686
|
-
if (col.getAttribute("data-ohw-footer-col") !== next) {
|
|
6687
|
-
col.setAttribute("data-ohw-footer-col", next);
|
|
6688
|
-
}
|
|
6689
|
-
});
|
|
6690
|
-
}
|
|
6691
|
-
function appendChildIfNeeded(parent, child) {
|
|
6692
|
-
if (parent.lastElementChild !== child) {
|
|
6693
|
-
parent.appendChild(child);
|
|
6694
|
-
}
|
|
6695
|
-
}
|
|
6696
|
-
function insertLinkBeforeNext(col, el, nextEl) {
|
|
6697
|
-
if (nextEl) {
|
|
6698
|
-
if (el.nextElementSibling !== nextEl) {
|
|
6699
|
-
col.insertBefore(el, nextEl);
|
|
6700
|
-
}
|
|
6701
|
-
return;
|
|
6702
|
-
}
|
|
6703
|
-
if (col.lastElementChild !== el) {
|
|
6704
|
-
col.appendChild(el);
|
|
6705
|
-
}
|
|
6706
|
-
}
|
|
6707
|
-
function applyFooterOrder(order) {
|
|
6708
|
-
const container = getFooterLinksContainer();
|
|
6709
|
-
if (!container) return;
|
|
6710
|
-
const columns = listFooterColumns();
|
|
6711
|
-
if (columns.length === 0) return;
|
|
6712
|
-
const currentOrder = getFooterOrderFromDom();
|
|
6713
|
-
if (ordersEqual(order, currentOrder)) {
|
|
6714
|
-
syncFooterColumnIndices(columns);
|
|
6715
|
-
return;
|
|
6716
|
-
}
|
|
6717
|
-
const colCount = Math.max(columns.length, order.length);
|
|
6718
|
-
const working = columns.slice(0, colCount);
|
|
6719
|
-
for (let i = 0; i < order.length && i < working.length; i++) {
|
|
6720
|
-
appendChildIfNeeded(container, working[i]);
|
|
6721
|
-
}
|
|
6722
|
-
for (let i = order.length; i < working.length; i++) {
|
|
6723
|
-
appendChildIfNeeded(container, working[i]);
|
|
6724
|
-
}
|
|
6725
|
-
const freshColumns = listFooterColumns();
|
|
6726
|
-
syncFooterColumnIndices(freshColumns);
|
|
6727
|
-
for (let c = 0; c < order.length; c++) {
|
|
6728
|
-
const col = freshColumns[c];
|
|
6729
|
-
if (!col) continue;
|
|
6730
|
-
const colOrder = order[c];
|
|
6731
|
-
for (let j = 0; j < colOrder.length; j++) {
|
|
6732
|
-
const hrefKey = colOrder[j];
|
|
6733
|
-
const el = findFooterLinkByKey(hrefKey);
|
|
6734
|
-
if (!el) continue;
|
|
6735
|
-
if (el.parentElement !== col) {
|
|
6736
|
-
col.appendChild(el);
|
|
6737
|
-
}
|
|
6738
|
-
const nextKey = colOrder[j + 1];
|
|
6739
|
-
const nextEl = nextKey ? findFooterLinkByKey(nextKey) : null;
|
|
6740
|
-
insertLinkBeforeNext(col, el, nextEl?.parentElement === col ? nextEl : null);
|
|
6741
|
-
}
|
|
6742
|
-
}
|
|
6743
|
-
}
|
|
6744
|
-
function ordersEqual(a, b) {
|
|
6745
|
-
if (a.length !== b.length) return false;
|
|
6746
|
-
for (let i = 0; i < a.length; i++) {
|
|
6747
|
-
const left = a[i];
|
|
6748
|
-
const right = b[i];
|
|
6749
|
-
if (left.length !== right.length) return false;
|
|
6750
|
-
for (let j = 0; j < left.length; j++) {
|
|
6751
|
-
if (left[j] !== right[j]) return false;
|
|
6752
|
-
}
|
|
6753
|
-
}
|
|
6754
|
-
return true;
|
|
6755
|
-
}
|
|
6756
|
-
function planFooterLinkMove(hrefKey, targetColIndex, insertIndex) {
|
|
6757
|
-
const order = getFooterOrderFromDom();
|
|
6758
|
-
if (targetColIndex < 0 || targetColIndex >= order.length) return null;
|
|
6759
|
-
let fromCol = -1;
|
|
6760
|
-
let fromIdx = -1;
|
|
6761
|
-
for (let c = 0; c < order.length; c++) {
|
|
6762
|
-
const idx = order[c].indexOf(hrefKey);
|
|
6763
|
-
if (idx >= 0) {
|
|
6764
|
-
fromCol = c;
|
|
6765
|
-
fromIdx = idx;
|
|
6766
|
-
break;
|
|
6767
|
-
}
|
|
6768
|
-
}
|
|
6769
|
-
if (fromCol < 0) return null;
|
|
6770
|
-
const next = order.map((col) => [...col]);
|
|
6771
|
-
next[fromCol].splice(fromIdx, 1);
|
|
6772
|
-
let adjusted = insertIndex;
|
|
6773
|
-
if (fromCol === targetColIndex && fromIdx < insertIndex) adjusted -= 1;
|
|
6774
|
-
adjusted = Math.max(0, Math.min(adjusted, next[targetColIndex].length));
|
|
6775
|
-
next[targetColIndex].splice(adjusted, 0, hrefKey);
|
|
6776
|
-
if (ordersEqual(next, order)) return null;
|
|
6777
|
-
return next;
|
|
6778
|
-
}
|
|
6779
|
-
function planFooterColumnMove(fromIndex, toIndex) {
|
|
6780
|
-
const order = getFooterOrderFromDom();
|
|
6781
|
-
const columns = listFooterColumns();
|
|
6782
|
-
if (fromIndex < 0 || fromIndex >= columns.length || toIndex < 0 || toIndex > columns.length) {
|
|
6783
|
-
return null;
|
|
6784
|
-
}
|
|
6785
|
-
if (toIndex === fromIndex || toIndex === fromIndex + 1) return null;
|
|
6786
|
-
const nextOrder = order.map((col) => [...col]);
|
|
6787
|
-
const [movedOrder] = nextOrder.splice(fromIndex, 1);
|
|
6788
|
-
if (!movedOrder) return null;
|
|
6789
|
-
let adjusted = toIndex;
|
|
6790
|
-
if (fromIndex < toIndex) adjusted -= 1;
|
|
6791
|
-
adjusted = Math.max(0, Math.min(adjusted, nextOrder.length));
|
|
6792
|
-
nextOrder.splice(adjusted, 0, movedOrder);
|
|
6793
|
-
if (ordersEqual(nextOrder, order)) return null;
|
|
6794
|
-
return nextOrder;
|
|
6795
|
-
}
|
|
6796
|
-
function parseFooterOrder(content) {
|
|
6797
|
-
const raw = content[FOOTER_ORDER_KEY];
|
|
6798
|
-
if (!raw) return null;
|
|
6799
|
-
try {
|
|
6800
|
-
const parsed = JSON.parse(raw);
|
|
6801
|
-
if (!Array.isArray(parsed)) return null;
|
|
6802
|
-
return parsed.filter((col) => Array.isArray(col)).map((col) => col.filter((key) => typeof key === "string" && key.length > 0));
|
|
6803
|
-
} catch {
|
|
6804
|
-
return null;
|
|
6805
|
-
}
|
|
6806
|
-
}
|
|
6807
|
-
function reconcileFooterOrderFromContent(content) {
|
|
6808
|
-
const order = parseFooterOrder(content);
|
|
6809
|
-
if (!order?.length) return;
|
|
6810
|
-
const current = getFooterOrderFromDom();
|
|
6811
|
-
if (ordersEqual(order, current)) {
|
|
6812
|
-
syncFooterColumnIndices(listFooterColumns());
|
|
6813
|
-
return;
|
|
6814
|
-
}
|
|
6815
|
-
applyFooterOrder(order);
|
|
6816
|
-
}
|
|
6817
|
-
function buildLinkDropSlots(column, columnIndex) {
|
|
6818
|
-
const links = listFooterLinksInColumn(column);
|
|
6819
|
-
const colRect = column.getBoundingClientRect();
|
|
6820
|
-
const slots = [];
|
|
6821
|
-
const barThickness = 3;
|
|
6822
|
-
if (links.length === 0) {
|
|
6823
|
-
slots.push({
|
|
6824
|
-
insertIndex: 0,
|
|
6825
|
-
columnIndex,
|
|
6826
|
-
left: colRect.left,
|
|
6827
|
-
top: colRect.top + colRect.height / 2 - barThickness / 2,
|
|
6828
|
-
width: colRect.width,
|
|
6829
|
-
height: barThickness,
|
|
6830
|
-
direction: "horizontal"
|
|
6831
|
-
});
|
|
6832
|
-
return slots;
|
|
6833
|
-
}
|
|
6834
|
-
for (let i = 0; i <= links.length; i++) {
|
|
6835
|
-
let top;
|
|
6836
|
-
if (i === 0) {
|
|
6837
|
-
top = links[0].getBoundingClientRect().top - barThickness / 2;
|
|
6838
|
-
} else if (i === links.length) {
|
|
6839
|
-
const last = links[links.length - 1].getBoundingClientRect();
|
|
6840
|
-
top = last.bottom - barThickness / 2;
|
|
6841
|
-
} else {
|
|
6842
|
-
const prev = links[i - 1].getBoundingClientRect();
|
|
6843
|
-
const next = links[i].getBoundingClientRect();
|
|
6844
|
-
top = (prev.bottom + next.top) / 2 - barThickness / 2;
|
|
6845
|
-
}
|
|
6846
|
-
const widthRef = i === 0 ? links[0].getBoundingClientRect() : i === links.length ? links[links.length - 1].getBoundingClientRect() : links[i].getBoundingClientRect();
|
|
6847
|
-
slots.push({
|
|
6848
|
-
insertIndex: i,
|
|
6849
|
-
columnIndex,
|
|
6850
|
-
left: widthRef.left,
|
|
6851
|
-
top,
|
|
6852
|
-
width: Math.max(widthRef.width, colRect.width * 0.8),
|
|
6853
|
-
height: barThickness,
|
|
6854
|
-
direction: "horizontal"
|
|
6855
|
-
});
|
|
6856
|
-
}
|
|
6857
|
-
return slots;
|
|
6858
|
-
}
|
|
6859
|
-
function buildColumnDropSlots() {
|
|
6860
|
-
const columns = listFooterColumns();
|
|
6861
|
-
const slots = [];
|
|
6862
|
-
const barThickness = 3;
|
|
6863
|
-
if (columns.length === 0) return slots;
|
|
6864
|
-
for (let i = 0; i <= columns.length; i++) {
|
|
6865
|
-
let left;
|
|
6866
|
-
let height;
|
|
6867
|
-
let top;
|
|
6868
|
-
if (i === 0) {
|
|
6869
|
-
const first = columns[0].getBoundingClientRect();
|
|
6870
|
-
left = first.left - barThickness / 2;
|
|
6871
|
-
top = first.top;
|
|
6872
|
-
height = first.height;
|
|
6873
|
-
} else if (i === columns.length) {
|
|
6874
|
-
const last = columns[columns.length - 1].getBoundingClientRect();
|
|
6875
|
-
left = last.right - barThickness / 2;
|
|
6876
|
-
top = last.top;
|
|
6877
|
-
height = last.height;
|
|
6878
|
-
} else {
|
|
6879
|
-
const prev = columns[i - 1].getBoundingClientRect();
|
|
6880
|
-
const next = columns[i].getBoundingClientRect();
|
|
6881
|
-
left = (prev.right + next.left) / 2 - barThickness / 2;
|
|
6882
|
-
top = Math.min(prev.top, next.top);
|
|
6883
|
-
height = Math.max(prev.bottom, next.bottom) - top;
|
|
6884
|
-
}
|
|
6885
|
-
slots.push({
|
|
6886
|
-
insertIndex: i,
|
|
6887
|
-
columnIndex: i,
|
|
6888
|
-
left,
|
|
6889
|
-
top,
|
|
6890
|
-
width: barThickness,
|
|
6891
|
-
height: Math.max(height, 24),
|
|
6892
|
-
direction: "vertical"
|
|
6893
|
-
});
|
|
6894
|
-
}
|
|
6895
|
-
return slots;
|
|
6896
|
-
}
|
|
6897
|
-
function hitTestLinkDropSlot(clientX, clientY, draggedHrefKey) {
|
|
6898
|
-
const columns = listFooterColumns();
|
|
6899
|
-
let best = null;
|
|
6900
|
-
for (let c = 0; c < columns.length; c++) {
|
|
6901
|
-
const col = columns[c];
|
|
6902
|
-
const colRect = col.getBoundingClientRect();
|
|
6903
|
-
const inColX = clientX >= colRect.left - 24 && clientX <= colRect.right + 24;
|
|
6904
|
-
if (!inColX) continue;
|
|
6905
|
-
const slots = buildLinkDropSlots(col, c).filter((slot) => {
|
|
6906
|
-
const links = listFooterLinksInColumn(col);
|
|
6907
|
-
const fromIdx = links.findIndex(
|
|
6908
|
-
(el) => el.getAttribute("data-ohw-href-key") === draggedHrefKey
|
|
6909
|
-
);
|
|
6910
|
-
if (fromIdx < 0) return true;
|
|
6911
|
-
if (c === findColumnIndexForKey(draggedHrefKey) && (slot.insertIndex === fromIdx || slot.insertIndex === fromIdx + 1)) {
|
|
6912
|
-
return true;
|
|
6913
|
-
}
|
|
6914
|
-
return true;
|
|
6915
|
-
});
|
|
6916
|
-
for (const slot of slots) {
|
|
6917
|
-
const cy = slot.top + slot.height / 2;
|
|
6918
|
-
const dist = Math.abs(clientY - cy) + (inColX ? 0 : 1e3);
|
|
6919
|
-
if (!best || dist < best.dist) best = { slot, dist };
|
|
6920
|
-
}
|
|
6921
|
-
}
|
|
6922
|
-
return best?.slot ?? null;
|
|
6923
|
-
}
|
|
6924
|
-
function findColumnIndexForKey(hrefKey) {
|
|
6925
|
-
const order = getFooterOrderFromDom();
|
|
6926
|
-
for (let c = 0; c < order.length; c++) {
|
|
6927
|
-
if (order[c].includes(hrefKey)) return c;
|
|
6928
|
-
}
|
|
6929
|
-
return -1;
|
|
6930
|
-
}
|
|
6931
|
-
function hitTestColumnDropSlot(clientX, _clientY) {
|
|
6932
|
-
const slots = buildColumnDropSlots();
|
|
6933
|
-
let best = null;
|
|
6934
|
-
for (const slot of slots) {
|
|
6935
|
-
const cx2 = slot.left + slot.width / 2;
|
|
6936
|
-
const dist = Math.abs(clientX - cx2);
|
|
6937
|
-
if (!best || dist < best.dist) best = { slot, dist };
|
|
6938
|
-
}
|
|
6939
|
-
return best?.slot ?? null;
|
|
6940
|
-
}
|
|
6941
|
-
|
|
6942
|
-
// src/lib/carousel.ts
|
|
6943
|
-
var import_react8 = require("react");
|
|
6944
|
-
var CAROUSEL_ATTR = "data-ohw-carousel";
|
|
6945
|
-
var CAROUSEL_VALUE_ATTR = "data-ohw-carousel-value";
|
|
6946
|
-
var CAROUSEL_SLIDE_ATTR = "data-ohw-carousel-slide";
|
|
6947
|
-
var CAROUSEL_EVENT = "ohw:carousel-change";
|
|
6948
|
-
function listCarouselKeys() {
|
|
6949
|
-
const keys = /* @__PURE__ */ new Set();
|
|
6950
|
-
document.querySelectorAll(`[${CAROUSEL_ATTR}]`).forEach((el) => {
|
|
6951
|
-
const key = el.getAttribute("data-ohw-key");
|
|
6952
|
-
if (key) keys.add(key);
|
|
6953
|
-
});
|
|
6954
|
-
return [...keys];
|
|
6955
|
-
}
|
|
6956
|
-
function containersForKey(key) {
|
|
6957
|
-
return Array.from(
|
|
6958
|
-
document.querySelectorAll(`[${CAROUSEL_ATTR}][data-ohw-key="${CSS.escape(key)}"]`)
|
|
6959
|
-
);
|
|
6960
|
-
}
|
|
6961
|
-
function isCarouselKey(key) {
|
|
6962
|
-
return containersForKey(key).length > 0;
|
|
6963
|
-
}
|
|
6964
|
-
function parseSlides(raw) {
|
|
6965
|
-
if (!raw) return [];
|
|
6966
|
-
try {
|
|
6967
|
-
const parsed = JSON.parse(raw);
|
|
6968
|
-
if (!Array.isArray(parsed)) return [];
|
|
6969
|
-
return parsed.filter((s) => Boolean(s) && typeof s === "object").map((s) => ({ src: String(s.src ?? ""), alt: String(s.alt ?? "") }));
|
|
6970
|
-
} catch {
|
|
6971
|
-
return [];
|
|
6972
|
-
}
|
|
6973
|
-
}
|
|
6974
|
-
function readCarouselValue(key) {
|
|
6975
|
-
const container = containersForKey(key)[0];
|
|
6976
|
-
if (!container) return [];
|
|
6977
|
-
const fromAttr = parseSlides(container.getAttribute(CAROUSEL_VALUE_ATTR));
|
|
6978
|
-
if (fromAttr.length > 0) return fromAttr;
|
|
6979
|
-
return Array.from(container.querySelectorAll(`[${CAROUSEL_SLIDE_ATTR}]`)).filter((slide) => slide.closest(`[${CAROUSEL_ATTR}]`) === container).sort((a, b) => slideIndex(a) - slideIndex(b)).map((slide) => {
|
|
6980
|
-
const img = slide instanceof HTMLImageElement ? slide : slide.querySelector("img");
|
|
6981
|
-
return { src: img?.src ?? "", alt: img?.alt ?? "" };
|
|
6982
|
-
});
|
|
6983
|
-
}
|
|
6984
|
-
function slideIndex(el) {
|
|
6985
|
-
const raw = el.getAttribute(CAROUSEL_SLIDE_ATTR);
|
|
6986
|
-
const n = raw ? parseInt(raw, 10) : NaN;
|
|
6987
|
-
return Number.isFinite(n) ? n : 0;
|
|
6988
|
-
}
|
|
6989
|
-
function applyCarouselValue(key, slides) {
|
|
6990
|
-
const value = JSON.stringify(slides);
|
|
6991
|
-
for (const container of containersForKey(key)) {
|
|
6992
|
-
if (container.getAttribute(CAROUSEL_VALUE_ATTR) === value) continue;
|
|
6993
|
-
container.setAttribute(CAROUSEL_VALUE_ATTR, value);
|
|
6994
|
-
container.dispatchEvent(
|
|
6995
|
-
new CustomEvent(CAROUSEL_EVENT, { detail: { images: slides } })
|
|
6996
|
-
);
|
|
6997
|
-
}
|
|
6998
|
-
}
|
|
6999
|
-
function applyCarouselNode(key, val) {
|
|
7000
|
-
if (!isCarouselKey(key)) return false;
|
|
7001
|
-
applyCarouselValue(key, parseSlides(val));
|
|
7002
|
-
return true;
|
|
7003
|
-
}
|
|
7004
|
-
function useOhwCarousel(key, initial) {
|
|
7005
|
-
const [images, setImages] = (0, import_react8.useState)(initial);
|
|
7006
|
-
(0, import_react8.useEffect)(() => {
|
|
7007
|
-
const el = document.querySelector(
|
|
7008
|
-
`[${CAROUSEL_ATTR}][data-ohw-key="${CSS.escape(key)}"]`
|
|
7009
|
-
);
|
|
7010
|
-
if (!el) return;
|
|
7011
|
-
const onChange = (e) => {
|
|
7012
|
-
const detail = e.detail;
|
|
7013
|
-
if (Array.isArray(detail?.images)) setImages(detail.images);
|
|
7014
|
-
};
|
|
7015
|
-
el.addEventListener(CAROUSEL_EVENT, onChange);
|
|
7016
|
-
return () => el.removeEventListener(CAROUSEL_EVENT, onChange);
|
|
7017
|
-
}, [key]);
|
|
7018
|
-
const bind = {
|
|
7019
|
-
[CAROUSEL_ATTR]: "",
|
|
7020
|
-
"data-ohw-key": key,
|
|
7021
|
-
[CAROUSEL_VALUE_ATTR]: JSON.stringify(images)
|
|
7022
|
-
};
|
|
7023
|
-
return { images, setImages, bind };
|
|
7024
|
-
}
|
|
7025
|
-
|
|
7026
|
-
// src/ui/navbar-container-chrome.tsx
|
|
7027
|
-
var import_lucide_react11 = require("lucide-react");
|
|
7028
|
-
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
7029
|
-
function NavbarContainerChrome({
|
|
7030
|
-
rect,
|
|
7031
|
-
onAdd
|
|
7032
|
-
}) {
|
|
7033
|
-
const chromeGap = 6;
|
|
7034
|
-
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
7035
|
-
"div",
|
|
7036
|
-
{
|
|
7037
|
-
"data-ohw-navbar-container-chrome": "",
|
|
7038
|
-
"data-ohw-bridge": "",
|
|
7039
|
-
className: "pointer-events-none fixed z-[2147483647]",
|
|
7040
|
-
style: {
|
|
7041
|
-
top: rect.top - chromeGap,
|
|
7042
|
-
left: rect.left - chromeGap,
|
|
7043
|
-
width: rect.width + chromeGap * 2,
|
|
7044
|
-
height: rect.height + chromeGap * 2
|
|
7045
|
-
},
|
|
7046
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
7047
|
-
"button",
|
|
7048
|
-
{
|
|
7049
|
-
type: "button",
|
|
7050
|
-
"data-ohw-navbar-add-button": "",
|
|
7051
|
-
className: "pointer-events-auto absolute left-1/2 flex p-0.5 rounded-[10px] size-7 -translate-x-1/2 translate-y-1/2 items-center justify-center border border-border bg-background shadow-sm transition-colors hover:bg-muted/80",
|
|
7052
|
-
style: { top: "70%" },
|
|
7053
|
-
"aria-label": "Add item",
|
|
7054
|
-
onMouseDown: (e) => {
|
|
7055
|
-
e.preventDefault();
|
|
7056
|
-
e.stopPropagation();
|
|
7057
|
-
},
|
|
7058
|
-
onClick: (e) => {
|
|
7059
|
-
e.preventDefault();
|
|
7060
|
-
e.stopPropagation();
|
|
7061
|
-
onAdd();
|
|
7062
|
-
},
|
|
7063
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react11.Plus, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
|
|
7064
|
-
}
|
|
7065
|
-
)
|
|
7066
|
-
}
|
|
7067
|
-
);
|
|
5747
|
+
{ id: "manifesto", label: "Manifesto" },
|
|
5748
|
+
{ id: "story-letter", label: "Our Story" },
|
|
5749
|
+
{ id: "lagree-explainer", label: "Lagree Explainer" },
|
|
5750
|
+
{ id: "waitlist-cta", label: "Waitlist" },
|
|
5751
|
+
{ id: "personal-training", label: "Personal training" }
|
|
5752
|
+
],
|
|
5753
|
+
"/classes": [{ id: "class-library", label: "Class Library" }],
|
|
5754
|
+
"/pricing": [
|
|
5755
|
+
{ id: "page-header", label: "Page Header" },
|
|
5756
|
+
{ id: "free-class-cta", label: "Free Class" },
|
|
5757
|
+
{ id: "benefits-marquee", label: "Benefits" },
|
|
5758
|
+
{ id: "monthly-memberships", label: "Memberships" },
|
|
5759
|
+
{ id: "specialty-programs", label: "Specialty Programs" },
|
|
5760
|
+
{ id: "package-matcher", label: "Packages" },
|
|
5761
|
+
{ id: "wordmark", label: "Wordmark" }
|
|
5762
|
+
],
|
|
5763
|
+
"/studio": [
|
|
5764
|
+
{ id: "studio-intro", label: "Studio Intro" },
|
|
5765
|
+
{ id: "studio-features", label: "Studio Features" },
|
|
5766
|
+
{ id: "studio-gallery", label: "Studio Gallery" },
|
|
5767
|
+
{ id: "studio-visit", label: "Visit Studio" }
|
|
5768
|
+
],
|
|
5769
|
+
"/instructors": [{ id: "instructor-grid", label: "Instructors" }],
|
|
5770
|
+
"/contact": [
|
|
5771
|
+
{ id: "hello-hero", label: "Hello" },
|
|
5772
|
+
{ id: "contact-form", label: "Contact Form" },
|
|
5773
|
+
{ id: "faq", label: "FAQ" }
|
|
5774
|
+
]
|
|
5775
|
+
};
|
|
5776
|
+
function shouldUseDevFixtures() {
|
|
5777
|
+
if (typeof window === "undefined") return false;
|
|
5778
|
+
const raw = readPreservedSearch();
|
|
5779
|
+
const q = raw.startsWith("?") ? raw.slice(1) : raw;
|
|
5780
|
+
return new URLSearchParams(q).get("ohw-fixtures") === "1";
|
|
7068
5781
|
}
|
|
7069
5782
|
|
|
7070
|
-
// src/ui/drop-indicator.tsx
|
|
7071
|
-
var React9 = __toESM(require("react"), 1);
|
|
7072
|
-
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
7073
|
-
var dropIndicatorVariants = cva(
|
|
7074
|
-
"ov-gap-line pointer-events-none shrink-0 transition-opacity duration-150",
|
|
7075
|
-
{
|
|
7076
|
-
variants: {
|
|
7077
|
-
direction: {
|
|
7078
|
-
vertical: "h-6 w-[3px]",
|
|
7079
|
-
horizontal: "h-[3px] w-[200px]"
|
|
7080
|
-
},
|
|
7081
|
-
state: {
|
|
7082
|
-
default: "opacity-0",
|
|
7083
|
-
hover: "opacity-100",
|
|
7084
|
-
dragIdle: "opacity-40",
|
|
7085
|
-
dragActive: "opacity-100"
|
|
7086
|
-
}
|
|
7087
|
-
},
|
|
7088
|
-
defaultVariants: {
|
|
7089
|
-
direction: "vertical",
|
|
7090
|
-
state: "default"
|
|
7091
|
-
}
|
|
7092
|
-
}
|
|
7093
|
-
);
|
|
7094
|
-
var DropIndicator = React9.forwardRef(
|
|
7095
|
-
({ className, direction, state, ...props }, ref) => {
|
|
7096
|
-
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
7097
|
-
"div",
|
|
7098
|
-
{
|
|
7099
|
-
ref,
|
|
7100
|
-
"data-slot": "drop-indicator",
|
|
7101
|
-
"data-direction": direction ?? "vertical",
|
|
7102
|
-
"data-state": state ?? "default",
|
|
7103
|
-
"aria-hidden": "true",
|
|
7104
|
-
className: cn(dropIndicatorVariants({ direction, state }), className),
|
|
7105
|
-
...props
|
|
7106
|
-
}
|
|
7107
|
-
);
|
|
7108
|
-
}
|
|
7109
|
-
);
|
|
7110
|
-
DropIndicator.displayName = "DropIndicator";
|
|
7111
|
-
|
|
7112
5783
|
// src/ui/badge.tsx
|
|
7113
|
-
var
|
|
5784
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
7114
5785
|
var badgeVariants = cva(
|
|
7115
5786
|
"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",
|
|
7116
5787
|
{
|
|
@@ -7128,12 +5799,12 @@ var badgeVariants = cva(
|
|
|
7128
5799
|
}
|
|
7129
5800
|
);
|
|
7130
5801
|
function Badge({ className, variant, ...props }) {
|
|
7131
|
-
return /* @__PURE__ */ (0,
|
|
5802
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: cn(badgeVariants({ variant }), className), ...props });
|
|
7132
5803
|
}
|
|
7133
5804
|
|
|
7134
5805
|
// src/OhhwellsBridge.tsx
|
|
7135
|
-
var
|
|
7136
|
-
var
|
|
5806
|
+
var import_lucide_react4 = require("lucide-react");
|
|
5807
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
7137
5808
|
var PRIMARY2 = "#0885FE";
|
|
7138
5809
|
var IMAGE_FADE_MS = 300;
|
|
7139
5810
|
function runOpacityFade(el, onDone) {
|
|
@@ -7310,9 +5981,9 @@ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId,
|
|
|
7310
5981
|
tail.insertAdjacentElement("afterend", container);
|
|
7311
5982
|
}
|
|
7312
5983
|
const root = (0, import_client.createRoot)(container);
|
|
7313
|
-
(0,
|
|
5984
|
+
(0, import_react_dom.flushSync)(() => {
|
|
7314
5985
|
root.render(
|
|
7315
|
-
/* @__PURE__ */ (0,
|
|
5986
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
7316
5987
|
SchedulingWidget,
|
|
7317
5988
|
{
|
|
7318
5989
|
notifyOnConnect,
|
|
@@ -7352,7 +6023,7 @@ function mountSchedulingEntries(entries, notifyOnConnect = false) {
|
|
|
7352
6023
|
}
|
|
7353
6024
|
}
|
|
7354
6025
|
}
|
|
7355
|
-
function
|
|
6026
|
+
function getLinkHref(el) {
|
|
7356
6027
|
const anchor = el instanceof HTMLAnchorElement ? el : el.querySelector("a");
|
|
7357
6028
|
return anchor?.getAttribute("href") ?? "";
|
|
7358
6029
|
}
|
|
@@ -7374,7 +6045,7 @@ function isDragHandleDisabled(el) {
|
|
|
7374
6045
|
return raw === "true" || raw === "";
|
|
7375
6046
|
});
|
|
7376
6047
|
}
|
|
7377
|
-
function collectEditableNodes(
|
|
6048
|
+
function collectEditableNodes() {
|
|
7378
6049
|
const nodes = Array.from(document.querySelectorAll("[data-ohw-editable]")).map((el) => {
|
|
7379
6050
|
if (el.dataset.ohwEditable === "image") {
|
|
7380
6051
|
const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
|
|
@@ -7389,7 +6060,7 @@ function collectEditableNodes(extraContent) {
|
|
|
7389
6060
|
return { key: el.dataset.ohwKey ?? "", type: "video", text: getVideoEl(el)?.src ?? "" };
|
|
7390
6061
|
}
|
|
7391
6062
|
if (el.dataset.ohwEditable === "link") {
|
|
7392
|
-
return { key: el.dataset.ohwKey ?? "", type: "link", text:
|
|
6063
|
+
return { key: el.dataset.ohwKey ?? "", type: "link", text: getLinkHref(el) };
|
|
7393
6064
|
}
|
|
7394
6065
|
return {
|
|
7395
6066
|
key: el.dataset.ohwKey ?? "",
|
|
@@ -7400,16 +6071,8 @@ function collectEditableNodes(extraContent) {
|
|
|
7400
6071
|
document.querySelectorAll("[data-ohw-href-key]").forEach((el) => {
|
|
7401
6072
|
const key = el.getAttribute("data-ohw-href-key") ?? "";
|
|
7402
6073
|
if (!key) return;
|
|
7403
|
-
nodes.push({ key, type: "link", text:
|
|
6074
|
+
nodes.push({ key, type: "link", text: getLinkHref(el) });
|
|
7404
6075
|
});
|
|
7405
|
-
if (extraContent) {
|
|
7406
|
-
for (const key of [NAV_ORDER_KEY, FOOTER_ORDER_KEY, NAV_COUNT_KEY]) {
|
|
7407
|
-
const text = extraContent[key];
|
|
7408
|
-
if (typeof text === "string" && text.length > 0) {
|
|
7409
|
-
nodes.push({ key, type: "meta", text });
|
|
7410
|
-
}
|
|
7411
|
-
}
|
|
7412
|
-
}
|
|
7413
6076
|
document.querySelectorAll('[data-ohw-editable="video"]').forEach((el) => {
|
|
7414
6077
|
const key = el.dataset.ohwKey ?? "";
|
|
7415
6078
|
const video = getVideoEl(el);
|
|
@@ -7417,9 +6080,6 @@ function collectEditableNodes(extraContent) {
|
|
|
7417
6080
|
nodes.push({ key: `${key}${VIDEO_AUTOPLAY_SUFFIX}`, type: "video-setting", text: String(video.autoplay) });
|
|
7418
6081
|
nodes.push({ key: `${key}${VIDEO_MUTED_SUFFIX}`, type: "video-setting", text: String(video.muted) });
|
|
7419
6082
|
});
|
|
7420
|
-
for (const key of listCarouselKeys()) {
|
|
7421
|
-
nodes.push({ key, type: "carousel", text: JSON.stringify(readCarouselValue(key)) });
|
|
7422
|
-
}
|
|
7423
6083
|
return nodes;
|
|
7424
6084
|
}
|
|
7425
6085
|
function isMediaEditable(el) {
|
|
@@ -7497,7 +6157,7 @@ function applyLinkByKey(key, val) {
|
|
|
7497
6157
|
}
|
|
7498
6158
|
function isInsideLinkEditor(target) {
|
|
7499
6159
|
return Boolean(
|
|
7500
|
-
target.closest("[data-ohw-link-popover-root]") || target.closest("[data-ohw-link-modal-root]") || target.closest("[data-ohw-link-page-dropdown]") || target.closest(
|
|
6160
|
+
target.closest("[data-ohw-link-popover-root]") || target.closest("[data-ohw-link-modal-root]") || target.closest("[data-ohw-link-page-dropdown]") || target.closest('[data-slot="popover-content"]') || target.closest('[data-slot="dialog-content"]') || target.closest('[data-slot="dialog-overlay"]')
|
|
7501
6161
|
);
|
|
7502
6162
|
}
|
|
7503
6163
|
function getHrefKeyFromElement(el) {
|
|
@@ -7508,30 +6168,7 @@ function getHrefKeyFromElement(el) {
|
|
|
7508
6168
|
if (!key) return null;
|
|
7509
6169
|
return { anchor, key };
|
|
7510
6170
|
}
|
|
7511
|
-
function
|
|
7512
|
-
if (el.draggable) el.draggable = false;
|
|
7513
|
-
if (el.getAttribute("draggable") !== "false") {
|
|
7514
|
-
el.setAttribute("draggable", "false");
|
|
7515
|
-
}
|
|
7516
|
-
}
|
|
7517
|
-
function clearTextSelection() {
|
|
7518
|
-
const sel = window.getSelection();
|
|
7519
|
-
if (sel && !sel.isCollapsed) sel.removeAllRanges();
|
|
7520
|
-
}
|
|
7521
|
-
function armFooterPressDrag() {
|
|
7522
|
-
document.documentElement.setAttribute("data-ohw-footer-press-drag", "");
|
|
7523
|
-
}
|
|
7524
|
-
function lockFooterDuringDrag() {
|
|
7525
|
-
document.documentElement.removeAttribute("data-ohw-footer-press-drag");
|
|
7526
|
-
document.documentElement.setAttribute("data-ohw-item-dragging", "");
|
|
7527
|
-
clearTextSelection();
|
|
7528
|
-
}
|
|
7529
|
-
function unlockFooterDragInteraction() {
|
|
7530
|
-
document.documentElement.removeAttribute("data-ohw-footer-press-drag");
|
|
7531
|
-
document.documentElement.removeAttribute("data-ohw-item-dragging");
|
|
7532
|
-
clearTextSelection();
|
|
7533
|
-
}
|
|
7534
|
-
function isNavbarButton2(el) {
|
|
6171
|
+
function isNavbarButton(el) {
|
|
7535
6172
|
return Boolean(el.closest('[data-ohw-role="navbar-button"]'));
|
|
7536
6173
|
}
|
|
7537
6174
|
function getNavigationItemAnchor(el) {
|
|
@@ -7543,8 +6180,19 @@ function getNavigationItemAnchor(el) {
|
|
|
7543
6180
|
function isNavigationItem(el) {
|
|
7544
6181
|
return getNavigationItemAnchor(el) !== null;
|
|
7545
6182
|
}
|
|
6183
|
+
function getNavigationItemAddHintTarget(anchor) {
|
|
6184
|
+
const items = listNavigationItems();
|
|
6185
|
+
const idx = items.indexOf(anchor);
|
|
6186
|
+
if (idx >= 0 && idx < items.length - 1) return items[idx + 1];
|
|
6187
|
+
return anchor;
|
|
6188
|
+
}
|
|
6189
|
+
function listNavigationItems() {
|
|
6190
|
+
return Array.from(
|
|
6191
|
+
document.querySelectorAll("nav [data-ohw-href-key], footer [data-ohw-href-key]")
|
|
6192
|
+
).filter((el) => isNavigationItem(el));
|
|
6193
|
+
}
|
|
7546
6194
|
function getNavigationItemReorderState(anchor) {
|
|
7547
|
-
if (
|
|
6195
|
+
if (isNavbarButton(anchor)) return { key: null, disabled: false };
|
|
7548
6196
|
return getReorderHandleStateFromAnchor(anchor);
|
|
7549
6197
|
}
|
|
7550
6198
|
function getReorderHandleState(el) {
|
|
@@ -7566,120 +6214,6 @@ function clearHrefKeyHover(anchor) {
|
|
|
7566
6214
|
function isInsideNavigationItem(el) {
|
|
7567
6215
|
return getNavigationItemAnchor(el) !== null;
|
|
7568
6216
|
}
|
|
7569
|
-
function getNavigationRoot(el) {
|
|
7570
|
-
const explicit = el.closest("[data-ohw-nav-root]");
|
|
7571
|
-
if (explicit) return explicit;
|
|
7572
|
-
return el.closest("nav, footer, aside");
|
|
7573
|
-
}
|
|
7574
|
-
function findFooterItemGroup(item) {
|
|
7575
|
-
const footer = item.closest("footer");
|
|
7576
|
-
if (!footer) return null;
|
|
7577
|
-
let node = item.parentElement;
|
|
7578
|
-
while (node && node !== footer) {
|
|
7579
|
-
const hasDirectNavItems = Array.from(
|
|
7580
|
-
node.querySelectorAll(":scope > [data-ohw-href-key]")
|
|
7581
|
-
).some(isNavigationItem);
|
|
7582
|
-
if (hasDirectNavItems) return node;
|
|
7583
|
-
node = node.parentElement;
|
|
7584
|
-
}
|
|
7585
|
-
return null;
|
|
7586
|
-
}
|
|
7587
|
-
function isNavigationRoot(el) {
|
|
7588
|
-
return el.hasAttribute("data-ohw-nav-root") || el.matches("nav, footer, aside");
|
|
7589
|
-
}
|
|
7590
|
-
function isInferredFooterGroup(el) {
|
|
7591
|
-
const footer = el.closest("footer");
|
|
7592
|
-
if (!footer || el === footer) return false;
|
|
7593
|
-
return Array.from(el.querySelectorAll(":scope > [data-ohw-href-key]")).some(isNavigationItem);
|
|
7594
|
-
}
|
|
7595
|
-
function isNavigationContainer(el) {
|
|
7596
|
-
return el.hasAttribute("data-ohw-nav-container") || isNavigationRoot(el) || isInferredFooterGroup(el);
|
|
7597
|
-
}
|
|
7598
|
-
function isPointOverNavigation(x, y) {
|
|
7599
|
-
const navRoot = document.querySelector("[data-ohw-nav-root]") ?? document.querySelector("nav");
|
|
7600
|
-
if (!navRoot) return false;
|
|
7601
|
-
const r2 = navRoot.getBoundingClientRect();
|
|
7602
|
-
return x >= r2.left && x <= r2.right && y >= r2.top && y <= r2.bottom;
|
|
7603
|
-
}
|
|
7604
|
-
function isPointOverNavItem(container, x, y) {
|
|
7605
|
-
return Array.from(container.querySelectorAll("[data-ohw-href-key]")).some((el) => {
|
|
7606
|
-
if (!isNavigationItem(el) || isNavbarButton2(el)) return false;
|
|
7607
|
-
const itemRect = el.getBoundingClientRect();
|
|
7608
|
-
return x >= itemRect.left && x <= itemRect.right && y >= itemRect.top && y <= itemRect.bottom;
|
|
7609
|
-
});
|
|
7610
|
-
}
|
|
7611
|
-
function resolveNavContainerSelectionTarget(target, clientX, clientY) {
|
|
7612
|
-
if (getNavigationItemAnchor(target)) return null;
|
|
7613
|
-
if (target.closest('[data-ohw-role="navbar-button"]')) return null;
|
|
7614
|
-
const plainLink = target.closest("a");
|
|
7615
|
-
if (plainLink && !plainLink.hasAttribute("data-ohw-href-key") && !plainLink.closest("[data-ohw-nav-container]")) {
|
|
7616
|
-
return null;
|
|
7617
|
-
}
|
|
7618
|
-
const fromClosest = target.closest("[data-ohw-nav-container]");
|
|
7619
|
-
if (fromClosest && !isPointOverNavItem(fromClosest, clientX, clientY)) {
|
|
7620
|
-
return fromClosest;
|
|
7621
|
-
}
|
|
7622
|
-
const navRoot = target.closest("[data-ohw-nav-root]");
|
|
7623
|
-
if (!navRoot) return null;
|
|
7624
|
-
const container = navRoot.querySelector("[data-ohw-nav-container]");
|
|
7625
|
-
if (!container || isPointOverNavItem(container, clientX, clientY)) return null;
|
|
7626
|
-
if (target === navRoot || target.hasAttribute("data-ohw-nav-root")) {
|
|
7627
|
-
return container;
|
|
7628
|
-
}
|
|
7629
|
-
return null;
|
|
7630
|
-
}
|
|
7631
|
-
function getNavigationSelectionParent(el) {
|
|
7632
|
-
if (isNavigationItem(el)) {
|
|
7633
|
-
const explicit = el.closest("[data-ohw-nav-container]");
|
|
7634
|
-
if (explicit) return explicit;
|
|
7635
|
-
const footerGroup = findFooterItemGroup(el);
|
|
7636
|
-
if (footerGroup) return footerGroup;
|
|
7637
|
-
return getNavigationRoot(el);
|
|
7638
|
-
}
|
|
7639
|
-
if (el.hasAttribute("data-ohw-nav-container") || isInferredFooterGroup(el)) {
|
|
7640
|
-
return getNavigationRoot(el);
|
|
7641
|
-
}
|
|
7642
|
-
return null;
|
|
7643
|
-
}
|
|
7644
|
-
function placeCaretAtPoint(el, x, y) {
|
|
7645
|
-
const selection = window.getSelection();
|
|
7646
|
-
if (!selection) return;
|
|
7647
|
-
if (typeof document.caretRangeFromPoint === "function") {
|
|
7648
|
-
const range = document.caretRangeFromPoint(x, y);
|
|
7649
|
-
if (range && el.contains(range.startContainer)) {
|
|
7650
|
-
selection.removeAllRanges();
|
|
7651
|
-
selection.addRange(range);
|
|
7652
|
-
return;
|
|
7653
|
-
}
|
|
7654
|
-
}
|
|
7655
|
-
const caretPositionFromPoint = document.caretPositionFromPoint;
|
|
7656
|
-
if (typeof caretPositionFromPoint === "function") {
|
|
7657
|
-
const position = caretPositionFromPoint(x, y);
|
|
7658
|
-
if (position && el.contains(position.offsetNode)) {
|
|
7659
|
-
const range = document.createRange();
|
|
7660
|
-
range.setStart(position.offsetNode, position.offset);
|
|
7661
|
-
range.collapse(true);
|
|
7662
|
-
selection.removeAllRanges();
|
|
7663
|
-
selection.addRange(range);
|
|
7664
|
-
}
|
|
7665
|
-
}
|
|
7666
|
-
}
|
|
7667
|
-
function selectAllTextInEditable(el) {
|
|
7668
|
-
const selection = window.getSelection();
|
|
7669
|
-
if (!selection) return;
|
|
7670
|
-
const range = document.createRange();
|
|
7671
|
-
range.selectNodeContents(el);
|
|
7672
|
-
selection.removeAllRanges();
|
|
7673
|
-
selection.addRange(range);
|
|
7674
|
-
}
|
|
7675
|
-
function getNavigationLabelEditable(target) {
|
|
7676
|
-
const editable = target.closest('[data-ohw-editable="text"]');
|
|
7677
|
-
if (!editable) return null;
|
|
7678
|
-
const hrefCtx = getHrefKeyFromElement(editable);
|
|
7679
|
-
const navAnchor = hrefCtx ? getNavigationItemAnchor(hrefCtx.anchor) : null;
|
|
7680
|
-
if (!navAnchor) return null;
|
|
7681
|
-
return { editable, navAnchor };
|
|
7682
|
-
}
|
|
7683
6217
|
function collectSections() {
|
|
7684
6218
|
return collectSectionsFromDom();
|
|
7685
6219
|
}
|
|
@@ -7803,8 +6337,6 @@ var ICONS = {
|
|
|
7803
6337
|
insertUnorderedList: '<line x1="8" y1="6" x2="21" y2="6"/><line x1="8" y1="12" x2="21" y2="12"/><line x1="8" y1="18" x2="21" y2="18"/><line x1="3" y1="6" x2="3.01" y2="6"/><line x1="3" y1="12" x2="3.01" y2="12"/><line x1="3" y1="18" x2="3.01" y2="18"/>',
|
|
7804
6338
|
insertOrderedList: '<line x1="10" y1="6" x2="21" y2="6"/><line x1="10" y1="12" x2="21" y2="12"/><line x1="10" y1="18" x2="21" y2="18"/><path d="M4 6h1v4"/><path d="M4 10h2"/><path d="M6 18H4c0-1 2-2 2-3s-1-1.5-2-1"/>'
|
|
7805
6339
|
};
|
|
7806
|
-
var TOOLBAR_PILL_PADDING = 2;
|
|
7807
|
-
var TOOLBAR_TOGGLE_GAP = 4;
|
|
7808
6340
|
var TOOLBAR_GROUPS = [
|
|
7809
6341
|
[
|
|
7810
6342
|
{ cmd: "bold", title: "Bold" },
|
|
@@ -7829,7 +6361,7 @@ function EditGlowChrome({
|
|
|
7829
6361
|
dragDisabled = false
|
|
7830
6362
|
}) {
|
|
7831
6363
|
const GAP = 6;
|
|
7832
|
-
return /* @__PURE__ */ (0,
|
|
6364
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
7833
6365
|
"div",
|
|
7834
6366
|
{
|
|
7835
6367
|
ref: elRef,
|
|
@@ -7844,7 +6376,7 @@ function EditGlowChrome({
|
|
|
7844
6376
|
zIndex: 2147483646
|
|
7845
6377
|
},
|
|
7846
6378
|
children: [
|
|
7847
|
-
/* @__PURE__ */ (0,
|
|
6379
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
7848
6380
|
"div",
|
|
7849
6381
|
{
|
|
7850
6382
|
style: {
|
|
@@ -7857,7 +6389,7 @@ function EditGlowChrome({
|
|
|
7857
6389
|
}
|
|
7858
6390
|
}
|
|
7859
6391
|
),
|
|
7860
|
-
reorderHrefKey && /* @__PURE__ */ (0,
|
|
6392
|
+
reorderHrefKey && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
7861
6393
|
"div",
|
|
7862
6394
|
{
|
|
7863
6395
|
"data-ohw-drag-handle-container": "",
|
|
@@ -7869,7 +6401,7 @@ function EditGlowChrome({
|
|
|
7869
6401
|
transform: "translate(calc(-100% - 7px), -50%)",
|
|
7870
6402
|
pointerEvents: dragDisabled ? "none" : "auto"
|
|
7871
6403
|
},
|
|
7872
|
-
children: /* @__PURE__ */ (0,
|
|
6404
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
7873
6405
|
DragHandle,
|
|
7874
6406
|
{
|
|
7875
6407
|
"aria-label": `Reorder ${reorderHrefKey}`,
|
|
@@ -7973,7 +6505,7 @@ function FloatingToolbar({
|
|
|
7973
6505
|
onEditLink
|
|
7974
6506
|
}) {
|
|
7975
6507
|
const { top, left, transform } = calcToolbarPos(rect, parentScroll, 330);
|
|
7976
|
-
return /* @__PURE__ */ (0,
|
|
6508
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
7977
6509
|
"div",
|
|
7978
6510
|
{
|
|
7979
6511
|
ref: elRef,
|
|
@@ -7983,23 +6515,14 @@ function FloatingToolbar({
|
|
|
7983
6515
|
left,
|
|
7984
6516
|
transform,
|
|
7985
6517
|
zIndex: 2147483647,
|
|
7986
|
-
background: "#fff",
|
|
7987
|
-
border: "1px solid #E7E5E4",
|
|
7988
|
-
borderRadius: 6,
|
|
7989
|
-
boxShadow: "0px 2px 4px -2px rgba(0,0,0,.1),0px 4px 6px -1px rgba(0,0,0,.1)",
|
|
7990
|
-
display: "flex",
|
|
7991
|
-
alignItems: "center",
|
|
7992
|
-
padding: TOOLBAR_PILL_PADDING,
|
|
7993
|
-
gap: TOOLBAR_TOGGLE_GAP,
|
|
7994
|
-
fontFamily: "sans-serif",
|
|
7995
6518
|
pointerEvents: "auto"
|
|
7996
6519
|
},
|
|
7997
|
-
children: /* @__PURE__ */ (0,
|
|
7998
|
-
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ (0,
|
|
7999
|
-
gi > 0 && /* @__PURE__ */ (0,
|
|
6520
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(CustomToolbar, { children: [
|
|
6521
|
+
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_react6.default.Fragment, { children: [
|
|
6522
|
+
gi > 0 && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(CustomToolbarDivider, {}),
|
|
8000
6523
|
btns.map((btn) => {
|
|
8001
6524
|
const isActive = activeCommands.has(btn.cmd);
|
|
8002
|
-
return /* @__PURE__ */ (0,
|
|
6525
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
8003
6526
|
CustomToolbarButton,
|
|
8004
6527
|
{
|
|
8005
6528
|
title: btn.title,
|
|
@@ -8008,7 +6531,7 @@ function FloatingToolbar({
|
|
|
8008
6531
|
e.preventDefault();
|
|
8009
6532
|
onCommand(btn.cmd);
|
|
8010
6533
|
},
|
|
8011
|
-
children: /* @__PURE__ */ (0,
|
|
6534
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
8012
6535
|
"svg",
|
|
8013
6536
|
{
|
|
8014
6537
|
width: "16",
|
|
@@ -8029,7 +6552,7 @@ function FloatingToolbar({
|
|
|
8029
6552
|
);
|
|
8030
6553
|
})
|
|
8031
6554
|
] }, gi)),
|
|
8032
|
-
showEditLink ? /* @__PURE__ */ (0,
|
|
6555
|
+
showEditLink ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
8033
6556
|
CustomToolbarButton,
|
|
8034
6557
|
{
|
|
8035
6558
|
type: "button",
|
|
@@ -8043,7 +6566,7 @@ function FloatingToolbar({
|
|
|
8043
6566
|
e.preventDefault();
|
|
8044
6567
|
e.stopPropagation();
|
|
8045
6568
|
},
|
|
8046
|
-
children: /* @__PURE__ */ (0,
|
|
6569
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react4.Link, { className: "size-4 shrink-0", "aria-hidden": true })
|
|
8047
6570
|
}
|
|
8048
6571
|
) : null
|
|
8049
6572
|
] })
|
|
@@ -8060,7 +6583,7 @@ function StateToggle({
|
|
|
8060
6583
|
states,
|
|
8061
6584
|
onStateChange
|
|
8062
6585
|
}) {
|
|
8063
|
-
return /* @__PURE__ */ (0,
|
|
6586
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
8064
6587
|
ToggleGroup,
|
|
8065
6588
|
{
|
|
8066
6589
|
"data-ohw-state-toggle": "",
|
|
@@ -8074,7 +6597,7 @@ function StateToggle({
|
|
|
8074
6597
|
left: rect.right - 8,
|
|
8075
6598
|
transform: "translateX(-100%)"
|
|
8076
6599
|
},
|
|
8077
|
-
children: states.map((state) => /* @__PURE__ */ (0,
|
|
6600
|
+
children: states.map((state) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ToggleGroupItem, { value: state, size: "sm", children: state }, state))
|
|
8078
6601
|
}
|
|
8079
6602
|
);
|
|
8080
6603
|
}
|
|
@@ -8097,12 +6620,12 @@ function resolveSubdomain(subdomainFromQuery) {
|
|
|
8097
6620
|
return "";
|
|
8098
6621
|
}
|
|
8099
6622
|
function OhhwellsBridge() {
|
|
8100
|
-
const pathname = (0,
|
|
8101
|
-
const router = (0,
|
|
8102
|
-
const searchParams = (0,
|
|
6623
|
+
const pathname = (0, import_navigation.usePathname)();
|
|
6624
|
+
const router = (0, import_navigation.useRouter)();
|
|
6625
|
+
const searchParams = (0, import_navigation.useSearchParams)();
|
|
8103
6626
|
const isEditMode = isEditSessionActive();
|
|
8104
|
-
const [bridgeRoot, setBridgeRoot] = (0,
|
|
8105
|
-
(0,
|
|
6627
|
+
const [bridgeRoot, setBridgeRoot] = (0, import_react6.useState)(null);
|
|
6628
|
+
(0, import_react6.useEffect)(() => {
|
|
8106
6629
|
const figtreeFontId = "ohw-figtree-font";
|
|
8107
6630
|
if (!document.getElementById(figtreeFontId)) {
|
|
8108
6631
|
const preconnect1 = Object.assign(document.createElement("link"), { rel: "preconnect", href: "https://fonts.googleapis.com" });
|
|
@@ -8130,100 +6653,83 @@ function OhhwellsBridge() {
|
|
|
8130
6653
|
const subdomainFromQuery = searchParams.get("subdomain");
|
|
8131
6654
|
const subdomain = resolveSubdomain(subdomainFromQuery);
|
|
8132
6655
|
useLinkHrefGuardian(pathname, subdomain, isEditMode);
|
|
8133
|
-
const
|
|
6656
|
+
const postToParent = (0, import_react6.useCallback)((data) => {
|
|
8134
6657
|
if (typeof window !== "undefined" && window.parent !== window) {
|
|
8135
6658
|
window.parent.postMessage(data, "*");
|
|
8136
6659
|
}
|
|
8137
6660
|
}, []);
|
|
8138
|
-
const [fetchState, setFetchState] = (0,
|
|
8139
|
-
const autoSaveTimers = (0,
|
|
8140
|
-
const activeElRef = (0,
|
|
8141
|
-
const selectedElRef = (0,
|
|
8142
|
-
const originalContentRef = (0,
|
|
8143
|
-
const activeStateElRef = (0,
|
|
8144
|
-
const parentScrollRef = (0,
|
|
8145
|
-
const visibleViewportRef = (0,
|
|
8146
|
-
const [dialogPortalContainer, setDialogPortalContainer] = (0,
|
|
8147
|
-
const attachVisibleViewport = (0,
|
|
6661
|
+
const [fetchState, setFetchState] = (0, import_react6.useState)("idle");
|
|
6662
|
+
const autoSaveTimers = (0, import_react6.useRef)(/* @__PURE__ */ new Map());
|
|
6663
|
+
const activeElRef = (0, import_react6.useRef)(null);
|
|
6664
|
+
const selectedElRef = (0, import_react6.useRef)(null);
|
|
6665
|
+
const originalContentRef = (0, import_react6.useRef)(null);
|
|
6666
|
+
const activeStateElRef = (0, import_react6.useRef)(null);
|
|
6667
|
+
const parentScrollRef = (0, import_react6.useRef)(null);
|
|
6668
|
+
const visibleViewportRef = (0, import_react6.useRef)(null);
|
|
6669
|
+
const [dialogPortalContainer, setDialogPortalContainer] = (0, import_react6.useState)(null);
|
|
6670
|
+
const attachVisibleViewport = (0, import_react6.useCallback)((node) => {
|
|
8148
6671
|
visibleViewportRef.current = node;
|
|
8149
6672
|
setDialogPortalContainer(node);
|
|
8150
6673
|
if (node) applyVisibleViewport(node, parentScrollRef.current);
|
|
8151
6674
|
}, []);
|
|
8152
|
-
const toolbarElRef = (0,
|
|
8153
|
-
const glowElRef = (0,
|
|
8154
|
-
const hoveredImageRef = (0,
|
|
8155
|
-
const hoveredImageHasTextOverlapRef = (0,
|
|
8156
|
-
const dragOverElRef = (0,
|
|
8157
|
-
const [mediaHover, setMediaHover] = (0,
|
|
8158
|
-
const [
|
|
8159
|
-
const
|
|
8160
|
-
const
|
|
8161
|
-
const
|
|
8162
|
-
const
|
|
8163
|
-
const
|
|
8164
|
-
const activateRef = (0, import_react9.useRef)(() => {
|
|
6675
|
+
const toolbarElRef = (0, import_react6.useRef)(null);
|
|
6676
|
+
const glowElRef = (0, import_react6.useRef)(null);
|
|
6677
|
+
const hoveredImageRef = (0, import_react6.useRef)(null);
|
|
6678
|
+
const hoveredImageHasTextOverlapRef = (0, import_react6.useRef)(false);
|
|
6679
|
+
const dragOverElRef = (0, import_react6.useRef)(null);
|
|
6680
|
+
const [mediaHover, setMediaHover] = (0, import_react6.useState)(null);
|
|
6681
|
+
const [uploadingRects, setUploadingRects] = (0, import_react6.useState)({});
|
|
6682
|
+
const hoveredGapRef = (0, import_react6.useRef)(null);
|
|
6683
|
+
const imageUnhoverTimerRef = (0, import_react6.useRef)(null);
|
|
6684
|
+
const imageShowTimerRef = (0, import_react6.useRef)(null);
|
|
6685
|
+
const editStylesRef = (0, import_react6.useRef)(null);
|
|
6686
|
+
const activateRef = (0, import_react6.useRef)(() => {
|
|
8165
6687
|
});
|
|
8166
|
-
const deactivateRef = (0,
|
|
6688
|
+
const deactivateRef = (0, import_react6.useRef)(() => {
|
|
8167
6689
|
});
|
|
8168
|
-
const selectRef = (0,
|
|
6690
|
+
const selectRef = (0, import_react6.useRef)(() => {
|
|
8169
6691
|
});
|
|
8170
|
-
const
|
|
6692
|
+
const deselectRef = (0, import_react6.useRef)(() => {
|
|
8171
6693
|
});
|
|
8172
|
-
const
|
|
6694
|
+
const reselectNavigationItemRef = (0, import_react6.useRef)(() => {
|
|
8173
6695
|
});
|
|
8174
|
-
const
|
|
6696
|
+
const commitNavigationTextEditRef = (0, import_react6.useRef)(() => {
|
|
8175
6697
|
});
|
|
8176
|
-
const
|
|
6698
|
+
const refreshActiveCommandsRef = (0, import_react6.useRef)(() => {
|
|
8177
6699
|
});
|
|
8178
|
-
const
|
|
8179
|
-
|
|
8180
|
-
const
|
|
8181
|
-
|
|
8182
|
-
const
|
|
8183
|
-
const
|
|
8184
|
-
const
|
|
8185
|
-
const [toolbarVariant, setToolbarVariant] = (0, import_react9.useState)("none");
|
|
8186
|
-
const toolbarVariantRef = (0, import_react9.useRef)("none");
|
|
6700
|
+
const postToParentRef = (0, import_react6.useRef)(postToParent);
|
|
6701
|
+
postToParentRef.current = postToParent;
|
|
6702
|
+
const sectionsLoadedRef = (0, import_react6.useRef)(false);
|
|
6703
|
+
const pendingScheduleConfigRequests = (0, import_react6.useRef)([]);
|
|
6704
|
+
const [toolbarRect, setToolbarRect] = (0, import_react6.useState)(null);
|
|
6705
|
+
const [toolbarVariant, setToolbarVariant] = (0, import_react6.useState)("none");
|
|
6706
|
+
const toolbarVariantRef = (0, import_react6.useRef)("none");
|
|
8187
6707
|
toolbarVariantRef.current = toolbarVariant;
|
|
8188
|
-
const [reorderHrefKey, setReorderHrefKey] = (0,
|
|
8189
|
-
const [reorderDragDisabled, setReorderDragDisabled] = (0,
|
|
8190
|
-
const [toggleState, setToggleState] = (0,
|
|
8191
|
-
const [maxBadge, setMaxBadge] = (0,
|
|
8192
|
-
const [activeCommands, setActiveCommands] = (0,
|
|
8193
|
-
const [sectionGap, setSectionGap] = (0,
|
|
8194
|
-
const [toolbarShowEditLink, setToolbarShowEditLink] = (0,
|
|
8195
|
-
const
|
|
8196
|
-
const [
|
|
8197
|
-
const
|
|
8198
|
-
const [
|
|
8199
|
-
const
|
|
8200
|
-
const [
|
|
8201
|
-
const [
|
|
8202
|
-
const [
|
|
8203
|
-
const
|
|
8204
|
-
const
|
|
8205
|
-
const
|
|
8206
|
-
const
|
|
8207
|
-
const
|
|
8208
|
-
const footerPointerDragRef = (0, import_react9.useRef)(null);
|
|
8209
|
-
const suppressNextClickRef = (0, import_react9.useRef)(false);
|
|
8210
|
-
const [linkPopover, setLinkPopover] = (0, import_react9.useState)(null);
|
|
8211
|
-
const linkPopoverSessionRef = (0, import_react9.useRef)(null);
|
|
8212
|
-
const addNavAfterAnchorRef = (0, import_react9.useRef)(null);
|
|
8213
|
-
const editContentRef = (0, import_react9.useRef)({});
|
|
8214
|
-
const [sitePages, setSitePages] = (0, import_react9.useState)([]);
|
|
8215
|
-
const [sectionsByPath, setSectionsByPath] = (0, import_react9.useState)({});
|
|
8216
|
-
const sectionsPrefetchGenRef = (0, import_react9.useRef)(0);
|
|
8217
|
-
const setLinkPopoverRef = (0, import_react9.useRef)(setLinkPopover);
|
|
8218
|
-
const linkPopoverPanelRef = (0, import_react9.useRef)(null);
|
|
8219
|
-
const linkPopoverOpenRef = (0, import_react9.useRef)(false);
|
|
8220
|
-
const linkPopoverGraceUntilRef = (0, import_react9.useRef)(0);
|
|
6708
|
+
const [reorderHrefKey, setReorderHrefKey] = (0, import_react6.useState)(null);
|
|
6709
|
+
const [reorderDragDisabled, setReorderDragDisabled] = (0, import_react6.useState)(false);
|
|
6710
|
+
const [toggleState, setToggleState] = (0, import_react6.useState)(null);
|
|
6711
|
+
const [maxBadge, setMaxBadge] = (0, import_react6.useState)(null);
|
|
6712
|
+
const [activeCommands, setActiveCommands] = (0, import_react6.useState)(/* @__PURE__ */ new Set());
|
|
6713
|
+
const [sectionGap, setSectionGap] = (0, import_react6.useState)(null);
|
|
6714
|
+
const [toolbarShowEditLink, setToolbarShowEditLink] = (0, import_react6.useState)(false);
|
|
6715
|
+
const hoveredItemElRef = (0, import_react6.useRef)(null);
|
|
6716
|
+
const [hoveredItemRect, setHoveredItemRect] = (0, import_react6.useState)(null);
|
|
6717
|
+
const siblingHintElRef = (0, import_react6.useRef)(null);
|
|
6718
|
+
const [siblingHintRect, setSiblingHintRect] = (0, import_react6.useState)(null);
|
|
6719
|
+
const [isItemDragging, setIsItemDragging] = (0, import_react6.useState)(false);
|
|
6720
|
+
const [linkPopover, setLinkPopover] = (0, import_react6.useState)(null);
|
|
6721
|
+
const [sitePages, setSitePages] = (0, import_react6.useState)([]);
|
|
6722
|
+
const [sectionsByPath, setSectionsByPath] = (0, import_react6.useState)({});
|
|
6723
|
+
const sectionsPrefetchGenRef = (0, import_react6.useRef)(0);
|
|
6724
|
+
const setLinkPopoverRef = (0, import_react6.useRef)(setLinkPopover);
|
|
6725
|
+
const linkPopoverPanelRef = (0, import_react6.useRef)(null);
|
|
6726
|
+
const linkPopoverOpenRef = (0, import_react6.useRef)(false);
|
|
6727
|
+
const linkPopoverGraceUntilRef = (0, import_react6.useRef)(0);
|
|
8221
6728
|
setLinkPopoverRef.current = setLinkPopover;
|
|
8222
|
-
linkPopoverSessionRef.current = linkPopover;
|
|
8223
6729
|
const bumpLinkPopoverGrace = () => {
|
|
8224
6730
|
linkPopoverGraceUntilRef.current = Date.now() + 350;
|
|
8225
6731
|
};
|
|
8226
|
-
const runSectionsPrefetch = (0,
|
|
6732
|
+
const runSectionsPrefetch = (0, import_react6.useCallback)((pages) => {
|
|
8227
6733
|
if (!isEditMode || shouldUseDevFixtures() || pages.length === 0) return;
|
|
8228
6734
|
const gen = ++sectionsPrefetchGenRef.current;
|
|
8229
6735
|
const paths = pages.map((p) => p.path);
|
|
@@ -8242,9 +6748,9 @@ function OhhwellsBridge() {
|
|
|
8242
6748
|
);
|
|
8243
6749
|
});
|
|
8244
6750
|
}, [isEditMode, pathname]);
|
|
8245
|
-
const runSectionsPrefetchRef = (0,
|
|
6751
|
+
const runSectionsPrefetchRef = (0, import_react6.useRef)(runSectionsPrefetch);
|
|
8246
6752
|
runSectionsPrefetchRef.current = runSectionsPrefetch;
|
|
8247
|
-
(0,
|
|
6753
|
+
(0, import_react6.useEffect)(() => {
|
|
8248
6754
|
if (!linkPopover) return;
|
|
8249
6755
|
if (hoveredImageRef.current) {
|
|
8250
6756
|
hoveredImageRef.current = null;
|
|
@@ -8252,9 +6758,33 @@ function OhhwellsBridge() {
|
|
|
8252
6758
|
}
|
|
8253
6759
|
hoveredGapRef.current = null;
|
|
8254
6760
|
setSectionGap(null);
|
|
8255
|
-
|
|
8256
|
-
|
|
8257
|
-
|
|
6761
|
+
setMediaHover(null);
|
|
6762
|
+
postToParent({ type: "ow:link-modal-lock", locked: true });
|
|
6763
|
+
const html = document.documentElement;
|
|
6764
|
+
const body = document.body;
|
|
6765
|
+
const prevHtmlOverflow = html.style.overflow;
|
|
6766
|
+
const prevBodyOverflow = body.style.overflow;
|
|
6767
|
+
html.style.overflow = "hidden";
|
|
6768
|
+
body.style.overflow = "hidden";
|
|
6769
|
+
const preventBackgroundScroll = (e) => {
|
|
6770
|
+
const target = e.target;
|
|
6771
|
+
if (target instanceof Element && target.closest('[data-ohw-link-modal-root], [data-slot="dialog-overlay"]')) {
|
|
6772
|
+
return;
|
|
6773
|
+
}
|
|
6774
|
+
e.preventDefault();
|
|
6775
|
+
};
|
|
6776
|
+
const scrollOpts = { passive: false, capture: true };
|
|
6777
|
+
document.addEventListener("wheel", preventBackgroundScroll, scrollOpts);
|
|
6778
|
+
document.addEventListener("touchmove", preventBackgroundScroll, scrollOpts);
|
|
6779
|
+
return () => {
|
|
6780
|
+
postToParent({ type: "ow:link-modal-lock", locked: false });
|
|
6781
|
+
html.style.overflow = prevHtmlOverflow;
|
|
6782
|
+
body.style.overflow = prevBodyOverflow;
|
|
6783
|
+
document.removeEventListener("wheel", preventBackgroundScroll, scrollOpts);
|
|
6784
|
+
document.removeEventListener("touchmove", preventBackgroundScroll, scrollOpts);
|
|
6785
|
+
};
|
|
6786
|
+
}, [linkPopover, postToParent]);
|
|
6787
|
+
(0, import_react6.useEffect)(() => {
|
|
8258
6788
|
if (!isEditMode) return;
|
|
8259
6789
|
const useFixtures = shouldUseDevFixtures();
|
|
8260
6790
|
if (useFixtures) {
|
|
@@ -8275,17 +6805,17 @@ function OhhwellsBridge() {
|
|
|
8275
6805
|
runSectionsPrefetchRef.current(mapped);
|
|
8276
6806
|
};
|
|
8277
6807
|
window.addEventListener("message", onSitePages);
|
|
8278
|
-
if (!useFixtures)
|
|
6808
|
+
if (!useFixtures) postToParent({ type: "ow:request-site-pages" });
|
|
8279
6809
|
return () => window.removeEventListener("message", onSitePages);
|
|
8280
|
-
}, [isEditMode,
|
|
8281
|
-
(0,
|
|
6810
|
+
}, [isEditMode, postToParent]);
|
|
6811
|
+
(0, import_react6.useEffect)(() => {
|
|
8282
6812
|
if (!isEditMode || shouldUseDevFixtures()) return;
|
|
8283
6813
|
void loadAllSectionsManifest().then((manifest) => {
|
|
8284
6814
|
if (Object.keys(manifest).length === 0) return;
|
|
8285
6815
|
setSectionsByPath((prev) => ({ ...manifest, ...prev }));
|
|
8286
6816
|
});
|
|
8287
6817
|
}, [isEditMode]);
|
|
8288
|
-
(0,
|
|
6818
|
+
(0, import_react6.useEffect)(() => {
|
|
8289
6819
|
const update = () => {
|
|
8290
6820
|
const el = activeElRef.current ?? selectedElRef.current;
|
|
8291
6821
|
if (el) setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
|
|
@@ -8309,10 +6839,10 @@ function OhhwellsBridge() {
|
|
|
8309
6839
|
vvp.removeEventListener("resize", update);
|
|
8310
6840
|
};
|
|
8311
6841
|
}, []);
|
|
8312
|
-
const refreshStateRules = (0,
|
|
6842
|
+
const refreshStateRules = (0, import_react6.useCallback)(() => {
|
|
8313
6843
|
editStylesRef.current?.forceHover && (editStylesRef.current.forceHover.textContent = collectStateRules());
|
|
8314
6844
|
}, []);
|
|
8315
|
-
const processConfigRequest = (0,
|
|
6845
|
+
const processConfigRequest = (0, import_react6.useCallback)((insertAfterVal) => {
|
|
8316
6846
|
const tracker = getSectionsTracker();
|
|
8317
6847
|
let entries = [];
|
|
8318
6848
|
try {
|
|
@@ -8335,7 +6865,7 @@ function OhhwellsBridge() {
|
|
|
8335
6865
|
}
|
|
8336
6866
|
window.postMessage({ type: "ow:schedule-config", insertAfter: insertAfterVal, scheduleId: null }, "*");
|
|
8337
6867
|
}, [isEditMode]);
|
|
8338
|
-
const deactivate = (0,
|
|
6868
|
+
const deactivate = (0, import_react6.useCallback)(() => {
|
|
8339
6869
|
const el = activeElRef.current;
|
|
8340
6870
|
if (!el) return;
|
|
8341
6871
|
const key = el.dataset.ohwKey;
|
|
@@ -8364,25 +6894,21 @@ function OhhwellsBridge() {
|
|
|
8364
6894
|
setMaxBadge(null);
|
|
8365
6895
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
8366
6896
|
setToolbarShowEditLink(false);
|
|
8367
|
-
|
|
8368
|
-
}, [
|
|
8369
|
-
const deselect = (0,
|
|
6897
|
+
postToParent({ type: "ow:exit-edit" });
|
|
6898
|
+
}, [postToParent]);
|
|
6899
|
+
const deselect = (0, import_react6.useCallback)(() => {
|
|
8370
6900
|
selectedElRef.current = null;
|
|
8371
6901
|
setReorderHrefKey(null);
|
|
8372
6902
|
setReorderDragDisabled(false);
|
|
8373
|
-
setIsFooterFrameSelection(false);
|
|
8374
6903
|
siblingHintElRef.current = null;
|
|
8375
6904
|
setSiblingHintRect(null);
|
|
8376
|
-
setSiblingHintRects([]);
|
|
8377
6905
|
setIsItemDragging(false);
|
|
8378
|
-
hoveredNavContainerRef.current = null;
|
|
8379
|
-
setHoveredNavContainerRect(null);
|
|
8380
6906
|
if (!activeElRef.current) {
|
|
8381
6907
|
setToolbarRect(null);
|
|
8382
6908
|
setToolbarVariant("none");
|
|
8383
6909
|
}
|
|
8384
6910
|
}, []);
|
|
8385
|
-
const reselectNavigationItem = (0,
|
|
6911
|
+
const reselectNavigationItem = (0, import_react6.useCallback)((navAnchor) => {
|
|
8386
6912
|
selectedElRef.current = navAnchor;
|
|
8387
6913
|
const { key, disabled } = getNavigationItemReorderState(navAnchor);
|
|
8388
6914
|
setReorderHrefKey(key);
|
|
@@ -8392,7 +6918,7 @@ function OhhwellsBridge() {
|
|
|
8392
6918
|
setToolbarShowEditLink(false);
|
|
8393
6919
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
8394
6920
|
}, []);
|
|
8395
|
-
const commitNavigationTextEdit = (0,
|
|
6921
|
+
const commitNavigationTextEdit = (0, import_react6.useCallback)((navAnchor) => {
|
|
8396
6922
|
const el = activeElRef.current;
|
|
8397
6923
|
if (!el) return;
|
|
8398
6924
|
const key = el.dataset.ohwKey;
|
|
@@ -8405,9 +6931,9 @@ function OhhwellsBridge() {
|
|
|
8405
6931
|
const html = sanitizeHtml(el.innerHTML);
|
|
8406
6932
|
const original = originalContentRef.current ?? "";
|
|
8407
6933
|
if (html !== sanitizeHtml(original)) {
|
|
8408
|
-
|
|
6934
|
+
postToParent({ type: "ow:change", nodes: [{ key, text: html }] });
|
|
8409
6935
|
const h = document.documentElement.scrollHeight;
|
|
8410
|
-
if (h > 50)
|
|
6936
|
+
if (h > 50) postToParent({ type: "ow:height", height: h });
|
|
8411
6937
|
}
|
|
8412
6938
|
}
|
|
8413
6939
|
el.removeAttribute("contenteditable");
|
|
@@ -8415,366 +6941,81 @@ function OhhwellsBridge() {
|
|
|
8415
6941
|
setMaxBadge(null);
|
|
8416
6942
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
8417
6943
|
setToolbarShowEditLink(false);
|
|
8418
|
-
|
|
6944
|
+
postToParent({ type: "ow:exit-edit" });
|
|
8419
6945
|
reselectNavigationItem(navAnchor);
|
|
8420
|
-
}, [
|
|
8421
|
-
const
|
|
8422
|
-
const items = listNavbarItems();
|
|
8423
|
-
addNavAfterAnchorRef.current = items[items.length - 1] ?? null;
|
|
8424
|
-
deselectRef.current();
|
|
8425
|
-
deactivateRef.current();
|
|
8426
|
-
bumpLinkPopoverGrace();
|
|
8427
|
-
setLinkPopover({
|
|
8428
|
-
key: "__add-nav__",
|
|
8429
|
-
mode: "create",
|
|
8430
|
-
intent: "add-nav"
|
|
8431
|
-
});
|
|
8432
|
-
}, []);
|
|
8433
|
-
const clearFooterDragVisuals = (0, import_react9.useCallback)(() => {
|
|
8434
|
-
footerDragRef.current = null;
|
|
8435
|
-
setSiblingHintRects([]);
|
|
8436
|
-
setFooterDropSlots([]);
|
|
8437
|
-
setActiveFooterDropIndex(null);
|
|
8438
|
-
setDraggedItemRect(null);
|
|
8439
|
-
setIsItemDragging(false);
|
|
8440
|
-
unlockFooterDragInteraction();
|
|
8441
|
-
}, []);
|
|
8442
|
-
const refreshFooterDragVisuals = (0, import_react9.useCallback)((session, activeSlot, clientX, clientY) => {
|
|
8443
|
-
const dragged = session.draggedEl;
|
|
8444
|
-
setDraggedItemRect(dragged.getBoundingClientRect());
|
|
8445
|
-
if (typeof clientX === "number" && typeof clientY === "number") {
|
|
8446
|
-
session.lastClientX = clientX;
|
|
8447
|
-
session.lastClientY = clientY;
|
|
8448
|
-
}
|
|
8449
|
-
session.activeSlot = activeSlot;
|
|
8450
|
-
if (session.kind === "link") {
|
|
8451
|
-
const columns2 = listFooterColumns();
|
|
8452
|
-
const focusCols = /* @__PURE__ */ new Set([session.sourceColumnIndex]);
|
|
8453
|
-
if (activeSlot) focusCols.add(activeSlot.columnIndex);
|
|
8454
|
-
const siblingRects = [];
|
|
8455
|
-
columns2.forEach((col, i) => {
|
|
8456
|
-
if (!focusCols.has(i)) return;
|
|
8457
|
-
for (const link of listFooterLinksInColumn(col)) {
|
|
8458
|
-
if (link === dragged) continue;
|
|
8459
|
-
siblingRects.push(link.getBoundingClientRect());
|
|
8460
|
-
}
|
|
8461
|
-
});
|
|
8462
|
-
setSiblingHintRects(siblingRects);
|
|
8463
|
-
const slots2 = [];
|
|
8464
|
-
columns2.forEach((col, i) => {
|
|
8465
|
-
slots2.push(...buildLinkDropSlots(col, i));
|
|
8466
|
-
});
|
|
8467
|
-
setFooterDropSlots(slots2);
|
|
8468
|
-
const activeIdx2 = activeSlot ? slots2.findIndex((s) => s.columnIndex === activeSlot.columnIndex && s.insertIndex === activeSlot.insertIndex) : -1;
|
|
8469
|
-
setActiveFooterDropIndex(activeIdx2 >= 0 ? activeIdx2 : null);
|
|
8470
|
-
return;
|
|
8471
|
-
}
|
|
8472
|
-
const columns = listFooterColumns();
|
|
8473
|
-
setSiblingHintRects(columns.filter((col) => col !== dragged).map((col) => col.getBoundingClientRect()));
|
|
8474
|
-
const slots = buildColumnDropSlots();
|
|
8475
|
-
setFooterDropSlots(slots);
|
|
8476
|
-
const activeIdx = activeSlot ? slots.findIndex((s) => s.insertIndex === activeSlot.insertIndex) : -1;
|
|
8477
|
-
setActiveFooterDropIndex(activeIdx >= 0 ? activeIdx : null);
|
|
8478
|
-
}, []);
|
|
8479
|
-
const refreshFooterDragVisualsRef = (0, import_react9.useRef)(refreshFooterDragVisuals);
|
|
8480
|
-
refreshFooterDragVisualsRef.current = refreshFooterDragVisuals;
|
|
8481
|
-
const commitFooterDragRef = (0, import_react9.useRef)(() => {
|
|
8482
|
-
});
|
|
8483
|
-
const beginFooterDragRef = (0, import_react9.useRef)(() => {
|
|
8484
|
-
});
|
|
8485
|
-
const beginFooterDrag = (0, import_react9.useCallback)(
|
|
8486
|
-
(session) => {
|
|
8487
|
-
const rect = session.draggedEl.getBoundingClientRect();
|
|
8488
|
-
session.lastClientX = session.lastClientX || rect.left + rect.width / 2;
|
|
8489
|
-
session.lastClientY = session.lastClientY || rect.top + rect.height / 2;
|
|
8490
|
-
session.activeSlot = session.activeSlot ?? null;
|
|
8491
|
-
footerDragRef.current = session;
|
|
8492
|
-
setIsItemDragging(true);
|
|
8493
|
-
lockFooterDuringDrag();
|
|
8494
|
-
siblingHintElRef.current = null;
|
|
8495
|
-
setSiblingHintRect(null);
|
|
8496
|
-
if (session.wasSelected && selectedElRef.current === session.draggedEl) {
|
|
8497
|
-
setToolbarRect(rect);
|
|
8498
|
-
}
|
|
8499
|
-
const initialSlot = session.kind === "link" && session.hrefKey ? hitTestLinkDropSlot(session.lastClientX, session.lastClientY, session.hrefKey) : hitTestColumnDropSlot(session.lastClientX, session.lastClientY);
|
|
8500
|
-
refreshFooterDragVisuals(session, initialSlot, session.lastClientX, session.lastClientY);
|
|
8501
|
-
},
|
|
8502
|
-
[refreshFooterDragVisuals]
|
|
8503
|
-
);
|
|
8504
|
-
beginFooterDragRef.current = beginFooterDrag;
|
|
8505
|
-
const commitFooterDrag = (0, import_react9.useCallback)(
|
|
8506
|
-
(clientX, clientY) => {
|
|
8507
|
-
const session = footerDragRef.current;
|
|
8508
|
-
if (!session) {
|
|
8509
|
-
clearFooterDragVisuals();
|
|
8510
|
-
return;
|
|
8511
|
-
}
|
|
8512
|
-
const x = typeof clientX === "number" && (clientX !== 0 || clientY !== 0) ? clientX : session.lastClientX;
|
|
8513
|
-
const y = typeof clientY === "number" && (clientX !== 0 || clientY !== 0) ? clientY : session.lastClientY;
|
|
8514
|
-
let nextOrder = null;
|
|
8515
|
-
const slot = session.activeSlot ?? (session.kind === "link" && session.hrefKey ? hitTestLinkDropSlot(x, y, session.hrefKey) : session.kind === "column" ? hitTestColumnDropSlot(x, y) : null);
|
|
8516
|
-
if (session.kind === "link" && session.hrefKey && slot) {
|
|
8517
|
-
nextOrder = planFooterLinkMove(session.hrefKey, slot.columnIndex, slot.insertIndex);
|
|
8518
|
-
} else if (session.kind === "column" && slot) {
|
|
8519
|
-
nextOrder = planFooterColumnMove(session.sourceColumnIndex, slot.insertIndex);
|
|
8520
|
-
}
|
|
8521
|
-
const wasSelected = session.wasSelected;
|
|
8522
|
-
const draggedEl = session.draggedEl;
|
|
8523
|
-
const hrefKey = session.hrefKey;
|
|
8524
|
-
let movedColumnIndex = null;
|
|
8525
|
-
if (session.kind === "column" && slot && nextOrder) {
|
|
8526
|
-
let adjusted = slot.insertIndex;
|
|
8527
|
-
if (session.sourceColumnIndex < slot.insertIndex) adjusted -= 1;
|
|
8528
|
-
movedColumnIndex = Math.max(0, Math.min(adjusted, nextOrder.length - 1));
|
|
8529
|
-
}
|
|
8530
|
-
clearFooterDragVisuals();
|
|
8531
|
-
if (nextOrder) {
|
|
8532
|
-
const orderJson = JSON.stringify(nextOrder);
|
|
8533
|
-
editContentRef.current = {
|
|
8534
|
-
...editContentRef.current,
|
|
8535
|
-
[FOOTER_ORDER_KEY]: orderJson
|
|
8536
|
-
};
|
|
8537
|
-
applyFooterOrder(nextOrder);
|
|
8538
|
-
document.querySelectorAll("footer [data-ohw-href-key]").forEach(disableNativeHrefDrag);
|
|
8539
|
-
requestAnimationFrame(() => {
|
|
8540
|
-
if (editContentRef.current[FOOTER_ORDER_KEY] === orderJson) {
|
|
8541
|
-
applyFooterOrder(nextOrder);
|
|
8542
|
-
document.querySelectorAll("footer [data-ohw-href-key]").forEach(disableNativeHrefDrag);
|
|
8543
|
-
}
|
|
8544
|
-
});
|
|
8545
|
-
postToParentRef.current({
|
|
8546
|
-
type: "ow:change",
|
|
8547
|
-
nodes: [{ key: FOOTER_ORDER_KEY, text: orderJson }]
|
|
8548
|
-
});
|
|
8549
|
-
}
|
|
8550
|
-
const still = (hrefKey ? document.querySelector(`footer [data-ohw-href-key="${CSS.escape(hrefKey)}"]`) : null) ?? (movedColumnIndex !== null ? listFooterColumns()[movedColumnIndex] ?? null : null) ?? (document.body.contains(draggedEl) ? draggedEl : null);
|
|
8551
|
-
if (still && isNavigationItem(still)) {
|
|
8552
|
-
selectRef.current(still);
|
|
8553
|
-
} else if (still && isNavigationContainer(still)) {
|
|
8554
|
-
selectFrameRef.current(still);
|
|
8555
|
-
} else if (wasSelected) {
|
|
8556
|
-
deselectRef.current();
|
|
8557
|
-
}
|
|
8558
|
-
},
|
|
8559
|
-
[clearFooterDragVisuals]
|
|
8560
|
-
);
|
|
8561
|
-
commitFooterDragRef.current = commitFooterDrag;
|
|
8562
|
-
const startFooterLinkDrag = (0, import_react9.useCallback)(
|
|
8563
|
-
(anchor, clientX, clientY, wasSelected) => {
|
|
8564
|
-
const hrefKey = anchor.getAttribute("data-ohw-href-key");
|
|
8565
|
-
if (!hrefKey || !isFooterHrefKey(hrefKey)) return false;
|
|
8566
|
-
const column = findFooterColumnForLink(anchor);
|
|
8567
|
-
const columns = listFooterColumns();
|
|
8568
|
-
beginFooterDrag({
|
|
8569
|
-
kind: "link",
|
|
8570
|
-
hrefKey,
|
|
8571
|
-
columnEl: column,
|
|
8572
|
-
sourceColumnIndex: column ? columns.indexOf(column) : 0,
|
|
8573
|
-
wasSelected,
|
|
8574
|
-
draggedEl: anchor,
|
|
8575
|
-
lastClientX: clientX,
|
|
8576
|
-
lastClientY: clientY,
|
|
8577
|
-
activeSlot: null
|
|
8578
|
-
});
|
|
8579
|
-
return true;
|
|
8580
|
-
},
|
|
8581
|
-
[beginFooterDrag]
|
|
8582
|
-
);
|
|
8583
|
-
const startFooterColumnDrag = (0, import_react9.useCallback)(
|
|
8584
|
-
(columnEl, clientX, clientY, wasSelected) => {
|
|
8585
|
-
const columns = listFooterColumns();
|
|
8586
|
-
const idx = columns.indexOf(columnEl);
|
|
8587
|
-
if (idx < 0) return false;
|
|
8588
|
-
beginFooterDrag({
|
|
8589
|
-
kind: "column",
|
|
8590
|
-
hrefKey: null,
|
|
8591
|
-
columnEl,
|
|
8592
|
-
sourceColumnIndex: idx,
|
|
8593
|
-
wasSelected,
|
|
8594
|
-
draggedEl: columnEl,
|
|
8595
|
-
lastClientX: clientX,
|
|
8596
|
-
lastClientY: clientY,
|
|
8597
|
-
activeSlot: null
|
|
8598
|
-
});
|
|
8599
|
-
return true;
|
|
8600
|
-
},
|
|
8601
|
-
[beginFooterDrag]
|
|
8602
|
-
);
|
|
8603
|
-
const handleItemDragStart = (0, import_react9.useCallback)(
|
|
8604
|
-
(e) => {
|
|
8605
|
-
const selected = selectedElRef.current;
|
|
8606
|
-
if (!selected) {
|
|
8607
|
-
setIsItemDragging(true);
|
|
8608
|
-
return;
|
|
8609
|
-
}
|
|
8610
|
-
const clientX = e?.clientX ?? selected.getBoundingClientRect().left + 8;
|
|
8611
|
-
const clientY = e?.clientY ?? selected.getBoundingClientRect().top + 8;
|
|
8612
|
-
if (startFooterLinkDrag(selected, clientX, clientY, true)) return;
|
|
8613
|
-
if (selected.hasAttribute("data-ohw-footer-col") || isInferredFooterGroup(selected) && selected.closest("footer")) {
|
|
8614
|
-
if (startFooterColumnDrag(selected, clientX, clientY, true)) return;
|
|
8615
|
-
}
|
|
8616
|
-
siblingHintElRef.current = null;
|
|
8617
|
-
setSiblingHintRect(null);
|
|
8618
|
-
setIsItemDragging(true);
|
|
8619
|
-
},
|
|
8620
|
-
[startFooterColumnDrag, startFooterLinkDrag]
|
|
8621
|
-
);
|
|
8622
|
-
const handleItemDragEnd = (0, import_react9.useCallback)(
|
|
8623
|
-
(e) => {
|
|
8624
|
-
if (footerDragRef.current) {
|
|
8625
|
-
const x = e?.clientX;
|
|
8626
|
-
const y = e?.clientY;
|
|
8627
|
-
if (typeof x === "number" && typeof y === "number" && (x !== 0 || y !== 0)) {
|
|
8628
|
-
commitFooterDrag(x, y);
|
|
8629
|
-
} else {
|
|
8630
|
-
commitFooterDrag();
|
|
8631
|
-
}
|
|
8632
|
-
return;
|
|
8633
|
-
}
|
|
8634
|
-
setIsItemDragging(false);
|
|
8635
|
-
},
|
|
8636
|
-
[commitFooterDrag]
|
|
8637
|
-
);
|
|
8638
|
-
const handleItemChromePointerDown = (0, import_react9.useCallback)((e) => {
|
|
8639
|
-
if (e.button !== 0) return;
|
|
6946
|
+
}, [postToParent, reselectNavigationItem]);
|
|
6947
|
+
const handleAddNavigationItem = (0, import_react6.useCallback)(() => {
|
|
8640
6948
|
const selected = selectedElRef.current;
|
|
8641
6949
|
if (!selected) return;
|
|
8642
|
-
|
|
8643
|
-
|
|
8644
|
-
|
|
8645
|
-
footerPointerDragRef.current = {
|
|
8646
|
-
el: selected,
|
|
8647
|
-
kind: "link",
|
|
8648
|
-
startX: e.clientX,
|
|
8649
|
-
startY: e.clientY,
|
|
8650
|
-
pointerId: e.pointerId,
|
|
8651
|
-
wasSelected: true,
|
|
8652
|
-
started: false
|
|
8653
|
-
};
|
|
8654
|
-
return;
|
|
8655
|
-
}
|
|
8656
|
-
if (selected.hasAttribute("data-ohw-footer-col") || isInferredFooterGroup(selected) && selected.closest("footer")) {
|
|
8657
|
-
footerPointerDragRef.current = {
|
|
8658
|
-
el: selected,
|
|
8659
|
-
kind: "column",
|
|
8660
|
-
startX: e.clientX,
|
|
8661
|
-
startY: e.clientY,
|
|
8662
|
-
pointerId: e.pointerId,
|
|
8663
|
-
wasSelected: true,
|
|
8664
|
-
started: false
|
|
8665
|
-
};
|
|
8666
|
-
}
|
|
6950
|
+
const target = getNavigationItemAddHintTarget(selected);
|
|
6951
|
+
siblingHintElRef.current = target;
|
|
6952
|
+
setSiblingHintRect(target.getBoundingClientRect());
|
|
8667
6953
|
}, []);
|
|
8668
|
-
const
|
|
8669
|
-
|
|
8670
|
-
|
|
8671
|
-
|
|
8672
|
-
|
|
8673
|
-
|
|
8674
|
-
|
|
8675
|
-
const editable = selected.querySelector('[data-ohw-editable="text"]') ?? selected.querySelector("[data-ohw-editable]");
|
|
8676
|
-
if (!editable) return;
|
|
8677
|
-
activateRef.current(editable, { caretX: clientX, caretY: clientY });
|
|
6954
|
+
const handleItemDragStart = (0, import_react6.useCallback)(() => {
|
|
6955
|
+
siblingHintElRef.current = null;
|
|
6956
|
+
setSiblingHintRect(null);
|
|
6957
|
+
setIsItemDragging(true);
|
|
6958
|
+
}, []);
|
|
6959
|
+
const handleItemDragEnd = (0, import_react6.useCallback)(() => {
|
|
6960
|
+
setIsItemDragging(false);
|
|
8678
6961
|
}, []);
|
|
8679
6962
|
reselectNavigationItemRef.current = reselectNavigationItem;
|
|
8680
6963
|
commitNavigationTextEditRef.current = commitNavigationTextEdit;
|
|
8681
|
-
const select = (0,
|
|
8682
|
-
(anchor)
|
|
8683
|
-
|
|
8684
|
-
|
|
8685
|
-
|
|
8686
|
-
|
|
8687
|
-
|
|
8688
|
-
|
|
8689
|
-
|
|
8690
|
-
|
|
8691
|
-
|
|
8692
|
-
|
|
8693
|
-
|
|
8694
|
-
|
|
8695
|
-
|
|
8696
|
-
|
|
8697
|
-
|
|
8698
|
-
|
|
8699
|
-
|
|
8700
|
-
|
|
8701
|
-
|
|
8702
|
-
|
|
8703
|
-
|
|
8704
|
-
|
|
8705
|
-
|
|
8706
|
-
|
|
8707
|
-
(
|
|
8708
|
-
|
|
8709
|
-
|
|
8710
|
-
|
|
8711
|
-
|
|
8712
|
-
|
|
8713
|
-
|
|
8714
|
-
|
|
8715
|
-
|
|
8716
|
-
|
|
8717
|
-
|
|
8718
|
-
|
|
8719
|
-
|
|
8720
|
-
isFooterColumn ? listFooterColumns().filter((column) => column !== el).map((column) => column.getBoundingClientRect()) : []
|
|
8721
|
-
);
|
|
8722
|
-
setIsItemDragging(false);
|
|
6964
|
+
const select = (0, import_react6.useCallback)((anchor) => {
|
|
6965
|
+
if (!isNavigationItem(anchor)) return;
|
|
6966
|
+
if (activeElRef.current) deactivate();
|
|
6967
|
+
selectedElRef.current = anchor;
|
|
6968
|
+
clearHrefKeyHover(anchor);
|
|
6969
|
+
setHoveredItemRect(null);
|
|
6970
|
+
hoveredItemElRef.current = null;
|
|
6971
|
+
siblingHintElRef.current = null;
|
|
6972
|
+
setSiblingHintRect(null);
|
|
6973
|
+
setIsItemDragging(false);
|
|
6974
|
+
const { key, disabled } = getNavigationItemReorderState(anchor);
|
|
6975
|
+
setReorderHrefKey(key);
|
|
6976
|
+
setReorderDragDisabled(disabled);
|
|
6977
|
+
setToolbarVariant("link-action");
|
|
6978
|
+
setToolbarRect(anchor.getBoundingClientRect());
|
|
6979
|
+
setToolbarShowEditLink(false);
|
|
6980
|
+
setActiveCommands(/* @__PURE__ */ new Set());
|
|
6981
|
+
}, [deactivate]);
|
|
6982
|
+
const activate = (0, import_react6.useCallback)((el) => {
|
|
6983
|
+
if (activeElRef.current === el) return;
|
|
6984
|
+
selectedElRef.current = null;
|
|
6985
|
+
deactivate();
|
|
6986
|
+
if (hoveredImageRef.current) {
|
|
6987
|
+
hoveredImageRef.current = null;
|
|
6988
|
+
setMediaHover(null);
|
|
6989
|
+
}
|
|
6990
|
+
setToolbarVariant("rich-text");
|
|
6991
|
+
siblingHintElRef.current = null;
|
|
6992
|
+
setSiblingHintRect(null);
|
|
6993
|
+
setIsItemDragging(false);
|
|
6994
|
+
el.setAttribute("contenteditable", "true");
|
|
6995
|
+
el.removeAttribute("data-ohw-hovered");
|
|
6996
|
+
el.closest("[data-ohw-href-key]")?.removeAttribute("data-ohw-hovered");
|
|
6997
|
+
activeElRef.current = el;
|
|
6998
|
+
originalContentRef.current = el.innerHTML;
|
|
6999
|
+
el.focus();
|
|
7000
|
+
setToolbarShowEditLink(Boolean(getHrefKeyFromElement(el)));
|
|
7001
|
+
const navAnchor = getNavigationItemAnchor(el);
|
|
7002
|
+
if (navAnchor) {
|
|
8723
7003
|
setReorderHrefKey(null);
|
|
8724
7004
|
setReorderDragDisabled(false);
|
|
8725
|
-
|
|
8726
|
-
|
|
8727
|
-
|
|
8728
|
-
|
|
8729
|
-
|
|
8730
|
-
|
|
8731
|
-
|
|
8732
|
-
|
|
8733
|
-
|
|
8734
|
-
(el, options) => {
|
|
8735
|
-
if (activeElRef.current === el) return;
|
|
8736
|
-
selectedElRef.current = null;
|
|
8737
|
-
deactivate();
|
|
8738
|
-
if (hoveredImageRef.current) {
|
|
8739
|
-
hoveredImageRef.current = null;
|
|
8740
|
-
postToParentRef.current({ type: "ow:image-unhover" });
|
|
8741
|
-
}
|
|
8742
|
-
setToolbarVariant("rich-text");
|
|
8743
|
-
siblingHintElRef.current = null;
|
|
8744
|
-
setSiblingHintRect(null);
|
|
8745
|
-
setSiblingHintRects([]);
|
|
8746
|
-
setIsItemDragging(false);
|
|
8747
|
-
el.setAttribute("contenteditable", "true");
|
|
8748
|
-
el.removeAttribute("data-ohw-hovered");
|
|
8749
|
-
el.closest("[data-ohw-href-key]")?.removeAttribute("data-ohw-hovered");
|
|
8750
|
-
activeElRef.current = el;
|
|
8751
|
-
originalContentRef.current = el.innerHTML;
|
|
8752
|
-
el.focus();
|
|
8753
|
-
if (options?.caretX !== void 0 && options?.caretY !== void 0) {
|
|
8754
|
-
placeCaretAtPoint(el, options.caretX, options.caretY);
|
|
8755
|
-
}
|
|
8756
|
-
setToolbarShowEditLink(Boolean(getHrefKeyFromElement(el)));
|
|
8757
|
-
const navAnchor = getNavigationItemAnchor(el);
|
|
8758
|
-
if (navAnchor) {
|
|
8759
|
-
setReorderHrefKey(null);
|
|
8760
|
-
setReorderDragDisabled(false);
|
|
8761
|
-
} else {
|
|
8762
|
-
const { key: reorderKey, disabled: reorderDisabled } = getReorderHandleState(el);
|
|
8763
|
-
setReorderHrefKey(reorderKey);
|
|
8764
|
-
setReorderDragDisabled(reorderDisabled);
|
|
8765
|
-
}
|
|
8766
|
-
setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
|
|
8767
|
-
postToParent2({ type: "ow:enter-edit", key: el.dataset.ohwKey });
|
|
8768
|
-
requestAnimationFrame(() => refreshActiveCommandsRef.current());
|
|
8769
|
-
},
|
|
8770
|
-
[deactivate, postToParent2]
|
|
8771
|
-
);
|
|
7005
|
+
} else {
|
|
7006
|
+
const { key: reorderKey, disabled: reorderDisabled } = getReorderHandleState(el);
|
|
7007
|
+
setReorderHrefKey(reorderKey);
|
|
7008
|
+
setReorderDragDisabled(reorderDisabled);
|
|
7009
|
+
}
|
|
7010
|
+
setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
|
|
7011
|
+
postToParent({ type: "ow:enter-edit", key: el.dataset.ohwKey });
|
|
7012
|
+
requestAnimationFrame(() => refreshActiveCommandsRef.current());
|
|
7013
|
+
}, [deactivate, postToParent]);
|
|
8772
7014
|
activateRef.current = activate;
|
|
8773
7015
|
deactivateRef.current = deactivate;
|
|
8774
7016
|
selectRef.current = select;
|
|
8775
|
-
selectFrameRef.current = selectFrame;
|
|
8776
7017
|
deselectRef.current = deselect;
|
|
8777
|
-
(0,
|
|
7018
|
+
(0, import_react6.useLayoutEffect)(() => {
|
|
8778
7019
|
if (!subdomain || isEditMode) {
|
|
8779
7020
|
setFetchState("done");
|
|
8780
7021
|
return;
|
|
@@ -8784,7 +7025,6 @@ function OhhwellsBridge() {
|
|
|
8784
7025
|
for (const [key, val] of Object.entries(content)) {
|
|
8785
7026
|
if (key === "__ohw_sections") continue;
|
|
8786
7027
|
if (applyVideoSettingNode(key, val)) continue;
|
|
8787
|
-
if (applyCarouselNode(key, val)) continue;
|
|
8788
7028
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
8789
7029
|
if (el.dataset.ohwEditable === "image") {
|
|
8790
7030
|
const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
|
|
@@ -8815,8 +7055,6 @@ function OhhwellsBridge() {
|
|
|
8815
7055
|
});
|
|
8816
7056
|
applyLinkByKey(key, val);
|
|
8817
7057
|
}
|
|
8818
|
-
reconcileNavbarItemsFromContent(content);
|
|
8819
|
-
reconcileFooterOrderFromContent(content);
|
|
8820
7058
|
enforceLinkHrefs();
|
|
8821
7059
|
initSectionsFromContent(content, true);
|
|
8822
7060
|
sectionsLoadedRef.current = true;
|
|
@@ -8845,7 +7083,7 @@ function OhhwellsBridge() {
|
|
|
8845
7083
|
cancelled = true;
|
|
8846
7084
|
};
|
|
8847
7085
|
}, [subdomain, isEditMode]);
|
|
8848
|
-
(0,
|
|
7086
|
+
(0, import_react6.useEffect)(() => {
|
|
8849
7087
|
if (!subdomain || isEditMode) return;
|
|
8850
7088
|
let debounceTimer = null;
|
|
8851
7089
|
let observer = null;
|
|
@@ -8858,7 +7096,6 @@ function OhhwellsBridge() {
|
|
|
8858
7096
|
for (const [key, val] of Object.entries(content)) {
|
|
8859
7097
|
if (key === "__ohw_sections") continue;
|
|
8860
7098
|
if (applyVideoSettingNode(key, val)) continue;
|
|
8861
|
-
if (applyCarouselNode(key, val)) continue;
|
|
8862
7099
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
8863
7100
|
if (el.dataset.ohwEditable === "image") {
|
|
8864
7101
|
const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
|
|
@@ -8877,8 +7114,6 @@ function OhhwellsBridge() {
|
|
|
8877
7114
|
});
|
|
8878
7115
|
applyLinkByKey(key, val);
|
|
8879
7116
|
}
|
|
8880
|
-
reconcileNavbarItemsFromContent(content);
|
|
8881
|
-
reconcileFooterOrderFromContent(content);
|
|
8882
7117
|
} finally {
|
|
8883
7118
|
observer?.observe(document.body, { childList: true, subtree: true });
|
|
8884
7119
|
}
|
|
@@ -8896,71 +7131,26 @@ function OhhwellsBridge() {
|
|
|
8896
7131
|
if (debounceTimer) clearTimeout(debounceTimer);
|
|
8897
7132
|
};
|
|
8898
7133
|
}, [subdomain, isEditMode, pathname]);
|
|
8899
|
-
(0,
|
|
7134
|
+
(0, import_react6.useLayoutEffect)(() => {
|
|
8900
7135
|
const el = document.getElementById("ohw-loader");
|
|
8901
7136
|
if (!el) return;
|
|
8902
7137
|
const visible = Boolean(subdomain) && fetchState !== "done";
|
|
8903
7138
|
el.style.display = visible ? "flex" : "none";
|
|
8904
7139
|
}, [subdomain, fetchState]);
|
|
8905
|
-
(0,
|
|
8906
|
-
|
|
8907
|
-
}, [pathname,
|
|
8908
|
-
(0,
|
|
7140
|
+
(0, import_react6.useEffect)(() => {
|
|
7141
|
+
postToParent({ type: "ow:navigation", path: pathname });
|
|
7142
|
+
}, [pathname, postToParent]);
|
|
7143
|
+
(0, import_react6.useEffect)(() => {
|
|
8909
7144
|
if (!isEditMode) return;
|
|
8910
|
-
if (linkPopoverSessionRef.current?.intent === "add-nav") return;
|
|
8911
|
-
if (document.querySelector("[data-ohw-section-picker]")) return;
|
|
8912
7145
|
setLinkPopover(null);
|
|
8913
7146
|
deselectRef.current();
|
|
8914
7147
|
deactivateRef.current();
|
|
8915
7148
|
}, [pathname, isEditMode]);
|
|
8916
|
-
(0,
|
|
8917
|
-
const contentForNav = () => {
|
|
8918
|
-
if (isEditMode) return editContentRef.current;
|
|
8919
|
-
if (!subdomain) return {};
|
|
8920
|
-
return contentCache.get(subdomain) ?? {};
|
|
8921
|
-
};
|
|
8922
|
-
let applying = false;
|
|
8923
|
-
let rafId = null;
|
|
8924
|
-
const run = () => {
|
|
8925
|
-
if (footerDragRef.current || applying) return;
|
|
8926
|
-
applying = true;
|
|
8927
|
-
try {
|
|
8928
|
-
const content = contentForNav();
|
|
8929
|
-
reconcileNavbarItemsFromContent(content);
|
|
8930
|
-
reconcileFooterOrderFromContent(content);
|
|
8931
|
-
document.querySelectorAll("footer [data-ohw-href-key]").forEach((el) => {
|
|
8932
|
-
if (isFooterHrefKey(el.getAttribute("data-ohw-href-key"))) {
|
|
8933
|
-
disableNativeHrefDrag(el);
|
|
8934
|
-
}
|
|
8935
|
-
});
|
|
8936
|
-
} finally {
|
|
8937
|
-
applying = false;
|
|
8938
|
-
}
|
|
8939
|
-
};
|
|
8940
|
-
const scheduleRun = () => {
|
|
8941
|
-
if (rafId !== null) cancelAnimationFrame(rafId);
|
|
8942
|
-
rafId = requestAnimationFrame(() => {
|
|
8943
|
-
rafId = null;
|
|
8944
|
-
run();
|
|
8945
|
-
});
|
|
8946
|
-
};
|
|
8947
|
-
run();
|
|
8948
|
-
const nav = document.querySelector("nav");
|
|
8949
|
-
const footer = document.querySelector("footer");
|
|
8950
|
-
const observer = new MutationObserver(scheduleRun);
|
|
8951
|
-
if (nav) observer.observe(nav, { childList: true, subtree: true });
|
|
8952
|
-
if (footer) observer.observe(footer, { childList: true, subtree: true });
|
|
8953
|
-
if (!nav && !footer) return;
|
|
8954
|
-
return () => {
|
|
8955
|
-
observer.disconnect();
|
|
8956
|
-
if (rafId !== null) cancelAnimationFrame(rafId);
|
|
8957
|
-
};
|
|
8958
|
-
}, [isEditMode, pathname, subdomain, fetchState]);
|
|
8959
|
-
(0, import_react9.useEffect)(() => {
|
|
7149
|
+
(0, import_react6.useEffect)(() => {
|
|
8960
7150
|
if (!isEditMode) return;
|
|
8961
7151
|
const measure = () => {
|
|
8962
7152
|
const h = document.body.scrollHeight;
|
|
8963
|
-
if (h > 50)
|
|
7153
|
+
if (h > 50) postToParent({ type: "ow:height", height: h });
|
|
8964
7154
|
};
|
|
8965
7155
|
const t1 = setTimeout(measure, 50);
|
|
8966
7156
|
const t2 = setTimeout(measure, 500);
|
|
@@ -8979,8 +7169,8 @@ function OhhwellsBridge() {
|
|
|
8979
7169
|
if (resizeTimer) clearTimeout(resizeTimer);
|
|
8980
7170
|
window.removeEventListener("resize", handleResize);
|
|
8981
7171
|
};
|
|
8982
|
-
}, [pathname, isEditMode,
|
|
8983
|
-
(0,
|
|
7172
|
+
}, [pathname, isEditMode, postToParent]);
|
|
7173
|
+
(0, import_react6.useEffect)(() => {
|
|
8984
7174
|
if (!subdomainFromQuery || isEditMode) return;
|
|
8985
7175
|
const handleClick = (e) => {
|
|
8986
7176
|
const anchor = e.target.closest("a");
|
|
@@ -8996,7 +7186,7 @@ function OhhwellsBridge() {
|
|
|
8996
7186
|
document.addEventListener("click", handleClick, true);
|
|
8997
7187
|
return () => document.removeEventListener("click", handleClick, true);
|
|
8998
7188
|
}, [subdomainFromQuery, isEditMode, router]);
|
|
8999
|
-
(0,
|
|
7189
|
+
(0, import_react6.useEffect)(() => {
|
|
9000
7190
|
if (!isEditMode) {
|
|
9001
7191
|
editStylesRef.current?.base.remove();
|
|
9002
7192
|
editStylesRef.current?.forceHover.remove();
|
|
@@ -9019,29 +7209,6 @@ function OhhwellsBridge() {
|
|
|
9019
7209
|
[data-ohw-editable] {
|
|
9020
7210
|
display: block;
|
|
9021
7211
|
}
|
|
9022
|
-
/* Native <a> drag steals clicks \u2014 disable for edit links; reorder via press-to-drag / handle. */
|
|
9023
|
-
footer [data-ohw-href-key] {
|
|
9024
|
-
-webkit-user-drag: none !important;
|
|
9025
|
-
}
|
|
9026
|
-
footer [data-ohw-footer-col]:hover {
|
|
9027
|
-
outline: 1.5px dashed ${PRIMARY2} !important;
|
|
9028
|
-
outline-offset: 6px;
|
|
9029
|
-
border-radius: 8px;
|
|
9030
|
-
}
|
|
9031
|
-
html[data-ohw-footer-press-drag] footer,
|
|
9032
|
-
html[data-ohw-footer-press-drag] footer * {
|
|
9033
|
-
user-select: none !important;
|
|
9034
|
-
-webkit-user-select: none !important;
|
|
9035
|
-
}
|
|
9036
|
-
html[data-ohw-item-dragging] footer,
|
|
9037
|
-
html[data-ohw-item-dragging] footer * {
|
|
9038
|
-
user-select: none !important;
|
|
9039
|
-
-webkit-user-select: none !important;
|
|
9040
|
-
pointer-events: none !important;
|
|
9041
|
-
}
|
|
9042
|
-
html[data-ohw-item-dragging] {
|
|
9043
|
-
cursor: grabbing !important;
|
|
9044
|
-
}
|
|
9045
7212
|
[data-ohw-editable]:not([contenteditable]):not([data-ohw-editable="image"]):not([data-ohw-editable="bg-image"]):not([data-ohw-editable="video"]) { cursor: text !important; }
|
|
9046
7213
|
[data-ohw-editable="image"], [data-ohw-editable="image"] *,
|
|
9047
7214
|
[data-ohw-editable="video"], [data-ohw-editable="video"] *,
|
|
@@ -9084,49 +7251,15 @@ function OhhwellsBridge() {
|
|
|
9084
7251
|
document.head.appendChild(forceHover);
|
|
9085
7252
|
document.head.appendChild(stateViews);
|
|
9086
7253
|
editStylesRef.current = { base, forceHover, stateViews };
|
|
9087
|
-
}
|
|
9088
|
-
refreshStateRules();
|
|
9089
|
-
const handleClick = (e) => {
|
|
9090
|
-
|
|
9091
|
-
|
|
9092
|
-
|
|
9093
|
-
|
|
9094
|
-
|
|
9095
|
-
|
|
9096
|
-
const target = e.target;
|
|
9097
|
-
if (target.closest("[data-ohw-toolbar]")) return;
|
|
9098
|
-
if (target.closest("[data-ohw-state-toggle]")) return;
|
|
9099
|
-
if (target.closest("[data-ohw-max-badge]")) return;
|
|
9100
|
-
if (isInsideLinkEditor(target)) return;
|
|
9101
|
-
if (target.closest('[data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
|
|
9102
|
-
if (target.closest("[data-ohw-item-drag-surface]")) {
|
|
9103
|
-
e.preventDefault();
|
|
9104
|
-
e.stopPropagation();
|
|
9105
|
-
const selected = selectedElRef.current;
|
|
9106
|
-
if (selected && isNavigationItem(selected)) {
|
|
9107
|
-
const editable2 = selected.querySelector('[data-ohw-editable="text"]') ?? selected.querySelector("[data-ohw-editable]");
|
|
9108
|
-
if (editable2) {
|
|
9109
|
-
activateRef.current(editable2, {
|
|
9110
|
-
caretX: e.clientX,
|
|
9111
|
-
caretY: e.clientY
|
|
9112
|
-
});
|
|
9113
|
-
}
|
|
9114
|
-
} else if (selected?.hasAttribute("data-ohw-footer-col")) {
|
|
9115
|
-
const link = listFooterLinksInColumn(selected).find((el) => {
|
|
9116
|
-
const r2 = el.getBoundingClientRect();
|
|
9117
|
-
return e.clientX >= r2.left && e.clientX <= r2.right && e.clientY >= r2.top && e.clientY <= r2.bottom;
|
|
9118
|
-
});
|
|
9119
|
-
if (link) selectRef.current(link);
|
|
9120
|
-
}
|
|
9121
|
-
return;
|
|
9122
|
-
}
|
|
9123
|
-
const navFromChrome = resolveNavContainerSelectionTarget(target, e.clientX, e.clientY);
|
|
9124
|
-
if (navFromChrome) {
|
|
9125
|
-
e.preventDefault();
|
|
9126
|
-
e.stopPropagation();
|
|
9127
|
-
selectFrameRef.current(navFromChrome);
|
|
9128
|
-
return;
|
|
9129
|
-
}
|
|
7254
|
+
}
|
|
7255
|
+
refreshStateRules();
|
|
7256
|
+
const handleClick = (e) => {
|
|
7257
|
+
const target = e.target;
|
|
7258
|
+
if (target.closest("[data-ohw-toolbar]")) return;
|
|
7259
|
+
if (target.closest("[data-ohw-state-toggle]")) return;
|
|
7260
|
+
if (target.closest("[data-ohw-max-badge]")) return;
|
|
7261
|
+
if (isInsideLinkEditor(target)) return;
|
|
7262
|
+
if (target.closest('[data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
|
|
9130
7263
|
e.preventDefault();
|
|
9131
7264
|
e.stopPropagation();
|
|
9132
7265
|
return;
|
|
@@ -9141,8 +7274,7 @@ function OhhwellsBridge() {
|
|
|
9141
7274
|
bumpLinkPopoverGrace();
|
|
9142
7275
|
setLinkPopoverRef.current({
|
|
9143
7276
|
key: editable.dataset.ohwKey ?? "",
|
|
9144
|
-
|
|
9145
|
-
target: getLinkHref2(editable)
|
|
7277
|
+
target: getLinkHref(editable)
|
|
9146
7278
|
});
|
|
9147
7279
|
return;
|
|
9148
7280
|
}
|
|
@@ -9158,8 +7290,7 @@ function OhhwellsBridge() {
|
|
|
9158
7290
|
e.preventDefault();
|
|
9159
7291
|
e.stopPropagation();
|
|
9160
7292
|
if (selectedElRef.current === navAnchor) {
|
|
9161
|
-
|
|
9162
|
-
activateRef.current(editable, { caretX: e.clientX, caretY: e.clientY });
|
|
7293
|
+
activateRef.current(editable);
|
|
9163
7294
|
return;
|
|
9164
7295
|
}
|
|
9165
7296
|
selectRef.current(navAnchor);
|
|
@@ -9174,42 +7305,10 @@ function OhhwellsBridge() {
|
|
|
9174
7305
|
if (hrefAnchor) {
|
|
9175
7306
|
e.preventDefault();
|
|
9176
7307
|
e.stopPropagation();
|
|
9177
|
-
if (selectedElRef.current === hrefAnchor)
|
|
9178
|
-
const textEditable = hrefAnchor.querySelector('[data-ohw-editable="text"]') ?? hrefAnchor.querySelector("[data-ohw-editable]");
|
|
9179
|
-
if (textEditable) {
|
|
9180
|
-
activateRef.current(textEditable, {
|
|
9181
|
-
caretX: e.clientX,
|
|
9182
|
-
caretY: e.clientY
|
|
9183
|
-
});
|
|
9184
|
-
}
|
|
9185
|
-
return;
|
|
9186
|
-
}
|
|
7308
|
+
if (selectedElRef.current === hrefAnchor) return;
|
|
9187
7309
|
selectRef.current(hrefAnchor);
|
|
9188
7310
|
return;
|
|
9189
7311
|
}
|
|
9190
|
-
const footerColClick = target.closest("[data-ohw-footer-col]");
|
|
9191
|
-
if (footerColClick) {
|
|
9192
|
-
e.preventDefault();
|
|
9193
|
-
e.stopPropagation();
|
|
9194
|
-
selectFrameRef.current(footerColClick);
|
|
9195
|
-
return;
|
|
9196
|
-
}
|
|
9197
|
-
const navContainerToSelect = resolveNavContainerSelectionTarget(target, e.clientX, e.clientY);
|
|
9198
|
-
if (navContainerToSelect) {
|
|
9199
|
-
e.preventDefault();
|
|
9200
|
-
e.stopPropagation();
|
|
9201
|
-
selectFrameRef.current(navContainerToSelect);
|
|
9202
|
-
return;
|
|
9203
|
-
}
|
|
9204
|
-
const selectedContainer = selectedElRef.current;
|
|
9205
|
-
if (selectedContainer && isNavigationContainer(selectedContainer)) {
|
|
9206
|
-
const navItem = getNavigationItemAnchor(target);
|
|
9207
|
-
if (!navItem && (selectedContainer === target || selectedContainer.contains(target))) {
|
|
9208
|
-
e.preventDefault();
|
|
9209
|
-
e.stopPropagation();
|
|
9210
|
-
return;
|
|
9211
|
-
}
|
|
9212
|
-
}
|
|
9213
7312
|
if (activeElRef.current) {
|
|
9214
7313
|
const sel = window.getSelection();
|
|
9215
7314
|
if (sel && !sel.isCollapsed) {
|
|
@@ -9235,58 +7334,10 @@ function OhhwellsBridge() {
|
|
|
9235
7334
|
deselectRef.current();
|
|
9236
7335
|
deactivateRef.current();
|
|
9237
7336
|
};
|
|
9238
|
-
const handleDblClick = (e) => {
|
|
9239
|
-
const target = e.target;
|
|
9240
|
-
if (target.closest("[data-ohw-toolbar]")) return;
|
|
9241
|
-
if (target.closest("[data-ohw-state-toggle]")) return;
|
|
9242
|
-
if (target.closest("[data-ohw-max-badge]")) return;
|
|
9243
|
-
if (isInsideLinkEditor(target)) return;
|
|
9244
|
-
if (target.closest('[data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
|
|
9245
|
-
return;
|
|
9246
|
-
}
|
|
9247
|
-
const navLabel = getNavigationLabelEditable(target);
|
|
9248
|
-
if (!navLabel) return;
|
|
9249
|
-
const { editable } = navLabel;
|
|
9250
|
-
e.preventDefault();
|
|
9251
|
-
e.stopPropagation();
|
|
9252
|
-
if (activeElRef.current !== editable) {
|
|
9253
|
-
activateRef.current(editable);
|
|
9254
|
-
}
|
|
9255
|
-
requestAnimationFrame(() => {
|
|
9256
|
-
selectAllTextInEditable(editable);
|
|
9257
|
-
refreshActiveCommandsRef.current();
|
|
9258
|
-
});
|
|
9259
|
-
};
|
|
9260
7337
|
const handleMouseOver = (e) => {
|
|
9261
|
-
if (document.documentElement.hasAttribute("data-ohw-section-picking")) return;
|
|
9262
7338
|
const target = e.target;
|
|
9263
|
-
if (toolbarVariantRef.current !== "select-frame") {
|
|
9264
|
-
const navContainer = target.closest("[data-ohw-nav-container]");
|
|
9265
|
-
if (navContainer && !getNavigationItemAnchor(target)) {
|
|
9266
|
-
hoveredNavContainerRef.current = navContainer;
|
|
9267
|
-
setHoveredNavContainerRect(navContainer.getBoundingClientRect());
|
|
9268
|
-
hoveredItemElRef.current = null;
|
|
9269
|
-
setHoveredItemRect(null);
|
|
9270
|
-
return;
|
|
9271
|
-
}
|
|
9272
|
-
if (!target.closest("[data-ohw-nav-container]")) {
|
|
9273
|
-
hoveredNavContainerRef.current = null;
|
|
9274
|
-
setHoveredNavContainerRect(null);
|
|
9275
|
-
}
|
|
9276
|
-
}
|
|
9277
|
-
const footerCol = target.closest("[data-ohw-footer-col]");
|
|
9278
|
-
if (footerCol) {
|
|
9279
|
-
hoveredNavContainerRef.current = null;
|
|
9280
|
-
setHoveredNavContainerRect(null);
|
|
9281
|
-
if (selectedElRef.current === footerCol) return;
|
|
9282
|
-
hoveredItemElRef.current = footerCol;
|
|
9283
|
-
setHoveredItemRect(footerCol.getBoundingClientRect());
|
|
9284
|
-
return;
|
|
9285
|
-
}
|
|
9286
7339
|
const navAnchor = getNavigationItemAnchor(target);
|
|
9287
7340
|
if (navAnchor) {
|
|
9288
|
-
hoveredNavContainerRef.current = null;
|
|
9289
|
-
setHoveredNavContainerRect(null);
|
|
9290
7341
|
const selected2 = selectedElRef.current;
|
|
9291
7342
|
if (selected2 === navAnchor || selected2?.contains(navAnchor)) return;
|
|
9292
7343
|
clearHrefKeyHover(navAnchor);
|
|
@@ -9311,23 +7362,6 @@ function OhhwellsBridge() {
|
|
|
9311
7362
|
};
|
|
9312
7363
|
const handleMouseOut = (e) => {
|
|
9313
7364
|
const target = e.target;
|
|
9314
|
-
if (target.closest("[data-ohw-nav-container]")) {
|
|
9315
|
-
const related2 = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
9316
|
-
if (related2?.closest("[data-ohw-nav-container], [data-ohw-navbar-container-chrome], [data-ohw-navbar-add-button]")) {
|
|
9317
|
-
return;
|
|
9318
|
-
}
|
|
9319
|
-
hoveredNavContainerRef.current = null;
|
|
9320
|
-
setHoveredNavContainerRect(null);
|
|
9321
|
-
}
|
|
9322
|
-
const footerCol = target.closest("[data-ohw-footer-col]");
|
|
9323
|
-
if (footerCol && hoveredItemElRef.current === footerCol) {
|
|
9324
|
-
const related2 = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
9325
|
-
if (related2?.closest("[data-ohw-drag-handle-container], [data-ohw-item-interaction]")) return;
|
|
9326
|
-
if (related2?.closest("[data-ohw-footer-col]") === footerCol) return;
|
|
9327
|
-
hoveredItemElRef.current = null;
|
|
9328
|
-
setHoveredItemRect(null);
|
|
9329
|
-
return;
|
|
9330
|
-
}
|
|
9331
7365
|
const navAnchor = getNavigationItemAnchor(target);
|
|
9332
7366
|
if (navAnchor) {
|
|
9333
7367
|
const related2 = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
@@ -9449,85 +7483,42 @@ function OhhwellsBridge() {
|
|
|
9449
7483
|
}
|
|
9450
7484
|
return smallest;
|
|
9451
7485
|
};
|
|
9452
|
-
const dismissImageHover = () => {
|
|
9453
|
-
if (hoveredImageRef.current) {
|
|
9454
|
-
hoveredImageRef.current = null;
|
|
9455
|
-
hoveredImageHasTextOverlapRef.current = false;
|
|
9456
|
-
resumeAnimTracks();
|
|
9457
|
-
postToParentRef.current({ type: "ow:image-unhover" });
|
|
9458
|
-
}
|
|
9459
|
-
clearImageHover();
|
|
9460
|
-
};
|
|
9461
|
-
const probeNavigationHoverAt = (x, y) => {
|
|
9462
|
-
if (toolbarVariantRef.current === "select-frame") {
|
|
9463
|
-
hoveredNavContainerRef.current = null;
|
|
9464
|
-
setHoveredNavContainerRect(null);
|
|
9465
|
-
return;
|
|
9466
|
-
}
|
|
9467
|
-
const navContainer = document.querySelector("[data-ohw-nav-container]");
|
|
9468
|
-
if (!navContainer) {
|
|
9469
|
-
hoveredNavContainerRef.current = null;
|
|
9470
|
-
setHoveredNavContainerRect(null);
|
|
9471
|
-
return;
|
|
9472
|
-
}
|
|
9473
|
-
const containerRect = navContainer.getBoundingClientRect();
|
|
9474
|
-
const overContainer = x >= containerRect.left && x <= containerRect.right && y >= containerRect.top && y <= containerRect.bottom;
|
|
9475
|
-
if (!overContainer) {
|
|
9476
|
-
hoveredNavContainerRef.current = null;
|
|
9477
|
-
setHoveredNavContainerRect(null);
|
|
9478
|
-
return;
|
|
9479
|
-
}
|
|
9480
|
-
const navItemHit = Array.from(
|
|
9481
|
-
navContainer.querySelectorAll("[data-ohw-href-key]")
|
|
9482
|
-
).find((el) => {
|
|
9483
|
-
if (!isNavigationItem(el) || isNavbarButton2(el)) return false;
|
|
9484
|
-
const itemRect = el.getBoundingClientRect();
|
|
9485
|
-
return x >= itemRect.left && x <= itemRect.right && y >= itemRect.top && y <= itemRect.bottom;
|
|
9486
|
-
});
|
|
9487
|
-
if (navItemHit) {
|
|
9488
|
-
hoveredNavContainerRef.current = null;
|
|
9489
|
-
setHoveredNavContainerRect(null);
|
|
9490
|
-
const selected = selectedElRef.current;
|
|
9491
|
-
if (selected !== navItemHit && !selected?.contains(navItemHit)) {
|
|
9492
|
-
clearHrefKeyHover(navItemHit);
|
|
9493
|
-
hoveredItemElRef.current = navItemHit;
|
|
9494
|
-
setHoveredItemRect(navItemHit.getBoundingClientRect());
|
|
9495
|
-
}
|
|
9496
|
-
return;
|
|
9497
|
-
}
|
|
9498
|
-
hoveredNavContainerRef.current = navContainer;
|
|
9499
|
-
setHoveredNavContainerRect(containerRect);
|
|
9500
|
-
hoveredItemElRef.current = null;
|
|
9501
|
-
setHoveredItemRect(null);
|
|
9502
|
-
};
|
|
9503
7486
|
const probeImageAt = (clientX, clientY, isDragOver = false, fromParentViewport = false) => {
|
|
9504
7487
|
if (linkPopoverOpenRef.current) {
|
|
9505
|
-
|
|
9506
|
-
|
|
9507
|
-
|
|
9508
|
-
|
|
9509
|
-
|
|
9510
|
-
|
|
9511
|
-
probeNavigationHoverAt(x, y);
|
|
7488
|
+
if (hoveredImageRef.current) {
|
|
7489
|
+
hoveredImageRef.current = null;
|
|
7490
|
+
hoveredImageHasTextOverlapRef.current = false;
|
|
7491
|
+
resumeAnimTracks();
|
|
7492
|
+
clearImageHover();
|
|
7493
|
+
}
|
|
9512
7494
|
return;
|
|
9513
7495
|
}
|
|
9514
|
-
hoveredNavContainerRef.current = null;
|
|
9515
|
-
setHoveredNavContainerRect(null);
|
|
9516
7496
|
const toggleEl = document.querySelector("[data-ohw-state-toggle]");
|
|
9517
7497
|
if (toggleEl) {
|
|
7498
|
+
const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
9518
7499
|
const tr = toggleEl.getBoundingClientRect();
|
|
9519
7500
|
if (x >= tr.left && x <= tr.right && y >= tr.top && y <= tr.bottom) {
|
|
9520
|
-
|
|
7501
|
+
if (hoveredImageRef.current) {
|
|
7502
|
+
hoveredImageRef.current = null;
|
|
7503
|
+
resumeAnimTracks();
|
|
7504
|
+
clearImageHover();
|
|
7505
|
+
}
|
|
9521
7506
|
return;
|
|
9522
7507
|
}
|
|
9523
7508
|
}
|
|
9524
7509
|
const imgEl = findImageAtPoint(clientX, clientY, fromParentViewport);
|
|
9525
7510
|
const activeEl = activeElRef.current;
|
|
9526
7511
|
if (activeEl && (!imgEl || imgEl.contains(activeEl))) {
|
|
9527
|
-
|
|
7512
|
+
if (hoveredImageRef.current) {
|
|
7513
|
+
hoveredImageRef.current = null;
|
|
7514
|
+
hoveredImageHasTextOverlapRef.current = false;
|
|
7515
|
+
resumeAnimTracks();
|
|
7516
|
+
clearImageHover();
|
|
7517
|
+
}
|
|
9528
7518
|
return;
|
|
9529
7519
|
}
|
|
9530
7520
|
if (imgEl) {
|
|
7521
|
+
const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
9531
7522
|
const topEl = document.elementFromPoint(x, y);
|
|
9532
7523
|
if (topEl?.closest('[data-ohw-toolbar], [data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
|
|
9533
7524
|
if (hoveredImageRef.current) {
|
|
@@ -9627,12 +7618,12 @@ function OhhwellsBridge() {
|
|
|
9627
7618
|
resumeAnimTracks();
|
|
9628
7619
|
clearImageHover();
|
|
9629
7620
|
}
|
|
9630
|
-
const { x
|
|
7621
|
+
const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
9631
7622
|
const textEl = Array.from(
|
|
9632
7623
|
document.querySelectorAll(NON_MEDIA_SELECTOR)
|
|
9633
7624
|
).find((el) => {
|
|
9634
7625
|
const er = el.getBoundingClientRect();
|
|
9635
|
-
return
|
|
7626
|
+
return x >= er.left && x <= er.right && y >= er.top && y <= er.bottom;
|
|
9636
7627
|
});
|
|
9637
7628
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
9638
7629
|
if (textEl && !textEl.hasAttribute("contenteditable")) {
|
|
@@ -9656,14 +7647,6 @@ function OhhwellsBridge() {
|
|
|
9656
7647
|
}
|
|
9657
7648
|
};
|
|
9658
7649
|
const probeHoverCardsAt = (clientX, clientY, fromParentViewport = false) => {
|
|
9659
|
-
if (linkPopoverOpenRef.current || document.documentElement.hasAttribute("data-ohw-section-picking")) {
|
|
9660
|
-
if (activeStateElRef.current) {
|
|
9661
|
-
activeStateElRef.current.removeAttribute("data-ohw-state-hovered");
|
|
9662
|
-
activeStateElRef.current = null;
|
|
9663
|
-
setToggleState(null);
|
|
9664
|
-
}
|
|
9665
|
-
return;
|
|
9666
|
-
}
|
|
9667
7650
|
const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
9668
7651
|
const toggleEl = document.querySelector("[data-ohw-state-toggle]");
|
|
9669
7652
|
if (toggleEl) {
|
|
@@ -9736,14 +7719,6 @@ function OhhwellsBridge() {
|
|
|
9736
7719
|
probeHoverCardsAt(clientX, clientY);
|
|
9737
7720
|
};
|
|
9738
7721
|
const handleDragOver = (e) => {
|
|
9739
|
-
const footerSession = footerDragRef.current;
|
|
9740
|
-
if (footerSession) {
|
|
9741
|
-
e.preventDefault();
|
|
9742
|
-
if (e.dataTransfer) e.dataTransfer.dropEffect = "move";
|
|
9743
|
-
const slot = footerSession.kind === "link" && footerSession.hrefKey ? hitTestLinkDropSlot(e.clientX, e.clientY, footerSession.hrefKey) : hitTestColumnDropSlot(e.clientX, e.clientY);
|
|
9744
|
-
refreshFooterDragVisualsRef.current(footerSession, slot, e.clientX, e.clientY);
|
|
9745
|
-
return;
|
|
9746
|
-
}
|
|
9747
7722
|
e.preventDefault();
|
|
9748
7723
|
const el = findImageAtPoint(e.clientX, e.clientY, false);
|
|
9749
7724
|
if (!el) {
|
|
@@ -9926,7 +7901,6 @@ function OhhwellsBridge() {
|
|
|
9926
7901
|
continue;
|
|
9927
7902
|
}
|
|
9928
7903
|
if (applyVideoSettingNode(key, val)) continue;
|
|
9929
|
-
if (applyCarouselNode(key, val)) continue;
|
|
9930
7904
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
9931
7905
|
if (el.dataset.ohwEditable === "image") {
|
|
9932
7906
|
const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
|
|
@@ -9949,9 +7923,6 @@ function OhhwellsBridge() {
|
|
|
9949
7923
|
sectionsLoadedRef.current = true;
|
|
9950
7924
|
pendingScheduleConfigRequests.current.splice(0).forEach(processConfigRequest);
|
|
9951
7925
|
}
|
|
9952
|
-
editContentRef.current = { ...editContentRef.current, ...content };
|
|
9953
|
-
reconcileNavbarItemsFromContent(editContentRef.current);
|
|
9954
|
-
reconcileFooterOrderFromContent(editContentRef.current);
|
|
9955
7926
|
enforceLinkHrefs();
|
|
9956
7927
|
postToParentRef.current({ type: "ow:hydrate-done" });
|
|
9957
7928
|
};
|
|
@@ -9959,7 +7930,6 @@ function OhhwellsBridge() {
|
|
|
9959
7930
|
const handleDeactivate = (e) => {
|
|
9960
7931
|
if (e.data?.type !== "ow:deactivate") return;
|
|
9961
7932
|
if (Date.now() < linkPopoverGraceUntilRef.current) return;
|
|
9962
|
-
if (document.querySelector("[data-ohw-section-picker]")) return;
|
|
9963
7933
|
if (linkPopoverOpenRef.current) {
|
|
9964
7934
|
setLinkPopoverRef.current(null);
|
|
9965
7935
|
return;
|
|
@@ -9968,40 +7938,13 @@ function OhhwellsBridge() {
|
|
|
9968
7938
|
deactivateRef.current();
|
|
9969
7939
|
};
|
|
9970
7940
|
window.addEventListener("message", handleDeactivate);
|
|
9971
|
-
const handleUiEscape = (e) => {
|
|
9972
|
-
if (e.data?.type !== "ui:escape") return;
|
|
9973
|
-
if (linkPopoverOpenRef.current) {
|
|
9974
|
-
setLinkPopoverRef.current(null);
|
|
9975
|
-
}
|
|
9976
|
-
};
|
|
9977
|
-
window.addEventListener("message", handleUiEscape);
|
|
9978
7941
|
const handleKeyDown = (e) => {
|
|
9979
|
-
if (e.key === "Escape" && document.querySelector("[data-ohw-section-picker]")) return;
|
|
9980
|
-
if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === "a" && activeElRef.current) {
|
|
9981
|
-
const navAnchor = getNavigationItemAnchor(activeElRef.current);
|
|
9982
|
-
if (navAnchor) {
|
|
9983
|
-
e.preventDefault();
|
|
9984
|
-
selectAllTextInEditable(activeElRef.current);
|
|
9985
|
-
refreshActiveCommandsRef.current();
|
|
9986
|
-
return;
|
|
9987
|
-
}
|
|
9988
|
-
}
|
|
9989
7942
|
if (e.key === "Escape" && linkPopoverOpenRef.current) {
|
|
9990
7943
|
setLinkPopoverRef.current(null);
|
|
9991
7944
|
return;
|
|
9992
7945
|
}
|
|
9993
7946
|
if (e.key === "Escape" && selectedElRef.current && !activeElRef.current) {
|
|
9994
|
-
|
|
9995
|
-
deselectRef.current();
|
|
9996
|
-
return;
|
|
9997
|
-
}
|
|
9998
|
-
const parent = getNavigationSelectionParent(selectedElRef.current);
|
|
9999
|
-
if (parent) {
|
|
10000
|
-
e.preventDefault();
|
|
10001
|
-
selectFrameRef.current(parent);
|
|
10002
|
-
} else {
|
|
10003
|
-
deselectRef.current();
|
|
10004
|
-
}
|
|
7947
|
+
deselectRef.current();
|
|
10005
7948
|
return;
|
|
10006
7949
|
}
|
|
10007
7950
|
if (e.key === "Escape" && activeElRef.current) {
|
|
@@ -10059,23 +8002,9 @@ function OhhwellsBridge() {
|
|
|
10059
8002
|
if (hoveredItemElRef.current) {
|
|
10060
8003
|
setHoveredItemRect(hoveredItemElRef.current.getBoundingClientRect());
|
|
10061
8004
|
}
|
|
10062
|
-
if (hoveredNavContainerRef.current) {
|
|
10063
|
-
setHoveredNavContainerRect(hoveredNavContainerRef.current.getBoundingClientRect());
|
|
10064
|
-
}
|
|
10065
8005
|
if (siblingHintElRef.current) {
|
|
10066
8006
|
setSiblingHintRect(siblingHintElRef.current.getBoundingClientRect());
|
|
10067
8007
|
}
|
|
10068
|
-
const selected = selectedElRef.current;
|
|
10069
|
-
if (selected && !footerDragRef.current && (selected.hasAttribute("data-ohw-footer-col") || Boolean(selected.closest("footer") && isInferredFooterGroup(selected)))) {
|
|
10070
|
-
setSiblingHintRects(
|
|
10071
|
-
listFooterColumns().filter((column) => column !== selected).map((column) => column.getBoundingClientRect())
|
|
10072
|
-
);
|
|
10073
|
-
}
|
|
10074
|
-
if (footerDragRef.current) {
|
|
10075
|
-
const session = footerDragRef.current;
|
|
10076
|
-
const slot = session.kind === "link" && session.hrefKey ? hitTestLinkDropSlot(session.lastClientX, session.lastClientY, session.hrefKey) : hitTestColumnDropSlot(session.lastClientX, session.lastClientY);
|
|
10077
|
-
refreshFooterDragVisualsRef.current(session, slot, session.lastClientX, session.lastClientY);
|
|
10078
|
-
}
|
|
10079
8008
|
if (hoveredImageRef.current) {
|
|
10080
8009
|
const el = hoveredImageRef.current;
|
|
10081
8010
|
const r2 = el.getBoundingClientRect();
|
|
@@ -10086,7 +8015,7 @@ function OhhwellsBridge() {
|
|
|
10086
8015
|
};
|
|
10087
8016
|
const handleSave = (e) => {
|
|
10088
8017
|
if (e.data?.type !== "ow:save") return;
|
|
10089
|
-
const nodes = collectEditableNodes(
|
|
8018
|
+
const nodes = collectEditableNodes();
|
|
10090
8019
|
const tracker = document.querySelector("[data-ohw-sections-tracker]");
|
|
10091
8020
|
if (tracker?.textContent) nodes.push({ key: "__ohw_sections", type: "sections", text: tracker.textContent });
|
|
10092
8021
|
postToParentRef.current({ type: "ow:save-result", nodes });
|
|
@@ -10171,7 +8100,6 @@ function OhhwellsBridge() {
|
|
|
10171
8100
|
const handleDocMouseLeave = () => {
|
|
10172
8101
|
hoveredImageRef.current = null;
|
|
10173
8102
|
setMediaHover(null);
|
|
10174
|
-
setCarouselHover(null);
|
|
10175
8103
|
document.querySelectorAll("[data-ohw-state-hovered]").forEach((el) => el.removeAttribute("data-ohw-state-hovered"));
|
|
10176
8104
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
10177
8105
|
activeStateElRef.current = null;
|
|
@@ -10211,48 +8139,6 @@ function OhhwellsBridge() {
|
|
|
10211
8139
|
if (e.data?.type !== "ow:canvas-height" || typeof e.data.height !== "number") return;
|
|
10212
8140
|
document.documentElement.style.setProperty("--ohw-canvas-h", `${e.data.height}px`);
|
|
10213
8141
|
};
|
|
10214
|
-
const handleCarouselChange = (e) => {
|
|
10215
|
-
if (e.data?.type !== "ow:carousel-change") return;
|
|
10216
|
-
const { key, images } = e.data;
|
|
10217
|
-
if (!key || !Array.isArray(images)) return;
|
|
10218
|
-
const text = JSON.stringify(images);
|
|
10219
|
-
applyCarouselValue(key, images);
|
|
10220
|
-
editContentRef.current = { ...editContentRef.current, [key]: text };
|
|
10221
|
-
postToParentRef.current({ type: "ow:change", nodes: [{ key, text }] });
|
|
10222
|
-
setCarouselHover(null);
|
|
10223
|
-
};
|
|
10224
|
-
const findCarouselAtPoint = (clientX, clientY) => {
|
|
10225
|
-
const containers = Array.from(document.querySelectorAll(`[${CAROUSEL_ATTR}]`));
|
|
10226
|
-
for (let i = containers.length - 1; i >= 0; i--) {
|
|
10227
|
-
const r2 = containers[i].getBoundingClientRect();
|
|
10228
|
-
if (clientX >= r2.left && clientX <= r2.right && clientY >= r2.top && clientY <= r2.bottom) {
|
|
10229
|
-
return containers[i];
|
|
10230
|
-
}
|
|
10231
|
-
}
|
|
10232
|
-
return null;
|
|
10233
|
-
};
|
|
10234
|
-
const isPointOverEditable = (scope, clientX, clientY) => {
|
|
10235
|
-
const editables = scope.querySelectorAll("[data-ohw-editable], [data-ohw-href-key]");
|
|
10236
|
-
for (const el of editables) {
|
|
10237
|
-
const r2 = el.getBoundingClientRect();
|
|
10238
|
-
if (clientX >= r2.left && clientX <= r2.right && clientY >= r2.top && clientY <= r2.bottom) return true;
|
|
10239
|
-
}
|
|
10240
|
-
return false;
|
|
10241
|
-
};
|
|
10242
|
-
const handleCarouselHover = (e) => {
|
|
10243
|
-
const container = findCarouselAtPoint(e.clientX, e.clientY);
|
|
10244
|
-
const scope = container?.closest("[data-ohw-section]") ?? container?.parentElement ?? null;
|
|
10245
|
-
if (!container || !scope || isPointOverEditable(scope, e.clientX, e.clientY)) {
|
|
10246
|
-
setCarouselHover((prev) => prev ? null : prev);
|
|
10247
|
-
return;
|
|
10248
|
-
}
|
|
10249
|
-
const key = container.getAttribute("data-ohw-key") ?? "";
|
|
10250
|
-
if (!key) return;
|
|
10251
|
-
const r2 = getVisibleRect(container);
|
|
10252
|
-
setCarouselHover(
|
|
10253
|
-
(prev) => prev && prev.key === key && prev.rect.top === r2.top && prev.rect.left === r2.left && prev.rect.width === r2.width && prev.rect.height === r2.height ? prev : { key, rect: { top: r2.top, left: r2.left, width: r2.width, height: r2.height } }
|
|
10254
|
-
);
|
|
10255
|
-
};
|
|
10256
8142
|
const applyToolbarPos = (rect) => {
|
|
10257
8143
|
const ps = parentScrollRef.current;
|
|
10258
8144
|
const approxW = 330;
|
|
@@ -10312,45 +8198,9 @@ function OhhwellsBridge() {
|
|
|
10312
8198
|
return clientX >= r2.left && clientX <= r2.right && clientY >= r2.top && clientY <= r2.bottom;
|
|
10313
8199
|
});
|
|
10314
8200
|
if (textEditable) {
|
|
10315
|
-
|
|
10316
|
-
const navAnchor = hrefCtx ? getNavigationItemAnchor(hrefCtx.anchor) : null;
|
|
10317
|
-
if (navAnchor) {
|
|
10318
|
-
if (selectedElRef.current === navAnchor) {
|
|
10319
|
-
activateRef.current(textEditable, { caretX: clientX, caretY: clientY });
|
|
10320
|
-
} else {
|
|
10321
|
-
selectRef.current(navAnchor);
|
|
10322
|
-
}
|
|
10323
|
-
return;
|
|
10324
|
-
}
|
|
10325
|
-
activateRef.current(textEditable, { caretX: clientX, caretY: clientY });
|
|
8201
|
+
activateRef.current(textEditable);
|
|
10326
8202
|
return;
|
|
10327
8203
|
}
|
|
10328
|
-
const navContainer = document.querySelector("[data-ohw-nav-container]");
|
|
10329
|
-
if (navContainer) {
|
|
10330
|
-
const r2 = navContainer.getBoundingClientRect();
|
|
10331
|
-
const pad = 8;
|
|
10332
|
-
const over = clientX >= r2.left - pad && clientX <= r2.right + pad && clientY >= r2.top - pad && clientY <= r2.bottom + pad;
|
|
10333
|
-
if (over && !isPointOverNavItem(navContainer, clientX, clientY)) {
|
|
10334
|
-
selectFrameRef.current(navContainer);
|
|
10335
|
-
return;
|
|
10336
|
-
}
|
|
10337
|
-
}
|
|
10338
|
-
const navRoot = document.querySelector("[data-ohw-nav-root]");
|
|
10339
|
-
if (navRoot && navContainer) {
|
|
10340
|
-
const rr = navRoot.getBoundingClientRect();
|
|
10341
|
-
if (clientX >= rr.left && clientX <= rr.right && clientY >= rr.top && clientY <= rr.bottom && !isPointOverNavItem(navContainer, clientX, clientY)) {
|
|
10342
|
-
const book = navRoot.querySelector('[data-ohw-role="navbar-button"]');
|
|
10343
|
-
if (book) {
|
|
10344
|
-
const br = book.getBoundingClientRect();
|
|
10345
|
-
if (clientX >= br.left && clientX <= br.right && clientY >= br.top && clientY <= br.bottom) {
|
|
10346
|
-
deactivateRef.current();
|
|
10347
|
-
return;
|
|
10348
|
-
}
|
|
10349
|
-
}
|
|
10350
|
-
selectFrameRef.current(navContainer);
|
|
10351
|
-
return;
|
|
10352
|
-
}
|
|
10353
|
-
}
|
|
10354
8204
|
deactivateRef.current();
|
|
10355
8205
|
};
|
|
10356
8206
|
window.addEventListener("message", handleSave);
|
|
@@ -10361,7 +8211,6 @@ function OhhwellsBridge() {
|
|
|
10361
8211
|
window.addEventListener("message", handleRemoveSchedulingSection);
|
|
10362
8212
|
window.addEventListener("message", handleImageUrl);
|
|
10363
8213
|
window.addEventListener("message", handleImageUploading);
|
|
10364
|
-
window.addEventListener("message", handleCarouselChange);
|
|
10365
8214
|
window.addEventListener("message", handleCanvasHeight);
|
|
10366
8215
|
window.addEventListener("message", handleParentScroll);
|
|
10367
8216
|
window.addEventListener("message", handlePointerSync);
|
|
@@ -10373,13 +8222,11 @@ function OhhwellsBridge() {
|
|
|
10373
8222
|
};
|
|
10374
8223
|
window.addEventListener("resize", handleViewportResize, { passive: true });
|
|
10375
8224
|
document.addEventListener("click", handleClick, true);
|
|
10376
|
-
document.addEventListener("dblclick", handleDblClick, true);
|
|
10377
8225
|
document.addEventListener("paste", handlePaste, true);
|
|
10378
8226
|
document.addEventListener("input", handleInput, true);
|
|
10379
8227
|
document.addEventListener("mouseover", handleMouseOver, true);
|
|
10380
8228
|
document.addEventListener("mouseout", handleMouseOut, true);
|
|
10381
8229
|
document.addEventListener("mousemove", handleMouseMove, true);
|
|
10382
|
-
document.addEventListener("mousemove", handleCarouselHover, true);
|
|
10383
8230
|
document.addEventListener("mouseleave", handleDocMouseLeave);
|
|
10384
8231
|
document.addEventListener("dragover", handleDragOver, true);
|
|
10385
8232
|
document.addEventListener("dragleave", handleDragLeave, true);
|
|
@@ -10389,13 +8236,11 @@ function OhhwellsBridge() {
|
|
|
10389
8236
|
window.addEventListener("scroll", handleScroll, true);
|
|
10390
8237
|
return () => {
|
|
10391
8238
|
document.removeEventListener("click", handleClick, true);
|
|
10392
|
-
document.removeEventListener("dblclick", handleDblClick, true);
|
|
10393
8239
|
document.removeEventListener("paste", handlePaste, true);
|
|
10394
8240
|
document.removeEventListener("input", handleInput, true);
|
|
10395
8241
|
document.removeEventListener("mouseover", handleMouseOver, true);
|
|
10396
8242
|
document.removeEventListener("mouseout", handleMouseOut, true);
|
|
10397
8243
|
document.removeEventListener("mousemove", handleMouseMove, true);
|
|
10398
|
-
document.removeEventListener("mousemove", handleCarouselHover, true);
|
|
10399
8244
|
document.removeEventListener("mouseleave", handleDocMouseLeave);
|
|
10400
8245
|
document.removeEventListener("dragover", handleDragOver, true);
|
|
10401
8246
|
document.removeEventListener("dragleave", handleDragLeave, true);
|
|
@@ -10411,7 +8256,6 @@ function OhhwellsBridge() {
|
|
|
10411
8256
|
window.removeEventListener("message", handleRemoveSchedulingSection);
|
|
10412
8257
|
window.removeEventListener("message", handleImageUrl);
|
|
10413
8258
|
window.removeEventListener("message", handleImageUploading);
|
|
10414
|
-
window.removeEventListener("message", handleCarouselChange);
|
|
10415
8259
|
window.removeEventListener("message", handleCanvasHeight);
|
|
10416
8260
|
window.removeEventListener("message", handleParentScroll);
|
|
10417
8261
|
window.removeEventListener("resize", handleViewportResize);
|
|
@@ -10419,162 +8263,13 @@ function OhhwellsBridge() {
|
|
|
10419
8263
|
window.removeEventListener("message", handleClickAt);
|
|
10420
8264
|
window.removeEventListener("message", handleHydrate);
|
|
10421
8265
|
window.removeEventListener("message", handleDeactivate);
|
|
10422
|
-
window.removeEventListener("message", handleUiEscape);
|
|
10423
8266
|
autoSaveTimers.current.forEach(clearTimeout);
|
|
10424
8267
|
autoSaveTimers.current.clear();
|
|
10425
8268
|
if (imageUnhoverTimerRef.current) clearTimeout(imageUnhoverTimerRef.current);
|
|
10426
8269
|
if (imageShowTimerRef.current) clearTimeout(imageShowTimerRef.current);
|
|
10427
8270
|
};
|
|
10428
8271
|
}, [isEditMode, refreshStateRules]);
|
|
10429
|
-
(0,
|
|
10430
|
-
if (!isEditMode) return;
|
|
10431
|
-
const THRESHOLD = 10;
|
|
10432
|
-
const resolveWasSelected = (el) => {
|
|
10433
|
-
if (selectedElRef.current === el) return true;
|
|
10434
|
-
const activeAnchor = activeElRef.current ? getNavigationItemAnchor(activeElRef.current) : null;
|
|
10435
|
-
return activeAnchor === el;
|
|
10436
|
-
};
|
|
10437
|
-
const onPointerDown = (e) => {
|
|
10438
|
-
if (e.button !== 0) return;
|
|
10439
|
-
if (footerDragRef.current) return;
|
|
10440
|
-
const target = e.target;
|
|
10441
|
-
if (!target) return;
|
|
10442
|
-
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]')) {
|
|
10443
|
-
return;
|
|
10444
|
-
}
|
|
10445
|
-
if (target.closest("[data-ohw-item-drag-surface]")) return;
|
|
10446
|
-
const anchor = getNavigationItemAnchor(target);
|
|
10447
|
-
const hrefKey = anchor?.getAttribute("data-ohw-href-key") ?? null;
|
|
10448
|
-
if (anchor && isFooterHrefKey(hrefKey)) {
|
|
10449
|
-
armFooterPressDrag();
|
|
10450
|
-
footerPointerDragRef.current = {
|
|
10451
|
-
el: anchor,
|
|
10452
|
-
kind: "link",
|
|
10453
|
-
startX: e.clientX,
|
|
10454
|
-
startY: e.clientY,
|
|
10455
|
-
pointerId: e.pointerId,
|
|
10456
|
-
wasSelected: resolveWasSelected(anchor),
|
|
10457
|
-
started: false
|
|
10458
|
-
};
|
|
10459
|
-
return;
|
|
10460
|
-
}
|
|
10461
|
-
const col = target.closest("[data-ohw-footer-col]");
|
|
10462
|
-
if (col && !getNavigationItemAnchor(target)) {
|
|
10463
|
-
armFooterPressDrag();
|
|
10464
|
-
footerPointerDragRef.current = {
|
|
10465
|
-
el: col,
|
|
10466
|
-
kind: "column",
|
|
10467
|
-
startX: e.clientX,
|
|
10468
|
-
startY: e.clientY,
|
|
10469
|
-
pointerId: e.pointerId,
|
|
10470
|
-
wasSelected: resolveWasSelected(col),
|
|
10471
|
-
started: false
|
|
10472
|
-
};
|
|
10473
|
-
}
|
|
10474
|
-
};
|
|
10475
|
-
const onPointerMove = (e) => {
|
|
10476
|
-
const pending = footerPointerDragRef.current;
|
|
10477
|
-
if (!pending) return;
|
|
10478
|
-
if (pending.started) {
|
|
10479
|
-
e.preventDefault();
|
|
10480
|
-
clearTextSelection();
|
|
10481
|
-
const session = footerDragRef.current;
|
|
10482
|
-
if (!session) return;
|
|
10483
|
-
const slot = session.kind === "link" && session.hrefKey ? hitTestLinkDropSlot(e.clientX, e.clientY, session.hrefKey) : hitTestColumnDropSlot(e.clientX, e.clientY);
|
|
10484
|
-
refreshFooterDragVisualsRef.current(session, slot, e.clientX, e.clientY);
|
|
10485
|
-
return;
|
|
10486
|
-
}
|
|
10487
|
-
const dx = e.clientX - pending.startX;
|
|
10488
|
-
const dy = e.clientY - pending.startY;
|
|
10489
|
-
if (dx * dx + dy * dy < THRESHOLD * THRESHOLD) return;
|
|
10490
|
-
e.preventDefault();
|
|
10491
|
-
pending.started = true;
|
|
10492
|
-
clearTextSelection();
|
|
10493
|
-
try {
|
|
10494
|
-
document.body.setPointerCapture(pending.pointerId);
|
|
10495
|
-
} catch {
|
|
10496
|
-
}
|
|
10497
|
-
if (linkPopoverOpenRef.current) {
|
|
10498
|
-
setLinkPopoverRef.current(null);
|
|
10499
|
-
}
|
|
10500
|
-
if (activeElRef.current) {
|
|
10501
|
-
deactivateRef.current();
|
|
10502
|
-
}
|
|
10503
|
-
if (pending.kind === "link") {
|
|
10504
|
-
const key = pending.el.getAttribute("data-ohw-href-key");
|
|
10505
|
-
if (!key) return;
|
|
10506
|
-
const column = findFooterColumnForLink(pending.el);
|
|
10507
|
-
const columns2 = listFooterColumns();
|
|
10508
|
-
beginFooterDragRef.current({
|
|
10509
|
-
kind: "link",
|
|
10510
|
-
hrefKey: key,
|
|
10511
|
-
columnEl: column,
|
|
10512
|
-
sourceColumnIndex: column ? columns2.indexOf(column) : 0,
|
|
10513
|
-
wasSelected: pending.wasSelected,
|
|
10514
|
-
draggedEl: pending.el,
|
|
10515
|
-
lastClientX: e.clientX,
|
|
10516
|
-
lastClientY: e.clientY,
|
|
10517
|
-
activeSlot: null
|
|
10518
|
-
});
|
|
10519
|
-
return;
|
|
10520
|
-
}
|
|
10521
|
-
const columns = listFooterColumns();
|
|
10522
|
-
const idx = columns.indexOf(pending.el);
|
|
10523
|
-
if (idx < 0) return;
|
|
10524
|
-
beginFooterDragRef.current({
|
|
10525
|
-
kind: "column",
|
|
10526
|
-
hrefKey: null,
|
|
10527
|
-
columnEl: pending.el,
|
|
10528
|
-
sourceColumnIndex: idx,
|
|
10529
|
-
wasSelected: pending.wasSelected,
|
|
10530
|
-
draggedEl: pending.el,
|
|
10531
|
-
lastClientX: e.clientX,
|
|
10532
|
-
lastClientY: e.clientY,
|
|
10533
|
-
activeSlot: null
|
|
10534
|
-
});
|
|
10535
|
-
};
|
|
10536
|
-
const endPointerDrag = (e) => {
|
|
10537
|
-
const pending = footerPointerDragRef.current;
|
|
10538
|
-
footerPointerDragRef.current = null;
|
|
10539
|
-
try {
|
|
10540
|
-
if (document.body.hasPointerCapture(e.pointerId)) {
|
|
10541
|
-
document.body.releasePointerCapture(e.pointerId);
|
|
10542
|
-
}
|
|
10543
|
-
} catch {
|
|
10544
|
-
}
|
|
10545
|
-
if (!pending?.started) {
|
|
10546
|
-
unlockFooterDragInteraction();
|
|
10547
|
-
return;
|
|
10548
|
-
}
|
|
10549
|
-
suppressNextClickRef.current = true;
|
|
10550
|
-
commitFooterDragRef.current(e.clientX, e.clientY);
|
|
10551
|
-
};
|
|
10552
|
-
const blockSelectStart = (e) => {
|
|
10553
|
-
if (footerDragRef.current || footerPointerDragRef.current?.started || document.documentElement.hasAttribute("data-ohw-footer-press-drag")) {
|
|
10554
|
-
e.preventDefault();
|
|
10555
|
-
}
|
|
10556
|
-
};
|
|
10557
|
-
const onDragEnd = (_e) => {
|
|
10558
|
-
if (!footerDragRef.current) return;
|
|
10559
|
-
commitFooterDragRef.current();
|
|
10560
|
-
};
|
|
10561
|
-
document.addEventListener("pointerdown", onPointerDown, true);
|
|
10562
|
-
document.addEventListener("pointermove", onPointerMove, true);
|
|
10563
|
-
document.addEventListener("pointerup", endPointerDrag, true);
|
|
10564
|
-
document.addEventListener("pointercancel", endPointerDrag, true);
|
|
10565
|
-
document.addEventListener("selectstart", blockSelectStart, true);
|
|
10566
|
-
document.addEventListener("dragend", onDragEnd, true);
|
|
10567
|
-
return () => {
|
|
10568
|
-
document.removeEventListener("pointerdown", onPointerDown, true);
|
|
10569
|
-
document.removeEventListener("pointermove", onPointerMove, true);
|
|
10570
|
-
document.removeEventListener("pointerup", endPointerDrag, true);
|
|
10571
|
-
document.removeEventListener("pointercancel", endPointerDrag, true);
|
|
10572
|
-
document.removeEventListener("selectstart", blockSelectStart, true);
|
|
10573
|
-
document.removeEventListener("dragend", onDragEnd, true);
|
|
10574
|
-
unlockFooterDragInteraction();
|
|
10575
|
-
};
|
|
10576
|
-
}, [isEditMode]);
|
|
10577
|
-
(0, import_react9.useEffect)(() => {
|
|
8272
|
+
(0, import_react6.useEffect)(() => {
|
|
10578
8273
|
const handler = (e) => {
|
|
10579
8274
|
if (e.data?.type !== "ow:request-schedule-config") return;
|
|
10580
8275
|
const insertAfterVal = e.data.insertAfter;
|
|
@@ -10590,7 +8285,7 @@ function OhhwellsBridge() {
|
|
|
10590
8285
|
window.addEventListener("message", handler);
|
|
10591
8286
|
return () => window.removeEventListener("message", handler);
|
|
10592
8287
|
}, [processConfigRequest]);
|
|
10593
|
-
(0,
|
|
8288
|
+
(0, import_react6.useEffect)(() => {
|
|
10594
8289
|
if (!isEditMode) return;
|
|
10595
8290
|
document.querySelectorAll("[data-ohw-active-state]").forEach((el) => {
|
|
10596
8291
|
el.removeAttribute("data-ohw-active-state");
|
|
@@ -10611,33 +8306,27 @@ function OhhwellsBridge() {
|
|
|
10611
8306
|
const next = { ...prev, [pathKey]: sections };
|
|
10612
8307
|
return shouldUseDevFixtures() ? { ...DEV_SECTIONS_BY_PATH, ...next } : next;
|
|
10613
8308
|
});
|
|
10614
|
-
|
|
10615
|
-
|
|
10616
|
-
version: "1",
|
|
10617
|
-
path: pathname,
|
|
10618
|
-
nodes: collectEditableNodes(editContentRef.current),
|
|
10619
|
-
sections
|
|
10620
|
-
});
|
|
10621
|
-
postToParent2({ type: "ow:request-site-pages" });
|
|
8309
|
+
postToParent({ type: "ow:ready", version: "1", path: pathname, nodes: collectEditableNodes(), sections });
|
|
8310
|
+
postToParent({ type: "ow:request-site-pages" });
|
|
10622
8311
|
}, 150);
|
|
10623
8312
|
return () => {
|
|
10624
8313
|
cancelAnimationFrame(raf);
|
|
10625
8314
|
clearTimeout(timer);
|
|
10626
8315
|
};
|
|
10627
|
-
}, [pathname, isEditMode, refreshStateRules,
|
|
10628
|
-
(0,
|
|
8316
|
+
}, [pathname, isEditMode, refreshStateRules, postToParent]);
|
|
8317
|
+
(0, import_react6.useEffect)(() => {
|
|
10629
8318
|
scrollToHashSectionWhenReady();
|
|
10630
8319
|
const onHashChange = () => scrollToHashSectionWhenReady();
|
|
10631
8320
|
window.addEventListener("hashchange", onHashChange);
|
|
10632
8321
|
return () => window.removeEventListener("hashchange", onHashChange);
|
|
10633
8322
|
}, [pathname]);
|
|
10634
|
-
const handleCommand = (0,
|
|
8323
|
+
const handleCommand = (0, import_react6.useCallback)((cmd) => {
|
|
10635
8324
|
document.execCommand(cmd, false);
|
|
10636
8325
|
activeElRef.current?.focus();
|
|
10637
8326
|
if (activeElRef.current) setToolbarRect(getEditMeasureEl(activeElRef.current).getBoundingClientRect());
|
|
10638
8327
|
refreshActiveCommandsRef.current();
|
|
10639
8328
|
}, []);
|
|
10640
|
-
const handleStateChange = (0,
|
|
8329
|
+
const handleStateChange = (0, import_react6.useCallback)((state) => {
|
|
10641
8330
|
if (!activeStateElRef.current) return;
|
|
10642
8331
|
const el = activeStateElRef.current;
|
|
10643
8332
|
if (state === "Default") {
|
|
@@ -10650,22 +8339,18 @@ function OhhwellsBridge() {
|
|
|
10650
8339
|
}
|
|
10651
8340
|
setToggleState((prev) => prev ? { ...prev, activeState: state } : null);
|
|
10652
8341
|
}, [deactivate]);
|
|
10653
|
-
const closeLinkPopover = (0,
|
|
10654
|
-
|
|
10655
|
-
setLinkPopover(null);
|
|
10656
|
-
}, []);
|
|
10657
|
-
const openLinkPopoverForActive = (0, import_react9.useCallback)(() => {
|
|
8342
|
+
const closeLinkPopover = (0, import_react6.useCallback)(() => setLinkPopover(null), []);
|
|
8343
|
+
const openLinkPopoverForActive = (0, import_react6.useCallback)(() => {
|
|
10658
8344
|
const hrefCtx = getHrefKeyFromElement(activeElRef.current);
|
|
10659
8345
|
if (!hrefCtx) return;
|
|
10660
8346
|
bumpLinkPopoverGrace();
|
|
10661
8347
|
setLinkPopover({
|
|
10662
8348
|
key: hrefCtx.key,
|
|
10663
|
-
|
|
10664
|
-
target: getLinkHref2(hrefCtx.anchor)
|
|
8349
|
+
target: getLinkHref(hrefCtx.anchor)
|
|
10665
8350
|
});
|
|
10666
8351
|
deactivate();
|
|
10667
8352
|
}, [deactivate]);
|
|
10668
|
-
const openLinkPopoverForSelected = (0,
|
|
8353
|
+
const openLinkPopoverForSelected = (0, import_react6.useCallback)(() => {
|
|
10669
8354
|
const anchor = selectedElRef.current;
|
|
10670
8355
|
if (!anchor) return;
|
|
10671
8356
|
const key = anchor.getAttribute("data-ohw-href-key");
|
|
@@ -10673,80 +8358,30 @@ function OhhwellsBridge() {
|
|
|
10673
8358
|
bumpLinkPopoverGrace();
|
|
10674
8359
|
setLinkPopover({
|
|
10675
8360
|
key,
|
|
10676
|
-
|
|
10677
|
-
target: getLinkHref2(anchor)
|
|
8361
|
+
target: getLinkHref(anchor)
|
|
10678
8362
|
});
|
|
10679
8363
|
deselect();
|
|
10680
8364
|
}, [deselect]);
|
|
10681
|
-
const handleLinkPopoverSubmit = (0,
|
|
8365
|
+
const handleLinkPopoverSubmit = (0, import_react6.useCallback)(
|
|
10682
8366
|
(target) => {
|
|
10683
|
-
|
|
10684
|
-
|
|
10685
|
-
if (session.intent === "add-nav") {
|
|
10686
|
-
const trimmed = target.trim();
|
|
10687
|
-
let href = trimmed;
|
|
10688
|
-
let label = "Untitled";
|
|
10689
|
-
if (trimmed) {
|
|
10690
|
-
const { pageRoute, sectionId } = parseTarget(trimmed);
|
|
10691
|
-
const page = resolvePage(pageRoute, sitePages);
|
|
10692
|
-
const pageSections = getSectionsForPath(sectionsByPath, pageRoute);
|
|
10693
|
-
const section = sectionId ? pageSections.find((s) => s.id === sectionId) : void 0;
|
|
10694
|
-
label = section?.label ?? page.title;
|
|
10695
|
-
href = trimmed;
|
|
10696
|
-
}
|
|
10697
|
-
const afterAnchor = addNavAfterAnchorRef.current;
|
|
10698
|
-
const { anchor, hrefKey, labelKey, index, order } = insertNavbarItem(href, label, afterAnchor);
|
|
10699
|
-
applyLinkByKey(hrefKey, href);
|
|
10700
|
-
document.querySelectorAll(`[data-ohw-key="${labelKey}"]`).forEach((el) => {
|
|
10701
|
-
el.textContent = label;
|
|
10702
|
-
});
|
|
10703
|
-
const navCount = String(index + 1);
|
|
10704
|
-
const orderJson = JSON.stringify(order);
|
|
10705
|
-
editContentRef.current = {
|
|
10706
|
-
...editContentRef.current,
|
|
10707
|
-
[hrefKey]: href,
|
|
10708
|
-
[labelKey]: label,
|
|
10709
|
-
[NAV_COUNT_KEY]: navCount,
|
|
10710
|
-
[NAV_ORDER_KEY]: orderJson
|
|
10711
|
-
};
|
|
10712
|
-
postToParent2({
|
|
10713
|
-
type: "ow:change",
|
|
10714
|
-
nodes: [
|
|
10715
|
-
{ key: hrefKey, text: href },
|
|
10716
|
-
{ key: labelKey, text: label },
|
|
10717
|
-
{ key: NAV_COUNT_KEY, text: navCount },
|
|
10718
|
-
{ key: NAV_ORDER_KEY, text: orderJson }
|
|
10719
|
-
]
|
|
10720
|
-
});
|
|
10721
|
-
postToParent2({ type: "ow:toast", title: "Link added", toastType: "success" });
|
|
10722
|
-
addNavAfterAnchorRef.current = null;
|
|
10723
|
-
setLinkPopover(null);
|
|
10724
|
-
enforceLinkHrefs();
|
|
10725
|
-
requestAnimationFrame(() => {
|
|
10726
|
-
selectRef.current(anchor);
|
|
10727
|
-
});
|
|
10728
|
-
return;
|
|
10729
|
-
}
|
|
10730
|
-
const { key } = session;
|
|
8367
|
+
if (!linkPopover) return;
|
|
8368
|
+
const { key } = linkPopover;
|
|
10731
8369
|
applyLinkByKey(key, target);
|
|
10732
|
-
|
|
8370
|
+
postToParent({ type: "ow:change", nodes: [{ key, text: target }] });
|
|
10733
8371
|
setLinkPopover(null);
|
|
10734
8372
|
},
|
|
10735
|
-
[
|
|
10736
|
-
);
|
|
10737
|
-
const handleMediaReplace = (0, import_react9.useCallback)(
|
|
10738
|
-
(key) => {
|
|
10739
|
-
postToParent2({ type: "ow:image-pick", key, elementType: mediaHover?.elementType ?? "image" });
|
|
10740
|
-
},
|
|
10741
|
-
[postToParent2, mediaHover?.elementType]
|
|
8373
|
+
[linkPopover, postToParent]
|
|
10742
8374
|
);
|
|
10743
|
-
const
|
|
8375
|
+
const showEditLink = toolbarShowEditLink;
|
|
8376
|
+
const currentSections = sectionsByPath[pathname] ?? [];
|
|
8377
|
+
linkPopoverOpenRef.current = linkPopover !== null;
|
|
8378
|
+
const handleMediaReplace = (0, import_react6.useCallback)(
|
|
10744
8379
|
(key) => {
|
|
10745
|
-
|
|
8380
|
+
postToParent({ type: "ow:image-pick", key, elementType: mediaHover?.elementType ?? "image" });
|
|
10746
8381
|
},
|
|
10747
|
-
[
|
|
8382
|
+
[postToParent, mediaHover?.elementType]
|
|
10748
8383
|
);
|
|
10749
|
-
const handleMediaFadeOutComplete = (0,
|
|
8384
|
+
const handleMediaFadeOutComplete = (0, import_react6.useCallback)((key) => {
|
|
10750
8385
|
setUploadingRects((prev) => {
|
|
10751
8386
|
if (!(key in prev)) return prev;
|
|
10752
8387
|
const next = { ...prev };
|
|
@@ -10754,7 +8389,7 @@ function OhhwellsBridge() {
|
|
|
10754
8389
|
return next;
|
|
10755
8390
|
});
|
|
10756
8391
|
}, []);
|
|
10757
|
-
const handleVideoSettingsChange = (0,
|
|
8392
|
+
const handleVideoSettingsChange = (0, import_react6.useCallback)(
|
|
10758
8393
|
(key, settings) => {
|
|
10759
8394
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
10760
8395
|
const video = getVideoEl(el);
|
|
@@ -10762,7 +8397,7 @@ function OhhwellsBridge() {
|
|
|
10762
8397
|
if (typeof settings.autoplay === "boolean") video.autoplay = settings.autoplay;
|
|
10763
8398
|
if (typeof settings.muted === "boolean") video.muted = settings.muted;
|
|
10764
8399
|
syncVideoPlayback(video);
|
|
10765
|
-
|
|
8400
|
+
postToParent({
|
|
10766
8401
|
type: "ow:change",
|
|
10767
8402
|
nodes: [
|
|
10768
8403
|
{ key: `${key}${VIDEO_AUTOPLAY_SUFFIX}`, text: String(video.autoplay) },
|
|
@@ -10774,15 +8409,12 @@ function OhhwellsBridge() {
|
|
|
10774
8409
|
);
|
|
10775
8410
|
});
|
|
10776
8411
|
},
|
|
10777
|
-
[
|
|
8412
|
+
[postToParent]
|
|
10778
8413
|
);
|
|
10779
|
-
|
|
10780
|
-
|
|
10781
|
-
|
|
10782
|
-
|
|
10783
|
-
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_jsx_runtime25.Fragment, { children: [
|
|
10784
|
-
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
|
|
10785
|
-
Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
8414
|
+
return bridgeRoot ? (0, import_react_dom2.createPortal)(
|
|
8415
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
|
|
8416
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
|
|
8417
|
+
Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
10786
8418
|
MediaOverlay,
|
|
10787
8419
|
{
|
|
10788
8420
|
hover: { key, rect, elementType: "image", isDragOver: false, hasTextOverlap: false },
|
|
@@ -10793,7 +8425,7 @@ function OhhwellsBridge() {
|
|
|
10793
8425
|
},
|
|
10794
8426
|
`uploading-${key}`
|
|
10795
8427
|
)),
|
|
10796
|
-
mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */ (0,
|
|
8428
|
+
mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
10797
8429
|
MediaOverlay,
|
|
10798
8430
|
{
|
|
10799
8431
|
hover: mediaHover,
|
|
@@ -10802,33 +8434,53 @@ function OhhwellsBridge() {
|
|
|
10802
8434
|
onVideoSettingsChange: handleVideoSettingsChange
|
|
10803
8435
|
}
|
|
10804
8436
|
),
|
|
10805
|
-
|
|
10806
|
-
siblingHintRect && !isItemDragging &&
|
|
10807
|
-
|
|
10808
|
-
|
|
10809
|
-
isItemDragging && footerDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
10810
|
-
"div",
|
|
8437
|
+
siblingHintRect && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
|
|
8438
|
+
hoveredItemRect && !siblingHintRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
|
|
8439
|
+
toolbarRect && toolbarVariant === "link-action" && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
8440
|
+
ItemInteractionLayer,
|
|
10811
8441
|
{
|
|
10812
|
-
|
|
10813
|
-
|
|
10814
|
-
|
|
10815
|
-
|
|
10816
|
-
|
|
10817
|
-
|
|
10818
|
-
|
|
10819
|
-
|
|
10820
|
-
|
|
10821
|
-
|
|
10822
|
-
|
|
10823
|
-
|
|
10824
|
-
|
|
10825
|
-
|
|
10826
|
-
|
|
10827
|
-
|
|
10828
|
-
|
|
10829
|
-
|
|
8442
|
+
rect: toolbarRect,
|
|
8443
|
+
elRef: glowElRef,
|
|
8444
|
+
state: isItemDragging ? "dragging" : resolveItemInteractionState(toolbarRect, parentScrollRef.current),
|
|
8445
|
+
showHandle: Boolean(reorderHrefKey),
|
|
8446
|
+
dragDisabled: reorderDragDisabled,
|
|
8447
|
+
dragHandleLabel: reorderHrefKey ? `Reorder ${reorderHrefKey}` : "Reorder item",
|
|
8448
|
+
onDragHandleDragStart: handleItemDragStart,
|
|
8449
|
+
onDragHandleDragEnd: handleItemDragEnd,
|
|
8450
|
+
toolbar: isItemDragging ? void 0 : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
8451
|
+
ItemActionToolbar,
|
|
8452
|
+
{
|
|
8453
|
+
onEditLink: openLinkPopoverForSelected,
|
|
8454
|
+
onAddItem: handleAddNavigationItem,
|
|
8455
|
+
addItemDisabled: false
|
|
8456
|
+
}
|
|
8457
|
+
)
|
|
8458
|
+
}
|
|
8459
|
+
),
|
|
8460
|
+
toolbarRect && toolbarVariant === "rich-text" && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
|
|
8461
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
8462
|
+
EditGlowChrome,
|
|
8463
|
+
{
|
|
8464
|
+
rect: toolbarRect,
|
|
8465
|
+
elRef: glowElRef,
|
|
8466
|
+
reorderHrefKey,
|
|
8467
|
+
dragDisabled: reorderDragDisabled
|
|
8468
|
+
}
|
|
8469
|
+
),
|
|
8470
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
8471
|
+
FloatingToolbar,
|
|
8472
|
+
{
|
|
8473
|
+
rect: toolbarRect,
|
|
8474
|
+
parentScroll: parentScrollRef.current,
|
|
8475
|
+
elRef: toolbarElRef,
|
|
8476
|
+
onCommand: handleCommand,
|
|
8477
|
+
activeCommands,
|
|
8478
|
+
showEditLink,
|
|
8479
|
+
onEditLink: openLinkPopoverForActive
|
|
8480
|
+
}
|
|
8481
|
+
)
|
|
10830
8482
|
] }),
|
|
10831
|
-
maxBadge && /* @__PURE__ */ (0,
|
|
8483
|
+
maxBadge && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
10832
8484
|
"div",
|
|
10833
8485
|
{
|
|
10834
8486
|
"data-ohw-max-badge": "",
|
|
@@ -10854,29 +8506,56 @@ function OhhwellsBridge() {
|
|
|
10854
8506
|
]
|
|
10855
8507
|
}
|
|
10856
8508
|
),
|
|
10857
|
-
toggleState &&
|
|
10858
|
-
|
|
10859
|
-
|
|
10860
|
-
|
|
10861
|
-
|
|
10862
|
-
|
|
10863
|
-
|
|
10864
|
-
|
|
10865
|
-
|
|
10866
|
-
|
|
10867
|
-
|
|
10868
|
-
|
|
10869
|
-
|
|
8509
|
+
toggleState && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
8510
|
+
StateToggle,
|
|
8511
|
+
{
|
|
8512
|
+
rect: toggleState.rect,
|
|
8513
|
+
activeState: toggleState.activeState,
|
|
8514
|
+
states: toggleState.states,
|
|
8515
|
+
onStateChange: handleStateChange
|
|
8516
|
+
}
|
|
8517
|
+
),
|
|
8518
|
+
sectionGap && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
8519
|
+
"div",
|
|
8520
|
+
{
|
|
8521
|
+
"data-ohw-section-insert-line": "",
|
|
8522
|
+
className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
|
|
8523
|
+
style: { top: sectionGap.y, transform: "translateY(-50%)" },
|
|
8524
|
+
children: [
|
|
8525
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
|
|
8526
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
8527
|
+
Badge,
|
|
8528
|
+
{
|
|
8529
|
+
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",
|
|
8530
|
+
onClick: () => {
|
|
8531
|
+
window.parent.postMessage(
|
|
8532
|
+
{ type: "ow:add-section", insertAfter: sectionGap.insertAfter, insertBefore: sectionGap.insertBefore },
|
|
8533
|
+
"*"
|
|
8534
|
+
);
|
|
10870
8535
|
},
|
|
10871
|
-
"
|
|
10872
|
-
|
|
10873
|
-
|
|
10874
|
-
|
|
10875
|
-
|
|
10876
|
-
|
|
10877
|
-
|
|
10878
|
-
|
|
10879
|
-
|
|
8536
|
+
children: "Add Section"
|
|
8537
|
+
}
|
|
8538
|
+
),
|
|
8539
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } })
|
|
8540
|
+
]
|
|
8541
|
+
}
|
|
8542
|
+
),
|
|
8543
|
+
linkPopover && dialogPortalContainer ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
8544
|
+
LinkPopover,
|
|
8545
|
+
{
|
|
8546
|
+
panelRef: linkPopoverPanelRef,
|
|
8547
|
+
portalContainer: dialogPortalContainer,
|
|
8548
|
+
open: true,
|
|
8549
|
+
mode: "edit",
|
|
8550
|
+
pages: sitePages,
|
|
8551
|
+
sections: currentSections,
|
|
8552
|
+
sectionsByPath,
|
|
8553
|
+
initialTarget: linkPopover.target,
|
|
8554
|
+
onClose: closeLinkPopover,
|
|
8555
|
+
onSubmit: handleLinkPopoverSubmit
|
|
8556
|
+
},
|
|
8557
|
+
`${linkPopover.key}-${pathname}`
|
|
8558
|
+
) : null
|
|
10880
8559
|
] }),
|
|
10881
8560
|
bridgeRoot
|
|
10882
8561
|
) : null;
|
|
@@ -10887,7 +8566,6 @@ function OhhwellsBridge() {
|
|
|
10887
8566
|
CustomToolbarButton,
|
|
10888
8567
|
CustomToolbarDivider,
|
|
10889
8568
|
DragHandle,
|
|
10890
|
-
DropIndicator,
|
|
10891
8569
|
ItemActionToolbar,
|
|
10892
8570
|
ItemInteractionLayer,
|
|
10893
8571
|
LinkEditorPanel,
|
|
@@ -10902,14 +8580,12 @@ function OhhwellsBridge() {
|
|
|
10902
8580
|
TooltipProvider,
|
|
10903
8581
|
TooltipTrigger,
|
|
10904
8582
|
buildTarget,
|
|
10905
|
-
dropIndicatorVariants,
|
|
10906
8583
|
filterAvailablePages,
|
|
10907
8584
|
getEditModeInitialState,
|
|
10908
8585
|
isEditSessionActive,
|
|
10909
8586
|
isValidUrl,
|
|
10910
8587
|
parseTarget,
|
|
10911
8588
|
toggleVariants,
|
|
10912
|
-
useOhwCarousel,
|
|
10913
8589
|
validateUrlInput
|
|
10914
8590
|
});
|
|
10915
8591
|
//# sourceMappingURL=index.cjs.map
|