@ohhwells/bridge 0.1.38-next.69 → 0.1.39
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 +700 -3004
- 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 +709 -3010
- package/dist/index.js.map +1 -1
- package/dist/styles.css +34 -169
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
// src/OhhwellsBridge.tsx
|
|
4
|
-
import
|
|
4
|
+
import React9, { useCallback as useCallback2, useEffect as useEffect4, useLayoutEffect as useLayoutEffect2, useRef as useRef4, useState as useState5 } from "react";
|
|
5
5
|
import { createRoot } from "react-dom/client";
|
|
6
6
|
import { flushSync } from "react-dom";
|
|
7
7
|
|
|
@@ -10,9 +10,6 @@ var linkHrefStore = /* @__PURE__ */ new Map();
|
|
|
10
10
|
function setStoredLinkHref(key, href) {
|
|
11
11
|
linkHrefStore.set(key, href);
|
|
12
12
|
}
|
|
13
|
-
function getStoredLinkHref(key) {
|
|
14
|
-
return linkHrefStore.get(key);
|
|
15
|
-
}
|
|
16
13
|
function enforceLinkHrefs() {
|
|
17
14
|
document.querySelectorAll("[data-ohw-href-key]").forEach((el) => {
|
|
18
15
|
const key = el.getAttribute("data-ohw-href-key") ?? "";
|
|
@@ -48,13 +45,12 @@ function useLinkHrefGuardian(...deps) {
|
|
|
48
45
|
}
|
|
49
46
|
|
|
50
47
|
// src/ui/SchedulingWidget.tsx
|
|
51
|
-
import {
|
|
48
|
+
import { useEffect, useId, useMemo, useRef, useState as useState2 } from "react";
|
|
52
49
|
|
|
53
50
|
// src/ui/EmailCaptureModal.tsx
|
|
54
51
|
import { useState } from "react";
|
|
55
52
|
import { Dialog } from "radix-ui";
|
|
56
53
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
57
|
-
var isValidEmail = (value) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value);
|
|
58
54
|
function Spinner() {
|
|
59
55
|
return /* @__PURE__ */ jsxs(
|
|
60
56
|
"svg",
|
|
@@ -88,17 +84,12 @@ function EmailCaptureModal({ title, subtitle, onSubmit, onClose }) {
|
|
|
88
84
|
const [error, setError] = useState(null);
|
|
89
85
|
const isBook = title === "Confirm your spot";
|
|
90
86
|
const handleSubmit = async () => {
|
|
91
|
-
|
|
92
|
-
if (!trimmed) return;
|
|
93
|
-
if (!isValidEmail(trimmed)) {
|
|
94
|
-
setError("Please enter a valid email address.");
|
|
95
|
-
return;
|
|
96
|
-
}
|
|
87
|
+
if (!email.trim()) return;
|
|
97
88
|
setLoading(true);
|
|
98
89
|
setError(null);
|
|
99
90
|
try {
|
|
100
|
-
await onSubmit(
|
|
101
|
-
setSubmittedEmail(
|
|
91
|
+
await onSubmit(email.trim());
|
|
92
|
+
setSubmittedEmail(email.trim());
|
|
102
93
|
setSuccess(true);
|
|
103
94
|
} catch (e) {
|
|
104
95
|
setError(e instanceof Error ? e.message : "Something went wrong. Please try again.");
|
|
@@ -173,10 +164,7 @@ function EmailCaptureModal({ title, subtitle, onSubmit, onClose }) {
|
|
|
173
164
|
{
|
|
174
165
|
type: "email",
|
|
175
166
|
value: email,
|
|
176
|
-
onChange: (e) =>
|
|
177
|
-
setEmail(e.target.value);
|
|
178
|
-
if (error) setError(null);
|
|
179
|
-
},
|
|
167
|
+
onChange: (e) => setEmail(e.target.value),
|
|
180
168
|
onKeyDown: handleKeyDown,
|
|
181
169
|
placeholder: "hello@gmail.com",
|
|
182
170
|
autoFocus: true,
|
|
@@ -233,20 +221,12 @@ function formatClassTime(cls) {
|
|
|
233
221
|
const em = endTotal % 60;
|
|
234
222
|
return `${h}:${cls.startTime.minutes}-${eh}:${String(em).padStart(2, "0")}`;
|
|
235
223
|
}
|
|
236
|
-
function formatBookingLabel(cls) {
|
|
237
|
-
const price = cls.price;
|
|
238
|
-
const isFree = price === null || price === void 0 || `${price}` === "" || `${price}` === "0";
|
|
239
|
-
return isFree ? "Book for free" : `Book for ${cls.currency ?? ""} ${price}`.trim();
|
|
240
|
-
}
|
|
241
224
|
function getBookingsOnDate(cls, date) {
|
|
242
225
|
if (!cls.bookings?.length) return 0;
|
|
243
|
-
const
|
|
244
|
-
target.setHours(0, 0, 0, 0);
|
|
226
|
+
const ds = date.toISOString().split("T")[0];
|
|
245
227
|
return cls.bookings.filter((b) => {
|
|
246
228
|
try {
|
|
247
|
-
|
|
248
|
-
bookingDate.setHours(0, 0, 0, 0);
|
|
249
|
-
return bookingDate.getTime() === target.getTime();
|
|
229
|
+
return new Date(b.classDate).toISOString().split("T")[0] === ds;
|
|
250
230
|
} catch {
|
|
251
231
|
return false;
|
|
252
232
|
}
|
|
@@ -511,7 +491,7 @@ function ScheduleView({ schedule, dates, selectedIdx, onSelectDate, onOpenModal
|
|
|
511
491
|
}
|
|
512
492
|
)
|
|
513
493
|
] }),
|
|
514
|
-
|
|
494
|
+
/* @__PURE__ */ jsx2("div", { className: "sm:hidden flex flex-col gap-px", children: isFull ? /* @__PURE__ */ jsx2("span", { className: "font-body text-sm text-(--color-dark,#200C02) opacity-80", children: "Full" }) : /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
515
495
|
/* @__PURE__ */ jsxs2("span", { className: "font-body text-sm text-(--color-dark,#200C02) opacity-80", children: [
|
|
516
496
|
available,
|
|
517
497
|
"/",
|
|
@@ -523,10 +503,9 @@ function ScheduleView({ schedule, dates, selectedIdx, onSelectDate, onOpenModal
|
|
|
523
503
|
/* @__PURE__ */ jsxs2("div", { className: "flex flex-1 flex-col gap-2 min-w-0 sm:contents", children: [
|
|
524
504
|
/* @__PURE__ */ jsxs2("div", { className: "flex-1 flex flex-col gap-2 min-w-0", children: [
|
|
525
505
|
/* @__PURE__ */ jsx2("span", { className: "font-body text-base font-bold text-(--color-dark,#200C02) block truncate", children: cls.name }),
|
|
526
|
-
cls.hostName && /* @__PURE__ */ jsx2("span", { className: "font-body text-base font-normal text-(--color-dark,#200C02) opacity-80 block truncate", children: cls.hostName })
|
|
527
|
-
cls.description && /* @__PURE__ */ jsx2("span", { className: "font-body text-sm font-normal text-(--color-dark,#200C02) opacity-70 block truncate", children: cls.description })
|
|
506
|
+
cls.hostName && /* @__PURE__ */ jsx2("span", { className: "font-body text-base font-normal text-(--color-dark,#200C02) opacity-80 block truncate", children: cls.hostName })
|
|
528
507
|
] }),
|
|
529
|
-
|
|
508
|
+
/* @__PURE__ */ jsx2("div", { className: "hidden sm:flex w-14 shrink-0 flex-col gap-px", children: isFull ? /* @__PURE__ */ jsx2("span", { className: "font-body text-sm text-(--color-dark,#200C02) opacity-80", children: "Full" }) : /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
530
509
|
/* @__PURE__ */ jsxs2("span", { className: "font-body text-sm text-(--color-dark,#200C02) opacity-80", children: [
|
|
531
510
|
available,
|
|
532
511
|
"/",
|
|
@@ -551,7 +530,7 @@ function ScheduleView({ schedule, dates, selectedIdx, onSelectDate, onOpenModal
|
|
|
551
530
|
if (!cls.id) return;
|
|
552
531
|
onOpenModal?.(isFull ? "waitlist" : "book", cls.id, selectedDate);
|
|
553
532
|
},
|
|
554
|
-
children: isFull ? "Join Waitlist" :
|
|
533
|
+
children: isFull ? "Join Waitlist" : "Book Now"
|
|
555
534
|
}
|
|
556
535
|
)
|
|
557
536
|
] })
|
|
@@ -593,17 +572,6 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
593
572
|
const [isHovered, setIsHovered] = useState2(false);
|
|
594
573
|
const [modalState, setModalState] = useState2(null);
|
|
595
574
|
const switchScheduleIdRef = useRef(null);
|
|
596
|
-
const liveScheduleIdRef = useRef(null);
|
|
597
|
-
const refetchLiveSchedule = useCallback(async () => {
|
|
598
|
-
const id = liveScheduleIdRef.current;
|
|
599
|
-
if (!id) return;
|
|
600
|
-
try {
|
|
601
|
-
const res = await fetch(`${API_URL}/api/schedule/id/${id}`);
|
|
602
|
-
const data = await res.json();
|
|
603
|
-
if (data?.id) setSchedule(data);
|
|
604
|
-
} catch {
|
|
605
|
-
}
|
|
606
|
-
}, []);
|
|
607
575
|
const dates = useMemo(() => {
|
|
608
576
|
const today = /* @__PURE__ */ new Date();
|
|
609
577
|
today.setHours(0, 0, 0, 0);
|
|
@@ -623,18 +591,6 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
623
591
|
}
|
|
624
592
|
}
|
|
625
593
|
}, [schedule, dates]);
|
|
626
|
-
useEffect(() => {
|
|
627
|
-
if (typeof window === "undefined") return;
|
|
628
|
-
const onVisible = () => {
|
|
629
|
-
if (!document.hidden) void refetchLiveSchedule();
|
|
630
|
-
};
|
|
631
|
-
window.addEventListener("focus", refetchLiveSchedule);
|
|
632
|
-
document.addEventListener("visibilitychange", onVisible);
|
|
633
|
-
return () => {
|
|
634
|
-
window.removeEventListener("focus", refetchLiveSchedule);
|
|
635
|
-
document.removeEventListener("visibilitychange", onVisible);
|
|
636
|
-
};
|
|
637
|
-
}, [refetchLiveSchedule]);
|
|
638
594
|
useEffect(() => {
|
|
639
595
|
if (typeof window === "undefined") return;
|
|
640
596
|
const isInEditor = window.self !== window.top;
|
|
@@ -696,7 +652,7 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
696
652
|
setLoading(false);
|
|
697
653
|
return;
|
|
698
654
|
}
|
|
699
|
-
|
|
655
|
+
;
|
|
700
656
|
(async () => {
|
|
701
657
|
try {
|
|
702
658
|
const res = await fetch(`${API_URL}/api/schedule/id/${effectiveId}`);
|
|
@@ -753,14 +709,18 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
753
709
|
const data = await res.json().catch(() => ({}));
|
|
754
710
|
throw new Error(data?.message ?? "Something went wrong. Please try again.");
|
|
755
711
|
}
|
|
756
|
-
await refetchLiveSchedule();
|
|
757
712
|
};
|
|
758
713
|
const handleReplaceSchedule = () => {
|
|
759
714
|
setIsHovered(false);
|
|
760
|
-
|
|
761
|
-
{
|
|
762
|
-
|
|
763
|
-
|
|
715
|
+
if (schedule) {
|
|
716
|
+
window.parent.postMessage({
|
|
717
|
+
type: "ow:schedule-connected",
|
|
718
|
+
schedule: { id: schedule.id, name: schedule.name },
|
|
719
|
+
insertAfter
|
|
720
|
+
}, "*");
|
|
721
|
+
} else {
|
|
722
|
+
window.parent.postMessage({ type: "ow:scheduling-not-connected", insertAfter }, "*");
|
|
723
|
+
}
|
|
764
724
|
};
|
|
765
725
|
if (!inEditor && !loading && !schedule) return null;
|
|
766
726
|
const sectionId = `scheduling-${insertAfter}`;
|
|
@@ -803,19 +763,7 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
803
763
|
),
|
|
804
764
|
/* @__PURE__ */ jsxs2("div", { className: "max-w-[1280px] mx-auto flex flex-col items-center gap-16", children: [
|
|
805
765
|
/* @__PURE__ */ jsxs2("div", { className: "flex flex-col items-center gap-4", children: [
|
|
806
|
-
/* @__PURE__ */ jsx2(
|
|
807
|
-
"h2",
|
|
808
|
-
{
|
|
809
|
-
className: "font-display text-center m-0 text-(--color-dark,#200C02)",
|
|
810
|
-
style: {
|
|
811
|
-
fontSize: "var(--fs-section-h2, clamp(40px, 4.4vw, 64px))",
|
|
812
|
-
fontWeight: "var(--font-weight-heading, 400)",
|
|
813
|
-
lineHeight: 1.05,
|
|
814
|
-
letterSpacing: "-0.02em"
|
|
815
|
-
},
|
|
816
|
-
children: schedule?.name ?? "Book an appointment"
|
|
817
|
-
}
|
|
818
|
-
),
|
|
766
|
+
/* @__PURE__ */ jsx2("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" }),
|
|
819
767
|
schedule?.description && /* @__PURE__ */ jsx2("p", { className: "font-body text-body text-center m-0 text-(--color-accent,#A89B83)", children: schedule.description })
|
|
820
768
|
] }),
|
|
821
769
|
/* @__PURE__ */ jsxs2("div", { className: "w-full flex flex-col items-end gap-3", children: [
|
|
@@ -4401,7 +4349,6 @@ function ItemActionToolbar({
|
|
|
4401
4349
|
onEditLink,
|
|
4402
4350
|
onAddItem,
|
|
4403
4351
|
onMore,
|
|
4404
|
-
editLinkDisabled = false,
|
|
4405
4352
|
addItemDisabled = true,
|
|
4406
4353
|
moreDisabled = true,
|
|
4407
4354
|
tooltipSide = "bottom"
|
|
@@ -4410,12 +4357,10 @@ function ItemActionToolbar({
|
|
|
4410
4357
|
/* @__PURE__ */ jsx8(
|
|
4411
4358
|
ToolbarActionTooltip,
|
|
4412
4359
|
{
|
|
4413
|
-
label: "
|
|
4360
|
+
label: "Add link",
|
|
4414
4361
|
side: tooltipSide,
|
|
4415
|
-
disabled: editLinkDisabled,
|
|
4416
4362
|
buttonProps: {
|
|
4417
4363
|
onMouseDown: (e) => {
|
|
4418
|
-
if (editLinkDisabled) return;
|
|
4419
4364
|
e.preventDefault();
|
|
4420
4365
|
e.stopPropagation();
|
|
4421
4366
|
onEditLink?.();
|
|
@@ -4493,7 +4438,7 @@ function getChromeStyle(state) {
|
|
|
4493
4438
|
case "dragging":
|
|
4494
4439
|
return {
|
|
4495
4440
|
border: `2px solid ${PRIMARY}`,
|
|
4496
|
-
boxShadow:
|
|
4441
|
+
boxShadow: DRAG_SHADOW
|
|
4497
4442
|
};
|
|
4498
4443
|
default:
|
|
4499
4444
|
return {};
|
|
@@ -4509,8 +4454,6 @@ function ItemInteractionLayer({
|
|
|
4509
4454
|
dragHandleLabel = "Reorder item",
|
|
4510
4455
|
onDragHandleDragStart,
|
|
4511
4456
|
onDragHandleDragEnd,
|
|
4512
|
-
onItemPointerDown,
|
|
4513
|
-
onItemClick,
|
|
4514
4457
|
chromeGap = 6,
|
|
4515
4458
|
className
|
|
4516
4459
|
}) {
|
|
@@ -4518,8 +4461,7 @@ function ItemInteractionLayer({
|
|
|
4518
4461
|
const isActive = state === "active-top" || state === "active-bottom";
|
|
4519
4462
|
const isDragging = state === "dragging";
|
|
4520
4463
|
const showToolbar = isActive && toolbar;
|
|
4521
|
-
const showDragHandle =
|
|
4522
|
-
const itemDragEnabled = isActive && showHandle && !isDragging && !dragDisabled;
|
|
4464
|
+
const showDragHandle = isActive && showHandle && !isDragging;
|
|
4523
4465
|
return /* @__PURE__ */ jsxs4(
|
|
4524
4466
|
"div",
|
|
4525
4467
|
{
|
|
@@ -4544,28 +4486,11 @@ function ItemInteractionLayer({
|
|
|
4544
4486
|
style: getChromeStyle(state)
|
|
4545
4487
|
}
|
|
4546
4488
|
),
|
|
4547
|
-
itemDragEnabled && /* @__PURE__ */ jsx9(
|
|
4548
|
-
"div",
|
|
4549
|
-
{
|
|
4550
|
-
"data-ohw-item-drag-surface": "",
|
|
4551
|
-
className: "pointer-events-auto absolute inset-0 cursor-grab rounded-lg active:cursor-grabbing",
|
|
4552
|
-
onPointerDown: (e) => {
|
|
4553
|
-
if (e.button !== 0) return;
|
|
4554
|
-
onItemPointerDown?.(e);
|
|
4555
|
-
},
|
|
4556
|
-
onClick: (e) => {
|
|
4557
|
-
e.preventDefault();
|
|
4558
|
-
e.stopPropagation();
|
|
4559
|
-
onItemClick?.(e.clientX, e.clientY);
|
|
4560
|
-
}
|
|
4561
|
-
}
|
|
4562
|
-
),
|
|
4563
4489
|
showDragHandle && /* @__PURE__ */ jsx9(
|
|
4564
4490
|
"div",
|
|
4565
4491
|
{
|
|
4566
4492
|
"data-ohw-drag-handle-container": "",
|
|
4567
|
-
className: "pointer-events-auto absolute left-0 top-1/2
|
|
4568
|
-
style: isDragging ? { visibility: "hidden" } : void 0,
|
|
4493
|
+
className: "pointer-events-auto absolute left-0 top-1/2 -translate-x-[calc(100%+7px)] -translate-y-1/2",
|
|
4569
4494
|
children: /* @__PURE__ */ jsx9(
|
|
4570
4495
|
DragHandle,
|
|
4571
4496
|
{
|
|
@@ -4788,12 +4713,15 @@ function MediaOverlay({
|
|
|
4788
4713
|
className: "flex items-center justify-center cursor-pointer",
|
|
4789
4714
|
style: {
|
|
4790
4715
|
...box,
|
|
4791
|
-
//
|
|
4792
|
-
//
|
|
4793
|
-
|
|
4716
|
+
// When text overlays this media, let clicks fall THROUGH to the text underneath. In the
|
|
4717
|
+
// parent this needed a whole `ow:click-at` round-trip to re-hit-test inside the iframe;
|
|
4718
|
+
// in-document, pointer-events does it natively. The button below opts back in, so
|
|
4719
|
+
// Replace still works.
|
|
4720
|
+
pointerEvents: hover.hasTextOverlap ? "none" : "auto",
|
|
4794
4721
|
boxShadow: "inset 0 0 0 1.5px var(--color-primary)",
|
|
4795
4722
|
background: "color-mix(in srgb, var(--color-primary) 20%, transparent)"
|
|
4796
4723
|
},
|
|
4724
|
+
onClick: () => onReplace(hover.key),
|
|
4797
4725
|
children: /* @__PURE__ */ jsxs5(
|
|
4798
4726
|
Button,
|
|
4799
4727
|
{
|
|
@@ -4818,64 +4746,9 @@ function MediaOverlay({
|
|
|
4818
4746
|
] });
|
|
4819
4747
|
}
|
|
4820
4748
|
|
|
4821
|
-
// src/ui/CarouselOverlay.tsx
|
|
4822
|
-
import { GalleryHorizontal } from "lucide-react";
|
|
4823
|
-
import { jsx as jsx12, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
4824
|
-
var OVERLAY_BUTTON_STYLE2 = {
|
|
4825
|
-
pointerEvents: "auto",
|
|
4826
|
-
fontFamily: "Inter, sans-serif",
|
|
4827
|
-
fontSize: 12,
|
|
4828
|
-
color: "#000"
|
|
4829
|
-
};
|
|
4830
|
-
function CarouselOverlay({
|
|
4831
|
-
hover,
|
|
4832
|
-
onEdit
|
|
4833
|
-
}) {
|
|
4834
|
-
const { rect } = hover;
|
|
4835
|
-
return /* @__PURE__ */ jsx12(
|
|
4836
|
-
"div",
|
|
4837
|
-
{
|
|
4838
|
-
"data-ohw-bridge": "",
|
|
4839
|
-
"data-ohw-carousel-overlay": "",
|
|
4840
|
-
className: "flex cursor-pointer items-center justify-center",
|
|
4841
|
-
style: {
|
|
4842
|
-
position: "fixed",
|
|
4843
|
-
top: rect.top,
|
|
4844
|
-
left: rect.left,
|
|
4845
|
-
width: rect.width,
|
|
4846
|
-
height: rect.height,
|
|
4847
|
-
zIndex: 2147483646,
|
|
4848
|
-
pointerEvents: "auto",
|
|
4849
|
-
boxShadow: "inset 0 0 0 1.5px var(--color-primary)",
|
|
4850
|
-
background: "color-mix(in srgb, var(--color-primary) 20%, transparent)"
|
|
4851
|
-
},
|
|
4852
|
-
onClick: () => onEdit(hover.key),
|
|
4853
|
-
children: /* @__PURE__ */ jsxs6(
|
|
4854
|
-
Button,
|
|
4855
|
-
{
|
|
4856
|
-
"data-ohw-carousel-overlay": "",
|
|
4857
|
-
variant: "outline",
|
|
4858
|
-
size: "sm",
|
|
4859
|
-
className: "cursor-pointer gap-1.5 hover:bg-background",
|
|
4860
|
-
style: OVERLAY_BUTTON_STYLE2,
|
|
4861
|
-
onMouseDown: (e) => e.preventDefault(),
|
|
4862
|
-
onClick: (e) => {
|
|
4863
|
-
e.stopPropagation();
|
|
4864
|
-
onEdit(hover.key);
|
|
4865
|
-
},
|
|
4866
|
-
children: [
|
|
4867
|
-
/* @__PURE__ */ jsx12(GalleryHorizontal, { size: 14 }),
|
|
4868
|
-
"Edit gallery"
|
|
4869
|
-
]
|
|
4870
|
-
}
|
|
4871
|
-
)
|
|
4872
|
-
}
|
|
4873
|
-
);
|
|
4874
|
-
}
|
|
4875
|
-
|
|
4876
4749
|
// src/OhhwellsBridge.tsx
|
|
4877
|
-
import { createPortal
|
|
4878
|
-
import { usePathname
|
|
4750
|
+
import { createPortal } from "react-dom";
|
|
4751
|
+
import { usePathname, useRouter, useSearchParams } from "next/navigation";
|
|
4879
4752
|
|
|
4880
4753
|
// src/lib/session-search.ts
|
|
4881
4754
|
var STORAGE_KEY = "ohw-preserved-search";
|
|
@@ -4905,7 +4778,6 @@ function parseSectionsFromRoot(root) {
|
|
|
4905
4778
|
for (const el of root.querySelectorAll("[data-ohw-section]")) {
|
|
4906
4779
|
const id = el.getAttribute("data-ohw-section") ?? "";
|
|
4907
4780
|
if (!id || seen.has(id)) continue;
|
|
4908
|
-
if (el.parentElement?.closest("[data-ohw-section]")) continue;
|
|
4909
4781
|
seen.add(id);
|
|
4910
4782
|
const label = el.getAttribute("data-ohw-section-label") ?? titleCaseSectionId(id);
|
|
4911
4783
|
sections.push({ id, label });
|
|
@@ -5152,22 +5024,54 @@ function scrollToHashSectionWhenReady(behavior = "smooth") {
|
|
|
5152
5024
|
tick();
|
|
5153
5025
|
}
|
|
5154
5026
|
|
|
5155
|
-
// src/ui/link-modal/LinkPopover.tsx
|
|
5156
|
-
import { useEffect as useEffect6 } from "react";
|
|
5157
|
-
|
|
5158
5027
|
// src/ui/dialog.tsx
|
|
5159
5028
|
import * as React7 from "react";
|
|
5160
5029
|
import { Dialog as DialogPrimitive } from "radix-ui";
|
|
5161
|
-
|
|
5030
|
+
|
|
5031
|
+
// src/ui/icons.tsx
|
|
5032
|
+
import { jsx as jsx12, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
5033
|
+
function IconX({ className, ...props }) {
|
|
5034
|
+
return /* @__PURE__ */ jsxs6("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
5035
|
+
/* @__PURE__ */ jsx12("path", { d: "M18 6 6 18" }),
|
|
5036
|
+
/* @__PURE__ */ jsx12("path", { d: "m6 6 12 12" })
|
|
5037
|
+
] });
|
|
5038
|
+
}
|
|
5039
|
+
function IconChevronDown({ className, ...props }) {
|
|
5040
|
+
return /* @__PURE__ */ jsx12("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: /* @__PURE__ */ jsx12("path", { d: "m6 9 6 6 6-6" }) });
|
|
5041
|
+
}
|
|
5042
|
+
function IconFile({ className, ...props }) {
|
|
5043
|
+
return /* @__PURE__ */ jsxs6("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
5044
|
+
/* @__PURE__ */ jsx12("path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z" }),
|
|
5045
|
+
/* @__PURE__ */ jsx12("path", { d: "M14 2v4a2 2 0 0 0 2 2h4" })
|
|
5046
|
+
] });
|
|
5047
|
+
}
|
|
5048
|
+
function IconInfo({ className, ...props }) {
|
|
5049
|
+
return /* @__PURE__ */ jsxs6("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
5050
|
+
/* @__PURE__ */ jsx12("circle", { cx: "12", cy: "12", r: "10" }),
|
|
5051
|
+
/* @__PURE__ */ jsx12("path", { d: "M12 16v-4" }),
|
|
5052
|
+
/* @__PURE__ */ jsx12("path", { d: "M12 8h.01" })
|
|
5053
|
+
] });
|
|
5054
|
+
}
|
|
5055
|
+
function IconArrowRight({ className, ...props }) {
|
|
5056
|
+
return /* @__PURE__ */ jsxs6("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
5057
|
+
/* @__PURE__ */ jsx12("path", { d: "M5 12h14" }),
|
|
5058
|
+
/* @__PURE__ */ jsx12("path", { d: "m12 5 7 7-7 7" })
|
|
5059
|
+
] });
|
|
5060
|
+
}
|
|
5061
|
+
function IconSection({ className, ...props }) {
|
|
5062
|
+
return /* @__PURE__ */ jsxs6("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
5063
|
+
/* @__PURE__ */ jsx12("rect", { width: "18", height: "7", x: "3", y: "3", rx: "1" }),
|
|
5064
|
+
/* @__PURE__ */ jsx12("rect", { width: "9", height: "7", x: "3", y: "14", rx: "1" }),
|
|
5065
|
+
/* @__PURE__ */ jsx12("rect", { width: "5", height: "7", x: "16", y: "14", rx: "1" })
|
|
5066
|
+
] });
|
|
5067
|
+
}
|
|
5068
|
+
|
|
5069
|
+
// src/ui/dialog.tsx
|
|
5162
5070
|
import { jsx as jsx13, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
5163
|
-
function Dialog2({
|
|
5164
|
-
...props
|
|
5165
|
-
}) {
|
|
5071
|
+
function Dialog2({ ...props }) {
|
|
5166
5072
|
return /* @__PURE__ */ jsx13(DialogPrimitive.Root, { "data-slot": "dialog", ...props });
|
|
5167
5073
|
}
|
|
5168
|
-
function DialogPortal({
|
|
5169
|
-
...props
|
|
5170
|
-
}) {
|
|
5074
|
+
function DialogPortal({ ...props }) {
|
|
5171
5075
|
return /* @__PURE__ */ jsx13(DialogPrimitive.Portal, { ...props });
|
|
5172
5076
|
}
|
|
5173
5077
|
function DialogOverlay({
|
|
@@ -5184,69 +5088,52 @@ function DialogOverlay({
|
|
|
5184
5088
|
}
|
|
5185
5089
|
);
|
|
5186
5090
|
}
|
|
5187
|
-
var DialogContent = React7.forwardRef(
|
|
5188
|
-
|
|
5189
|
-
|
|
5190
|
-
|
|
5191
|
-
|
|
5192
|
-
|
|
5193
|
-
|
|
5194
|
-
|
|
5195
|
-
|
|
5196
|
-
|
|
5197
|
-
|
|
5198
|
-
|
|
5199
|
-
|
|
5200
|
-
|
|
5201
|
-
|
|
5202
|
-
|
|
5203
|
-
|
|
5204
|
-
|
|
5205
|
-
|
|
5206
|
-
children
|
|
5207
|
-
|
|
5208
|
-
|
|
5209
|
-
|
|
5210
|
-
|
|
5211
|
-
|
|
5212
|
-
|
|
5213
|
-
|
|
5214
|
-
|
|
5215
|
-
|
|
5216
|
-
|
|
5217
|
-
|
|
5218
|
-
|
|
5219
|
-
|
|
5220
|
-
|
|
5221
|
-
}
|
|
5222
|
-
);
|
|
5091
|
+
var DialogContent = React7.forwardRef(({ className, children, showCloseButton = true, container, ...props }, ref) => {
|
|
5092
|
+
const positionMode = container ? "absolute" : "fixed";
|
|
5093
|
+
return /* @__PURE__ */ jsxs7(DialogPortal, { container: container ?? void 0, children: [
|
|
5094
|
+
/* @__PURE__ */ jsx13(DialogOverlay, { className: cn(positionMode, "inset-0") }),
|
|
5095
|
+
/* @__PURE__ */ jsxs7(
|
|
5096
|
+
DialogPrimitive.Content,
|
|
5097
|
+
{
|
|
5098
|
+
ref,
|
|
5099
|
+
"data-slot": "dialog-content",
|
|
5100
|
+
className: cn(
|
|
5101
|
+
positionMode,
|
|
5102
|
+
"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",
|
|
5103
|
+
"rounded-xl border border-border bg-background font-sans shadow-lg outline-none",
|
|
5104
|
+
container ? "max-h-[calc(100%-32px)] max-w-[calc(100%-16px)]" : "max-h-[calc(100vh-32px)] max-w-[calc(100vw-16px)]",
|
|
5105
|
+
className
|
|
5106
|
+
),
|
|
5107
|
+
onMouseDown: (e) => e.stopPropagation(),
|
|
5108
|
+
...props,
|
|
5109
|
+
children: [
|
|
5110
|
+
children,
|
|
5111
|
+
showCloseButton ? /* @__PURE__ */ jsx13(
|
|
5112
|
+
DialogPrimitive.Close,
|
|
5113
|
+
{
|
|
5114
|
+
type: "button",
|
|
5115
|
+
className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50",
|
|
5116
|
+
"aria-label": "Close",
|
|
5117
|
+
children: /* @__PURE__ */ jsx13(IconX, { "aria-hidden": true })
|
|
5118
|
+
}
|
|
5119
|
+
) : null
|
|
5120
|
+
]
|
|
5121
|
+
}
|
|
5122
|
+
)
|
|
5123
|
+
] });
|
|
5124
|
+
});
|
|
5223
5125
|
DialogContent.displayName = DialogPrimitive.Content.displayName;
|
|
5224
|
-
function DialogHeader({
|
|
5225
|
-
className,
|
|
5226
|
-
...props
|
|
5227
|
-
}) {
|
|
5126
|
+
function DialogHeader({ className, ...props }) {
|
|
5228
5127
|
return /* @__PURE__ */ jsx13("div", { className: cn("flex flex-col gap-1.5", className), ...props });
|
|
5229
5128
|
}
|
|
5230
|
-
function DialogFooter({
|
|
5231
|
-
className,
|
|
5232
|
-
...props
|
|
5233
|
-
}) {
|
|
5234
|
-
return /* @__PURE__ */ jsx13(
|
|
5235
|
-
"div",
|
|
5236
|
-
{
|
|
5237
|
-
className: cn("flex items-center justify-end gap-2", className),
|
|
5238
|
-
...props
|
|
5239
|
-
}
|
|
5240
|
-
);
|
|
5129
|
+
function DialogFooter({ className, ...props }) {
|
|
5130
|
+
return /* @__PURE__ */ jsx13("div", { className: cn("flex items-center justify-end gap-2", className), ...props });
|
|
5241
5131
|
}
|
|
5242
5132
|
var DialogTitle = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx13(
|
|
5243
5133
|
DialogPrimitive.Title,
|
|
5244
5134
|
{
|
|
5245
5135
|
ref,
|
|
5246
|
-
className: cn(
|
|
5247
|
-
"text-lg font-semibold leading-none tracking-tight text-card-foreground",
|
|
5248
|
-
className
|
|
5249
|
-
),
|
|
5136
|
+
className: cn("text-lg font-semibold leading-none tracking-tight text-card-foreground", className),
|
|
5250
5137
|
...props
|
|
5251
5138
|
}
|
|
5252
5139
|
));
|
|
@@ -5262,40 +5149,19 @@ var DialogDescription = React7.forwardRef(({ className, ...props }, ref) => /* @
|
|
|
5262
5149
|
DialogDescription.displayName = DialogPrimitive.Description.displayName;
|
|
5263
5150
|
var DialogClose = DialogPrimitive.Close;
|
|
5264
5151
|
|
|
5265
|
-
// src/ui/link-modal/LinkEditorPanel.tsx
|
|
5266
|
-
import { Info, X as X3 } from "lucide-react";
|
|
5267
|
-
|
|
5268
5152
|
// src/ui/link-modal/DestinationBreadcrumb.tsx
|
|
5269
|
-
import { ArrowRight, File, GalleryVertical } from "lucide-react";
|
|
5270
5153
|
import { jsx as jsx14, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
5271
|
-
function DestinationBreadcrumb({
|
|
5272
|
-
pageTitle,
|
|
5273
|
-
sectionLabel
|
|
5274
|
-
}) {
|
|
5154
|
+
function DestinationBreadcrumb({ pageTitle, sectionLabel }) {
|
|
5275
5155
|
return /* @__PURE__ */ jsxs8("div", { className: "flex w-full flex-col gap-2", children: [
|
|
5276
|
-
/* @__PURE__ */ jsx14("p", { className: "text-sm font-medium
|
|
5156
|
+
/* @__PURE__ */ jsx14("p", { className: "text-sm font-medium text-foreground", children: "Destination" }),
|
|
5277
5157
|
/* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-3", children: [
|
|
5278
5158
|
/* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2", children: [
|
|
5279
|
-
/* @__PURE__ */ jsx14(
|
|
5280
|
-
/* @__PURE__ */ jsx14("span", { className: "text-sm font-medium leading-none text-foreground
|
|
5159
|
+
/* @__PURE__ */ jsx14(IconFile, { className: "shrink-0 text-foreground", "aria-hidden": true }),
|
|
5160
|
+
/* @__PURE__ */ jsx14("span", { className: "text-sm font-medium leading-none text-foreground", children: pageTitle })
|
|
5281
5161
|
] }),
|
|
5282
|
-
/* @__PURE__ */ jsx14(
|
|
5283
|
-
ArrowRight,
|
|
5284
|
-
{
|
|
5285
|
-
size: 16,
|
|
5286
|
-
className: "shrink-0 text-muted-foreground",
|
|
5287
|
-
"aria-hidden": true
|
|
5288
|
-
}
|
|
5289
|
-
),
|
|
5162
|
+
/* @__PURE__ */ jsx14(IconArrowRight, { className: "shrink-0 text-muted-foreground", "aria-hidden": true }),
|
|
5290
5163
|
/* @__PURE__ */ jsxs8("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
|
|
5291
|
-
/* @__PURE__ */ jsx14(
|
|
5292
|
-
GalleryVertical,
|
|
5293
|
-
{
|
|
5294
|
-
size: 16,
|
|
5295
|
-
className: "shrink-0 text-foreground",
|
|
5296
|
-
"aria-hidden": true
|
|
5297
|
-
}
|
|
5298
|
-
),
|
|
5164
|
+
/* @__PURE__ */ jsx14(IconSection, { className: "shrink-0 text-foreground", "aria-hidden": true }),
|
|
5299
5165
|
/* @__PURE__ */ jsx14("span", { className: "truncate text-sm font-medium leading-none text-foreground", children: sectionLabel })
|
|
5300
5166
|
] })
|
|
5301
5167
|
] })
|
|
@@ -5303,13 +5169,8 @@ function DestinationBreadcrumb({
|
|
|
5303
5169
|
}
|
|
5304
5170
|
|
|
5305
5171
|
// src/ui/link-modal/SectionTreeItem.tsx
|
|
5306
|
-
import { GalleryVertical as GalleryVertical2 } from "lucide-react";
|
|
5307
5172
|
import { jsx as jsx15, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
5308
|
-
function SectionTreeItem({
|
|
5309
|
-
section,
|
|
5310
|
-
onSelect,
|
|
5311
|
-
selected
|
|
5312
|
-
}) {
|
|
5173
|
+
function SectionTreeItem({ section, onSelect, selected }) {
|
|
5313
5174
|
const interactive = Boolean(onSelect);
|
|
5314
5175
|
return /* @__PURE__ */ jsxs9("div", { className: "flex h-9 w-full items-end pl-3", children: [
|
|
5315
5176
|
/* @__PURE__ */ jsx15(
|
|
@@ -5337,23 +5198,25 @@ function SectionTreeItem({
|
|
|
5337
5198
|
interactive && selected && "border-primary"
|
|
5338
5199
|
),
|
|
5339
5200
|
children: [
|
|
5340
|
-
/* @__PURE__ */ jsx15(
|
|
5341
|
-
GalleryVertical2,
|
|
5342
|
-
{
|
|
5343
|
-
size: 16,
|
|
5344
|
-
className: "shrink-0 text-foreground",
|
|
5345
|
-
"aria-hidden": true
|
|
5346
|
-
}
|
|
5347
|
-
),
|
|
5201
|
+
/* @__PURE__ */ jsx15(IconSection, { className: "shrink-0 text-foreground", "aria-hidden": true }),
|
|
5348
5202
|
/* @__PURE__ */ jsx15("span", { className: "truncate text-sm font-normal leading-5 text-foreground", children: section.label })
|
|
5349
5203
|
]
|
|
5350
5204
|
}
|
|
5351
5205
|
)
|
|
5352
5206
|
] });
|
|
5353
5207
|
}
|
|
5208
|
+
function SectionPickerList({ sections, onSelect }) {
|
|
5209
|
+
if (sections.length === 0) {
|
|
5210
|
+
return /* @__PURE__ */ jsx15("p", { className: "text-sm text-muted-foreground", children: "No sections found on this page." });
|
|
5211
|
+
}
|
|
5212
|
+
return /* @__PURE__ */ jsxs9("div", { className: "flex flex-col gap-1", children: [
|
|
5213
|
+
/* @__PURE__ */ jsx15("p", { className: "text-sm text-muted-foreground", children: "Pick a section this link should scroll to." }),
|
|
5214
|
+
sections.map((section) => /* @__PURE__ */ jsx15(SectionTreeItem, { section, onSelect }, section.id))
|
|
5215
|
+
] });
|
|
5216
|
+
}
|
|
5354
5217
|
|
|
5355
5218
|
// src/ui/link-modal/UrlOrPageInput.tsx
|
|
5356
|
-
import {
|
|
5219
|
+
import { useId as useId2, useRef as useRef3, useState as useState3 } from "react";
|
|
5357
5220
|
|
|
5358
5221
|
// src/ui/input.tsx
|
|
5359
5222
|
import * as React8 from "react";
|
|
@@ -5392,11 +5255,8 @@ function Label({ className, ...props }) {
|
|
|
5392
5255
|
}
|
|
5393
5256
|
|
|
5394
5257
|
// src/ui/link-modal/UrlOrPageInput.tsx
|
|
5395
|
-
import { ChevronDown, File as File2, X as X2 } from "lucide-react";
|
|
5396
5258
|
import { jsx as jsx18, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
5397
|
-
function FieldChevron({
|
|
5398
|
-
onClick
|
|
5399
|
-
}) {
|
|
5259
|
+
function FieldChevron({ onClick }) {
|
|
5400
5260
|
return /* @__PURE__ */ jsx18(
|
|
5401
5261
|
"button",
|
|
5402
5262
|
{
|
|
@@ -5405,7 +5265,7 @@ function FieldChevron({
|
|
|
5405
5265
|
onClick,
|
|
5406
5266
|
"aria-label": "Open page list",
|
|
5407
5267
|
tabIndex: -1,
|
|
5408
|
-
children: /* @__PURE__ */ jsx18(
|
|
5268
|
+
children: /* @__PURE__ */ jsx18(IconChevronDown, {})
|
|
5409
5269
|
}
|
|
5410
5270
|
);
|
|
5411
5271
|
}
|
|
@@ -5423,29 +5283,7 @@ function UrlOrPageInput({
|
|
|
5423
5283
|
}) {
|
|
5424
5284
|
const inputId = useId2();
|
|
5425
5285
|
const inputRef = useRef3(null);
|
|
5426
|
-
const rootRef = useRef3(null);
|
|
5427
5286
|
const [isFocused, setIsFocused] = useState3(false);
|
|
5428
|
-
useEffect3(() => {
|
|
5429
|
-
if (!dropdownOpen) return;
|
|
5430
|
-
const isOutside = (e) => {
|
|
5431
|
-
const root = rootRef.current;
|
|
5432
|
-
if (!root) return true;
|
|
5433
|
-
const path = typeof e.composedPath === "function" ? e.composedPath() : [];
|
|
5434
|
-
if (path.includes(root)) return false;
|
|
5435
|
-
const target = e.target;
|
|
5436
|
-
return !(target instanceof Node && root.contains(target));
|
|
5437
|
-
};
|
|
5438
|
-
const closeIfOutside = (e) => {
|
|
5439
|
-
if (!isOutside(e)) return;
|
|
5440
|
-
onDropdownOpenChange(false);
|
|
5441
|
-
};
|
|
5442
|
-
document.addEventListener("pointerdown", closeIfOutside, true);
|
|
5443
|
-
document.addEventListener("mousedown", closeIfOutside, true);
|
|
5444
|
-
return () => {
|
|
5445
|
-
document.removeEventListener("pointerdown", closeIfOutside, true);
|
|
5446
|
-
document.removeEventListener("mousedown", closeIfOutside, true);
|
|
5447
|
-
};
|
|
5448
|
-
}, [dropdownOpen, onDropdownOpenChange]);
|
|
5449
5287
|
const openDropdown = () => {
|
|
5450
5288
|
if (readOnly || filteredPages.length === 0) return;
|
|
5451
5289
|
onDropdownOpenChange(true);
|
|
@@ -5463,21 +5301,14 @@ function UrlOrPageInput({
|
|
|
5463
5301
|
requestAnimationFrame(() => inputRef.current?.focus());
|
|
5464
5302
|
};
|
|
5465
5303
|
const fieldClassName = cn(
|
|
5466
|
-
"data-ohw-link-field flex h-
|
|
5304
|
+
"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]",
|
|
5467
5305
|
urlError ? "border-destructive shadow-[0_0_0_1px_var(--ohw-destructive)]" : isFocused ? "border-primary shadow-[0_0_0_1px_var(--ohw-primary)]" : "border-input"
|
|
5468
5306
|
);
|
|
5469
5307
|
return /* @__PURE__ */ jsxs10("div", { className: "flex w-full flex-col gap-2 p-0", children: [
|
|
5470
5308
|
/* @__PURE__ */ jsx18(Label, { htmlFor: inputId, className: cn(urlError && "text-destructive"), children: "Destination" }),
|
|
5471
|
-
/* @__PURE__ */ jsxs10("div", {
|
|
5309
|
+
/* @__PURE__ */ jsxs10("div", { className: "relative w-full", children: [
|
|
5472
5310
|
/* @__PURE__ */ jsxs10("div", { "data-ohw-link-field": true, className: fieldClassName, children: [
|
|
5473
|
-
selectedPage ? /* @__PURE__ */ jsx18("div", { className: "flex shrink-0 items-center pr-2", children: /* @__PURE__ */ jsx18(
|
|
5474
|
-
File2,
|
|
5475
|
-
{
|
|
5476
|
-
size: 16,
|
|
5477
|
-
className: "shrink-0 text-foreground",
|
|
5478
|
-
"aria-hidden": true
|
|
5479
|
-
}
|
|
5480
|
-
) }) : null,
|
|
5311
|
+
selectedPage ? /* @__PURE__ */ jsx18("div", { className: "flex shrink-0 items-center pr-2", children: /* @__PURE__ */ jsx18(IconFile, { className: "text-foreground", "aria-hidden": true }) }) : null,
|
|
5481
5312
|
readOnly ? /* @__PURE__ */ jsx18("span", { className: "min-w-0 flex-1 truncate text-sm leading-5 text-foreground", children: selectedPage?.title ?? value }) : /* @__PURE__ */ jsx18(
|
|
5482
5313
|
Input,
|
|
5483
5314
|
{
|
|
@@ -5489,14 +5320,7 @@ function UrlOrPageInput({
|
|
|
5489
5320
|
setIsFocused(true);
|
|
5490
5321
|
if (!selectedPage) openDropdown();
|
|
5491
5322
|
},
|
|
5492
|
-
onBlur: () =>
|
|
5493
|
-
setIsFocused(false);
|
|
5494
|
-
requestAnimationFrame(() => {
|
|
5495
|
-
if (!rootRef.current?.contains(document.activeElement)) {
|
|
5496
|
-
onDropdownOpenChange(false);
|
|
5497
|
-
}
|
|
5498
|
-
});
|
|
5499
|
-
},
|
|
5323
|
+
onBlur: () => setIsFocused(false),
|
|
5500
5324
|
placeholder,
|
|
5501
5325
|
className: cn(
|
|
5502
5326
|
"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",
|
|
@@ -5512,7 +5336,7 @@ function UrlOrPageInput({
|
|
|
5512
5336
|
onMouseDown: clearSelection,
|
|
5513
5337
|
"aria-label": "Clear selected page",
|
|
5514
5338
|
tabIndex: -1,
|
|
5515
|
-
children: /* @__PURE__ */ jsx18(
|
|
5339
|
+
children: /* @__PURE__ */ jsx18(IconX, { "aria-hidden": true })
|
|
5516
5340
|
}
|
|
5517
5341
|
) : null,
|
|
5518
5342
|
!readOnly ? /* @__PURE__ */ jsx18(FieldChevron, { onClick: toggleDropdown }) : null
|
|
@@ -5521,7 +5345,7 @@ function UrlOrPageInput({
|
|
|
5521
5345
|
"div",
|
|
5522
5346
|
{
|
|
5523
5347
|
"data-ohw-link-page-dropdown": "",
|
|
5524
|
-
className: "absolute left-0 right-0 top-[calc(100%+4px)] z-
|
|
5348
|
+
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",
|
|
5525
5349
|
onMouseDown: (e) => e.preventDefault(),
|
|
5526
5350
|
children: filteredPages.map((page) => /* @__PURE__ */ jsxs10(
|
|
5527
5351
|
"button",
|
|
@@ -5530,7 +5354,7 @@ function UrlOrPageInput({
|
|
|
5530
5354
|
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",
|
|
5531
5355
|
onClick: () => onPageSelect(page),
|
|
5532
5356
|
children: [
|
|
5533
|
-
/* @__PURE__ */ jsx18(
|
|
5357
|
+
/* @__PURE__ */ jsx18(IconFile, { className: "shrink-0", "aria-hidden": true }),
|
|
5534
5358
|
/* @__PURE__ */ jsx18("span", { className: "truncate", children: page.title })
|
|
5535
5359
|
]
|
|
5536
5360
|
},
|
|
@@ -5543,458 +5367,30 @@ function UrlOrPageInput({
|
|
|
5543
5367
|
] });
|
|
5544
5368
|
}
|
|
5545
5369
|
|
|
5546
|
-
// src/ui/link-modal/
|
|
5547
|
-
import {
|
|
5548
|
-
function
|
|
5549
|
-
|
|
5550
|
-
|
|
5551
|
-
|
|
5552
|
-
|
|
5553
|
-
|
|
5554
|
-
|
|
5555
|
-
|
|
5556
|
-
|
|
5557
|
-
|
|
5558
|
-
|
|
5559
|
-
|
|
5560
|
-
)
|
|
5561
|
-
|
|
5562
|
-
/* @__PURE__ */ jsxs11("div", { className: "flex w-full flex-col gap-3 px-6 pb-8 pt-1", children: [
|
|
5563
|
-
state.showBreadcrumb && state.selectedPage && state.selectedSection ? /* @__PURE__ */ jsx19(
|
|
5564
|
-
DestinationBreadcrumb,
|
|
5565
|
-
{
|
|
5566
|
-
pageTitle: state.selectedPage.title,
|
|
5567
|
-
sectionLabel: state.selectedSection.label
|
|
5568
|
-
}
|
|
5569
|
-
) : /* @__PURE__ */ jsx19(
|
|
5570
|
-
UrlOrPageInput,
|
|
5571
|
-
{
|
|
5572
|
-
value: state.searchValue,
|
|
5573
|
-
selectedPage: state.selectedPage,
|
|
5574
|
-
dropdownOpen: state.dropdownOpen,
|
|
5575
|
-
onDropdownOpenChange: state.setDropdownOpen,
|
|
5576
|
-
filteredPages: state.filteredPages,
|
|
5577
|
-
onInputChange: state.handleInputChange,
|
|
5578
|
-
onPageSelect: state.handlePageSelect,
|
|
5579
|
-
urlError: state.urlError
|
|
5580
|
-
}
|
|
5581
|
-
),
|
|
5582
|
-
state.showChooseSection ? /* @__PURE__ */ jsxs11("div", { className: "flex flex-col justify-center gap-2", children: [
|
|
5583
|
-
/* @__PURE__ */ jsx19(
|
|
5584
|
-
Button,
|
|
5585
|
-
{
|
|
5586
|
-
type: "button",
|
|
5587
|
-
variant: "outline",
|
|
5588
|
-
className: "w-fit cursor-pointer",
|
|
5589
|
-
size: "sm",
|
|
5590
|
-
onClick: state.handleChooseSection,
|
|
5591
|
-
children: "Choose a section"
|
|
5592
|
-
}
|
|
5593
|
-
),
|
|
5594
|
-
/* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-1 text-sm text-muted-foreground", children: [
|
|
5595
|
-
/* @__PURE__ */ jsx19(Info, { size: 16, className: "shrink-0", "aria-hidden": true }),
|
|
5596
|
-
/* @__PURE__ */ jsx19("span", { children: "Pick a section this link should scroll to." })
|
|
5597
|
-
] })
|
|
5598
|
-
] }) : null,
|
|
5599
|
-
state.showSectionRow && state.selectedSection ? /* @__PURE__ */ jsx19(SectionTreeItem, { section: state.selectedSection, selected: true }) : null
|
|
5600
|
-
] }),
|
|
5601
|
-
/* @__PURE__ */ jsxs11(DialogFooter, { className: "w-full px-6 pb-6", children: [
|
|
5602
|
-
/* @__PURE__ */ jsx19(
|
|
5603
|
-
Button,
|
|
5604
|
-
{
|
|
5605
|
-
type: "button",
|
|
5606
|
-
variant: isCancel ? "outline" : "ghost",
|
|
5607
|
-
className: "leading-6 shadow-none cursor-pointer",
|
|
5608
|
-
style: isCancel ? {
|
|
5609
|
-
backgroundColor: "var(--ohw-background)",
|
|
5610
|
-
borderColor: "var(--ohw-border)",
|
|
5611
|
-
color: "var(--ohw-foreground)"
|
|
5612
|
-
} : void 0,
|
|
5613
|
-
onClick: state.handleSecondary,
|
|
5614
|
-
children: state.secondaryLabel
|
|
5615
|
-
}
|
|
5616
|
-
),
|
|
5617
|
-
/* @__PURE__ */ jsx19(
|
|
5618
|
-
Button,
|
|
5619
|
-
{
|
|
5620
|
-
type: "button",
|
|
5621
|
-
className: "border-0 leading-6 shadow-none hover:opacity-90 disabled:opacity-50 cursor-pointer",
|
|
5622
|
-
style: {
|
|
5623
|
-
backgroundColor: "var(--ohw-primary)",
|
|
5624
|
-
color: "var(--ohw-primary-foreground)"
|
|
5625
|
-
},
|
|
5626
|
-
disabled: !state.isValid,
|
|
5627
|
-
onClick: state.handleSubmit,
|
|
5628
|
-
children: state.submitLabel
|
|
5629
|
-
}
|
|
5630
|
-
)
|
|
5631
|
-
] })
|
|
5632
|
-
] });
|
|
5633
|
-
}
|
|
5634
|
-
|
|
5635
|
-
// src/ui/link-modal/SectionPickerOverlay.tsx
|
|
5636
|
-
import { useCallback as useCallback2, useEffect as useEffect4, useMemo as useMemo2, useRef as useRef4, useState as useState4 } from "react";
|
|
5637
|
-
import { createPortal } from "react-dom";
|
|
5638
|
-
import { ArrowLeft, Check } from "lucide-react";
|
|
5639
|
-
import { usePathname, useRouter } from "next/navigation";
|
|
5640
|
-
import { jsx as jsx20, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
5641
|
-
var DIM_OVERLAY = "rgba(0, 0, 0, 0.45)";
|
|
5642
|
-
function rectsEqual(a, b) {
|
|
5643
|
-
if (a.size !== b.size) return false;
|
|
5644
|
-
for (const [id, rect] of a) {
|
|
5645
|
-
const other = b.get(id);
|
|
5646
|
-
if (!other || rect.top !== other.top || rect.left !== other.left || rect.width !== other.width || rect.height !== other.height) {
|
|
5647
|
-
return false;
|
|
5648
|
-
}
|
|
5649
|
-
}
|
|
5650
|
-
return true;
|
|
5651
|
-
}
|
|
5652
|
-
function readSectionRects(sectionIds) {
|
|
5653
|
-
const next = /* @__PURE__ */ new Map();
|
|
5654
|
-
for (const id of sectionIds) {
|
|
5655
|
-
const el = document.querySelector(
|
|
5656
|
-
`[data-ohw-section="${CSS.escape(id)}"]`
|
|
5657
|
-
);
|
|
5658
|
-
if (el) next.set(id, el.getBoundingClientRect());
|
|
5659
|
-
}
|
|
5660
|
-
return next;
|
|
5661
|
-
}
|
|
5662
|
-
function hitTestSectionId(x, y, sectionIds, rects) {
|
|
5663
|
-
for (const id of sectionIds) {
|
|
5664
|
-
const rect = rects.get(id);
|
|
5665
|
-
if (!rect || rect.width <= 0 || rect.height <= 0) continue;
|
|
5666
|
-
if (x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom) {
|
|
5667
|
-
return id;
|
|
5668
|
-
}
|
|
5669
|
-
}
|
|
5670
|
-
return null;
|
|
5671
|
-
}
|
|
5672
|
-
function useSectionRects(sectionIdsKey, enabled) {
|
|
5673
|
-
const [rects, setRects] = useState4(/* @__PURE__ */ new Map());
|
|
5674
|
-
const sectionIds = useMemo2(
|
|
5675
|
-
() => sectionIdsKey ? sectionIdsKey.split("\0") : [],
|
|
5676
|
-
[sectionIdsKey]
|
|
5370
|
+
// src/ui/link-modal/useLinkModalState.ts
|
|
5371
|
+
import { useCallback, useEffect as useEffect3, useMemo as useMemo2, useState as useState4 } from "react";
|
|
5372
|
+
function useLinkModalState({
|
|
5373
|
+
open,
|
|
5374
|
+
mode,
|
|
5375
|
+
pages,
|
|
5376
|
+
sections: _sections,
|
|
5377
|
+
sectionsByPath,
|
|
5378
|
+
initialTarget,
|
|
5379
|
+
existingTargets,
|
|
5380
|
+
onClose,
|
|
5381
|
+
onSubmit
|
|
5382
|
+
}) {
|
|
5383
|
+
const availablePages = useMemo2(
|
|
5384
|
+
() => mode === "create" ? filterAvailablePages(pages, existingTargets) : pages,
|
|
5385
|
+
[mode, pages, existingTargets]
|
|
5677
5386
|
);
|
|
5678
|
-
|
|
5679
|
-
|
|
5680
|
-
|
|
5681
|
-
|
|
5682
|
-
|
|
5683
|
-
|
|
5684
|
-
|
|
5685
|
-
setRects((prev) => rectsEqual(prev, next) ? prev : next);
|
|
5686
|
-
};
|
|
5687
|
-
update();
|
|
5688
|
-
const opts = { capture: true, passive: true };
|
|
5689
|
-
window.addEventListener("scroll", update, opts);
|
|
5690
|
-
window.addEventListener("resize", update);
|
|
5691
|
-
const vv = window.visualViewport;
|
|
5692
|
-
vv?.addEventListener("resize", update);
|
|
5693
|
-
vv?.addEventListener("scroll", update);
|
|
5694
|
-
const ro = new ResizeObserver(update);
|
|
5695
|
-
for (const id of sectionIds) {
|
|
5696
|
-
const el = document.querySelector(
|
|
5697
|
-
`[data-ohw-section="${CSS.escape(id)}"]`
|
|
5698
|
-
);
|
|
5699
|
-
if (el) ro.observe(el);
|
|
5700
|
-
}
|
|
5701
|
-
return () => {
|
|
5702
|
-
window.removeEventListener("scroll", update, opts);
|
|
5703
|
-
window.removeEventListener("resize", update);
|
|
5704
|
-
vv?.removeEventListener("resize", update);
|
|
5705
|
-
vv?.removeEventListener("scroll", update);
|
|
5706
|
-
ro.disconnect();
|
|
5707
|
-
};
|
|
5708
|
-
}, [sectionIds, enabled]);
|
|
5709
|
-
return rects;
|
|
5710
|
-
}
|
|
5711
|
-
function SectionPickerOverlay({
|
|
5712
|
-
pagePath,
|
|
5713
|
-
sections,
|
|
5714
|
-
onBack,
|
|
5715
|
-
onSelect
|
|
5716
|
-
}) {
|
|
5717
|
-
const router = useRouter();
|
|
5718
|
-
const pathname = usePathname();
|
|
5719
|
-
const [selectedId, setSelectedId] = useState4(null);
|
|
5720
|
-
const [hoveredId, setHoveredId] = useState4(null);
|
|
5721
|
-
const pointerRef = useRef4(null);
|
|
5722
|
-
const pointerScreenRef = useRef4(null);
|
|
5723
|
-
const iframeOffsetTopRef = useRef4(null);
|
|
5724
|
-
const sectionIdsRef = useRef4([]);
|
|
5725
|
-
const [chromeClip, setChromeClip] = useState4(
|
|
5726
|
-
() => ({
|
|
5727
|
-
top: 0,
|
|
5728
|
-
bottom: typeof window !== "undefined" ? window.innerHeight : 0
|
|
5729
|
-
})
|
|
5730
|
-
);
|
|
5731
|
-
const normalizedTarget = normalizePath(pagePath);
|
|
5732
|
-
const isOnTargetPage = normalizePath(pathname) === normalizedTarget;
|
|
5733
|
-
useEffect4(() => {
|
|
5734
|
-
if (isOnTargetPage) return;
|
|
5735
|
-
const search = readPreservedSearch();
|
|
5736
|
-
router.push(`${normalizedTarget}${search}`);
|
|
5737
|
-
}, [isOnTargetPage, normalizedTarget, router]);
|
|
5738
|
-
useEffect4(() => {
|
|
5739
|
-
document.documentElement.setAttribute("data-ohw-section-picking", "");
|
|
5740
|
-
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => {
|
|
5741
|
-
el.removeAttribute("data-ohw-hovered");
|
|
5742
|
-
});
|
|
5743
|
-
document.querySelectorAll("[data-ohw-state-hovered]").forEach((el) => {
|
|
5744
|
-
el.removeAttribute("data-ohw-state-hovered");
|
|
5745
|
-
});
|
|
5746
|
-
return () => {
|
|
5747
|
-
document.documentElement.removeAttribute("data-ohw-section-picking");
|
|
5748
|
-
};
|
|
5749
|
-
}, []);
|
|
5750
|
-
const liveSections = useMemo2(() => {
|
|
5751
|
-
if (!isOnTargetPage) return sections;
|
|
5752
|
-
const live = collectSectionsFromDom();
|
|
5753
|
-
if (live.length === 0) return sections;
|
|
5754
|
-
const labels = new Map(sections.map((s) => [s.id, s.label]));
|
|
5755
|
-
return live.map((s) => ({ id: s.id, label: labels.get(s.id) ?? s.label }));
|
|
5756
|
-
}, [isOnTargetPage, sections, pathname]);
|
|
5757
|
-
const sectionIdsKey = useMemo2(
|
|
5758
|
-
() => liveSections.map((s) => s.id).join("\0"),
|
|
5759
|
-
[liveSections]
|
|
5760
|
-
);
|
|
5761
|
-
const sectionIds = useMemo2(
|
|
5762
|
-
() => liveSections.map((s) => s.id),
|
|
5763
|
-
[liveSections]
|
|
5764
|
-
);
|
|
5765
|
-
sectionIdsRef.current = sectionIds;
|
|
5766
|
-
const rects = useSectionRects(sectionIdsKey, isOnTargetPage);
|
|
5767
|
-
const applyHoverAt = useCallback2(
|
|
5768
|
-
(x, y, liveRects) => {
|
|
5769
|
-
const ids = sectionIdsRef.current;
|
|
5770
|
-
const map = liveRects ?? readSectionRects(ids);
|
|
5771
|
-
const next = hitTestSectionId(x, y, ids, map);
|
|
5772
|
-
setHoveredId((prev) => prev === next ? prev : next);
|
|
5773
|
-
},
|
|
5774
|
-
[]
|
|
5775
|
-
);
|
|
5776
|
-
useEffect4(() => {
|
|
5777
|
-
const applyClip = (iframeOffsetTop, visibleCanvasTop, canvasH) => {
|
|
5778
|
-
const top = Math.max(0, visibleCanvasTop - iframeOffsetTop);
|
|
5779
|
-
const bottom = Math.min(
|
|
5780
|
-
window.innerHeight,
|
|
5781
|
-
visibleCanvasTop + canvasH - iframeOffsetTop
|
|
5782
|
-
);
|
|
5783
|
-
setChromeClip(
|
|
5784
|
-
(prev) => prev.top === top && prev.bottom === bottom ? prev : { top, bottom: Math.max(top, bottom) }
|
|
5785
|
-
);
|
|
5786
|
-
};
|
|
5787
|
-
const onParentScroll = (e) => {
|
|
5788
|
-
if (e.data?.type !== "ow:parent-scroll") return;
|
|
5789
|
-
const { iframeOffsetTop, headerH, canvasH } = e.data;
|
|
5790
|
-
applyClip(iframeOffsetTop, headerH, canvasH);
|
|
5791
|
-
iframeOffsetTopRef.current = iframeOffsetTop;
|
|
5792
|
-
if (!pointerScreenRef.current && pointerRef.current) {
|
|
5793
|
-
pointerScreenRef.current = {
|
|
5794
|
-
x: pointerRef.current.x,
|
|
5795
|
-
y: pointerRef.current.y + iframeOffsetTop
|
|
5796
|
-
};
|
|
5797
|
-
}
|
|
5798
|
-
const screen = pointerScreenRef.current;
|
|
5799
|
-
if (screen) {
|
|
5800
|
-
const next = { x: screen.x, y: screen.y - iframeOffsetTop };
|
|
5801
|
-
pointerRef.current = next;
|
|
5802
|
-
applyHoverAt(next.x, next.y);
|
|
5803
|
-
}
|
|
5804
|
-
};
|
|
5805
|
-
const onResize = () => {
|
|
5806
|
-
setChromeClip((prev) => {
|
|
5807
|
-
const bottom = Math.max(prev.top, window.innerHeight);
|
|
5808
|
-
return prev.bottom === bottom ? prev : { ...prev, bottom };
|
|
5809
|
-
});
|
|
5810
|
-
};
|
|
5811
|
-
window.addEventListener("message", onParentScroll);
|
|
5812
|
-
window.addEventListener("resize", onResize);
|
|
5813
|
-
return () => {
|
|
5814
|
-
window.removeEventListener("message", onParentScroll);
|
|
5815
|
-
window.removeEventListener("resize", onResize);
|
|
5816
|
-
};
|
|
5817
|
-
}, [applyHoverAt]);
|
|
5818
|
-
useEffect4(() => {
|
|
5819
|
-
const ptr = pointerRef.current;
|
|
5820
|
-
if (!ptr) return;
|
|
5821
|
-
applyHoverAt(ptr.x, ptr.y, rects);
|
|
5822
|
-
}, [rects, applyHoverAt]);
|
|
5823
|
-
useEffect4(() => {
|
|
5824
|
-
const rememberPointer = (clientX, clientY) => {
|
|
5825
|
-
pointerRef.current = { x: clientX, y: clientY };
|
|
5826
|
-
const top = iframeOffsetTopRef.current;
|
|
5827
|
-
if (top != null) {
|
|
5828
|
-
pointerScreenRef.current = { x: clientX, y: clientY + top };
|
|
5829
|
-
}
|
|
5830
|
-
applyHoverAt(clientX, clientY, rects);
|
|
5831
|
-
};
|
|
5832
|
-
const onPointerMove = (e) => {
|
|
5833
|
-
rememberPointer(e.clientX, e.clientY);
|
|
5834
|
-
};
|
|
5835
|
-
const onPointerSync = (e) => {
|
|
5836
|
-
if (e.data?.type !== "ow:pointer-sync") return;
|
|
5837
|
-
const { clientX, clientY } = e.data;
|
|
5838
|
-
rememberPointer(clientX, clientY);
|
|
5839
|
-
};
|
|
5840
|
-
window.addEventListener("pointermove", onPointerMove, { passive: true });
|
|
5841
|
-
window.addEventListener("message", onPointerSync);
|
|
5842
|
-
return () => {
|
|
5843
|
-
window.removeEventListener("pointermove", onPointerMove);
|
|
5844
|
-
window.removeEventListener("message", onPointerSync);
|
|
5845
|
-
};
|
|
5846
|
-
}, [rects, applyHoverAt]);
|
|
5847
|
-
const handleSelect = useCallback2(
|
|
5848
|
-
(section) => {
|
|
5849
|
-
if (selectedId) return;
|
|
5850
|
-
setSelectedId(section.id);
|
|
5851
|
-
onSelect(section);
|
|
5852
|
-
},
|
|
5853
|
-
[selectedId, onSelect]
|
|
5854
|
-
);
|
|
5855
|
-
useEffect4(() => {
|
|
5856
|
-
const onKeyDown = (e) => {
|
|
5857
|
-
if (e.key === "Escape") {
|
|
5858
|
-
e.preventDefault();
|
|
5859
|
-
e.stopPropagation();
|
|
5860
|
-
onBack();
|
|
5861
|
-
}
|
|
5862
|
-
};
|
|
5863
|
-
window.addEventListener("keydown", onKeyDown, true);
|
|
5864
|
-
return () => window.removeEventListener("keydown", onKeyDown, true);
|
|
5865
|
-
}, [onBack]);
|
|
5866
|
-
const portalRoot = typeof document !== "undefined" ? document.querySelector("[data-ohw-bridge-root]") ?? document.body : null;
|
|
5867
|
-
if (!portalRoot) return null;
|
|
5868
|
-
return createPortal(
|
|
5869
|
-
/* @__PURE__ */ jsxs12(
|
|
5870
|
-
"div",
|
|
5871
|
-
{
|
|
5872
|
-
"data-ohw-section-picker": "",
|
|
5873
|
-
"data-ohw-bridge": "",
|
|
5874
|
-
className: `pointer-events-none fixed inset-0 z-[2147483647] transition-opacity duration-200 ${"opacity-100"}`,
|
|
5875
|
-
"aria-modal": true,
|
|
5876
|
-
role: "dialog",
|
|
5877
|
-
"aria-label": "Choose a section",
|
|
5878
|
-
children: [
|
|
5879
|
-
/* @__PURE__ */ jsx20(
|
|
5880
|
-
"div",
|
|
5881
|
-
{
|
|
5882
|
-
className: "pointer-events-auto fixed left-5 z-[2]",
|
|
5883
|
-
style: { top: chromeClip.top + 20 },
|
|
5884
|
-
children: /* @__PURE__ */ jsxs12(
|
|
5885
|
-
Button,
|
|
5886
|
-
{
|
|
5887
|
-
type: "button",
|
|
5888
|
-
variant: "outline",
|
|
5889
|
-
size: "sm",
|
|
5890
|
-
className: "h-8 min-w-0 gap-1 border-border bg-background px-2 py-1.5 shadow-sm hover:bg-muted cursor-pointer",
|
|
5891
|
-
onClick: onBack,
|
|
5892
|
-
children: [
|
|
5893
|
-
/* @__PURE__ */ jsx20(ArrowLeft, { className: "size-4 shrink-0", "aria-hidden": true }),
|
|
5894
|
-
"Back"
|
|
5895
|
-
]
|
|
5896
|
-
}
|
|
5897
|
-
)
|
|
5898
|
-
}
|
|
5899
|
-
),
|
|
5900
|
-
/* @__PURE__ */ jsx20(
|
|
5901
|
-
"div",
|
|
5902
|
-
{
|
|
5903
|
-
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",
|
|
5904
|
-
style: {
|
|
5905
|
-
top: chromeClip.bottom - 20,
|
|
5906
|
-
transform: "translate(-50%, -100%)",
|
|
5907
|
-
backgroundColor: "var(--ohw-popover-foreground, #0c0a09)"
|
|
5908
|
-
},
|
|
5909
|
-
"data-ohw-section-picker-hint": "",
|
|
5910
|
-
children: "Click on section to select"
|
|
5911
|
-
}
|
|
5912
|
-
),
|
|
5913
|
-
!isOnTargetPage ? /* @__PURE__ */ jsx20(
|
|
5914
|
-
"div",
|
|
5915
|
-
{
|
|
5916
|
-
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",
|
|
5917
|
-
style: { top: chromeClip.top + 64 },
|
|
5918
|
-
children: "Loading page preview\u2026"
|
|
5919
|
-
}
|
|
5920
|
-
) : null,
|
|
5921
|
-
isOnTargetPage && liveSections.length === 0 ? /* @__PURE__ */ jsx20("div", { className: "pointer-events-auto fixed inset-0 z-[1] flex items-center justify-center bg-muted/40", children: /* @__PURE__ */ jsx20("p", { className: "text-sm text-muted-foreground", children: "No sections found on this page." }) }) : null,
|
|
5922
|
-
isOnTargetPage ? liveSections.map((section) => {
|
|
5923
|
-
const rect = rects.get(section.id);
|
|
5924
|
-
if (!rect || rect.width <= 0 || rect.height <= 0) return null;
|
|
5925
|
-
const isSelected = selectedId === section.id;
|
|
5926
|
-
const isHovered = hoveredId === section.id;
|
|
5927
|
-
const isLit = isSelected || isHovered;
|
|
5928
|
-
return /* @__PURE__ */ jsxs12(
|
|
5929
|
-
"button",
|
|
5930
|
-
{
|
|
5931
|
-
type: "button",
|
|
5932
|
-
className: "pointer-events-auto fixed z-[1] cursor-pointer border-0 bg-transparent p-0 transition-[background-color] duration-150",
|
|
5933
|
-
style: {
|
|
5934
|
-
top: rect.top,
|
|
5935
|
-
left: rect.left,
|
|
5936
|
-
width: rect.width,
|
|
5937
|
-
height: rect.height,
|
|
5938
|
-
backgroundColor: isLit ? "transparent" : DIM_OVERLAY
|
|
5939
|
-
},
|
|
5940
|
-
"aria-label": `Select section ${section.label}`,
|
|
5941
|
-
onClick: () => handleSelect(section),
|
|
5942
|
-
children: [
|
|
5943
|
-
isLit ? /* @__PURE__ */ jsx20(
|
|
5944
|
-
"span",
|
|
5945
|
-
{
|
|
5946
|
-
className: "pointer-events-none absolute",
|
|
5947
|
-
style: {
|
|
5948
|
-
inset: 4,
|
|
5949
|
-
borderRadius: "var(--radius, 6px)",
|
|
5950
|
-
border: "1.5px dashed var(--primary, #0885FE)",
|
|
5951
|
-
boxSizing: "border-box"
|
|
5952
|
-
},
|
|
5953
|
-
"aria-hidden": true
|
|
5954
|
-
}
|
|
5955
|
-
) : null,
|
|
5956
|
-
isSelected ? /* @__PURE__ */ jsx20(
|
|
5957
|
-
"span",
|
|
5958
|
-
{
|
|
5959
|
-
className: "absolute right-3 top-3 flex size-8 items-center justify-center rounded-full text-white",
|
|
5960
|
-
style: { backgroundColor: "var(--ohw-primary, #0885fe)" },
|
|
5961
|
-
"aria-hidden": true,
|
|
5962
|
-
children: /* @__PURE__ */ jsx20(Check, { className: "size-5" })
|
|
5963
|
-
}
|
|
5964
|
-
) : null
|
|
5965
|
-
]
|
|
5966
|
-
},
|
|
5967
|
-
section.id
|
|
5968
|
-
);
|
|
5969
|
-
}) : null
|
|
5970
|
-
]
|
|
5971
|
-
}
|
|
5972
|
-
),
|
|
5973
|
-
portalRoot
|
|
5974
|
-
);
|
|
5975
|
-
}
|
|
5976
|
-
|
|
5977
|
-
// src/ui/link-modal/useLinkModalState.ts
|
|
5978
|
-
import { useCallback as useCallback3, useEffect as useEffect5, useMemo as useMemo3, useState as useState5 } from "react";
|
|
5979
|
-
function useLinkModalState({
|
|
5980
|
-
open,
|
|
5981
|
-
mode,
|
|
5982
|
-
pages,
|
|
5983
|
-
sections: _sections,
|
|
5984
|
-
sectionsByPath,
|
|
5985
|
-
initialTarget,
|
|
5986
|
-
existingTargets: _existingTargets,
|
|
5987
|
-
onClose,
|
|
5988
|
-
onSubmit
|
|
5989
|
-
}) {
|
|
5990
|
-
const availablePages = useMemo3(() => pages, [pages]);
|
|
5991
|
-
const [searchValue, setSearchValue] = useState5("");
|
|
5992
|
-
const [selectedPage, setSelectedPage] = useState5(null);
|
|
5993
|
-
const [selectedSection, setSelectedSection] = useState5(null);
|
|
5994
|
-
const [step, setStep] = useState5("input");
|
|
5995
|
-
const [dropdownOpen, setDropdownOpen] = useState5(false);
|
|
5996
|
-
const [urlError, setUrlError] = useState5("");
|
|
5997
|
-
const reset = useCallback3(() => {
|
|
5387
|
+
const [searchValue, setSearchValue] = useState4("");
|
|
5388
|
+
const [selectedPage, setSelectedPage] = useState4(null);
|
|
5389
|
+
const [selectedSection, setSelectedSection] = useState4(null);
|
|
5390
|
+
const [step, setStep] = useState4("input");
|
|
5391
|
+
const [dropdownOpen, setDropdownOpen] = useState4(false);
|
|
5392
|
+
const [urlError, setUrlError] = useState4("");
|
|
5393
|
+
const reset = useCallback(() => {
|
|
5998
5394
|
setSearchValue("");
|
|
5999
5395
|
setSelectedPage(null);
|
|
6000
5396
|
setSelectedSection(null);
|
|
@@ -6002,7 +5398,7 @@ function useLinkModalState({
|
|
|
6002
5398
|
setDropdownOpen(false);
|
|
6003
5399
|
setUrlError("");
|
|
6004
5400
|
}, []);
|
|
6005
|
-
|
|
5401
|
+
useEffect3(() => {
|
|
6006
5402
|
if (!open) return;
|
|
6007
5403
|
if (mode === "edit" && initialTarget) {
|
|
6008
5404
|
const { pageRoute } = parseTarget(initialTarget);
|
|
@@ -6017,12 +5413,12 @@ function useLinkModalState({
|
|
|
6017
5413
|
}
|
|
6018
5414
|
setDropdownOpen(false);
|
|
6019
5415
|
setUrlError("");
|
|
6020
|
-
}, [open, mode, initialTarget, reset]);
|
|
6021
|
-
const filteredPages =
|
|
5416
|
+
}, [open, mode, initialTarget, pages, sectionsByPath, reset]);
|
|
5417
|
+
const filteredPages = useMemo2(() => {
|
|
6022
5418
|
if (!searchValue.trim()) return availablePages;
|
|
6023
5419
|
return availablePages.filter((p) => p.title.toLowerCase().startsWith(searchValue.toLowerCase()));
|
|
6024
5420
|
}, [availablePages, searchValue]);
|
|
6025
|
-
const activeSections =
|
|
5421
|
+
const activeSections = useMemo2(() => {
|
|
6026
5422
|
if (!selectedPage) return [];
|
|
6027
5423
|
return getSectionsForPath(sectionsByPath, selectedPage.path);
|
|
6028
5424
|
}, [selectedPage, sectionsByPath]);
|
|
@@ -6064,14 +5460,11 @@ function useLinkModalState({
|
|
|
6064
5460
|
const handleBackToSections = () => {
|
|
6065
5461
|
setStep("sectionPicker");
|
|
6066
5462
|
};
|
|
6067
|
-
const handleSectionPickerBack = () => {
|
|
6068
|
-
setStep("input");
|
|
6069
|
-
};
|
|
6070
5463
|
const handleClose = () => {
|
|
6071
5464
|
reset();
|
|
6072
5465
|
onClose();
|
|
6073
5466
|
};
|
|
6074
|
-
const isValid =
|
|
5467
|
+
const isValid = useMemo2(() => {
|
|
6075
5468
|
if (urlError) return false;
|
|
6076
5469
|
if (showBreadcrumb) return true;
|
|
6077
5470
|
if (selectedPage) return true;
|
|
@@ -6104,7 +5497,7 @@ function useLinkModalState({
|
|
|
6104
5497
|
onSubmit(normalizeUrl(searchValue));
|
|
6105
5498
|
handleClose();
|
|
6106
5499
|
};
|
|
6107
|
-
const submitLabel =
|
|
5500
|
+
const submitLabel = mode === "edit" ? "Save" : "Create";
|
|
6108
5501
|
const title = mode === "edit" ? "Edit navigation item" : "Create navigation item";
|
|
6109
5502
|
const secondaryLabel = showBreadcrumb ? "Back to sections" : "Cancel";
|
|
6110
5503
|
const handleSecondary = showBreadcrumb ? handleBackToSections : handleClose;
|
|
@@ -6131,29 +5524,23 @@ function useLinkModalState({
|
|
|
6131
5524
|
handleChooseSection,
|
|
6132
5525
|
handleSectionSelect,
|
|
6133
5526
|
handleBackToSections,
|
|
6134
|
-
handleSectionPickerBack,
|
|
6135
5527
|
handleClose,
|
|
6136
5528
|
handleSecondary,
|
|
6137
5529
|
handleSubmit
|
|
6138
5530
|
};
|
|
6139
5531
|
}
|
|
6140
5532
|
|
|
6141
|
-
// src/ui/link-modal/
|
|
6142
|
-
import { Fragment as
|
|
6143
|
-
function
|
|
6144
|
-
window.parent?.postMessage(data, "*");
|
|
6145
|
-
}
|
|
6146
|
-
function LinkPopover({
|
|
5533
|
+
// src/ui/link-modal/LinkEditorPanel.tsx
|
|
5534
|
+
import { Fragment as Fragment3, jsx as jsx19, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
5535
|
+
function LinkEditorPanel({
|
|
6147
5536
|
open = true,
|
|
6148
|
-
panelRef,
|
|
6149
|
-
portalContainer,
|
|
6150
|
-
onClose,
|
|
6151
5537
|
mode = "create",
|
|
6152
5538
|
pages,
|
|
6153
5539
|
sections = [],
|
|
6154
5540
|
sectionsByPath,
|
|
6155
5541
|
initialTarget,
|
|
6156
5542
|
existingTargets = [],
|
|
5543
|
+
onClose,
|
|
6157
5544
|
onSubmit
|
|
6158
5545
|
}) {
|
|
6159
5546
|
const state = useLinkModalState({
|
|
@@ -6167,109 +5554,115 @@ function LinkPopover({
|
|
|
6167
5554
|
onClose,
|
|
6168
5555
|
onSubmit
|
|
6169
5556
|
});
|
|
6170
|
-
const
|
|
6171
|
-
|
|
6172
|
-
|
|
6173
|
-
|
|
6174
|
-
postToParent({ type: "ui:unlock" });
|
|
6175
|
-
postToParent({ type: "ow:section-picker", active: true });
|
|
6176
|
-
document.documentElement.style.overflow = "";
|
|
6177
|
-
document.body.style.overflow = "";
|
|
6178
|
-
return () => {
|
|
6179
|
-
postToParent({ type: "ow:section-picker", active: false });
|
|
6180
|
-
};
|
|
6181
|
-
}
|
|
6182
|
-
postToParent({ type: "ow:section-picker", active: false });
|
|
6183
|
-
postToParent({ type: "ui:lock" });
|
|
6184
|
-
const html = document.documentElement;
|
|
6185
|
-
const body = document.body;
|
|
6186
|
-
const prevHtmlOverflow = html.style.overflow;
|
|
6187
|
-
const prevBodyOverflow = body.style.overflow;
|
|
6188
|
-
const prevHtmlOverscroll = html.style.overscrollBehavior;
|
|
6189
|
-
const prevBodyOverscroll = body.style.overscrollBehavior;
|
|
6190
|
-
html.style.overflow = "hidden";
|
|
6191
|
-
body.style.overflow = "hidden";
|
|
6192
|
-
html.style.overscrollBehavior = "none";
|
|
6193
|
-
body.style.overscrollBehavior = "none";
|
|
6194
|
-
const canScrollElement = (el, deltaY) => {
|
|
6195
|
-
const { overflowY } = getComputedStyle(el);
|
|
6196
|
-
if (overflowY !== "auto" && overflowY !== "scroll") return false;
|
|
6197
|
-
if (el.scrollHeight <= el.clientHeight + 1) return false;
|
|
6198
|
-
if (deltaY < 0) return el.scrollTop > 0;
|
|
6199
|
-
if (deltaY > 0)
|
|
6200
|
-
return el.scrollTop + el.clientHeight < el.scrollHeight - 1;
|
|
6201
|
-
return true;
|
|
6202
|
-
};
|
|
6203
|
-
const allowsInternalScroll = (e) => {
|
|
6204
|
-
const target = e.target;
|
|
6205
|
-
if (!(target instanceof Element)) return false;
|
|
6206
|
-
const scrollRoot = target.closest(
|
|
6207
|
-
"[data-ohw-link-page-dropdown], [data-ohw-allow-scroll]"
|
|
6208
|
-
);
|
|
6209
|
-
if (!scrollRoot) return false;
|
|
6210
|
-
const deltaY = e instanceof WheelEvent ? e.deltaY : 0;
|
|
6211
|
-
return canScrollElement(scrollRoot, deltaY);
|
|
6212
|
-
};
|
|
6213
|
-
const preventBackgroundScroll = (e) => {
|
|
6214
|
-
if (allowsInternalScroll(e)) return;
|
|
6215
|
-
e.preventDefault();
|
|
6216
|
-
};
|
|
6217
|
-
const scrollOpts = { passive: false, capture: true };
|
|
6218
|
-
document.addEventListener("wheel", preventBackgroundScroll, scrollOpts);
|
|
6219
|
-
document.addEventListener("touchmove", preventBackgroundScroll, scrollOpts);
|
|
6220
|
-
return () => {
|
|
6221
|
-
postToParent({ type: "ui:unlock" });
|
|
6222
|
-
html.style.overflow = prevHtmlOverflow;
|
|
6223
|
-
body.style.overflow = prevBodyOverflow;
|
|
6224
|
-
html.style.overscrollBehavior = prevHtmlOverscroll;
|
|
6225
|
-
body.style.overscrollBehavior = prevBodyOverscroll;
|
|
6226
|
-
document.removeEventListener(
|
|
6227
|
-
"wheel",
|
|
6228
|
-
preventBackgroundScroll,
|
|
6229
|
-
scrollOpts
|
|
6230
|
-
);
|
|
6231
|
-
document.removeEventListener(
|
|
6232
|
-
"touchmove",
|
|
6233
|
-
preventBackgroundScroll,
|
|
6234
|
-
scrollOpts
|
|
6235
|
-
);
|
|
6236
|
-
};
|
|
6237
|
-
}, [open, sectionPickerActive]);
|
|
6238
|
-
return /* @__PURE__ */ jsxs13(Fragment4, { children: [
|
|
6239
|
-
/* @__PURE__ */ jsx21(
|
|
6240
|
-
Dialog2,
|
|
6241
|
-
{
|
|
6242
|
-
open: open && !sectionPickerActive,
|
|
6243
|
-
onOpenChange: (next) => {
|
|
6244
|
-
if (!next) onClose?.();
|
|
6245
|
-
},
|
|
6246
|
-
children: /* @__PURE__ */ jsx21(
|
|
6247
|
-
DialogContent,
|
|
6248
|
-
{
|
|
6249
|
-
ref: panelRef,
|
|
6250
|
-
container: portalContainer,
|
|
6251
|
-
"data-ohw-link-popover-root": "",
|
|
6252
|
-
"data-ohw-link-modal-root": "",
|
|
6253
|
-
"data-ohw-bridge": "",
|
|
6254
|
-
showCloseButton: false,
|
|
6255
|
-
className: "gap-0 p-0 w-full max-w-[448px] pointer-events-auto z-[2147483646] overflow-visible",
|
|
6256
|
-
children: /* @__PURE__ */ jsx21(LinkEditorPanel, { state, onClose })
|
|
6257
|
-
}
|
|
6258
|
-
)
|
|
6259
|
-
}
|
|
6260
|
-
),
|
|
6261
|
-
sectionPickerActive && state.selectedPage ? /* @__PURE__ */ jsx21(
|
|
6262
|
-
SectionPickerOverlay,
|
|
5557
|
+
const isCancel = state.secondaryLabel === "Cancel";
|
|
5558
|
+
return /* @__PURE__ */ jsxs11(Fragment3, { children: [
|
|
5559
|
+
/* @__PURE__ */ jsx19(DialogClose, { asChild: true, children: /* @__PURE__ */ jsx19(
|
|
5560
|
+
"button",
|
|
6263
5561
|
{
|
|
6264
|
-
|
|
6265
|
-
|
|
6266
|
-
|
|
6267
|
-
|
|
5562
|
+
type: "button",
|
|
5563
|
+
className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50",
|
|
5564
|
+
"aria-label": "Close",
|
|
5565
|
+
children: /* @__PURE__ */ jsx19(IconX, { "aria-hidden": true })
|
|
6268
5566
|
}
|
|
6269
|
-
)
|
|
5567
|
+
) }),
|
|
5568
|
+
/* @__PURE__ */ jsx19(DialogHeader, { className: "w-full gap-1.5 p-6 pr-12", children: /* @__PURE__ */ jsx19(DialogTitle, { className: "m-0 w-full break-words", children: state.title }) }),
|
|
5569
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex w-full flex-col gap-3 px-6 pb-8 pt-1", children: [
|
|
5570
|
+
state.showBreadcrumb && state.selectedPage && state.selectedSection ? /* @__PURE__ */ jsx19(
|
|
5571
|
+
DestinationBreadcrumb,
|
|
5572
|
+
{
|
|
5573
|
+
pageTitle: state.selectedPage.title,
|
|
5574
|
+
sectionLabel: state.selectedSection.label
|
|
5575
|
+
}
|
|
5576
|
+
) : /* @__PURE__ */ jsx19(
|
|
5577
|
+
UrlOrPageInput,
|
|
5578
|
+
{
|
|
5579
|
+
value: state.searchValue,
|
|
5580
|
+
selectedPage: state.selectedPage,
|
|
5581
|
+
dropdownOpen: state.dropdownOpen,
|
|
5582
|
+
onDropdownOpenChange: state.setDropdownOpen,
|
|
5583
|
+
filteredPages: state.filteredPages,
|
|
5584
|
+
onInputChange: state.handleInputChange,
|
|
5585
|
+
onPageSelect: state.handlePageSelect,
|
|
5586
|
+
urlError: state.urlError
|
|
5587
|
+
}
|
|
5588
|
+
),
|
|
5589
|
+
state.showChooseSection ? /* @__PURE__ */ jsxs11("div", { className: "flex flex-col justify-center gap-2", children: [
|
|
5590
|
+
/* @__PURE__ */ jsx19(Button, { type: "button", variant: "outline", className: "w-fit cursor-pointer", size: "sm", onClick: state.handleChooseSection, children: "Choose a section" }),
|
|
5591
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-1 text-sm text-muted-foreground", children: [
|
|
5592
|
+
/* @__PURE__ */ jsx19(IconInfo, { className: "shrink-0", "aria-hidden": true }),
|
|
5593
|
+
/* @__PURE__ */ jsx19("span", { children: "Pick a section this link should scroll to." })
|
|
5594
|
+
] })
|
|
5595
|
+
] }) : null,
|
|
5596
|
+
state.showSectionPicker ? /* @__PURE__ */ jsx19(SectionPickerList, { sections: state.activeSections, onSelect: state.handleSectionSelect }) : null,
|
|
5597
|
+
state.showSectionRow && state.selectedSection ? /* @__PURE__ */ jsx19(SectionTreeItem, { section: state.selectedSection, selected: true }) : null
|
|
5598
|
+
] }),
|
|
5599
|
+
/* @__PURE__ */ jsxs11(DialogFooter, { className: "w-full px-6 pb-6", children: [
|
|
5600
|
+
/* @__PURE__ */ jsx19(
|
|
5601
|
+
Button,
|
|
5602
|
+
{
|
|
5603
|
+
type: "button",
|
|
5604
|
+
variant: isCancel ? "outline" : "ghost",
|
|
5605
|
+
className: "leading-6 shadow-none cursor-pointer",
|
|
5606
|
+
style: isCancel ? {
|
|
5607
|
+
backgroundColor: "var(--ohw-background)",
|
|
5608
|
+
borderColor: "var(--ohw-border)",
|
|
5609
|
+
color: "var(--ohw-foreground)"
|
|
5610
|
+
} : void 0,
|
|
5611
|
+
onClick: state.handleSecondary,
|
|
5612
|
+
children: state.secondaryLabel
|
|
5613
|
+
}
|
|
5614
|
+
),
|
|
5615
|
+
/* @__PURE__ */ jsx19(
|
|
5616
|
+
Button,
|
|
5617
|
+
{
|
|
5618
|
+
type: "button",
|
|
5619
|
+
className: "border-0 leading-6 shadow-none hover:opacity-90 disabled:opacity-50 cursor-pointer",
|
|
5620
|
+
style: {
|
|
5621
|
+
backgroundColor: "var(--ohw-primary)",
|
|
5622
|
+
color: "var(--ohw-primary-foreground)"
|
|
5623
|
+
},
|
|
5624
|
+
disabled: !state.isValid,
|
|
5625
|
+
onClick: state.handleSubmit,
|
|
5626
|
+
children: state.submitLabel
|
|
5627
|
+
}
|
|
5628
|
+
)
|
|
5629
|
+
] })
|
|
6270
5630
|
] });
|
|
6271
5631
|
}
|
|
6272
5632
|
|
|
5633
|
+
// src/ui/link-modal/LinkPopover.tsx
|
|
5634
|
+
import { jsx as jsx20 } from "react/jsx-runtime";
|
|
5635
|
+
function LinkPopover({
|
|
5636
|
+
open = true,
|
|
5637
|
+
panelRef,
|
|
5638
|
+
portalContainer,
|
|
5639
|
+
onClose,
|
|
5640
|
+
...editorProps
|
|
5641
|
+
}) {
|
|
5642
|
+
return /* @__PURE__ */ jsx20(
|
|
5643
|
+
Dialog2,
|
|
5644
|
+
{
|
|
5645
|
+
open,
|
|
5646
|
+
onOpenChange: (next) => {
|
|
5647
|
+
if (!next) onClose?.();
|
|
5648
|
+
},
|
|
5649
|
+
children: /* @__PURE__ */ jsx20(
|
|
5650
|
+
DialogContent,
|
|
5651
|
+
{
|
|
5652
|
+
ref: panelRef,
|
|
5653
|
+
container: portalContainer,
|
|
5654
|
+
"data-ohw-link-popover-root": "",
|
|
5655
|
+
"data-ohw-link-modal-root": "",
|
|
5656
|
+
"data-ohw-bridge": "",
|
|
5657
|
+
showCloseButton: false,
|
|
5658
|
+
className: "gap-0 p-0 w-full md:w-md pointer-events-auto",
|
|
5659
|
+
children: /* @__PURE__ */ jsx20(LinkEditorPanel, { ...editorProps, open, onClose })
|
|
5660
|
+
}
|
|
5661
|
+
)
|
|
5662
|
+
}
|
|
5663
|
+
);
|
|
5664
|
+
}
|
|
5665
|
+
|
|
6273
5666
|
// src/ui/link-modal/devFixtures.ts
|
|
6274
5667
|
var DEV_SITE_PAGES = [
|
|
6275
5668
|
{ path: "/", title: "Home" },
|
|
@@ -6289,766 +5682,47 @@ var DEV_SECTIONS_BY_PATH = {
|
|
|
6289
5682
|
{ id: "founder-teaser", label: "Founder" },
|
|
6290
5683
|
{ id: "plan-form", label: "Plan Form" },
|
|
6291
5684
|
{ id: "testimonials", label: "Testimonials" },
|
|
6292
|
-
{ id: "wordmark", label: "Wordmark" }
|
|
6293
|
-
{ id: "footer", label: "Footer" }
|
|
5685
|
+
{ id: "wordmark", label: "Wordmark" }
|
|
6294
5686
|
],
|
|
6295
5687
|
"/about": [
|
|
6296
5688
|
{ id: "manifesto", label: "Manifesto" },
|
|
6297
5689
|
{ id: "story-letter", label: "Our Story" },
|
|
6298
5690
|
{ id: "lagree-explainer", label: "Lagree Explainer" },
|
|
6299
5691
|
{ id: "waitlist-cta", label: "Waitlist" },
|
|
6300
|
-
{ id: "personal-training", label: "Personal training" }
|
|
6301
|
-
{ id: "footer", label: "Footer" }
|
|
5692
|
+
{ id: "personal-training", label: "Personal training" }
|
|
6302
5693
|
],
|
|
6303
|
-
"/classes": [
|
|
6304
|
-
|
|
6305
|
-
{ id: "
|
|
6306
|
-
|
|
6307
|
-
|
|
6308
|
-
{ id: "
|
|
6309
|
-
{ id: "
|
|
6310
|
-
{ id: "
|
|
6311
|
-
{ id: "
|
|
6312
|
-
|
|
6313
|
-
|
|
6314
|
-
{ id: "
|
|
6315
|
-
{ id: "
|
|
6316
|
-
|
|
6317
|
-
|
|
6318
|
-
|
|
6319
|
-
|
|
6320
|
-
|
|
6321
|
-
{ id: "
|
|
6322
|
-
{ id: "
|
|
6323
|
-
|
|
6324
|
-
|
|
6325
|
-
|
|
6326
|
-
|
|
6327
|
-
|
|
6328
|
-
|
|
6329
|
-
|
|
6330
|
-
|
|
6331
|
-
{ id: "faq", label: "FAQ" },
|
|
6332
|
-
{ id: "footer", label: "Footer" }
|
|
6333
|
-
]
|
|
6334
|
-
};
|
|
6335
|
-
function shouldUseDevFixtures() {
|
|
6336
|
-
if (typeof window === "undefined") return false;
|
|
6337
|
-
const raw = readPreservedSearch();
|
|
6338
|
-
const q = raw.startsWith("?") ? raw.slice(1) : raw;
|
|
6339
|
-
return new URLSearchParams(q).get("ohw-fixtures") === "1";
|
|
6340
|
-
}
|
|
6341
|
-
|
|
6342
|
-
// src/lib/nav-items.ts
|
|
6343
|
-
var NAV_COUNT_KEY = "__ohw_nav_count";
|
|
6344
|
-
var NAV_ORDER_KEY = "__ohw_nav_order";
|
|
6345
|
-
function getLinkHref(el) {
|
|
6346
|
-
const key = el.getAttribute("data-ohw-href-key");
|
|
6347
|
-
if (key) {
|
|
6348
|
-
const stored = getStoredLinkHref(key);
|
|
6349
|
-
if (stored !== void 0) return stored;
|
|
6350
|
-
}
|
|
6351
|
-
return el.getAttribute("href") ?? "";
|
|
6352
|
-
}
|
|
6353
|
-
function isNavbarButton(el) {
|
|
6354
|
-
return el.hasAttribute("data-ohw-role") && el.getAttribute("data-ohw-role") === "navbar-button";
|
|
6355
|
-
}
|
|
6356
|
-
function isNavbarLinkItem(el) {
|
|
6357
|
-
if (!el.matches("[data-ohw-href-key]")) return false;
|
|
6358
|
-
if (isNavbarButton(el)) return false;
|
|
6359
|
-
if (!el.querySelector('[data-ohw-editable="text"]')) return false;
|
|
6360
|
-
return Boolean(el.closest("nav, [data-ohw-nav-container], [data-ohw-nav-drawer]"));
|
|
6361
|
-
}
|
|
6362
|
-
function getNavbarDesktopContainer() {
|
|
6363
|
-
return document.querySelector("[data-ohw-nav-container]");
|
|
6364
|
-
}
|
|
6365
|
-
function getNavbarDrawerContainer() {
|
|
6366
|
-
return document.querySelector("[data-ohw-nav-drawer]");
|
|
6367
|
-
}
|
|
6368
|
-
function listNavbarItems() {
|
|
6369
|
-
const desktop = getNavbarDesktopContainer();
|
|
6370
|
-
if (desktop) {
|
|
6371
|
-
return Array.from(desktop.querySelectorAll("[data-ohw-href-key]")).filter(isNavbarLinkItem);
|
|
6372
|
-
}
|
|
6373
|
-
const drawer = getNavbarDrawerContainer();
|
|
6374
|
-
if (drawer) {
|
|
6375
|
-
return Array.from(drawer.querySelectorAll("[data-ohw-href-key]")).filter(isNavbarLinkItem);
|
|
6376
|
-
}
|
|
6377
|
-
return Array.from(document.querySelectorAll("nav [data-ohw-href-key]")).filter(isNavbarLinkItem);
|
|
6378
|
-
}
|
|
6379
|
-
function parseNavIndexFromKey(key) {
|
|
6380
|
-
if (!key) return null;
|
|
6381
|
-
const match = key.match(/^nav-(\d+)-href$/);
|
|
6382
|
-
if (!match) return null;
|
|
6383
|
-
return parseInt(match[1], 10);
|
|
6384
|
-
}
|
|
6385
|
-
function getNavbarIndicesInDom() {
|
|
6386
|
-
const indices = /* @__PURE__ */ new Set();
|
|
6387
|
-
for (const item of listNavbarItems()) {
|
|
6388
|
-
const idx = parseNavIndexFromKey(item.getAttribute("data-ohw-href-key"));
|
|
6389
|
-
if (idx !== null) indices.add(idx);
|
|
6390
|
-
}
|
|
6391
|
-
return [...indices].sort((a, b) => a - b);
|
|
6392
|
-
}
|
|
6393
|
-
function getNextNavbarIndex() {
|
|
6394
|
-
const indices = getNavbarIndicesInDom();
|
|
6395
|
-
if (indices.length === 0) return 0;
|
|
6396
|
-
return Math.max(...indices) + 1;
|
|
6397
|
-
}
|
|
6398
|
-
function getNavbarExistingTargets() {
|
|
6399
|
-
return listNavbarItems().map((el) => getLinkHref(el)).filter(Boolean);
|
|
6400
|
-
}
|
|
6401
|
-
function getNavOrderFromDom() {
|
|
6402
|
-
return listNavbarItems().map((el) => el.getAttribute("data-ohw-href-key")).filter((key) => Boolean(key));
|
|
6403
|
-
}
|
|
6404
|
-
function parseNavOrder(content) {
|
|
6405
|
-
const raw = content[NAV_ORDER_KEY];
|
|
6406
|
-
if (!raw) return null;
|
|
6407
|
-
try {
|
|
6408
|
-
const parsed = JSON.parse(raw);
|
|
6409
|
-
if (!Array.isArray(parsed)) return null;
|
|
6410
|
-
return parsed.filter((key) => typeof key === "string" && key.length > 0);
|
|
6411
|
-
} catch {
|
|
6412
|
-
return null;
|
|
6413
|
-
}
|
|
6414
|
-
}
|
|
6415
|
-
function findCounterpartByHrefKey(hrefKey, root) {
|
|
6416
|
-
return root.querySelector(`[data-ohw-href-key="${CSS.escape(hrefKey)}"]`);
|
|
6417
|
-
}
|
|
6418
|
-
function cloneNavLinkShell(template) {
|
|
6419
|
-
const anchor = document.createElement("a");
|
|
6420
|
-
if (template) {
|
|
6421
|
-
anchor.style.cssText = template.style.cssText;
|
|
6422
|
-
if (template.className) anchor.className = template.className;
|
|
6423
|
-
}
|
|
6424
|
-
anchor.style.cursor = "pointer";
|
|
6425
|
-
anchor.style.textDecoration = "none";
|
|
6426
|
-
return anchor;
|
|
6427
|
-
}
|
|
6428
|
-
function buildNavLink(index, href, label, template) {
|
|
6429
|
-
const anchor = cloneNavLinkShell(template);
|
|
6430
|
-
anchor.href = href;
|
|
6431
|
-
anchor.setAttribute("data-ohw-href-key", `nav-${index}-href`);
|
|
6432
|
-
const span = document.createElement("span");
|
|
6433
|
-
span.setAttribute("data-ohw-editable", "text");
|
|
6434
|
-
span.setAttribute("data-ohw-key", `nav-${index}-label`);
|
|
6435
|
-
span.textContent = label;
|
|
6436
|
-
anchor.appendChild(span);
|
|
6437
|
-
return anchor;
|
|
6438
|
-
}
|
|
6439
|
-
function insertNavLinkInContainer(container, anchor, afterHrefKey) {
|
|
6440
|
-
if (!afterHrefKey) {
|
|
6441
|
-
container.appendChild(anchor);
|
|
6442
|
-
return;
|
|
6443
|
-
}
|
|
6444
|
-
const afterEl = findCounterpartByHrefKey(afterHrefKey, container);
|
|
6445
|
-
if (afterEl?.parentElement === container) {
|
|
6446
|
-
afterEl.insertAdjacentElement("afterend", anchor);
|
|
6447
|
-
return;
|
|
6448
|
-
}
|
|
6449
|
-
container.appendChild(anchor);
|
|
6450
|
-
}
|
|
6451
|
-
function insertNavbarItemDom(index, href, label, afterAnchor) {
|
|
6452
|
-
const afterHrefKey = afterAnchor?.getAttribute("data-ohw-href-key") ?? null;
|
|
6453
|
-
const desktopItems = getNavbarDesktopContainer()?.querySelectorAll("[data-ohw-href-key]") ?? [];
|
|
6454
|
-
const drawerItems = getNavbarDrawerContainer()?.querySelectorAll("[data-ohw-href-key]") ?? [];
|
|
6455
|
-
const desktopTemplate = Array.from(desktopItems).find(isNavbarLinkItem) ?? null;
|
|
6456
|
-
const drawerTemplate = Array.from(drawerItems).find(isNavbarLinkItem) ?? null;
|
|
6457
|
-
let primary = null;
|
|
6458
|
-
const desktopContainer = getNavbarDesktopContainer();
|
|
6459
|
-
if (desktopContainer) {
|
|
6460
|
-
const desktopAnchor = buildNavLink(index, href, label, desktopTemplate);
|
|
6461
|
-
insertNavLinkInContainer(desktopContainer, desktopAnchor, afterHrefKey);
|
|
6462
|
-
primary = desktopAnchor;
|
|
6463
|
-
}
|
|
6464
|
-
const drawerContainer = getNavbarDrawerContainer();
|
|
6465
|
-
if (drawerContainer) {
|
|
6466
|
-
const drawerAnchor = buildNavLink(index, href, label, drawerTemplate);
|
|
6467
|
-
insertNavLinkInContainer(drawerContainer, drawerAnchor, afterHrefKey);
|
|
6468
|
-
if (!primary) primary = drawerAnchor;
|
|
6469
|
-
}
|
|
6470
|
-
if (!primary) {
|
|
6471
|
-
const fallback = buildNavLink(index, href, label, listNavbarItems()[0] ?? null);
|
|
6472
|
-
const nav = document.querySelector("nav");
|
|
6473
|
-
nav?.appendChild(fallback);
|
|
6474
|
-
primary = fallback;
|
|
6475
|
-
}
|
|
6476
|
-
return primary;
|
|
6477
|
-
}
|
|
6478
|
-
function applyNavOrderToContainer(container, order) {
|
|
6479
|
-
const seen = /* @__PURE__ */ new Set();
|
|
6480
|
-
for (const hrefKey of order) {
|
|
6481
|
-
if (seen.has(hrefKey)) continue;
|
|
6482
|
-
seen.add(hrefKey);
|
|
6483
|
-
const el = findCounterpartByHrefKey(hrefKey, container);
|
|
6484
|
-
if (el) container.appendChild(el);
|
|
6485
|
-
}
|
|
6486
|
-
for (const el of container.querySelectorAll("[data-ohw-href-key]")) {
|
|
6487
|
-
if (!isNavbarLinkItem(el)) continue;
|
|
6488
|
-
const key = el.getAttribute("data-ohw-href-key");
|
|
6489
|
-
if (!key || seen.has(key)) continue;
|
|
6490
|
-
container.appendChild(el);
|
|
6491
|
-
}
|
|
6492
|
-
}
|
|
6493
|
-
function applyNavOrder(order) {
|
|
6494
|
-
const desktop = getNavbarDesktopContainer();
|
|
6495
|
-
if (desktop) applyNavOrderToContainer(desktop, order);
|
|
6496
|
-
const drawer = getNavbarDrawerContainer();
|
|
6497
|
-
if (drawer) applyNavOrderToContainer(drawer, order);
|
|
6498
|
-
}
|
|
6499
|
-
function collectNavbarIndicesFromContent(content) {
|
|
6500
|
-
const indices = /* @__PURE__ */ new Set();
|
|
6501
|
-
for (const key of Object.keys(content)) {
|
|
6502
|
-
const idx = parseNavIndexFromKey(key);
|
|
6503
|
-
if (idx !== null) indices.add(idx);
|
|
6504
|
-
}
|
|
6505
|
-
const countRaw = content[NAV_COUNT_KEY];
|
|
6506
|
-
if (countRaw) {
|
|
6507
|
-
const count = parseInt(countRaw, 10);
|
|
6508
|
-
if (Number.isFinite(count) && count > 0) {
|
|
6509
|
-
for (let i = 0; i < count; i++) indices.add(i);
|
|
6510
|
-
}
|
|
6511
|
-
}
|
|
6512
|
-
return [...indices].sort((a, b) => a - b);
|
|
6513
|
-
}
|
|
6514
|
-
function navbarIndexExistsInDom(index) {
|
|
6515
|
-
return document.querySelector(`[data-ohw-href-key="nav-${index}-href"]`) !== null;
|
|
6516
|
-
}
|
|
6517
|
-
function reconcileNavbarItemsFromContent(content) {
|
|
6518
|
-
const indices = collectNavbarIndicesFromContent(content);
|
|
6519
|
-
for (const index of indices) {
|
|
6520
|
-
if (navbarIndexExistsInDom(index)) continue;
|
|
6521
|
-
const href = content[`nav-${index}-href`];
|
|
6522
|
-
const label = content[`nav-${index}-label`];
|
|
6523
|
-
if (!href && !label) continue;
|
|
6524
|
-
insertNavbarItemDom(index, href ?? "/", label ?? "Untitled", null);
|
|
6525
|
-
}
|
|
6526
|
-
const order = parseNavOrder(content);
|
|
6527
|
-
if (order?.length) applyNavOrder(order);
|
|
6528
|
-
}
|
|
6529
|
-
function buildNavOrderAfterInsert(afterAnchor, newHrefKey) {
|
|
6530
|
-
const order = getNavOrderFromDom();
|
|
6531
|
-
if (!afterAnchor) {
|
|
6532
|
-
if (!order.includes(newHrefKey)) order.push(newHrefKey);
|
|
6533
|
-
return order;
|
|
6534
|
-
}
|
|
6535
|
-
const afterKey = afterAnchor.getAttribute("data-ohw-href-key");
|
|
6536
|
-
if (!afterKey) {
|
|
6537
|
-
if (!order.includes(newHrefKey)) order.push(newHrefKey);
|
|
6538
|
-
return order;
|
|
6539
|
-
}
|
|
6540
|
-
const withoutNew = order.filter((key) => key !== newHrefKey);
|
|
6541
|
-
const pos = withoutNew.indexOf(afterKey);
|
|
6542
|
-
if (pos >= 0) {
|
|
6543
|
-
withoutNew.splice(pos + 1, 0, newHrefKey);
|
|
6544
|
-
return withoutNew;
|
|
6545
|
-
}
|
|
6546
|
-
withoutNew.push(newHrefKey);
|
|
6547
|
-
return withoutNew;
|
|
6548
|
-
}
|
|
6549
|
-
function insertNavbarItem(href, label, afterAnchor = null) {
|
|
6550
|
-
const index = getNextNavbarIndex();
|
|
6551
|
-
const anchor = insertNavbarItemDom(index, href, label, afterAnchor);
|
|
6552
|
-
if (!anchor) throw new Error("Failed to insert navbar item");
|
|
6553
|
-
const hrefKey = `nav-${index}-href`;
|
|
6554
|
-
const order = buildNavOrderAfterInsert(afterAnchor, hrefKey);
|
|
6555
|
-
applyNavOrder(order);
|
|
6556
|
-
return {
|
|
6557
|
-
anchor,
|
|
6558
|
-
index,
|
|
6559
|
-
hrefKey,
|
|
6560
|
-
labelKey: `nav-${index}-label`,
|
|
6561
|
-
href,
|
|
6562
|
-
label,
|
|
6563
|
-
order
|
|
6564
|
-
};
|
|
6565
|
-
}
|
|
6566
|
-
|
|
6567
|
-
// src/lib/footer-items.ts
|
|
6568
|
-
var FOOTER_ORDER_KEY = "__ohw_footer_order";
|
|
6569
|
-
var FOOTER_HREF_RE = /^footer-(\d+)-(\d+)-href$/;
|
|
6570
|
-
function parseFooterHrefKey(key) {
|
|
6571
|
-
if (!key) return null;
|
|
6572
|
-
const match = key.match(FOOTER_HREF_RE);
|
|
6573
|
-
if (!match) return null;
|
|
6574
|
-
return { col: parseInt(match[1], 10), item: parseInt(match[2], 10) };
|
|
6575
|
-
}
|
|
6576
|
-
function isFooterHrefKey(key) {
|
|
6577
|
-
return parseFooterHrefKey(key) !== null;
|
|
6578
|
-
}
|
|
6579
|
-
function getFooterRoot() {
|
|
6580
|
-
return document.querySelector('footer[data-ohw-section="footer"], footer');
|
|
6581
|
-
}
|
|
6582
|
-
function getFooterLinksContainer() {
|
|
6583
|
-
return document.querySelector("[data-ohw-footer-links]") ?? document.querySelector(".rb-footer-links");
|
|
6584
|
-
}
|
|
6585
|
-
function isFooterLinkAnchor(el) {
|
|
6586
|
-
if (!el.matches("[data-ohw-href-key]")) return false;
|
|
6587
|
-
if (!isFooterHrefKey(el.getAttribute("data-ohw-href-key"))) return false;
|
|
6588
|
-
return Boolean(el.querySelector('[data-ohw-editable="text"]'));
|
|
6589
|
-
}
|
|
6590
|
-
function listFooterColumns() {
|
|
6591
|
-
const root = getFooterLinksContainer() ?? getFooterRoot()?.querySelector(".rb-footer-links") ?? null;
|
|
6592
|
-
if (!root) return [];
|
|
6593
|
-
const explicit = Array.from(root.querySelectorAll(":scope > [data-ohw-footer-col]"));
|
|
6594
|
-
if (explicit.length > 0) return explicit;
|
|
6595
|
-
return Array.from(root.children).filter((el) => {
|
|
6596
|
-
if (!(el instanceof HTMLElement)) return false;
|
|
6597
|
-
return Array.from(el.querySelectorAll(":scope > [data-ohw-href-key]")).some(
|
|
6598
|
-
isFooterLinkAnchor
|
|
6599
|
-
);
|
|
6600
|
-
});
|
|
6601
|
-
}
|
|
6602
|
-
function listFooterLinksInColumn(column) {
|
|
6603
|
-
return Array.from(column.querySelectorAll(":scope > [data-ohw-href-key]")).filter(
|
|
6604
|
-
isFooterLinkAnchor
|
|
6605
|
-
);
|
|
6606
|
-
}
|
|
6607
|
-
function findFooterColumnForLink(anchor) {
|
|
6608
|
-
const columns = listFooterColumns();
|
|
6609
|
-
return columns.find((col) => col.contains(anchor)) ?? null;
|
|
6610
|
-
}
|
|
6611
|
-
function getFooterOrderFromDom() {
|
|
6612
|
-
return listFooterColumns().map(
|
|
6613
|
-
(col) => listFooterLinksInColumn(col).map((el) => el.getAttribute("data-ohw-href-key")).filter((key) => Boolean(key))
|
|
6614
|
-
);
|
|
6615
|
-
}
|
|
6616
|
-
function findFooterLinkByKey(hrefKey) {
|
|
6617
|
-
return document.querySelector(
|
|
6618
|
-
`footer [data-ohw-href-key="${CSS.escape(hrefKey)}"]`
|
|
6619
|
-
);
|
|
6620
|
-
}
|
|
6621
|
-
function syncFooterColumnIndices(columns) {
|
|
6622
|
-
columns.forEach((col, index) => {
|
|
6623
|
-
const next = String(index);
|
|
6624
|
-
if (col.getAttribute("data-ohw-footer-col") !== next) {
|
|
6625
|
-
col.setAttribute("data-ohw-footer-col", next);
|
|
6626
|
-
}
|
|
6627
|
-
});
|
|
6628
|
-
}
|
|
6629
|
-
function appendChildIfNeeded(parent, child) {
|
|
6630
|
-
if (parent.lastElementChild !== child) {
|
|
6631
|
-
parent.appendChild(child);
|
|
6632
|
-
}
|
|
6633
|
-
}
|
|
6634
|
-
function insertLinkBeforeNext(col, el, nextEl) {
|
|
6635
|
-
if (nextEl) {
|
|
6636
|
-
if (el.nextElementSibling !== nextEl) {
|
|
6637
|
-
col.insertBefore(el, nextEl);
|
|
6638
|
-
}
|
|
6639
|
-
return;
|
|
6640
|
-
}
|
|
6641
|
-
if (col.lastElementChild !== el) {
|
|
6642
|
-
col.appendChild(el);
|
|
6643
|
-
}
|
|
6644
|
-
}
|
|
6645
|
-
function applyFooterOrder(order) {
|
|
6646
|
-
const container = getFooterLinksContainer();
|
|
6647
|
-
if (!container) return;
|
|
6648
|
-
const columns = listFooterColumns();
|
|
6649
|
-
if (columns.length === 0) return;
|
|
6650
|
-
const currentOrder = getFooterOrderFromDom();
|
|
6651
|
-
if (ordersEqual(order, currentOrder)) {
|
|
6652
|
-
syncFooterColumnIndices(columns);
|
|
6653
|
-
return;
|
|
6654
|
-
}
|
|
6655
|
-
const colCount = Math.max(columns.length, order.length);
|
|
6656
|
-
const working = columns.slice(0, colCount);
|
|
6657
|
-
for (let i = 0; i < order.length && i < working.length; i++) {
|
|
6658
|
-
appendChildIfNeeded(container, working[i]);
|
|
6659
|
-
}
|
|
6660
|
-
for (let i = order.length; i < working.length; i++) {
|
|
6661
|
-
appendChildIfNeeded(container, working[i]);
|
|
6662
|
-
}
|
|
6663
|
-
const freshColumns = listFooterColumns();
|
|
6664
|
-
syncFooterColumnIndices(freshColumns);
|
|
6665
|
-
for (let c = 0; c < order.length; c++) {
|
|
6666
|
-
const col = freshColumns[c];
|
|
6667
|
-
if (!col) continue;
|
|
6668
|
-
const colOrder = order[c];
|
|
6669
|
-
for (let j = 0; j < colOrder.length; j++) {
|
|
6670
|
-
const hrefKey = colOrder[j];
|
|
6671
|
-
const el = findFooterLinkByKey(hrefKey);
|
|
6672
|
-
if (!el) continue;
|
|
6673
|
-
if (el.parentElement !== col) {
|
|
6674
|
-
col.appendChild(el);
|
|
6675
|
-
}
|
|
6676
|
-
const nextKey = colOrder[j + 1];
|
|
6677
|
-
const nextEl = nextKey ? findFooterLinkByKey(nextKey) : null;
|
|
6678
|
-
insertLinkBeforeNext(col, el, nextEl?.parentElement === col ? nextEl : null);
|
|
6679
|
-
}
|
|
6680
|
-
}
|
|
6681
|
-
}
|
|
6682
|
-
function ordersEqual(a, b) {
|
|
6683
|
-
if (a.length !== b.length) return false;
|
|
6684
|
-
for (let i = 0; i < a.length; i++) {
|
|
6685
|
-
const left = a[i];
|
|
6686
|
-
const right = b[i];
|
|
6687
|
-
if (left.length !== right.length) return false;
|
|
6688
|
-
for (let j = 0; j < left.length; j++) {
|
|
6689
|
-
if (left[j] !== right[j]) return false;
|
|
6690
|
-
}
|
|
6691
|
-
}
|
|
6692
|
-
return true;
|
|
6693
|
-
}
|
|
6694
|
-
function planFooterLinkMove(hrefKey, targetColIndex, insertIndex) {
|
|
6695
|
-
const order = getFooterOrderFromDom();
|
|
6696
|
-
if (targetColIndex < 0 || targetColIndex >= order.length) return null;
|
|
6697
|
-
let fromCol = -1;
|
|
6698
|
-
let fromIdx = -1;
|
|
6699
|
-
for (let c = 0; c < order.length; c++) {
|
|
6700
|
-
const idx = order[c].indexOf(hrefKey);
|
|
6701
|
-
if (idx >= 0) {
|
|
6702
|
-
fromCol = c;
|
|
6703
|
-
fromIdx = idx;
|
|
6704
|
-
break;
|
|
6705
|
-
}
|
|
6706
|
-
}
|
|
6707
|
-
if (fromCol < 0) return null;
|
|
6708
|
-
const next = order.map((col) => [...col]);
|
|
6709
|
-
next[fromCol].splice(fromIdx, 1);
|
|
6710
|
-
let adjusted = insertIndex;
|
|
6711
|
-
if (fromCol === targetColIndex && fromIdx < insertIndex) adjusted -= 1;
|
|
6712
|
-
adjusted = Math.max(0, Math.min(adjusted, next[targetColIndex].length));
|
|
6713
|
-
next[targetColIndex].splice(adjusted, 0, hrefKey);
|
|
6714
|
-
if (ordersEqual(next, order)) return null;
|
|
6715
|
-
return next;
|
|
6716
|
-
}
|
|
6717
|
-
function planFooterColumnMove(fromIndex, toIndex) {
|
|
6718
|
-
const order = getFooterOrderFromDom();
|
|
6719
|
-
const columns = listFooterColumns();
|
|
6720
|
-
if (fromIndex < 0 || fromIndex >= columns.length || toIndex < 0 || toIndex > columns.length) {
|
|
6721
|
-
return null;
|
|
6722
|
-
}
|
|
6723
|
-
if (toIndex === fromIndex || toIndex === fromIndex + 1) return null;
|
|
6724
|
-
const nextOrder = order.map((col) => [...col]);
|
|
6725
|
-
const [movedOrder] = nextOrder.splice(fromIndex, 1);
|
|
6726
|
-
if (!movedOrder) return null;
|
|
6727
|
-
let adjusted = toIndex;
|
|
6728
|
-
if (fromIndex < toIndex) adjusted -= 1;
|
|
6729
|
-
adjusted = Math.max(0, Math.min(adjusted, nextOrder.length));
|
|
6730
|
-
nextOrder.splice(adjusted, 0, movedOrder);
|
|
6731
|
-
if (ordersEqual(nextOrder, order)) return null;
|
|
6732
|
-
return nextOrder;
|
|
6733
|
-
}
|
|
6734
|
-
function parseFooterOrder(content) {
|
|
6735
|
-
const raw = content[FOOTER_ORDER_KEY];
|
|
6736
|
-
if (!raw) return null;
|
|
6737
|
-
try {
|
|
6738
|
-
const parsed = JSON.parse(raw);
|
|
6739
|
-
if (!Array.isArray(parsed)) return null;
|
|
6740
|
-
return parsed.filter((col) => Array.isArray(col)).map((col) => col.filter((key) => typeof key === "string" && key.length > 0));
|
|
6741
|
-
} catch {
|
|
6742
|
-
return null;
|
|
6743
|
-
}
|
|
6744
|
-
}
|
|
6745
|
-
function reconcileFooterOrderFromContent(content) {
|
|
6746
|
-
const order = parseFooterOrder(content);
|
|
6747
|
-
if (!order?.length) return;
|
|
6748
|
-
const current = getFooterOrderFromDom();
|
|
6749
|
-
if (ordersEqual(order, current)) {
|
|
6750
|
-
syncFooterColumnIndices(listFooterColumns());
|
|
6751
|
-
return;
|
|
6752
|
-
}
|
|
6753
|
-
applyFooterOrder(order);
|
|
6754
|
-
}
|
|
6755
|
-
function buildLinkDropSlots(column, columnIndex) {
|
|
6756
|
-
const links = listFooterLinksInColumn(column);
|
|
6757
|
-
const colRect = column.getBoundingClientRect();
|
|
6758
|
-
const slots = [];
|
|
6759
|
-
const barThickness = 3;
|
|
6760
|
-
if (links.length === 0) {
|
|
6761
|
-
slots.push({
|
|
6762
|
-
insertIndex: 0,
|
|
6763
|
-
columnIndex,
|
|
6764
|
-
left: colRect.left,
|
|
6765
|
-
top: colRect.top + colRect.height / 2 - barThickness / 2,
|
|
6766
|
-
width: colRect.width,
|
|
6767
|
-
height: barThickness,
|
|
6768
|
-
direction: "horizontal"
|
|
6769
|
-
});
|
|
6770
|
-
return slots;
|
|
6771
|
-
}
|
|
6772
|
-
for (let i = 0; i <= links.length; i++) {
|
|
6773
|
-
let top;
|
|
6774
|
-
if (i === 0) {
|
|
6775
|
-
top = links[0].getBoundingClientRect().top - barThickness / 2;
|
|
6776
|
-
} else if (i === links.length) {
|
|
6777
|
-
const last = links[links.length - 1].getBoundingClientRect();
|
|
6778
|
-
top = last.bottom - barThickness / 2;
|
|
6779
|
-
} else {
|
|
6780
|
-
const prev = links[i - 1].getBoundingClientRect();
|
|
6781
|
-
const next = links[i].getBoundingClientRect();
|
|
6782
|
-
top = (prev.bottom + next.top) / 2 - barThickness / 2;
|
|
6783
|
-
}
|
|
6784
|
-
const widthRef = i === 0 ? links[0].getBoundingClientRect() : i === links.length ? links[links.length - 1].getBoundingClientRect() : links[i].getBoundingClientRect();
|
|
6785
|
-
slots.push({
|
|
6786
|
-
insertIndex: i,
|
|
6787
|
-
columnIndex,
|
|
6788
|
-
left: widthRef.left,
|
|
6789
|
-
top,
|
|
6790
|
-
width: Math.max(widthRef.width, colRect.width * 0.8),
|
|
6791
|
-
height: barThickness,
|
|
6792
|
-
direction: "horizontal"
|
|
6793
|
-
});
|
|
6794
|
-
}
|
|
6795
|
-
return slots;
|
|
6796
|
-
}
|
|
6797
|
-
function buildColumnDropSlots() {
|
|
6798
|
-
const columns = listFooterColumns();
|
|
6799
|
-
const slots = [];
|
|
6800
|
-
const barThickness = 3;
|
|
6801
|
-
if (columns.length === 0) return slots;
|
|
6802
|
-
for (let i = 0; i <= columns.length; i++) {
|
|
6803
|
-
let left;
|
|
6804
|
-
let height;
|
|
6805
|
-
let top;
|
|
6806
|
-
if (i === 0) {
|
|
6807
|
-
const first = columns[0].getBoundingClientRect();
|
|
6808
|
-
left = first.left - barThickness / 2;
|
|
6809
|
-
top = first.top;
|
|
6810
|
-
height = first.height;
|
|
6811
|
-
} else if (i === columns.length) {
|
|
6812
|
-
const last = columns[columns.length - 1].getBoundingClientRect();
|
|
6813
|
-
left = last.right - barThickness / 2;
|
|
6814
|
-
top = last.top;
|
|
6815
|
-
height = last.height;
|
|
6816
|
-
} else {
|
|
6817
|
-
const prev = columns[i - 1].getBoundingClientRect();
|
|
6818
|
-
const next = columns[i].getBoundingClientRect();
|
|
6819
|
-
left = (prev.right + next.left) / 2 - barThickness / 2;
|
|
6820
|
-
top = Math.min(prev.top, next.top);
|
|
6821
|
-
height = Math.max(prev.bottom, next.bottom) - top;
|
|
6822
|
-
}
|
|
6823
|
-
slots.push({
|
|
6824
|
-
insertIndex: i,
|
|
6825
|
-
columnIndex: i,
|
|
6826
|
-
left,
|
|
6827
|
-
top,
|
|
6828
|
-
width: barThickness,
|
|
6829
|
-
height: Math.max(height, 24),
|
|
6830
|
-
direction: "vertical"
|
|
6831
|
-
});
|
|
6832
|
-
}
|
|
6833
|
-
return slots;
|
|
6834
|
-
}
|
|
6835
|
-
function hitTestLinkDropSlot(clientX, clientY, draggedHrefKey) {
|
|
6836
|
-
const columns = listFooterColumns();
|
|
6837
|
-
let best = null;
|
|
6838
|
-
for (let c = 0; c < columns.length; c++) {
|
|
6839
|
-
const col = columns[c];
|
|
6840
|
-
const colRect = col.getBoundingClientRect();
|
|
6841
|
-
const inColX = clientX >= colRect.left - 24 && clientX <= colRect.right + 24;
|
|
6842
|
-
if (!inColX) continue;
|
|
6843
|
-
const slots = buildLinkDropSlots(col, c).filter((slot) => {
|
|
6844
|
-
const links = listFooterLinksInColumn(col);
|
|
6845
|
-
const fromIdx = links.findIndex(
|
|
6846
|
-
(el) => el.getAttribute("data-ohw-href-key") === draggedHrefKey
|
|
6847
|
-
);
|
|
6848
|
-
if (fromIdx < 0) return true;
|
|
6849
|
-
if (c === findColumnIndexForKey(draggedHrefKey) && (slot.insertIndex === fromIdx || slot.insertIndex === fromIdx + 1)) {
|
|
6850
|
-
return true;
|
|
6851
|
-
}
|
|
6852
|
-
return true;
|
|
6853
|
-
});
|
|
6854
|
-
for (const slot of slots) {
|
|
6855
|
-
const cy = slot.top + slot.height / 2;
|
|
6856
|
-
const dist = Math.abs(clientY - cy) + (inColX ? 0 : 1e3);
|
|
6857
|
-
if (!best || dist < best.dist) best = { slot, dist };
|
|
6858
|
-
}
|
|
6859
|
-
}
|
|
6860
|
-
return best?.slot ?? null;
|
|
6861
|
-
}
|
|
6862
|
-
function findColumnIndexForKey(hrefKey) {
|
|
6863
|
-
const order = getFooterOrderFromDom();
|
|
6864
|
-
for (let c = 0; c < order.length; c++) {
|
|
6865
|
-
if (order[c].includes(hrefKey)) return c;
|
|
6866
|
-
}
|
|
6867
|
-
return -1;
|
|
6868
|
-
}
|
|
6869
|
-
function hitTestColumnDropSlot(clientX, _clientY) {
|
|
6870
|
-
const slots = buildColumnDropSlots();
|
|
6871
|
-
let best = null;
|
|
6872
|
-
for (const slot of slots) {
|
|
6873
|
-
const cx2 = slot.left + slot.width / 2;
|
|
6874
|
-
const dist = Math.abs(clientX - cx2);
|
|
6875
|
-
if (!best || dist < best.dist) best = { slot, dist };
|
|
6876
|
-
}
|
|
6877
|
-
return best?.slot ?? null;
|
|
6878
|
-
}
|
|
6879
|
-
|
|
6880
|
-
// src/lib/carousel.ts
|
|
6881
|
-
import { useEffect as useEffect7, useState as useState6 } from "react";
|
|
6882
|
-
var CAROUSEL_ATTR = "data-ohw-carousel";
|
|
6883
|
-
var CAROUSEL_VALUE_ATTR = "data-ohw-carousel-value";
|
|
6884
|
-
var CAROUSEL_SLIDE_ATTR = "data-ohw-carousel-slide";
|
|
6885
|
-
var CAROUSEL_EVENT = "ohw:carousel-change";
|
|
6886
|
-
function listCarouselKeys() {
|
|
6887
|
-
const keys = /* @__PURE__ */ new Set();
|
|
6888
|
-
document.querySelectorAll(`[${CAROUSEL_ATTR}]`).forEach((el) => {
|
|
6889
|
-
const key = el.getAttribute("data-ohw-key");
|
|
6890
|
-
if (key) keys.add(key);
|
|
6891
|
-
});
|
|
6892
|
-
return [...keys];
|
|
6893
|
-
}
|
|
6894
|
-
function containersForKey(key) {
|
|
6895
|
-
return Array.from(
|
|
6896
|
-
document.querySelectorAll(`[${CAROUSEL_ATTR}][data-ohw-key="${CSS.escape(key)}"]`)
|
|
6897
|
-
);
|
|
6898
|
-
}
|
|
6899
|
-
function isCarouselKey(key) {
|
|
6900
|
-
return containersForKey(key).length > 0;
|
|
6901
|
-
}
|
|
6902
|
-
function parseSlides(raw) {
|
|
6903
|
-
if (!raw) return [];
|
|
6904
|
-
try {
|
|
6905
|
-
const parsed = JSON.parse(raw);
|
|
6906
|
-
if (!Array.isArray(parsed)) return [];
|
|
6907
|
-
return parsed.filter((s) => Boolean(s) && typeof s === "object").map((s) => ({ src: String(s.src ?? ""), alt: String(s.alt ?? "") }));
|
|
6908
|
-
} catch {
|
|
6909
|
-
return [];
|
|
6910
|
-
}
|
|
6911
|
-
}
|
|
6912
|
-
function readCarouselValue(key) {
|
|
6913
|
-
const container = containersForKey(key)[0];
|
|
6914
|
-
if (!container) return [];
|
|
6915
|
-
const fromAttr = parseSlides(container.getAttribute(CAROUSEL_VALUE_ATTR));
|
|
6916
|
-
if (fromAttr.length > 0) return fromAttr;
|
|
6917
|
-
return Array.from(container.querySelectorAll(`[${CAROUSEL_SLIDE_ATTR}]`)).filter((slide) => slide.closest(`[${CAROUSEL_ATTR}]`) === container).sort((a, b) => slideIndex(a) - slideIndex(b)).map((slide) => {
|
|
6918
|
-
const img = slide instanceof HTMLImageElement ? slide : slide.querySelector("img");
|
|
6919
|
-
return { src: img?.src ?? "", alt: img?.alt ?? "" };
|
|
6920
|
-
});
|
|
6921
|
-
}
|
|
6922
|
-
function slideIndex(el) {
|
|
6923
|
-
const raw = el.getAttribute(CAROUSEL_SLIDE_ATTR);
|
|
6924
|
-
const n = raw ? parseInt(raw, 10) : NaN;
|
|
6925
|
-
return Number.isFinite(n) ? n : 0;
|
|
6926
|
-
}
|
|
6927
|
-
function applyCarouselValue(key, slides) {
|
|
6928
|
-
const value = JSON.stringify(slides);
|
|
6929
|
-
for (const container of containersForKey(key)) {
|
|
6930
|
-
if (container.getAttribute(CAROUSEL_VALUE_ATTR) === value) continue;
|
|
6931
|
-
container.setAttribute(CAROUSEL_VALUE_ATTR, value);
|
|
6932
|
-
container.dispatchEvent(
|
|
6933
|
-
new CustomEvent(CAROUSEL_EVENT, { detail: { images: slides } })
|
|
6934
|
-
);
|
|
6935
|
-
}
|
|
6936
|
-
}
|
|
6937
|
-
function applyCarouselNode(key, val) {
|
|
6938
|
-
if (!isCarouselKey(key)) return false;
|
|
6939
|
-
applyCarouselValue(key, parseSlides(val));
|
|
6940
|
-
return true;
|
|
6941
|
-
}
|
|
6942
|
-
function useOhwCarousel(key, initial) {
|
|
6943
|
-
const [images, setImages] = useState6(initial);
|
|
6944
|
-
useEffect7(() => {
|
|
6945
|
-
const el = document.querySelector(
|
|
6946
|
-
`[${CAROUSEL_ATTR}][data-ohw-key="${CSS.escape(key)}"]`
|
|
6947
|
-
);
|
|
6948
|
-
if (!el) return;
|
|
6949
|
-
const onChange = (e) => {
|
|
6950
|
-
const detail = e.detail;
|
|
6951
|
-
if (Array.isArray(detail?.images)) setImages(detail.images);
|
|
6952
|
-
};
|
|
6953
|
-
el.addEventListener(CAROUSEL_EVENT, onChange);
|
|
6954
|
-
return () => el.removeEventListener(CAROUSEL_EVENT, onChange);
|
|
6955
|
-
}, [key]);
|
|
6956
|
-
const bind = {
|
|
6957
|
-
[CAROUSEL_ATTR]: "",
|
|
6958
|
-
"data-ohw-key": key,
|
|
6959
|
-
[CAROUSEL_VALUE_ATTR]: JSON.stringify(images)
|
|
6960
|
-
};
|
|
6961
|
-
return { images, setImages, bind };
|
|
6962
|
-
}
|
|
6963
|
-
|
|
6964
|
-
// src/ui/navbar-container-chrome.tsx
|
|
6965
|
-
import { Plus as Plus2 } from "lucide-react";
|
|
6966
|
-
import { jsx as jsx22 } from "react/jsx-runtime";
|
|
6967
|
-
function NavbarContainerChrome({
|
|
6968
|
-
rect,
|
|
6969
|
-
onAdd
|
|
6970
|
-
}) {
|
|
6971
|
-
const chromeGap = 6;
|
|
6972
|
-
return /* @__PURE__ */ jsx22(
|
|
6973
|
-
"div",
|
|
6974
|
-
{
|
|
6975
|
-
"data-ohw-navbar-container-chrome": "",
|
|
6976
|
-
"data-ohw-bridge": "",
|
|
6977
|
-
className: "pointer-events-none fixed z-[2147483647]",
|
|
6978
|
-
style: {
|
|
6979
|
-
top: rect.top - chromeGap,
|
|
6980
|
-
left: rect.left - chromeGap,
|
|
6981
|
-
width: rect.width + chromeGap * 2,
|
|
6982
|
-
height: rect.height + chromeGap * 2
|
|
6983
|
-
},
|
|
6984
|
-
children: /* @__PURE__ */ jsx22(
|
|
6985
|
-
"button",
|
|
6986
|
-
{
|
|
6987
|
-
type: "button",
|
|
6988
|
-
"data-ohw-navbar-add-button": "",
|
|
6989
|
-
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",
|
|
6990
|
-
style: { top: "70%" },
|
|
6991
|
-
"aria-label": "Add item",
|
|
6992
|
-
onMouseDown: (e) => {
|
|
6993
|
-
e.preventDefault();
|
|
6994
|
-
e.stopPropagation();
|
|
6995
|
-
},
|
|
6996
|
-
onClick: (e) => {
|
|
6997
|
-
e.preventDefault();
|
|
6998
|
-
e.stopPropagation();
|
|
6999
|
-
onAdd();
|
|
7000
|
-
},
|
|
7001
|
-
children: /* @__PURE__ */ jsx22(Plus2, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
|
|
7002
|
-
}
|
|
7003
|
-
)
|
|
7004
|
-
}
|
|
7005
|
-
);
|
|
5694
|
+
"/classes": [{ id: "class-library", label: "Class Library" }],
|
|
5695
|
+
"/pricing": [
|
|
5696
|
+
{ id: "page-header", label: "Page Header" },
|
|
5697
|
+
{ id: "free-class-cta", label: "Free Class" },
|
|
5698
|
+
{ id: "benefits-marquee", label: "Benefits" },
|
|
5699
|
+
{ id: "monthly-memberships", label: "Memberships" },
|
|
5700
|
+
{ id: "specialty-programs", label: "Specialty Programs" },
|
|
5701
|
+
{ id: "package-matcher", label: "Packages" },
|
|
5702
|
+
{ id: "wordmark", label: "Wordmark" }
|
|
5703
|
+
],
|
|
5704
|
+
"/studio": [
|
|
5705
|
+
{ id: "studio-intro", label: "Studio Intro" },
|
|
5706
|
+
{ id: "studio-features", label: "Studio Features" },
|
|
5707
|
+
{ id: "studio-gallery", label: "Studio Gallery" },
|
|
5708
|
+
{ id: "studio-visit", label: "Visit Studio" }
|
|
5709
|
+
],
|
|
5710
|
+
"/instructors": [{ id: "instructor-grid", label: "Instructors" }],
|
|
5711
|
+
"/contact": [
|
|
5712
|
+
{ id: "hello-hero", label: "Hello" },
|
|
5713
|
+
{ id: "contact-form", label: "Contact Form" },
|
|
5714
|
+
{ id: "faq", label: "FAQ" }
|
|
5715
|
+
]
|
|
5716
|
+
};
|
|
5717
|
+
function shouldUseDevFixtures() {
|
|
5718
|
+
if (typeof window === "undefined") return false;
|
|
5719
|
+
const raw = readPreservedSearch();
|
|
5720
|
+
const q = raw.startsWith("?") ? raw.slice(1) : raw;
|
|
5721
|
+
return new URLSearchParams(q).get("ohw-fixtures") === "1";
|
|
7006
5722
|
}
|
|
7007
5723
|
|
|
7008
|
-
// src/ui/drop-indicator.tsx
|
|
7009
|
-
import * as React9 from "react";
|
|
7010
|
-
import { jsx as jsx23 } from "react/jsx-runtime";
|
|
7011
|
-
var dropIndicatorVariants = cva(
|
|
7012
|
-
"ov-gap-line pointer-events-none shrink-0 transition-opacity duration-150",
|
|
7013
|
-
{
|
|
7014
|
-
variants: {
|
|
7015
|
-
direction: {
|
|
7016
|
-
vertical: "h-6 w-[3px]",
|
|
7017
|
-
horizontal: "h-[3px] w-[200px]"
|
|
7018
|
-
},
|
|
7019
|
-
state: {
|
|
7020
|
-
default: "opacity-0",
|
|
7021
|
-
hover: "opacity-100",
|
|
7022
|
-
dragIdle: "opacity-40",
|
|
7023
|
-
dragActive: "opacity-100"
|
|
7024
|
-
}
|
|
7025
|
-
},
|
|
7026
|
-
defaultVariants: {
|
|
7027
|
-
direction: "vertical",
|
|
7028
|
-
state: "default"
|
|
7029
|
-
}
|
|
7030
|
-
}
|
|
7031
|
-
);
|
|
7032
|
-
var DropIndicator = React9.forwardRef(
|
|
7033
|
-
({ className, direction, state, ...props }, ref) => {
|
|
7034
|
-
return /* @__PURE__ */ jsx23(
|
|
7035
|
-
"div",
|
|
7036
|
-
{
|
|
7037
|
-
ref,
|
|
7038
|
-
"data-slot": "drop-indicator",
|
|
7039
|
-
"data-direction": direction ?? "vertical",
|
|
7040
|
-
"data-state": state ?? "default",
|
|
7041
|
-
"aria-hidden": "true",
|
|
7042
|
-
className: cn(dropIndicatorVariants({ direction, state }), className),
|
|
7043
|
-
...props
|
|
7044
|
-
}
|
|
7045
|
-
);
|
|
7046
|
-
}
|
|
7047
|
-
);
|
|
7048
|
-
DropIndicator.displayName = "DropIndicator";
|
|
7049
|
-
|
|
7050
5724
|
// src/ui/badge.tsx
|
|
7051
|
-
import { jsx as
|
|
5725
|
+
import { jsx as jsx21 } from "react/jsx-runtime";
|
|
7052
5726
|
var badgeVariants = cva(
|
|
7053
5727
|
"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",
|
|
7054
5728
|
{
|
|
@@ -7066,12 +5740,12 @@ var badgeVariants = cva(
|
|
|
7066
5740
|
}
|
|
7067
5741
|
);
|
|
7068
5742
|
function Badge({ className, variant, ...props }) {
|
|
7069
|
-
return /* @__PURE__ */
|
|
5743
|
+
return /* @__PURE__ */ jsx21("div", { className: cn(badgeVariants({ variant }), className), ...props });
|
|
7070
5744
|
}
|
|
7071
5745
|
|
|
7072
5746
|
// src/OhhwellsBridge.tsx
|
|
7073
5747
|
import { Link as Link2 } from "lucide-react";
|
|
7074
|
-
import { Fragment as
|
|
5748
|
+
import { Fragment as Fragment4, jsx as jsx22, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
7075
5749
|
var PRIMARY2 = "#0885FE";
|
|
7076
5750
|
var IMAGE_FADE_MS = 300;
|
|
7077
5751
|
function runOpacityFade(el, onDone) {
|
|
@@ -7250,7 +5924,7 @@ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId,
|
|
|
7250
5924
|
const root = createRoot(container);
|
|
7251
5925
|
flushSync(() => {
|
|
7252
5926
|
root.render(
|
|
7253
|
-
/* @__PURE__ */
|
|
5927
|
+
/* @__PURE__ */ jsx22(
|
|
7254
5928
|
SchedulingWidget,
|
|
7255
5929
|
{
|
|
7256
5930
|
notifyOnConnect,
|
|
@@ -7290,7 +5964,7 @@ function mountSchedulingEntries(entries, notifyOnConnect = false) {
|
|
|
7290
5964
|
}
|
|
7291
5965
|
}
|
|
7292
5966
|
}
|
|
7293
|
-
function
|
|
5967
|
+
function getLinkHref(el) {
|
|
7294
5968
|
const anchor = el instanceof HTMLAnchorElement ? el : el.querySelector("a");
|
|
7295
5969
|
return anchor?.getAttribute("href") ?? "";
|
|
7296
5970
|
}
|
|
@@ -7312,7 +5986,7 @@ function isDragHandleDisabled(el) {
|
|
|
7312
5986
|
return raw === "true" || raw === "";
|
|
7313
5987
|
});
|
|
7314
5988
|
}
|
|
7315
|
-
function collectEditableNodes(
|
|
5989
|
+
function collectEditableNodes() {
|
|
7316
5990
|
const nodes = Array.from(document.querySelectorAll("[data-ohw-editable]")).map((el) => {
|
|
7317
5991
|
if (el.dataset.ohwEditable === "image") {
|
|
7318
5992
|
const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
|
|
@@ -7327,7 +6001,7 @@ function collectEditableNodes(extraContent) {
|
|
|
7327
6001
|
return { key: el.dataset.ohwKey ?? "", type: "video", text: getVideoEl(el)?.src ?? "" };
|
|
7328
6002
|
}
|
|
7329
6003
|
if (el.dataset.ohwEditable === "link") {
|
|
7330
|
-
return { key: el.dataset.ohwKey ?? "", type: "link", text:
|
|
6004
|
+
return { key: el.dataset.ohwKey ?? "", type: "link", text: getLinkHref(el) };
|
|
7331
6005
|
}
|
|
7332
6006
|
return {
|
|
7333
6007
|
key: el.dataset.ohwKey ?? "",
|
|
@@ -7338,16 +6012,8 @@ function collectEditableNodes(extraContent) {
|
|
|
7338
6012
|
document.querySelectorAll("[data-ohw-href-key]").forEach((el) => {
|
|
7339
6013
|
const key = el.getAttribute("data-ohw-href-key") ?? "";
|
|
7340
6014
|
if (!key) return;
|
|
7341
|
-
nodes.push({ key, type: "link", text:
|
|
6015
|
+
nodes.push({ key, type: "link", text: getLinkHref(el) });
|
|
7342
6016
|
});
|
|
7343
|
-
if (extraContent) {
|
|
7344
|
-
for (const key of [NAV_ORDER_KEY, FOOTER_ORDER_KEY, NAV_COUNT_KEY]) {
|
|
7345
|
-
const text = extraContent[key];
|
|
7346
|
-
if (typeof text === "string" && text.length > 0) {
|
|
7347
|
-
nodes.push({ key, type: "meta", text });
|
|
7348
|
-
}
|
|
7349
|
-
}
|
|
7350
|
-
}
|
|
7351
6017
|
document.querySelectorAll('[data-ohw-editable="video"]').forEach((el) => {
|
|
7352
6018
|
const key = el.dataset.ohwKey ?? "";
|
|
7353
6019
|
const video = getVideoEl(el);
|
|
@@ -7355,10 +6021,13 @@ function collectEditableNodes(extraContent) {
|
|
|
7355
6021
|
nodes.push({ key: `${key}${VIDEO_AUTOPLAY_SUFFIX}`, type: "video-setting", text: String(video.autoplay) });
|
|
7356
6022
|
nodes.push({ key: `${key}${VIDEO_MUTED_SUFFIX}`, type: "video-setting", text: String(video.muted) });
|
|
7357
6023
|
});
|
|
7358
|
-
|
|
7359
|
-
|
|
7360
|
-
|
|
7361
|
-
|
|
6024
|
+
const seen = /* @__PURE__ */ new Set();
|
|
6025
|
+
return nodes.filter((node) => {
|
|
6026
|
+
if (!node.key) return true;
|
|
6027
|
+
if (seen.has(node.key)) return false;
|
|
6028
|
+
seen.add(node.key);
|
|
6029
|
+
return true;
|
|
6030
|
+
});
|
|
7362
6031
|
}
|
|
7363
6032
|
function isMediaEditable(el) {
|
|
7364
6033
|
const t = el.dataset.ohwEditable;
|
|
@@ -7435,7 +6104,7 @@ function applyLinkByKey(key, val) {
|
|
|
7435
6104
|
}
|
|
7436
6105
|
function isInsideLinkEditor(target) {
|
|
7437
6106
|
return Boolean(
|
|
7438
|
-
target.closest("[data-ohw-link-popover-root]") || target.closest("[data-ohw-link-modal-root]") || target.closest("[data-ohw-link-page-dropdown]") || target.closest(
|
|
6107
|
+
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"]')
|
|
7439
6108
|
);
|
|
7440
6109
|
}
|
|
7441
6110
|
function getHrefKeyFromElement(el) {
|
|
@@ -7446,30 +6115,7 @@ function getHrefKeyFromElement(el) {
|
|
|
7446
6115
|
if (!key) return null;
|
|
7447
6116
|
return { anchor, key };
|
|
7448
6117
|
}
|
|
7449
|
-
function
|
|
7450
|
-
if (el.draggable) el.draggable = false;
|
|
7451
|
-
if (el.getAttribute("draggable") !== "false") {
|
|
7452
|
-
el.setAttribute("draggable", "false");
|
|
7453
|
-
}
|
|
7454
|
-
}
|
|
7455
|
-
function clearTextSelection() {
|
|
7456
|
-
const sel = window.getSelection();
|
|
7457
|
-
if (sel && !sel.isCollapsed) sel.removeAllRanges();
|
|
7458
|
-
}
|
|
7459
|
-
function armFooterPressDrag() {
|
|
7460
|
-
document.documentElement.setAttribute("data-ohw-footer-press-drag", "");
|
|
7461
|
-
}
|
|
7462
|
-
function lockFooterDuringDrag() {
|
|
7463
|
-
document.documentElement.removeAttribute("data-ohw-footer-press-drag");
|
|
7464
|
-
document.documentElement.setAttribute("data-ohw-item-dragging", "");
|
|
7465
|
-
clearTextSelection();
|
|
7466
|
-
}
|
|
7467
|
-
function unlockFooterDragInteraction() {
|
|
7468
|
-
document.documentElement.removeAttribute("data-ohw-footer-press-drag");
|
|
7469
|
-
document.documentElement.removeAttribute("data-ohw-item-dragging");
|
|
7470
|
-
clearTextSelection();
|
|
7471
|
-
}
|
|
7472
|
-
function isNavbarButton2(el) {
|
|
6118
|
+
function isNavbarButton(el) {
|
|
7473
6119
|
return Boolean(el.closest('[data-ohw-role="navbar-button"]'));
|
|
7474
6120
|
}
|
|
7475
6121
|
function getNavigationItemAnchor(el) {
|
|
@@ -7481,8 +6127,19 @@ function getNavigationItemAnchor(el) {
|
|
|
7481
6127
|
function isNavigationItem(el) {
|
|
7482
6128
|
return getNavigationItemAnchor(el) !== null;
|
|
7483
6129
|
}
|
|
6130
|
+
function getNavigationItemAddHintTarget(anchor) {
|
|
6131
|
+
const items = listNavigationItems();
|
|
6132
|
+
const idx = items.indexOf(anchor);
|
|
6133
|
+
if (idx >= 0 && idx < items.length - 1) return items[idx + 1];
|
|
6134
|
+
return anchor;
|
|
6135
|
+
}
|
|
6136
|
+
function listNavigationItems() {
|
|
6137
|
+
return Array.from(
|
|
6138
|
+
document.querySelectorAll("nav [data-ohw-href-key], footer [data-ohw-href-key]")
|
|
6139
|
+
).filter((el) => isNavigationItem(el));
|
|
6140
|
+
}
|
|
7484
6141
|
function getNavigationItemReorderState(anchor) {
|
|
7485
|
-
if (
|
|
6142
|
+
if (isNavbarButton(anchor)) return { key: null, disabled: false };
|
|
7486
6143
|
return getReorderHandleStateFromAnchor(anchor);
|
|
7487
6144
|
}
|
|
7488
6145
|
function getReorderHandleState(el) {
|
|
@@ -7504,120 +6161,6 @@ function clearHrefKeyHover(anchor) {
|
|
|
7504
6161
|
function isInsideNavigationItem(el) {
|
|
7505
6162
|
return getNavigationItemAnchor(el) !== null;
|
|
7506
6163
|
}
|
|
7507
|
-
function getNavigationRoot(el) {
|
|
7508
|
-
const explicit = el.closest("[data-ohw-nav-root]");
|
|
7509
|
-
if (explicit) return explicit;
|
|
7510
|
-
return el.closest("nav, footer, aside");
|
|
7511
|
-
}
|
|
7512
|
-
function findFooterItemGroup(item) {
|
|
7513
|
-
const footer = item.closest("footer");
|
|
7514
|
-
if (!footer) return null;
|
|
7515
|
-
let node = item.parentElement;
|
|
7516
|
-
while (node && node !== footer) {
|
|
7517
|
-
const hasDirectNavItems = Array.from(
|
|
7518
|
-
node.querySelectorAll(":scope > [data-ohw-href-key]")
|
|
7519
|
-
).some(isNavigationItem);
|
|
7520
|
-
if (hasDirectNavItems) return node;
|
|
7521
|
-
node = node.parentElement;
|
|
7522
|
-
}
|
|
7523
|
-
return null;
|
|
7524
|
-
}
|
|
7525
|
-
function isNavigationRoot(el) {
|
|
7526
|
-
return el.hasAttribute("data-ohw-nav-root") || el.matches("nav, footer, aside");
|
|
7527
|
-
}
|
|
7528
|
-
function isInferredFooterGroup(el) {
|
|
7529
|
-
const footer = el.closest("footer");
|
|
7530
|
-
if (!footer || el === footer) return false;
|
|
7531
|
-
return Array.from(el.querySelectorAll(":scope > [data-ohw-href-key]")).some(isNavigationItem);
|
|
7532
|
-
}
|
|
7533
|
-
function isNavigationContainer(el) {
|
|
7534
|
-
return el.hasAttribute("data-ohw-nav-container") || isNavigationRoot(el) || isInferredFooterGroup(el);
|
|
7535
|
-
}
|
|
7536
|
-
function isPointOverNavigation(x, y) {
|
|
7537
|
-
const navRoot = document.querySelector("[data-ohw-nav-root]") ?? document.querySelector("nav");
|
|
7538
|
-
if (!navRoot) return false;
|
|
7539
|
-
const r2 = navRoot.getBoundingClientRect();
|
|
7540
|
-
return x >= r2.left && x <= r2.right && y >= r2.top && y <= r2.bottom;
|
|
7541
|
-
}
|
|
7542
|
-
function isPointOverNavItem(container, x, y) {
|
|
7543
|
-
return Array.from(container.querySelectorAll("[data-ohw-href-key]")).some((el) => {
|
|
7544
|
-
if (!isNavigationItem(el) || isNavbarButton2(el)) return false;
|
|
7545
|
-
const itemRect = el.getBoundingClientRect();
|
|
7546
|
-
return x >= itemRect.left && x <= itemRect.right && y >= itemRect.top && y <= itemRect.bottom;
|
|
7547
|
-
});
|
|
7548
|
-
}
|
|
7549
|
-
function resolveNavContainerSelectionTarget(target, clientX, clientY) {
|
|
7550
|
-
if (getNavigationItemAnchor(target)) return null;
|
|
7551
|
-
if (target.closest('[data-ohw-role="navbar-button"]')) return null;
|
|
7552
|
-
const plainLink = target.closest("a");
|
|
7553
|
-
if (plainLink && !plainLink.hasAttribute("data-ohw-href-key") && !plainLink.closest("[data-ohw-nav-container]")) {
|
|
7554
|
-
return null;
|
|
7555
|
-
}
|
|
7556
|
-
const fromClosest = target.closest("[data-ohw-nav-container]");
|
|
7557
|
-
if (fromClosest && !isPointOverNavItem(fromClosest, clientX, clientY)) {
|
|
7558
|
-
return fromClosest;
|
|
7559
|
-
}
|
|
7560
|
-
const navRoot = target.closest("[data-ohw-nav-root]");
|
|
7561
|
-
if (!navRoot) return null;
|
|
7562
|
-
const container = navRoot.querySelector("[data-ohw-nav-container]");
|
|
7563
|
-
if (!container || isPointOverNavItem(container, clientX, clientY)) return null;
|
|
7564
|
-
if (target === navRoot || target.hasAttribute("data-ohw-nav-root")) {
|
|
7565
|
-
return container;
|
|
7566
|
-
}
|
|
7567
|
-
return null;
|
|
7568
|
-
}
|
|
7569
|
-
function getNavigationSelectionParent(el) {
|
|
7570
|
-
if (isNavigationItem(el)) {
|
|
7571
|
-
const explicit = el.closest("[data-ohw-nav-container]");
|
|
7572
|
-
if (explicit) return explicit;
|
|
7573
|
-
const footerGroup = findFooterItemGroup(el);
|
|
7574
|
-
if (footerGroup) return footerGroup;
|
|
7575
|
-
return getNavigationRoot(el);
|
|
7576
|
-
}
|
|
7577
|
-
if (el.hasAttribute("data-ohw-nav-container") || isInferredFooterGroup(el)) {
|
|
7578
|
-
return getNavigationRoot(el);
|
|
7579
|
-
}
|
|
7580
|
-
return null;
|
|
7581
|
-
}
|
|
7582
|
-
function placeCaretAtPoint(el, x, y) {
|
|
7583
|
-
const selection = window.getSelection();
|
|
7584
|
-
if (!selection) return;
|
|
7585
|
-
if (typeof document.caretRangeFromPoint === "function") {
|
|
7586
|
-
const range = document.caretRangeFromPoint(x, y);
|
|
7587
|
-
if (range && el.contains(range.startContainer)) {
|
|
7588
|
-
selection.removeAllRanges();
|
|
7589
|
-
selection.addRange(range);
|
|
7590
|
-
return;
|
|
7591
|
-
}
|
|
7592
|
-
}
|
|
7593
|
-
const caretPositionFromPoint = document.caretPositionFromPoint;
|
|
7594
|
-
if (typeof caretPositionFromPoint === "function") {
|
|
7595
|
-
const position = caretPositionFromPoint(x, y);
|
|
7596
|
-
if (position && el.contains(position.offsetNode)) {
|
|
7597
|
-
const range = document.createRange();
|
|
7598
|
-
range.setStart(position.offsetNode, position.offset);
|
|
7599
|
-
range.collapse(true);
|
|
7600
|
-
selection.removeAllRanges();
|
|
7601
|
-
selection.addRange(range);
|
|
7602
|
-
}
|
|
7603
|
-
}
|
|
7604
|
-
}
|
|
7605
|
-
function selectAllTextInEditable(el) {
|
|
7606
|
-
const selection = window.getSelection();
|
|
7607
|
-
if (!selection) return;
|
|
7608
|
-
const range = document.createRange();
|
|
7609
|
-
range.selectNodeContents(el);
|
|
7610
|
-
selection.removeAllRanges();
|
|
7611
|
-
selection.addRange(range);
|
|
7612
|
-
}
|
|
7613
|
-
function getNavigationLabelEditable(target) {
|
|
7614
|
-
const editable = target.closest('[data-ohw-editable="text"]');
|
|
7615
|
-
if (!editable) return null;
|
|
7616
|
-
const hrefCtx = getHrefKeyFromElement(editable);
|
|
7617
|
-
const navAnchor = hrefCtx ? getNavigationItemAnchor(hrefCtx.anchor) : null;
|
|
7618
|
-
if (!navAnchor) return null;
|
|
7619
|
-
return { editable, navAnchor };
|
|
7620
|
-
}
|
|
7621
6164
|
function collectSections() {
|
|
7622
6165
|
return collectSectionsFromDom();
|
|
7623
6166
|
}
|
|
@@ -7741,8 +6284,6 @@ var ICONS = {
|
|
|
7741
6284
|
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"/>',
|
|
7742
6285
|
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"/>'
|
|
7743
6286
|
};
|
|
7744
|
-
var TOOLBAR_PILL_PADDING = 2;
|
|
7745
|
-
var TOOLBAR_TOGGLE_GAP = 4;
|
|
7746
6287
|
var TOOLBAR_GROUPS = [
|
|
7747
6288
|
[
|
|
7748
6289
|
{ cmd: "bold", title: "Bold" },
|
|
@@ -7767,7 +6308,7 @@ function EditGlowChrome({
|
|
|
7767
6308
|
dragDisabled = false
|
|
7768
6309
|
}) {
|
|
7769
6310
|
const GAP = 6;
|
|
7770
|
-
return /* @__PURE__ */
|
|
6311
|
+
return /* @__PURE__ */ jsxs12(
|
|
7771
6312
|
"div",
|
|
7772
6313
|
{
|
|
7773
6314
|
ref: elRef,
|
|
@@ -7782,7 +6323,7 @@ function EditGlowChrome({
|
|
|
7782
6323
|
zIndex: 2147483646
|
|
7783
6324
|
},
|
|
7784
6325
|
children: [
|
|
7785
|
-
/* @__PURE__ */
|
|
6326
|
+
/* @__PURE__ */ jsx22(
|
|
7786
6327
|
"div",
|
|
7787
6328
|
{
|
|
7788
6329
|
style: {
|
|
@@ -7795,7 +6336,7 @@ function EditGlowChrome({
|
|
|
7795
6336
|
}
|
|
7796
6337
|
}
|
|
7797
6338
|
),
|
|
7798
|
-
reorderHrefKey && /* @__PURE__ */
|
|
6339
|
+
reorderHrefKey && /* @__PURE__ */ jsx22(
|
|
7799
6340
|
"div",
|
|
7800
6341
|
{
|
|
7801
6342
|
"data-ohw-drag-handle-container": "",
|
|
@@ -7807,7 +6348,7 @@ function EditGlowChrome({
|
|
|
7807
6348
|
transform: "translate(calc(-100% - 7px), -50%)",
|
|
7808
6349
|
pointerEvents: dragDisabled ? "none" : "auto"
|
|
7809
6350
|
},
|
|
7810
|
-
children: /* @__PURE__ */
|
|
6351
|
+
children: /* @__PURE__ */ jsx22(
|
|
7811
6352
|
DragHandle,
|
|
7812
6353
|
{
|
|
7813
6354
|
"aria-label": `Reorder ${reorderHrefKey}`,
|
|
@@ -7911,7 +6452,7 @@ function FloatingToolbar({
|
|
|
7911
6452
|
onEditLink
|
|
7912
6453
|
}) {
|
|
7913
6454
|
const { top, left, transform } = calcToolbarPos(rect, parentScroll, 330);
|
|
7914
|
-
return /* @__PURE__ */
|
|
6455
|
+
return /* @__PURE__ */ jsx22(
|
|
7915
6456
|
"div",
|
|
7916
6457
|
{
|
|
7917
6458
|
ref: elRef,
|
|
@@ -7921,23 +6462,14 @@ function FloatingToolbar({
|
|
|
7921
6462
|
left,
|
|
7922
6463
|
transform,
|
|
7923
6464
|
zIndex: 2147483647,
|
|
7924
|
-
background: "#fff",
|
|
7925
|
-
border: "1px solid #E7E5E4",
|
|
7926
|
-
borderRadius: 6,
|
|
7927
|
-
boxShadow: "0px 2px 4px -2px rgba(0,0,0,.1),0px 4px 6px -1px rgba(0,0,0,.1)",
|
|
7928
|
-
display: "flex",
|
|
7929
|
-
alignItems: "center",
|
|
7930
|
-
padding: TOOLBAR_PILL_PADDING,
|
|
7931
|
-
gap: TOOLBAR_TOGGLE_GAP,
|
|
7932
|
-
fontFamily: "sans-serif",
|
|
7933
6465
|
pointerEvents: "auto"
|
|
7934
6466
|
},
|
|
7935
|
-
children: /* @__PURE__ */
|
|
7936
|
-
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */
|
|
7937
|
-
gi > 0 && /* @__PURE__ */
|
|
6467
|
+
children: /* @__PURE__ */ jsxs12(CustomToolbar, { children: [
|
|
6468
|
+
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ jsxs12(React9.Fragment, { children: [
|
|
6469
|
+
gi > 0 && /* @__PURE__ */ jsx22(CustomToolbarDivider, {}),
|
|
7938
6470
|
btns.map((btn) => {
|
|
7939
6471
|
const isActive = activeCommands.has(btn.cmd);
|
|
7940
|
-
return /* @__PURE__ */
|
|
6472
|
+
return /* @__PURE__ */ jsx22(
|
|
7941
6473
|
CustomToolbarButton,
|
|
7942
6474
|
{
|
|
7943
6475
|
title: btn.title,
|
|
@@ -7946,7 +6478,7 @@ function FloatingToolbar({
|
|
|
7946
6478
|
e.preventDefault();
|
|
7947
6479
|
onCommand(btn.cmd);
|
|
7948
6480
|
},
|
|
7949
|
-
children: /* @__PURE__ */
|
|
6481
|
+
children: /* @__PURE__ */ jsx22(
|
|
7950
6482
|
"svg",
|
|
7951
6483
|
{
|
|
7952
6484
|
width: "16",
|
|
@@ -7967,7 +6499,7 @@ function FloatingToolbar({
|
|
|
7967
6499
|
);
|
|
7968
6500
|
})
|
|
7969
6501
|
] }, gi)),
|
|
7970
|
-
showEditLink ? /* @__PURE__ */
|
|
6502
|
+
showEditLink ? /* @__PURE__ */ jsx22(
|
|
7971
6503
|
CustomToolbarButton,
|
|
7972
6504
|
{
|
|
7973
6505
|
type: "button",
|
|
@@ -7981,7 +6513,7 @@ function FloatingToolbar({
|
|
|
7981
6513
|
e.preventDefault();
|
|
7982
6514
|
e.stopPropagation();
|
|
7983
6515
|
},
|
|
7984
|
-
children: /* @__PURE__ */
|
|
6516
|
+
children: /* @__PURE__ */ jsx22(Link2, { className: "size-4 shrink-0", "aria-hidden": true })
|
|
7985
6517
|
}
|
|
7986
6518
|
) : null
|
|
7987
6519
|
] })
|
|
@@ -7998,7 +6530,7 @@ function StateToggle({
|
|
|
7998
6530
|
states,
|
|
7999
6531
|
onStateChange
|
|
8000
6532
|
}) {
|
|
8001
|
-
return /* @__PURE__ */
|
|
6533
|
+
return /* @__PURE__ */ jsx22(
|
|
8002
6534
|
ToggleGroup,
|
|
8003
6535
|
{
|
|
8004
6536
|
"data-ohw-state-toggle": "",
|
|
@@ -8012,7 +6544,7 @@ function StateToggle({
|
|
|
8012
6544
|
left: rect.right - 8,
|
|
8013
6545
|
transform: "translateX(-100%)"
|
|
8014
6546
|
},
|
|
8015
|
-
children: states.map((state) => /* @__PURE__ */
|
|
6547
|
+
children: states.map((state) => /* @__PURE__ */ jsx22(ToggleGroupItem, { value: state, size: "sm", children: state }, state))
|
|
8016
6548
|
}
|
|
8017
6549
|
);
|
|
8018
6550
|
}
|
|
@@ -8035,12 +6567,12 @@ function resolveSubdomain(subdomainFromQuery) {
|
|
|
8035
6567
|
return "";
|
|
8036
6568
|
}
|
|
8037
6569
|
function OhhwellsBridge() {
|
|
8038
|
-
const pathname =
|
|
8039
|
-
const router =
|
|
6570
|
+
const pathname = usePathname();
|
|
6571
|
+
const router = useRouter();
|
|
8040
6572
|
const searchParams = useSearchParams();
|
|
8041
6573
|
const isEditMode = isEditSessionActive();
|
|
8042
|
-
const [bridgeRoot, setBridgeRoot] =
|
|
8043
|
-
|
|
6574
|
+
const [bridgeRoot, setBridgeRoot] = useState5(null);
|
|
6575
|
+
useEffect4(() => {
|
|
8044
6576
|
const figtreeFontId = "ohw-figtree-font";
|
|
8045
6577
|
if (!document.getElementById(figtreeFontId)) {
|
|
8046
6578
|
const preconnect1 = Object.assign(document.createElement("link"), { rel: "preconnect", href: "https://fonts.googleapis.com" });
|
|
@@ -8068,100 +6600,83 @@ function OhhwellsBridge() {
|
|
|
8068
6600
|
const subdomainFromQuery = searchParams.get("subdomain");
|
|
8069
6601
|
const subdomain = resolveSubdomain(subdomainFromQuery);
|
|
8070
6602
|
useLinkHrefGuardian(pathname, subdomain, isEditMode);
|
|
8071
|
-
const
|
|
6603
|
+
const postToParent = useCallback2((data) => {
|
|
8072
6604
|
if (typeof window !== "undefined" && window.parent !== window) {
|
|
8073
6605
|
window.parent.postMessage(data, "*");
|
|
8074
6606
|
}
|
|
8075
6607
|
}, []);
|
|
8076
|
-
const [fetchState, setFetchState] =
|
|
8077
|
-
const autoSaveTimers =
|
|
8078
|
-
const activeElRef =
|
|
8079
|
-
const selectedElRef =
|
|
8080
|
-
const originalContentRef =
|
|
8081
|
-
const activeStateElRef =
|
|
8082
|
-
const parentScrollRef =
|
|
8083
|
-
const visibleViewportRef =
|
|
8084
|
-
const [dialogPortalContainer, setDialogPortalContainer] =
|
|
8085
|
-
const attachVisibleViewport =
|
|
6608
|
+
const [fetchState, setFetchState] = useState5("idle");
|
|
6609
|
+
const autoSaveTimers = useRef4(/* @__PURE__ */ new Map());
|
|
6610
|
+
const activeElRef = useRef4(null);
|
|
6611
|
+
const selectedElRef = useRef4(null);
|
|
6612
|
+
const originalContentRef = useRef4(null);
|
|
6613
|
+
const activeStateElRef = useRef4(null);
|
|
6614
|
+
const parentScrollRef = useRef4(null);
|
|
6615
|
+
const visibleViewportRef = useRef4(null);
|
|
6616
|
+
const [dialogPortalContainer, setDialogPortalContainer] = useState5(null);
|
|
6617
|
+
const attachVisibleViewport = useCallback2((node) => {
|
|
8086
6618
|
visibleViewportRef.current = node;
|
|
8087
6619
|
setDialogPortalContainer(node);
|
|
8088
6620
|
if (node) applyVisibleViewport(node, parentScrollRef.current);
|
|
8089
6621
|
}, []);
|
|
8090
|
-
const toolbarElRef =
|
|
8091
|
-
const glowElRef =
|
|
8092
|
-
const hoveredImageRef =
|
|
8093
|
-
const hoveredImageHasTextOverlapRef =
|
|
8094
|
-
const dragOverElRef =
|
|
8095
|
-
const [mediaHover, setMediaHover] =
|
|
8096
|
-
const [
|
|
8097
|
-
const
|
|
8098
|
-
const
|
|
8099
|
-
const
|
|
8100
|
-
const
|
|
8101
|
-
const
|
|
8102
|
-
const activateRef = useRef5(() => {
|
|
8103
|
-
});
|
|
8104
|
-
const deactivateRef = useRef5(() => {
|
|
6622
|
+
const toolbarElRef = useRef4(null);
|
|
6623
|
+
const glowElRef = useRef4(null);
|
|
6624
|
+
const hoveredImageRef = useRef4(null);
|
|
6625
|
+
const hoveredImageHasTextOverlapRef = useRef4(false);
|
|
6626
|
+
const dragOverElRef = useRef4(null);
|
|
6627
|
+
const [mediaHover, setMediaHover] = useState5(null);
|
|
6628
|
+
const [uploadingRects, setUploadingRects] = useState5({});
|
|
6629
|
+
const hoveredGapRef = useRef4(null);
|
|
6630
|
+
const imageUnhoverTimerRef = useRef4(null);
|
|
6631
|
+
const imageShowTimerRef = useRef4(null);
|
|
6632
|
+
const editStylesRef = useRef4(null);
|
|
6633
|
+
const activateRef = useRef4(() => {
|
|
8105
6634
|
});
|
|
8106
|
-
const
|
|
6635
|
+
const deactivateRef = useRef4(() => {
|
|
8107
6636
|
});
|
|
8108
|
-
const
|
|
6637
|
+
const selectRef = useRef4(() => {
|
|
8109
6638
|
});
|
|
8110
|
-
const deselectRef =
|
|
6639
|
+
const deselectRef = useRef4(() => {
|
|
8111
6640
|
});
|
|
8112
|
-
const reselectNavigationItemRef =
|
|
6641
|
+
const reselectNavigationItemRef = useRef4(() => {
|
|
8113
6642
|
});
|
|
8114
|
-
const commitNavigationTextEditRef =
|
|
6643
|
+
const commitNavigationTextEditRef = useRef4(() => {
|
|
8115
6644
|
});
|
|
8116
|
-
const refreshActiveCommandsRef =
|
|
6645
|
+
const refreshActiveCommandsRef = useRef4(() => {
|
|
8117
6646
|
});
|
|
8118
|
-
const postToParentRef =
|
|
8119
|
-
postToParentRef.current =
|
|
8120
|
-
const sectionsLoadedRef =
|
|
8121
|
-
const pendingScheduleConfigRequests =
|
|
8122
|
-
const [toolbarRect, setToolbarRect] =
|
|
8123
|
-
const [toolbarVariant, setToolbarVariant] =
|
|
8124
|
-
const toolbarVariantRef =
|
|
6647
|
+
const postToParentRef = useRef4(postToParent);
|
|
6648
|
+
postToParentRef.current = postToParent;
|
|
6649
|
+
const sectionsLoadedRef = useRef4(false);
|
|
6650
|
+
const pendingScheduleConfigRequests = useRef4([]);
|
|
6651
|
+
const [toolbarRect, setToolbarRect] = useState5(null);
|
|
6652
|
+
const [toolbarVariant, setToolbarVariant] = useState5("none");
|
|
6653
|
+
const toolbarVariantRef = useRef4("none");
|
|
8125
6654
|
toolbarVariantRef.current = toolbarVariant;
|
|
8126
|
-
const [reorderHrefKey, setReorderHrefKey] =
|
|
8127
|
-
const [reorderDragDisabled, setReorderDragDisabled] =
|
|
8128
|
-
const [toggleState, setToggleState] =
|
|
8129
|
-
const [maxBadge, setMaxBadge] =
|
|
8130
|
-
const [activeCommands, setActiveCommands] =
|
|
8131
|
-
const [sectionGap, setSectionGap] =
|
|
8132
|
-
const [toolbarShowEditLink, setToolbarShowEditLink] =
|
|
8133
|
-
const
|
|
8134
|
-
const [
|
|
8135
|
-
const
|
|
8136
|
-
const [
|
|
8137
|
-
const
|
|
8138
|
-
const [
|
|
8139
|
-
const [
|
|
8140
|
-
const [
|
|
8141
|
-
const
|
|
8142
|
-
const
|
|
8143
|
-
const
|
|
8144
|
-
const
|
|
8145
|
-
const
|
|
8146
|
-
const footerPointerDragRef = useRef5(null);
|
|
8147
|
-
const suppressNextClickRef = useRef5(false);
|
|
8148
|
-
const [linkPopover, setLinkPopover] = useState7(null);
|
|
8149
|
-
const linkPopoverSessionRef = useRef5(null);
|
|
8150
|
-
const addNavAfterAnchorRef = useRef5(null);
|
|
8151
|
-
const editContentRef = useRef5({});
|
|
8152
|
-
const [sitePages, setSitePages] = useState7([]);
|
|
8153
|
-
const [sectionsByPath, setSectionsByPath] = useState7({});
|
|
8154
|
-
const sectionsPrefetchGenRef = useRef5(0);
|
|
8155
|
-
const setLinkPopoverRef = useRef5(setLinkPopover);
|
|
8156
|
-
const linkPopoverPanelRef = useRef5(null);
|
|
8157
|
-
const linkPopoverOpenRef = useRef5(false);
|
|
8158
|
-
const linkPopoverGraceUntilRef = useRef5(0);
|
|
6655
|
+
const [reorderHrefKey, setReorderHrefKey] = useState5(null);
|
|
6656
|
+
const [reorderDragDisabled, setReorderDragDisabled] = useState5(false);
|
|
6657
|
+
const [toggleState, setToggleState] = useState5(null);
|
|
6658
|
+
const [maxBadge, setMaxBadge] = useState5(null);
|
|
6659
|
+
const [activeCommands, setActiveCommands] = useState5(/* @__PURE__ */ new Set());
|
|
6660
|
+
const [sectionGap, setSectionGap] = useState5(null);
|
|
6661
|
+
const [toolbarShowEditLink, setToolbarShowEditLink] = useState5(false);
|
|
6662
|
+
const hoveredItemElRef = useRef4(null);
|
|
6663
|
+
const [hoveredItemRect, setHoveredItemRect] = useState5(null);
|
|
6664
|
+
const siblingHintElRef = useRef4(null);
|
|
6665
|
+
const [siblingHintRect, setSiblingHintRect] = useState5(null);
|
|
6666
|
+
const [isItemDragging, setIsItemDragging] = useState5(false);
|
|
6667
|
+
const [linkPopover, setLinkPopover] = useState5(null);
|
|
6668
|
+
const [sitePages, setSitePages] = useState5([]);
|
|
6669
|
+
const [sectionsByPath, setSectionsByPath] = useState5({});
|
|
6670
|
+
const sectionsPrefetchGenRef = useRef4(0);
|
|
6671
|
+
const setLinkPopoverRef = useRef4(setLinkPopover);
|
|
6672
|
+
const linkPopoverPanelRef = useRef4(null);
|
|
6673
|
+
const linkPopoverOpenRef = useRef4(false);
|
|
6674
|
+
const linkPopoverGraceUntilRef = useRef4(0);
|
|
8159
6675
|
setLinkPopoverRef.current = setLinkPopover;
|
|
8160
|
-
linkPopoverSessionRef.current = linkPopover;
|
|
8161
6676
|
const bumpLinkPopoverGrace = () => {
|
|
8162
6677
|
linkPopoverGraceUntilRef.current = Date.now() + 350;
|
|
8163
6678
|
};
|
|
8164
|
-
const runSectionsPrefetch =
|
|
6679
|
+
const runSectionsPrefetch = useCallback2((pages) => {
|
|
8165
6680
|
if (!isEditMode || shouldUseDevFixtures() || pages.length === 0) return;
|
|
8166
6681
|
const gen = ++sectionsPrefetchGenRef.current;
|
|
8167
6682
|
const paths = pages.map((p) => p.path);
|
|
@@ -8180,9 +6695,9 @@ function OhhwellsBridge() {
|
|
|
8180
6695
|
);
|
|
8181
6696
|
});
|
|
8182
6697
|
}, [isEditMode, pathname]);
|
|
8183
|
-
const runSectionsPrefetchRef =
|
|
6698
|
+
const runSectionsPrefetchRef = useRef4(runSectionsPrefetch);
|
|
8184
6699
|
runSectionsPrefetchRef.current = runSectionsPrefetch;
|
|
8185
|
-
|
|
6700
|
+
useEffect4(() => {
|
|
8186
6701
|
if (!linkPopover) return;
|
|
8187
6702
|
if (hoveredImageRef.current) {
|
|
8188
6703
|
hoveredImageRef.current = null;
|
|
@@ -8190,9 +6705,33 @@ function OhhwellsBridge() {
|
|
|
8190
6705
|
}
|
|
8191
6706
|
hoveredGapRef.current = null;
|
|
8192
6707
|
setSectionGap(null);
|
|
8193
|
-
|
|
8194
|
-
|
|
8195
|
-
|
|
6708
|
+
setMediaHover(null);
|
|
6709
|
+
postToParent({ type: "ow:link-modal-lock", locked: true });
|
|
6710
|
+
const html = document.documentElement;
|
|
6711
|
+
const body = document.body;
|
|
6712
|
+
const prevHtmlOverflow = html.style.overflow;
|
|
6713
|
+
const prevBodyOverflow = body.style.overflow;
|
|
6714
|
+
html.style.overflow = "hidden";
|
|
6715
|
+
body.style.overflow = "hidden";
|
|
6716
|
+
const preventBackgroundScroll = (e) => {
|
|
6717
|
+
const target = e.target;
|
|
6718
|
+
if (target instanceof Element && target.closest('[data-ohw-link-modal-root], [data-slot="dialog-overlay"]')) {
|
|
6719
|
+
return;
|
|
6720
|
+
}
|
|
6721
|
+
e.preventDefault();
|
|
6722
|
+
};
|
|
6723
|
+
const scrollOpts = { passive: false, capture: true };
|
|
6724
|
+
document.addEventListener("wheel", preventBackgroundScroll, scrollOpts);
|
|
6725
|
+
document.addEventListener("touchmove", preventBackgroundScroll, scrollOpts);
|
|
6726
|
+
return () => {
|
|
6727
|
+
postToParent({ type: "ow:link-modal-lock", locked: false });
|
|
6728
|
+
html.style.overflow = prevHtmlOverflow;
|
|
6729
|
+
body.style.overflow = prevBodyOverflow;
|
|
6730
|
+
document.removeEventListener("wheel", preventBackgroundScroll, scrollOpts);
|
|
6731
|
+
document.removeEventListener("touchmove", preventBackgroundScroll, scrollOpts);
|
|
6732
|
+
};
|
|
6733
|
+
}, [linkPopover, postToParent]);
|
|
6734
|
+
useEffect4(() => {
|
|
8196
6735
|
if (!isEditMode) return;
|
|
8197
6736
|
const useFixtures = shouldUseDevFixtures();
|
|
8198
6737
|
if (useFixtures) {
|
|
@@ -8213,17 +6752,17 @@ function OhhwellsBridge() {
|
|
|
8213
6752
|
runSectionsPrefetchRef.current(mapped);
|
|
8214
6753
|
};
|
|
8215
6754
|
window.addEventListener("message", onSitePages);
|
|
8216
|
-
if (!useFixtures)
|
|
6755
|
+
if (!useFixtures) postToParent({ type: "ow:request-site-pages" });
|
|
8217
6756
|
return () => window.removeEventListener("message", onSitePages);
|
|
8218
|
-
}, [isEditMode,
|
|
8219
|
-
|
|
6757
|
+
}, [isEditMode, postToParent]);
|
|
6758
|
+
useEffect4(() => {
|
|
8220
6759
|
if (!isEditMode || shouldUseDevFixtures()) return;
|
|
8221
6760
|
void loadAllSectionsManifest().then((manifest) => {
|
|
8222
6761
|
if (Object.keys(manifest).length === 0) return;
|
|
8223
6762
|
setSectionsByPath((prev) => ({ ...manifest, ...prev }));
|
|
8224
6763
|
});
|
|
8225
6764
|
}, [isEditMode]);
|
|
8226
|
-
|
|
6765
|
+
useEffect4(() => {
|
|
8227
6766
|
const update = () => {
|
|
8228
6767
|
const el = activeElRef.current ?? selectedElRef.current;
|
|
8229
6768
|
if (el) setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
|
|
@@ -8247,10 +6786,10 @@ function OhhwellsBridge() {
|
|
|
8247
6786
|
vvp.removeEventListener("resize", update);
|
|
8248
6787
|
};
|
|
8249
6788
|
}, []);
|
|
8250
|
-
const refreshStateRules =
|
|
6789
|
+
const refreshStateRules = useCallback2(() => {
|
|
8251
6790
|
editStylesRef.current?.forceHover && (editStylesRef.current.forceHover.textContent = collectStateRules());
|
|
8252
6791
|
}, []);
|
|
8253
|
-
const processConfigRequest =
|
|
6792
|
+
const processConfigRequest = useCallback2((insertAfterVal) => {
|
|
8254
6793
|
const tracker = getSectionsTracker();
|
|
8255
6794
|
let entries = [];
|
|
8256
6795
|
try {
|
|
@@ -8273,7 +6812,7 @@ function OhhwellsBridge() {
|
|
|
8273
6812
|
}
|
|
8274
6813
|
window.postMessage({ type: "ow:schedule-config", insertAfter: insertAfterVal, scheduleId: null }, "*");
|
|
8275
6814
|
}, [isEditMode]);
|
|
8276
|
-
const deactivate =
|
|
6815
|
+
const deactivate = useCallback2(() => {
|
|
8277
6816
|
const el = activeElRef.current;
|
|
8278
6817
|
if (!el) return;
|
|
8279
6818
|
const key = el.dataset.ohwKey;
|
|
@@ -8302,25 +6841,21 @@ function OhhwellsBridge() {
|
|
|
8302
6841
|
setMaxBadge(null);
|
|
8303
6842
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
8304
6843
|
setToolbarShowEditLink(false);
|
|
8305
|
-
|
|
8306
|
-
}, [
|
|
8307
|
-
const deselect =
|
|
6844
|
+
postToParent({ type: "ow:exit-edit" });
|
|
6845
|
+
}, [postToParent]);
|
|
6846
|
+
const deselect = useCallback2(() => {
|
|
8308
6847
|
selectedElRef.current = null;
|
|
8309
6848
|
setReorderHrefKey(null);
|
|
8310
6849
|
setReorderDragDisabled(false);
|
|
8311
|
-
setIsFooterFrameSelection(false);
|
|
8312
6850
|
siblingHintElRef.current = null;
|
|
8313
6851
|
setSiblingHintRect(null);
|
|
8314
|
-
setSiblingHintRects([]);
|
|
8315
6852
|
setIsItemDragging(false);
|
|
8316
|
-
hoveredNavContainerRef.current = null;
|
|
8317
|
-
setHoveredNavContainerRect(null);
|
|
8318
6853
|
if (!activeElRef.current) {
|
|
8319
6854
|
setToolbarRect(null);
|
|
8320
6855
|
setToolbarVariant("none");
|
|
8321
6856
|
}
|
|
8322
6857
|
}, []);
|
|
8323
|
-
const reselectNavigationItem =
|
|
6858
|
+
const reselectNavigationItem = useCallback2((navAnchor) => {
|
|
8324
6859
|
selectedElRef.current = navAnchor;
|
|
8325
6860
|
const { key, disabled } = getNavigationItemReorderState(navAnchor);
|
|
8326
6861
|
setReorderHrefKey(key);
|
|
@@ -8330,7 +6865,7 @@ function OhhwellsBridge() {
|
|
|
8330
6865
|
setToolbarShowEditLink(false);
|
|
8331
6866
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
8332
6867
|
}, []);
|
|
8333
|
-
const commitNavigationTextEdit =
|
|
6868
|
+
const commitNavigationTextEdit = useCallback2((navAnchor) => {
|
|
8334
6869
|
const el = activeElRef.current;
|
|
8335
6870
|
if (!el) return;
|
|
8336
6871
|
const key = el.dataset.ohwKey;
|
|
@@ -8343,9 +6878,9 @@ function OhhwellsBridge() {
|
|
|
8343
6878
|
const html = sanitizeHtml(el.innerHTML);
|
|
8344
6879
|
const original = originalContentRef.current ?? "";
|
|
8345
6880
|
if (html !== sanitizeHtml(original)) {
|
|
8346
|
-
|
|
6881
|
+
postToParent({ type: "ow:change", nodes: [{ key, text: html }] });
|
|
8347
6882
|
const h = document.documentElement.scrollHeight;
|
|
8348
|
-
if (h > 50)
|
|
6883
|
+
if (h > 50) postToParent({ type: "ow:height", height: h });
|
|
8349
6884
|
}
|
|
8350
6885
|
}
|
|
8351
6886
|
el.removeAttribute("contenteditable");
|
|
@@ -8353,364 +6888,79 @@ function OhhwellsBridge() {
|
|
|
8353
6888
|
setMaxBadge(null);
|
|
8354
6889
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
8355
6890
|
setToolbarShowEditLink(false);
|
|
8356
|
-
|
|
6891
|
+
postToParent({ type: "ow:exit-edit" });
|
|
8357
6892
|
reselectNavigationItem(navAnchor);
|
|
8358
|
-
}, [
|
|
8359
|
-
const
|
|
8360
|
-
const items = listNavbarItems();
|
|
8361
|
-
addNavAfterAnchorRef.current = items[items.length - 1] ?? null;
|
|
8362
|
-
deselectRef.current();
|
|
8363
|
-
deactivateRef.current();
|
|
8364
|
-
bumpLinkPopoverGrace();
|
|
8365
|
-
setLinkPopover({
|
|
8366
|
-
key: "__add-nav__",
|
|
8367
|
-
mode: "create",
|
|
8368
|
-
intent: "add-nav"
|
|
8369
|
-
});
|
|
8370
|
-
}, []);
|
|
8371
|
-
const clearFooterDragVisuals = useCallback4(() => {
|
|
8372
|
-
footerDragRef.current = null;
|
|
8373
|
-
setSiblingHintRects([]);
|
|
8374
|
-
setFooterDropSlots([]);
|
|
8375
|
-
setActiveFooterDropIndex(null);
|
|
8376
|
-
setDraggedItemRect(null);
|
|
8377
|
-
setIsItemDragging(false);
|
|
8378
|
-
unlockFooterDragInteraction();
|
|
8379
|
-
}, []);
|
|
8380
|
-
const refreshFooterDragVisuals = useCallback4((session, activeSlot, clientX, clientY) => {
|
|
8381
|
-
const dragged = session.draggedEl;
|
|
8382
|
-
setDraggedItemRect(dragged.getBoundingClientRect());
|
|
8383
|
-
if (typeof clientX === "number" && typeof clientY === "number") {
|
|
8384
|
-
session.lastClientX = clientX;
|
|
8385
|
-
session.lastClientY = clientY;
|
|
8386
|
-
}
|
|
8387
|
-
session.activeSlot = activeSlot;
|
|
8388
|
-
if (session.kind === "link") {
|
|
8389
|
-
const columns2 = listFooterColumns();
|
|
8390
|
-
const focusCols = /* @__PURE__ */ new Set([session.sourceColumnIndex]);
|
|
8391
|
-
if (activeSlot) focusCols.add(activeSlot.columnIndex);
|
|
8392
|
-
const siblingRects = [];
|
|
8393
|
-
columns2.forEach((col, i) => {
|
|
8394
|
-
if (!focusCols.has(i)) return;
|
|
8395
|
-
for (const link of listFooterLinksInColumn(col)) {
|
|
8396
|
-
if (link === dragged) continue;
|
|
8397
|
-
siblingRects.push(link.getBoundingClientRect());
|
|
8398
|
-
}
|
|
8399
|
-
});
|
|
8400
|
-
setSiblingHintRects(siblingRects);
|
|
8401
|
-
const slots2 = [];
|
|
8402
|
-
columns2.forEach((col, i) => {
|
|
8403
|
-
slots2.push(...buildLinkDropSlots(col, i));
|
|
8404
|
-
});
|
|
8405
|
-
setFooterDropSlots(slots2);
|
|
8406
|
-
const activeIdx2 = activeSlot ? slots2.findIndex((s) => s.columnIndex === activeSlot.columnIndex && s.insertIndex === activeSlot.insertIndex) : -1;
|
|
8407
|
-
setActiveFooterDropIndex(activeIdx2 >= 0 ? activeIdx2 : null);
|
|
8408
|
-
return;
|
|
8409
|
-
}
|
|
8410
|
-
const columns = listFooterColumns();
|
|
8411
|
-
setSiblingHintRects(columns.filter((col) => col !== dragged).map((col) => col.getBoundingClientRect()));
|
|
8412
|
-
const slots = buildColumnDropSlots();
|
|
8413
|
-
setFooterDropSlots(slots);
|
|
8414
|
-
const activeIdx = activeSlot ? slots.findIndex((s) => s.insertIndex === activeSlot.insertIndex) : -1;
|
|
8415
|
-
setActiveFooterDropIndex(activeIdx >= 0 ? activeIdx : null);
|
|
8416
|
-
}, []);
|
|
8417
|
-
const refreshFooterDragVisualsRef = useRef5(refreshFooterDragVisuals);
|
|
8418
|
-
refreshFooterDragVisualsRef.current = refreshFooterDragVisuals;
|
|
8419
|
-
const commitFooterDragRef = useRef5(() => {
|
|
8420
|
-
});
|
|
8421
|
-
const beginFooterDragRef = useRef5(() => {
|
|
8422
|
-
});
|
|
8423
|
-
const beginFooterDrag = useCallback4(
|
|
8424
|
-
(session) => {
|
|
8425
|
-
const rect = session.draggedEl.getBoundingClientRect();
|
|
8426
|
-
session.lastClientX = session.lastClientX || rect.left + rect.width / 2;
|
|
8427
|
-
session.lastClientY = session.lastClientY || rect.top + rect.height / 2;
|
|
8428
|
-
session.activeSlot = session.activeSlot ?? null;
|
|
8429
|
-
footerDragRef.current = session;
|
|
8430
|
-
setIsItemDragging(true);
|
|
8431
|
-
lockFooterDuringDrag();
|
|
8432
|
-
siblingHintElRef.current = null;
|
|
8433
|
-
setSiblingHintRect(null);
|
|
8434
|
-
if (session.wasSelected && selectedElRef.current === session.draggedEl) {
|
|
8435
|
-
setToolbarRect(rect);
|
|
8436
|
-
}
|
|
8437
|
-
const initialSlot = session.kind === "link" && session.hrefKey ? hitTestLinkDropSlot(session.lastClientX, session.lastClientY, session.hrefKey) : hitTestColumnDropSlot(session.lastClientX, session.lastClientY);
|
|
8438
|
-
refreshFooterDragVisuals(session, initialSlot, session.lastClientX, session.lastClientY);
|
|
8439
|
-
},
|
|
8440
|
-
[refreshFooterDragVisuals]
|
|
8441
|
-
);
|
|
8442
|
-
beginFooterDragRef.current = beginFooterDrag;
|
|
8443
|
-
const commitFooterDrag = useCallback4(
|
|
8444
|
-
(clientX, clientY) => {
|
|
8445
|
-
const session = footerDragRef.current;
|
|
8446
|
-
if (!session) {
|
|
8447
|
-
clearFooterDragVisuals();
|
|
8448
|
-
return;
|
|
8449
|
-
}
|
|
8450
|
-
const x = typeof clientX === "number" && (clientX !== 0 || clientY !== 0) ? clientX : session.lastClientX;
|
|
8451
|
-
const y = typeof clientY === "number" && (clientX !== 0 || clientY !== 0) ? clientY : session.lastClientY;
|
|
8452
|
-
let nextOrder = null;
|
|
8453
|
-
const slot = session.activeSlot ?? (session.kind === "link" && session.hrefKey ? hitTestLinkDropSlot(x, y, session.hrefKey) : session.kind === "column" ? hitTestColumnDropSlot(x, y) : null);
|
|
8454
|
-
if (session.kind === "link" && session.hrefKey && slot) {
|
|
8455
|
-
nextOrder = planFooterLinkMove(session.hrefKey, slot.columnIndex, slot.insertIndex);
|
|
8456
|
-
} else if (session.kind === "column" && slot) {
|
|
8457
|
-
nextOrder = planFooterColumnMove(session.sourceColumnIndex, slot.insertIndex);
|
|
8458
|
-
}
|
|
8459
|
-
const wasSelected = session.wasSelected;
|
|
8460
|
-
const draggedEl = session.draggedEl;
|
|
8461
|
-
const hrefKey = session.hrefKey;
|
|
8462
|
-
let movedColumnIndex = null;
|
|
8463
|
-
if (session.kind === "column" && slot && nextOrder) {
|
|
8464
|
-
let adjusted = slot.insertIndex;
|
|
8465
|
-
if (session.sourceColumnIndex < slot.insertIndex) adjusted -= 1;
|
|
8466
|
-
movedColumnIndex = Math.max(0, Math.min(adjusted, nextOrder.length - 1));
|
|
8467
|
-
}
|
|
8468
|
-
clearFooterDragVisuals();
|
|
8469
|
-
if (nextOrder) {
|
|
8470
|
-
const orderJson = JSON.stringify(nextOrder);
|
|
8471
|
-
editContentRef.current = {
|
|
8472
|
-
...editContentRef.current,
|
|
8473
|
-
[FOOTER_ORDER_KEY]: orderJson
|
|
8474
|
-
};
|
|
8475
|
-
applyFooterOrder(nextOrder);
|
|
8476
|
-
document.querySelectorAll("footer [data-ohw-href-key]").forEach(disableNativeHrefDrag);
|
|
8477
|
-
requestAnimationFrame(() => {
|
|
8478
|
-
if (editContentRef.current[FOOTER_ORDER_KEY] === orderJson) {
|
|
8479
|
-
applyFooterOrder(nextOrder);
|
|
8480
|
-
document.querySelectorAll("footer [data-ohw-href-key]").forEach(disableNativeHrefDrag);
|
|
8481
|
-
}
|
|
8482
|
-
});
|
|
8483
|
-
postToParentRef.current({
|
|
8484
|
-
type: "ow:change",
|
|
8485
|
-
nodes: [{ key: FOOTER_ORDER_KEY, text: orderJson }]
|
|
8486
|
-
});
|
|
8487
|
-
}
|
|
8488
|
-
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);
|
|
8489
|
-
if (still && isNavigationItem(still)) {
|
|
8490
|
-
selectRef.current(still);
|
|
8491
|
-
} else if (still && isNavigationContainer(still)) {
|
|
8492
|
-
selectFrameRef.current(still);
|
|
8493
|
-
} else if (wasSelected) {
|
|
8494
|
-
deselectRef.current();
|
|
8495
|
-
}
|
|
8496
|
-
},
|
|
8497
|
-
[clearFooterDragVisuals]
|
|
8498
|
-
);
|
|
8499
|
-
commitFooterDragRef.current = commitFooterDrag;
|
|
8500
|
-
const startFooterLinkDrag = useCallback4(
|
|
8501
|
-
(anchor, clientX, clientY, wasSelected) => {
|
|
8502
|
-
const hrefKey = anchor.getAttribute("data-ohw-href-key");
|
|
8503
|
-
if (!hrefKey || !isFooterHrefKey(hrefKey)) return false;
|
|
8504
|
-
const column = findFooterColumnForLink(anchor);
|
|
8505
|
-
const columns = listFooterColumns();
|
|
8506
|
-
beginFooterDrag({
|
|
8507
|
-
kind: "link",
|
|
8508
|
-
hrefKey,
|
|
8509
|
-
columnEl: column,
|
|
8510
|
-
sourceColumnIndex: column ? columns.indexOf(column) : 0,
|
|
8511
|
-
wasSelected,
|
|
8512
|
-
draggedEl: anchor,
|
|
8513
|
-
lastClientX: clientX,
|
|
8514
|
-
lastClientY: clientY,
|
|
8515
|
-
activeSlot: null
|
|
8516
|
-
});
|
|
8517
|
-
return true;
|
|
8518
|
-
},
|
|
8519
|
-
[beginFooterDrag]
|
|
8520
|
-
);
|
|
8521
|
-
const startFooterColumnDrag = useCallback4(
|
|
8522
|
-
(columnEl, clientX, clientY, wasSelected) => {
|
|
8523
|
-
const columns = listFooterColumns();
|
|
8524
|
-
const idx = columns.indexOf(columnEl);
|
|
8525
|
-
if (idx < 0) return false;
|
|
8526
|
-
beginFooterDrag({
|
|
8527
|
-
kind: "column",
|
|
8528
|
-
hrefKey: null,
|
|
8529
|
-
columnEl,
|
|
8530
|
-
sourceColumnIndex: idx,
|
|
8531
|
-
wasSelected,
|
|
8532
|
-
draggedEl: columnEl,
|
|
8533
|
-
lastClientX: clientX,
|
|
8534
|
-
lastClientY: clientY,
|
|
8535
|
-
activeSlot: null
|
|
8536
|
-
});
|
|
8537
|
-
return true;
|
|
8538
|
-
},
|
|
8539
|
-
[beginFooterDrag]
|
|
8540
|
-
);
|
|
8541
|
-
const handleItemDragStart = useCallback4(
|
|
8542
|
-
(e) => {
|
|
8543
|
-
const selected = selectedElRef.current;
|
|
8544
|
-
if (!selected) {
|
|
8545
|
-
setIsItemDragging(true);
|
|
8546
|
-
return;
|
|
8547
|
-
}
|
|
8548
|
-
const clientX = e?.clientX ?? selected.getBoundingClientRect().left + 8;
|
|
8549
|
-
const clientY = e?.clientY ?? selected.getBoundingClientRect().top + 8;
|
|
8550
|
-
if (startFooterLinkDrag(selected, clientX, clientY, true)) return;
|
|
8551
|
-
if (selected.hasAttribute("data-ohw-footer-col") || isInferredFooterGroup(selected) && selected.closest("footer")) {
|
|
8552
|
-
if (startFooterColumnDrag(selected, clientX, clientY, true)) return;
|
|
8553
|
-
}
|
|
8554
|
-
siblingHintElRef.current = null;
|
|
8555
|
-
setSiblingHintRect(null);
|
|
8556
|
-
setIsItemDragging(true);
|
|
8557
|
-
},
|
|
8558
|
-
[startFooterColumnDrag, startFooterLinkDrag]
|
|
8559
|
-
);
|
|
8560
|
-
const handleItemDragEnd = useCallback4(
|
|
8561
|
-
(e) => {
|
|
8562
|
-
if (footerDragRef.current) {
|
|
8563
|
-
const x = e?.clientX;
|
|
8564
|
-
const y = e?.clientY;
|
|
8565
|
-
if (typeof x === "number" && typeof y === "number" && (x !== 0 || y !== 0)) {
|
|
8566
|
-
commitFooterDrag(x, y);
|
|
8567
|
-
} else {
|
|
8568
|
-
commitFooterDrag();
|
|
8569
|
-
}
|
|
8570
|
-
return;
|
|
8571
|
-
}
|
|
8572
|
-
setIsItemDragging(false);
|
|
8573
|
-
},
|
|
8574
|
-
[commitFooterDrag]
|
|
8575
|
-
);
|
|
8576
|
-
const handleItemChromePointerDown = useCallback4((e) => {
|
|
8577
|
-
if (e.button !== 0) return;
|
|
6893
|
+
}, [postToParent, reselectNavigationItem]);
|
|
6894
|
+
const handleAddNavigationItem = useCallback2(() => {
|
|
8578
6895
|
const selected = selectedElRef.current;
|
|
8579
6896
|
if (!selected) return;
|
|
8580
|
-
|
|
8581
|
-
|
|
8582
|
-
|
|
8583
|
-
footerPointerDragRef.current = {
|
|
8584
|
-
el: selected,
|
|
8585
|
-
kind: "link",
|
|
8586
|
-
startX: e.clientX,
|
|
8587
|
-
startY: e.clientY,
|
|
8588
|
-
pointerId: e.pointerId,
|
|
8589
|
-
wasSelected: true,
|
|
8590
|
-
started: false
|
|
8591
|
-
};
|
|
8592
|
-
return;
|
|
8593
|
-
}
|
|
8594
|
-
if (selected.hasAttribute("data-ohw-footer-col") || isInferredFooterGroup(selected) && selected.closest("footer")) {
|
|
8595
|
-
footerPointerDragRef.current = {
|
|
8596
|
-
el: selected,
|
|
8597
|
-
kind: "column",
|
|
8598
|
-
startX: e.clientX,
|
|
8599
|
-
startY: e.clientY,
|
|
8600
|
-
pointerId: e.pointerId,
|
|
8601
|
-
wasSelected: true,
|
|
8602
|
-
started: false
|
|
8603
|
-
};
|
|
8604
|
-
}
|
|
6897
|
+
const target = getNavigationItemAddHintTarget(selected);
|
|
6898
|
+
siblingHintElRef.current = target;
|
|
6899
|
+
setSiblingHintRect(target.getBoundingClientRect());
|
|
8605
6900
|
}, []);
|
|
8606
|
-
const
|
|
8607
|
-
|
|
8608
|
-
|
|
8609
|
-
|
|
8610
|
-
|
|
8611
|
-
|
|
8612
|
-
|
|
8613
|
-
const editable = selected.querySelector('[data-ohw-editable="text"]') ?? selected.querySelector("[data-ohw-editable]");
|
|
8614
|
-
if (!editable) return;
|
|
8615
|
-
activateRef.current(editable, { caretX: clientX, caretY: clientY });
|
|
6901
|
+
const handleItemDragStart = useCallback2(() => {
|
|
6902
|
+
siblingHintElRef.current = null;
|
|
6903
|
+
setSiblingHintRect(null);
|
|
6904
|
+
setIsItemDragging(true);
|
|
6905
|
+
}, []);
|
|
6906
|
+
const handleItemDragEnd = useCallback2(() => {
|
|
6907
|
+
setIsItemDragging(false);
|
|
8616
6908
|
}, []);
|
|
8617
6909
|
reselectNavigationItemRef.current = reselectNavigationItem;
|
|
8618
6910
|
commitNavigationTextEditRef.current = commitNavigationTextEdit;
|
|
8619
|
-
const select =
|
|
8620
|
-
(anchor)
|
|
8621
|
-
|
|
8622
|
-
|
|
8623
|
-
|
|
8624
|
-
|
|
8625
|
-
|
|
8626
|
-
|
|
8627
|
-
|
|
8628
|
-
|
|
8629
|
-
|
|
8630
|
-
|
|
8631
|
-
|
|
8632
|
-
|
|
8633
|
-
|
|
8634
|
-
|
|
8635
|
-
|
|
8636
|
-
|
|
8637
|
-
|
|
8638
|
-
|
|
8639
|
-
|
|
8640
|
-
|
|
8641
|
-
|
|
8642
|
-
|
|
8643
|
-
|
|
8644
|
-
|
|
8645
|
-
(
|
|
8646
|
-
|
|
8647
|
-
|
|
8648
|
-
|
|
8649
|
-
|
|
8650
|
-
|
|
8651
|
-
|
|
8652
|
-
|
|
8653
|
-
|
|
8654
|
-
|
|
8655
|
-
|
|
8656
|
-
|
|
8657
|
-
|
|
8658
|
-
isFooterColumn ? listFooterColumns().filter((column) => column !== el).map((column) => column.getBoundingClientRect()) : []
|
|
8659
|
-
);
|
|
8660
|
-
setIsItemDragging(false);
|
|
6911
|
+
const select = useCallback2((anchor) => {
|
|
6912
|
+
if (!isNavigationItem(anchor)) return;
|
|
6913
|
+
if (activeElRef.current) deactivate();
|
|
6914
|
+
selectedElRef.current = anchor;
|
|
6915
|
+
clearHrefKeyHover(anchor);
|
|
6916
|
+
setHoveredItemRect(null);
|
|
6917
|
+
hoveredItemElRef.current = null;
|
|
6918
|
+
siblingHintElRef.current = null;
|
|
6919
|
+
setSiblingHintRect(null);
|
|
6920
|
+
setIsItemDragging(false);
|
|
6921
|
+
const { key, disabled } = getNavigationItemReorderState(anchor);
|
|
6922
|
+
setReorderHrefKey(key);
|
|
6923
|
+
setReorderDragDisabled(disabled);
|
|
6924
|
+
setToolbarVariant("link-action");
|
|
6925
|
+
setToolbarRect(anchor.getBoundingClientRect());
|
|
6926
|
+
setToolbarShowEditLink(false);
|
|
6927
|
+
setActiveCommands(/* @__PURE__ */ new Set());
|
|
6928
|
+
}, [deactivate]);
|
|
6929
|
+
const activate = useCallback2((el) => {
|
|
6930
|
+
if (activeElRef.current === el) return;
|
|
6931
|
+
selectedElRef.current = null;
|
|
6932
|
+
deactivate();
|
|
6933
|
+
if (hoveredImageRef.current) {
|
|
6934
|
+
hoveredImageRef.current = null;
|
|
6935
|
+
setMediaHover(null);
|
|
6936
|
+
}
|
|
6937
|
+
setToolbarVariant("rich-text");
|
|
6938
|
+
siblingHintElRef.current = null;
|
|
6939
|
+
setSiblingHintRect(null);
|
|
6940
|
+
setIsItemDragging(false);
|
|
6941
|
+
el.setAttribute("contenteditable", "true");
|
|
6942
|
+
el.removeAttribute("data-ohw-hovered");
|
|
6943
|
+
el.closest("[data-ohw-href-key]")?.removeAttribute("data-ohw-hovered");
|
|
6944
|
+
activeElRef.current = el;
|
|
6945
|
+
originalContentRef.current = el.innerHTML;
|
|
6946
|
+
el.focus();
|
|
6947
|
+
setToolbarShowEditLink(Boolean(getHrefKeyFromElement(el)));
|
|
6948
|
+
const navAnchor = getNavigationItemAnchor(el);
|
|
6949
|
+
if (navAnchor) {
|
|
8661
6950
|
setReorderHrefKey(null);
|
|
8662
6951
|
setReorderDragDisabled(false);
|
|
8663
|
-
|
|
8664
|
-
|
|
8665
|
-
|
|
8666
|
-
|
|
8667
|
-
|
|
8668
|
-
|
|
8669
|
-
|
|
8670
|
-
|
|
8671
|
-
|
|
8672
|
-
(el, options) => {
|
|
8673
|
-
if (activeElRef.current === el) return;
|
|
8674
|
-
selectedElRef.current = null;
|
|
8675
|
-
deactivate();
|
|
8676
|
-
if (hoveredImageRef.current) {
|
|
8677
|
-
hoveredImageRef.current = null;
|
|
8678
|
-
postToParentRef.current({ type: "ow:image-unhover" });
|
|
8679
|
-
}
|
|
8680
|
-
setToolbarVariant("rich-text");
|
|
8681
|
-
siblingHintElRef.current = null;
|
|
8682
|
-
setSiblingHintRect(null);
|
|
8683
|
-
setSiblingHintRects([]);
|
|
8684
|
-
setIsItemDragging(false);
|
|
8685
|
-
el.setAttribute("contenteditable", "true");
|
|
8686
|
-
el.removeAttribute("data-ohw-hovered");
|
|
8687
|
-
el.closest("[data-ohw-href-key]")?.removeAttribute("data-ohw-hovered");
|
|
8688
|
-
activeElRef.current = el;
|
|
8689
|
-
originalContentRef.current = el.innerHTML;
|
|
8690
|
-
el.focus();
|
|
8691
|
-
if (options?.caretX !== void 0 && options?.caretY !== void 0) {
|
|
8692
|
-
placeCaretAtPoint(el, options.caretX, options.caretY);
|
|
8693
|
-
}
|
|
8694
|
-
setToolbarShowEditLink(Boolean(getHrefKeyFromElement(el)));
|
|
8695
|
-
const navAnchor = getNavigationItemAnchor(el);
|
|
8696
|
-
if (navAnchor) {
|
|
8697
|
-
setReorderHrefKey(null);
|
|
8698
|
-
setReorderDragDisabled(false);
|
|
8699
|
-
} else {
|
|
8700
|
-
const { key: reorderKey, disabled: reorderDisabled } = getReorderHandleState(el);
|
|
8701
|
-
setReorderHrefKey(reorderKey);
|
|
8702
|
-
setReorderDragDisabled(reorderDisabled);
|
|
8703
|
-
}
|
|
8704
|
-
setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
|
|
8705
|
-
postToParent2({ type: "ow:enter-edit", key: el.dataset.ohwKey });
|
|
8706
|
-
requestAnimationFrame(() => refreshActiveCommandsRef.current());
|
|
8707
|
-
},
|
|
8708
|
-
[deactivate, postToParent2]
|
|
8709
|
-
);
|
|
6952
|
+
} else {
|
|
6953
|
+
const { key: reorderKey, disabled: reorderDisabled } = getReorderHandleState(el);
|
|
6954
|
+
setReorderHrefKey(reorderKey);
|
|
6955
|
+
setReorderDragDisabled(reorderDisabled);
|
|
6956
|
+
}
|
|
6957
|
+
setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
|
|
6958
|
+
postToParent({ type: "ow:enter-edit", key: el.dataset.ohwKey });
|
|
6959
|
+
requestAnimationFrame(() => refreshActiveCommandsRef.current());
|
|
6960
|
+
}, [deactivate, postToParent]);
|
|
8710
6961
|
activateRef.current = activate;
|
|
8711
6962
|
deactivateRef.current = deactivate;
|
|
8712
6963
|
selectRef.current = select;
|
|
8713
|
-
selectFrameRef.current = selectFrame;
|
|
8714
6964
|
deselectRef.current = deselect;
|
|
8715
6965
|
useLayoutEffect2(() => {
|
|
8716
6966
|
if (!subdomain || isEditMode) {
|
|
@@ -8722,7 +6972,6 @@ function OhhwellsBridge() {
|
|
|
8722
6972
|
for (const [key, val] of Object.entries(content)) {
|
|
8723
6973
|
if (key === "__ohw_sections") continue;
|
|
8724
6974
|
if (applyVideoSettingNode(key, val)) continue;
|
|
8725
|
-
if (applyCarouselNode(key, val)) continue;
|
|
8726
6975
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
8727
6976
|
if (el.dataset.ohwEditable === "image") {
|
|
8728
6977
|
const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
|
|
@@ -8753,8 +7002,6 @@ function OhhwellsBridge() {
|
|
|
8753
7002
|
});
|
|
8754
7003
|
applyLinkByKey(key, val);
|
|
8755
7004
|
}
|
|
8756
|
-
reconcileNavbarItemsFromContent(content);
|
|
8757
|
-
reconcileFooterOrderFromContent(content);
|
|
8758
7005
|
enforceLinkHrefs();
|
|
8759
7006
|
initSectionsFromContent(content, true);
|
|
8760
7007
|
sectionsLoadedRef.current = true;
|
|
@@ -8783,7 +7030,7 @@ function OhhwellsBridge() {
|
|
|
8783
7030
|
cancelled = true;
|
|
8784
7031
|
};
|
|
8785
7032
|
}, [subdomain, isEditMode]);
|
|
8786
|
-
|
|
7033
|
+
useEffect4(() => {
|
|
8787
7034
|
if (!subdomain || isEditMode) return;
|
|
8788
7035
|
let debounceTimer = null;
|
|
8789
7036
|
let observer = null;
|
|
@@ -8796,7 +7043,6 @@ function OhhwellsBridge() {
|
|
|
8796
7043
|
for (const [key, val] of Object.entries(content)) {
|
|
8797
7044
|
if (key === "__ohw_sections") continue;
|
|
8798
7045
|
if (applyVideoSettingNode(key, val)) continue;
|
|
8799
|
-
if (applyCarouselNode(key, val)) continue;
|
|
8800
7046
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
8801
7047
|
if (el.dataset.ohwEditable === "image") {
|
|
8802
7048
|
const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
|
|
@@ -8815,8 +7061,6 @@ function OhhwellsBridge() {
|
|
|
8815
7061
|
});
|
|
8816
7062
|
applyLinkByKey(key, val);
|
|
8817
7063
|
}
|
|
8818
|
-
reconcileNavbarItemsFromContent(content);
|
|
8819
|
-
reconcileFooterOrderFromContent(content);
|
|
8820
7064
|
} finally {
|
|
8821
7065
|
observer?.observe(document.body, { childList: true, subtree: true });
|
|
8822
7066
|
}
|
|
@@ -8840,65 +7084,20 @@ function OhhwellsBridge() {
|
|
|
8840
7084
|
const visible = Boolean(subdomain) && fetchState !== "done";
|
|
8841
7085
|
el.style.display = visible ? "flex" : "none";
|
|
8842
7086
|
}, [subdomain, fetchState]);
|
|
8843
|
-
|
|
8844
|
-
|
|
8845
|
-
}, [pathname,
|
|
8846
|
-
|
|
7087
|
+
useEffect4(() => {
|
|
7088
|
+
postToParent({ type: "ow:navigation", path: pathname });
|
|
7089
|
+
}, [pathname, postToParent]);
|
|
7090
|
+
useEffect4(() => {
|
|
8847
7091
|
if (!isEditMode) return;
|
|
8848
|
-
if (linkPopoverSessionRef.current?.intent === "add-nav") return;
|
|
8849
|
-
if (document.querySelector("[data-ohw-section-picker]")) return;
|
|
8850
7092
|
setLinkPopover(null);
|
|
8851
7093
|
deselectRef.current();
|
|
8852
7094
|
deactivateRef.current();
|
|
8853
7095
|
}, [pathname, isEditMode]);
|
|
8854
|
-
|
|
8855
|
-
const contentForNav = () => {
|
|
8856
|
-
if (isEditMode) return editContentRef.current;
|
|
8857
|
-
if (!subdomain) return {};
|
|
8858
|
-
return contentCache.get(subdomain) ?? {};
|
|
8859
|
-
};
|
|
8860
|
-
let applying = false;
|
|
8861
|
-
let rafId = null;
|
|
8862
|
-
const run = () => {
|
|
8863
|
-
if (footerDragRef.current || applying) return;
|
|
8864
|
-
applying = true;
|
|
8865
|
-
try {
|
|
8866
|
-
const content = contentForNav();
|
|
8867
|
-
reconcileNavbarItemsFromContent(content);
|
|
8868
|
-
reconcileFooterOrderFromContent(content);
|
|
8869
|
-
document.querySelectorAll("footer [data-ohw-href-key]").forEach((el) => {
|
|
8870
|
-
if (isFooterHrefKey(el.getAttribute("data-ohw-href-key"))) {
|
|
8871
|
-
disableNativeHrefDrag(el);
|
|
8872
|
-
}
|
|
8873
|
-
});
|
|
8874
|
-
} finally {
|
|
8875
|
-
applying = false;
|
|
8876
|
-
}
|
|
8877
|
-
};
|
|
8878
|
-
const scheduleRun = () => {
|
|
8879
|
-
if (rafId !== null) cancelAnimationFrame(rafId);
|
|
8880
|
-
rafId = requestAnimationFrame(() => {
|
|
8881
|
-
rafId = null;
|
|
8882
|
-
run();
|
|
8883
|
-
});
|
|
8884
|
-
};
|
|
8885
|
-
run();
|
|
8886
|
-
const nav = document.querySelector("nav");
|
|
8887
|
-
const footer = document.querySelector("footer");
|
|
8888
|
-
const observer = new MutationObserver(scheduleRun);
|
|
8889
|
-
if (nav) observer.observe(nav, { childList: true, subtree: true });
|
|
8890
|
-
if (footer) observer.observe(footer, { childList: true, subtree: true });
|
|
8891
|
-
if (!nav && !footer) return;
|
|
8892
|
-
return () => {
|
|
8893
|
-
observer.disconnect();
|
|
8894
|
-
if (rafId !== null) cancelAnimationFrame(rafId);
|
|
8895
|
-
};
|
|
8896
|
-
}, [isEditMode, pathname, subdomain, fetchState]);
|
|
8897
|
-
useEffect8(() => {
|
|
7096
|
+
useEffect4(() => {
|
|
8898
7097
|
if (!isEditMode) return;
|
|
8899
7098
|
const measure = () => {
|
|
8900
7099
|
const h = document.body.scrollHeight;
|
|
8901
|
-
if (h > 50)
|
|
7100
|
+
if (h > 50) postToParent({ type: "ow:height", height: h });
|
|
8902
7101
|
};
|
|
8903
7102
|
const t1 = setTimeout(measure, 50);
|
|
8904
7103
|
const t2 = setTimeout(measure, 500);
|
|
@@ -8917,8 +7116,8 @@ function OhhwellsBridge() {
|
|
|
8917
7116
|
if (resizeTimer) clearTimeout(resizeTimer);
|
|
8918
7117
|
window.removeEventListener("resize", handleResize);
|
|
8919
7118
|
};
|
|
8920
|
-
}, [pathname, isEditMode,
|
|
8921
|
-
|
|
7119
|
+
}, [pathname, isEditMode, postToParent]);
|
|
7120
|
+
useEffect4(() => {
|
|
8922
7121
|
if (!subdomainFromQuery || isEditMode) return;
|
|
8923
7122
|
const handleClick = (e) => {
|
|
8924
7123
|
const anchor = e.target.closest("a");
|
|
@@ -8934,7 +7133,7 @@ function OhhwellsBridge() {
|
|
|
8934
7133
|
document.addEventListener("click", handleClick, true);
|
|
8935
7134
|
return () => document.removeEventListener("click", handleClick, true);
|
|
8936
7135
|
}, [subdomainFromQuery, isEditMode, router]);
|
|
8937
|
-
|
|
7136
|
+
useEffect4(() => {
|
|
8938
7137
|
if (!isEditMode) {
|
|
8939
7138
|
editStylesRef.current?.base.remove();
|
|
8940
7139
|
editStylesRef.current?.forceHover.remove();
|
|
@@ -8957,29 +7156,6 @@ function OhhwellsBridge() {
|
|
|
8957
7156
|
[data-ohw-editable] {
|
|
8958
7157
|
display: block;
|
|
8959
7158
|
}
|
|
8960
|
-
/* Native <a> drag steals clicks \u2014 disable for edit links; reorder via press-to-drag / handle. */
|
|
8961
|
-
footer [data-ohw-href-key] {
|
|
8962
|
-
-webkit-user-drag: none !important;
|
|
8963
|
-
}
|
|
8964
|
-
footer [data-ohw-footer-col]:hover {
|
|
8965
|
-
outline: 1.5px dashed ${PRIMARY2} !important;
|
|
8966
|
-
outline-offset: 6px;
|
|
8967
|
-
border-radius: 8px;
|
|
8968
|
-
}
|
|
8969
|
-
html[data-ohw-footer-press-drag] footer,
|
|
8970
|
-
html[data-ohw-footer-press-drag] footer * {
|
|
8971
|
-
user-select: none !important;
|
|
8972
|
-
-webkit-user-select: none !important;
|
|
8973
|
-
}
|
|
8974
|
-
html[data-ohw-item-dragging] footer,
|
|
8975
|
-
html[data-ohw-item-dragging] footer * {
|
|
8976
|
-
user-select: none !important;
|
|
8977
|
-
-webkit-user-select: none !important;
|
|
8978
|
-
pointer-events: none !important;
|
|
8979
|
-
}
|
|
8980
|
-
html[data-ohw-item-dragging] {
|
|
8981
|
-
cursor: grabbing !important;
|
|
8982
|
-
}
|
|
8983
7159
|
[data-ohw-editable]:not([contenteditable]):not([data-ohw-editable="image"]):not([data-ohw-editable="bg-image"]):not([data-ohw-editable="video"]) { cursor: text !important; }
|
|
8984
7160
|
[data-ohw-editable="image"], [data-ohw-editable="image"] *,
|
|
8985
7161
|
[data-ohw-editable="video"], [data-ohw-editable="video"] *,
|
|
@@ -8988,7 +7164,6 @@ function OhhwellsBridge() {
|
|
|
8988
7164
|
[data-ohw-hovered]:not([contenteditable]):not([data-ohw-href-key]) {
|
|
8989
7165
|
outline: 2px dashed ${PRIMARY2} !important;
|
|
8990
7166
|
outline-offset: 4px;
|
|
8991
|
-
border-radius: 2px;
|
|
8992
7167
|
}
|
|
8993
7168
|
[data-ohw-href-key] [data-ohw-hovered],
|
|
8994
7169
|
[data-ohw-href-key][data-ohw-hovered],
|
|
@@ -9015,7 +7190,7 @@ function OhhwellsBridge() {
|
|
|
9015
7190
|
stateViews.textContent = `
|
|
9016
7191
|
[data-ohw-state-view]:not([data-ohw-state-view="default"]) { display: none; }
|
|
9017
7192
|
[data-ohw-state-view="default"] [data-ohw-editable] { pointer-events: auto !important; }
|
|
9018
|
-
[data-ohw-state-hovered] { outline: 2px dashed ${PRIMARY2} !important; outline-offset: 4px;
|
|
7193
|
+
[data-ohw-state-hovered] { outline: 2px dashed ${PRIMARY2} !important; outline-offset: 4px; }
|
|
9019
7194
|
[data-ohw-state-hovered]:has([data-ohw-hovered]) { outline: none !important; }
|
|
9020
7195
|
`;
|
|
9021
7196
|
document.head.appendChild(base);
|
|
@@ -9025,46 +7200,12 @@ function OhhwellsBridge() {
|
|
|
9025
7200
|
}
|
|
9026
7201
|
refreshStateRules();
|
|
9027
7202
|
const handleClick = (e) => {
|
|
9028
|
-
if (suppressNextClickRef.current) {
|
|
9029
|
-
suppressNextClickRef.current = false;
|
|
9030
|
-
e.preventDefault();
|
|
9031
|
-
e.stopPropagation();
|
|
9032
|
-
return;
|
|
9033
|
-
}
|
|
9034
7203
|
const target = e.target;
|
|
9035
7204
|
if (target.closest("[data-ohw-toolbar]")) return;
|
|
9036
7205
|
if (target.closest("[data-ohw-state-toggle]")) return;
|
|
9037
7206
|
if (target.closest("[data-ohw-max-badge]")) return;
|
|
9038
7207
|
if (isInsideLinkEditor(target)) return;
|
|
9039
7208
|
if (target.closest('[data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
|
|
9040
|
-
if (target.closest("[data-ohw-item-drag-surface]")) {
|
|
9041
|
-
e.preventDefault();
|
|
9042
|
-
e.stopPropagation();
|
|
9043
|
-
const selected = selectedElRef.current;
|
|
9044
|
-
if (selected && isNavigationItem(selected)) {
|
|
9045
|
-
const editable2 = selected.querySelector('[data-ohw-editable="text"]') ?? selected.querySelector("[data-ohw-editable]");
|
|
9046
|
-
if (editable2) {
|
|
9047
|
-
activateRef.current(editable2, {
|
|
9048
|
-
caretX: e.clientX,
|
|
9049
|
-
caretY: e.clientY
|
|
9050
|
-
});
|
|
9051
|
-
}
|
|
9052
|
-
} else if (selected?.hasAttribute("data-ohw-footer-col")) {
|
|
9053
|
-
const link = listFooterLinksInColumn(selected).find((el) => {
|
|
9054
|
-
const r2 = el.getBoundingClientRect();
|
|
9055
|
-
return e.clientX >= r2.left && e.clientX <= r2.right && e.clientY >= r2.top && e.clientY <= r2.bottom;
|
|
9056
|
-
});
|
|
9057
|
-
if (link) selectRef.current(link);
|
|
9058
|
-
}
|
|
9059
|
-
return;
|
|
9060
|
-
}
|
|
9061
|
-
const navFromChrome = resolveNavContainerSelectionTarget(target, e.clientX, e.clientY);
|
|
9062
|
-
if (navFromChrome) {
|
|
9063
|
-
e.preventDefault();
|
|
9064
|
-
e.stopPropagation();
|
|
9065
|
-
selectFrameRef.current(navFromChrome);
|
|
9066
|
-
return;
|
|
9067
|
-
}
|
|
9068
7209
|
e.preventDefault();
|
|
9069
7210
|
e.stopPropagation();
|
|
9070
7211
|
return;
|
|
@@ -9079,8 +7220,7 @@ function OhhwellsBridge() {
|
|
|
9079
7220
|
bumpLinkPopoverGrace();
|
|
9080
7221
|
setLinkPopoverRef.current({
|
|
9081
7222
|
key: editable.dataset.ohwKey ?? "",
|
|
9082
|
-
|
|
9083
|
-
target: getLinkHref2(editable)
|
|
7223
|
+
target: getLinkHref(editable)
|
|
9084
7224
|
});
|
|
9085
7225
|
return;
|
|
9086
7226
|
}
|
|
@@ -9096,58 +7236,25 @@ function OhhwellsBridge() {
|
|
|
9096
7236
|
e.preventDefault();
|
|
9097
7237
|
e.stopPropagation();
|
|
9098
7238
|
if (selectedElRef.current === navAnchor) {
|
|
9099
|
-
|
|
9100
|
-
|
|
9101
|
-
return;
|
|
9102
|
-
}
|
|
9103
|
-
selectRef.current(navAnchor);
|
|
9104
|
-
return;
|
|
9105
|
-
}
|
|
9106
|
-
e.preventDefault();
|
|
9107
|
-
e.stopPropagation();
|
|
9108
|
-
activateRef.current(editable);
|
|
9109
|
-
return;
|
|
9110
|
-
}
|
|
9111
|
-
const hrefAnchor = getNavigationItemAnchor(target);
|
|
9112
|
-
if (hrefAnchor) {
|
|
9113
|
-
e.preventDefault();
|
|
9114
|
-
e.stopPropagation();
|
|
9115
|
-
if (selectedElRef.current === hrefAnchor) {
|
|
9116
|
-
const textEditable = hrefAnchor.querySelector('[data-ohw-editable="text"]') ?? hrefAnchor.querySelector("[data-ohw-editable]");
|
|
9117
|
-
if (textEditable) {
|
|
9118
|
-
activateRef.current(textEditable, {
|
|
9119
|
-
caretX: e.clientX,
|
|
9120
|
-
caretY: e.clientY
|
|
9121
|
-
});
|
|
7239
|
+
activateRef.current(editable);
|
|
7240
|
+
return;
|
|
9122
7241
|
}
|
|
7242
|
+
selectRef.current(navAnchor);
|
|
9123
7243
|
return;
|
|
9124
7244
|
}
|
|
9125
|
-
selectRef.current(hrefAnchor);
|
|
9126
|
-
return;
|
|
9127
|
-
}
|
|
9128
|
-
const footerColClick = target.closest("[data-ohw-footer-col]");
|
|
9129
|
-
if (footerColClick) {
|
|
9130
7245
|
e.preventDefault();
|
|
9131
7246
|
e.stopPropagation();
|
|
9132
|
-
|
|
7247
|
+
activateRef.current(editable);
|
|
9133
7248
|
return;
|
|
9134
7249
|
}
|
|
9135
|
-
const
|
|
9136
|
-
if (
|
|
7250
|
+
const hrefAnchor = getNavigationItemAnchor(target);
|
|
7251
|
+
if (hrefAnchor) {
|
|
9137
7252
|
e.preventDefault();
|
|
9138
7253
|
e.stopPropagation();
|
|
9139
|
-
|
|
7254
|
+
if (selectedElRef.current === hrefAnchor) return;
|
|
7255
|
+
selectRef.current(hrefAnchor);
|
|
9140
7256
|
return;
|
|
9141
7257
|
}
|
|
9142
|
-
const selectedContainer = selectedElRef.current;
|
|
9143
|
-
if (selectedContainer && isNavigationContainer(selectedContainer)) {
|
|
9144
|
-
const navItem = getNavigationItemAnchor(target);
|
|
9145
|
-
if (!navItem && (selectedContainer === target || selectedContainer.contains(target))) {
|
|
9146
|
-
e.preventDefault();
|
|
9147
|
-
e.stopPropagation();
|
|
9148
|
-
return;
|
|
9149
|
-
}
|
|
9150
|
-
}
|
|
9151
7258
|
if (activeElRef.current) {
|
|
9152
7259
|
const sel = window.getSelection();
|
|
9153
7260
|
if (sel && !sel.isCollapsed) {
|
|
@@ -9173,58 +7280,10 @@ function OhhwellsBridge() {
|
|
|
9173
7280
|
deselectRef.current();
|
|
9174
7281
|
deactivateRef.current();
|
|
9175
7282
|
};
|
|
9176
|
-
const handleDblClick = (e) => {
|
|
9177
|
-
const target = e.target;
|
|
9178
|
-
if (target.closest("[data-ohw-toolbar]")) return;
|
|
9179
|
-
if (target.closest("[data-ohw-state-toggle]")) return;
|
|
9180
|
-
if (target.closest("[data-ohw-max-badge]")) return;
|
|
9181
|
-
if (isInsideLinkEditor(target)) return;
|
|
9182
|
-
if (target.closest('[data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
|
|
9183
|
-
return;
|
|
9184
|
-
}
|
|
9185
|
-
const navLabel = getNavigationLabelEditable(target);
|
|
9186
|
-
if (!navLabel) return;
|
|
9187
|
-
const { editable } = navLabel;
|
|
9188
|
-
e.preventDefault();
|
|
9189
|
-
e.stopPropagation();
|
|
9190
|
-
if (activeElRef.current !== editable) {
|
|
9191
|
-
activateRef.current(editable);
|
|
9192
|
-
}
|
|
9193
|
-
requestAnimationFrame(() => {
|
|
9194
|
-
selectAllTextInEditable(editable);
|
|
9195
|
-
refreshActiveCommandsRef.current();
|
|
9196
|
-
});
|
|
9197
|
-
};
|
|
9198
7283
|
const handleMouseOver = (e) => {
|
|
9199
|
-
if (document.documentElement.hasAttribute("data-ohw-section-picking")) return;
|
|
9200
7284
|
const target = e.target;
|
|
9201
|
-
if (toolbarVariantRef.current !== "select-frame") {
|
|
9202
|
-
const navContainer = target.closest("[data-ohw-nav-container]");
|
|
9203
|
-
if (navContainer && !getNavigationItemAnchor(target)) {
|
|
9204
|
-
hoveredNavContainerRef.current = navContainer;
|
|
9205
|
-
setHoveredNavContainerRect(navContainer.getBoundingClientRect());
|
|
9206
|
-
hoveredItemElRef.current = null;
|
|
9207
|
-
setHoveredItemRect(null);
|
|
9208
|
-
return;
|
|
9209
|
-
}
|
|
9210
|
-
if (!target.closest("[data-ohw-nav-container]")) {
|
|
9211
|
-
hoveredNavContainerRef.current = null;
|
|
9212
|
-
setHoveredNavContainerRect(null);
|
|
9213
|
-
}
|
|
9214
|
-
}
|
|
9215
|
-
const footerCol = target.closest("[data-ohw-footer-col]");
|
|
9216
|
-
if (footerCol) {
|
|
9217
|
-
hoveredNavContainerRef.current = null;
|
|
9218
|
-
setHoveredNavContainerRect(null);
|
|
9219
|
-
if (selectedElRef.current === footerCol) return;
|
|
9220
|
-
hoveredItemElRef.current = footerCol;
|
|
9221
|
-
setHoveredItemRect(footerCol.getBoundingClientRect());
|
|
9222
|
-
return;
|
|
9223
|
-
}
|
|
9224
7285
|
const navAnchor = getNavigationItemAnchor(target);
|
|
9225
7286
|
if (navAnchor) {
|
|
9226
|
-
hoveredNavContainerRef.current = null;
|
|
9227
|
-
setHoveredNavContainerRect(null);
|
|
9228
7287
|
const selected2 = selectedElRef.current;
|
|
9229
7288
|
if (selected2 === navAnchor || selected2?.contains(navAnchor)) return;
|
|
9230
7289
|
clearHrefKeyHover(navAnchor);
|
|
@@ -9249,23 +7308,6 @@ function OhhwellsBridge() {
|
|
|
9249
7308
|
};
|
|
9250
7309
|
const handleMouseOut = (e) => {
|
|
9251
7310
|
const target = e.target;
|
|
9252
|
-
if (target.closest("[data-ohw-nav-container]")) {
|
|
9253
|
-
const related2 = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
9254
|
-
if (related2?.closest("[data-ohw-nav-container], [data-ohw-navbar-container-chrome], [data-ohw-navbar-add-button]")) {
|
|
9255
|
-
return;
|
|
9256
|
-
}
|
|
9257
|
-
hoveredNavContainerRef.current = null;
|
|
9258
|
-
setHoveredNavContainerRect(null);
|
|
9259
|
-
}
|
|
9260
|
-
const footerCol = target.closest("[data-ohw-footer-col]");
|
|
9261
|
-
if (footerCol && hoveredItemElRef.current === footerCol) {
|
|
9262
|
-
const related2 = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
9263
|
-
if (related2?.closest("[data-ohw-drag-handle-container], [data-ohw-item-interaction]")) return;
|
|
9264
|
-
if (related2?.closest("[data-ohw-footer-col]") === footerCol) return;
|
|
9265
|
-
hoveredItemElRef.current = null;
|
|
9266
|
-
setHoveredItemRect(null);
|
|
9267
|
-
return;
|
|
9268
|
-
}
|
|
9269
7311
|
const navAnchor = getNavigationItemAnchor(target);
|
|
9270
7312
|
if (navAnchor) {
|
|
9271
7313
|
const related2 = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
@@ -9377,97 +7419,69 @@ function OhhwellsBridge() {
|
|
|
9377
7419
|
const stickyPad = 48;
|
|
9378
7420
|
const withinPad = x >= pr.left - stickyPad && x <= pr.left + pr.width + stickyPad && y >= pr.top - stickyPad && y <= pr.top + pr.height + stickyPad;
|
|
9379
7421
|
if (withinPad) {
|
|
9380
|
-
|
|
7422
|
+
if (smallest !== pinned && candidatePool.includes(smallest)) {
|
|
9381
7423
|
const sr = getVisibleRect(smallest);
|
|
9382
|
-
const
|
|
9383
|
-
|
|
9384
|
-
}
|
|
9385
|
-
|
|
7424
|
+
const overOther = x >= sr.left && x <= sr.left + sr.width && y >= sr.top && y <= sr.top + sr.height;
|
|
7425
|
+
if (overOther) return smallest;
|
|
7426
|
+
}
|
|
7427
|
+
return pinned;
|
|
9386
7428
|
}
|
|
9387
7429
|
}
|
|
9388
7430
|
return smallest;
|
|
9389
7431
|
};
|
|
9390
|
-
const dismissImageHover = () => {
|
|
9391
|
-
if (hoveredImageRef.current) {
|
|
9392
|
-
hoveredImageRef.current = null;
|
|
9393
|
-
hoveredImageHasTextOverlapRef.current = false;
|
|
9394
|
-
resumeAnimTracks();
|
|
9395
|
-
postToParentRef.current({ type: "ow:image-unhover" });
|
|
9396
|
-
}
|
|
9397
|
-
clearImageHover();
|
|
9398
|
-
};
|
|
9399
|
-
const probeNavigationHoverAt = (x, y) => {
|
|
9400
|
-
if (toolbarVariantRef.current === "select-frame") {
|
|
9401
|
-
hoveredNavContainerRef.current = null;
|
|
9402
|
-
setHoveredNavContainerRect(null);
|
|
9403
|
-
return;
|
|
9404
|
-
}
|
|
9405
|
-
const navContainer = document.querySelector("[data-ohw-nav-container]");
|
|
9406
|
-
if (!navContainer) {
|
|
9407
|
-
hoveredNavContainerRef.current = null;
|
|
9408
|
-
setHoveredNavContainerRect(null);
|
|
9409
|
-
return;
|
|
9410
|
-
}
|
|
9411
|
-
const containerRect = navContainer.getBoundingClientRect();
|
|
9412
|
-
const overContainer = x >= containerRect.left && x <= containerRect.right && y >= containerRect.top && y <= containerRect.bottom;
|
|
9413
|
-
if (!overContainer) {
|
|
9414
|
-
hoveredNavContainerRef.current = null;
|
|
9415
|
-
setHoveredNavContainerRect(null);
|
|
9416
|
-
return;
|
|
9417
|
-
}
|
|
9418
|
-
const navItemHit = Array.from(
|
|
9419
|
-
navContainer.querySelectorAll("[data-ohw-href-key]")
|
|
9420
|
-
).find((el) => {
|
|
9421
|
-
if (!isNavigationItem(el) || isNavbarButton2(el)) return false;
|
|
9422
|
-
const itemRect = el.getBoundingClientRect();
|
|
9423
|
-
return x >= itemRect.left && x <= itemRect.right && y >= itemRect.top && y <= itemRect.bottom;
|
|
9424
|
-
});
|
|
9425
|
-
if (navItemHit) {
|
|
9426
|
-
hoveredNavContainerRef.current = null;
|
|
9427
|
-
setHoveredNavContainerRect(null);
|
|
9428
|
-
const selected = selectedElRef.current;
|
|
9429
|
-
if (selected !== navItemHit && !selected?.contains(navItemHit)) {
|
|
9430
|
-
clearHrefKeyHover(navItemHit);
|
|
9431
|
-
hoveredItemElRef.current = navItemHit;
|
|
9432
|
-
setHoveredItemRect(navItemHit.getBoundingClientRect());
|
|
9433
|
-
}
|
|
9434
|
-
return;
|
|
9435
|
-
}
|
|
9436
|
-
hoveredNavContainerRef.current = navContainer;
|
|
9437
|
-
setHoveredNavContainerRect(containerRect);
|
|
9438
|
-
hoveredItemElRef.current = null;
|
|
9439
|
-
setHoveredItemRect(null);
|
|
9440
|
-
};
|
|
9441
7432
|
const probeImageAt = (clientX, clientY, isDragOver = false, fromParentViewport = false) => {
|
|
9442
7433
|
if (linkPopoverOpenRef.current) {
|
|
9443
|
-
|
|
9444
|
-
|
|
9445
|
-
|
|
9446
|
-
|
|
9447
|
-
|
|
9448
|
-
|
|
9449
|
-
probeNavigationHoverAt(x, y);
|
|
7434
|
+
if (hoveredImageRef.current) {
|
|
7435
|
+
hoveredImageRef.current = null;
|
|
7436
|
+
hoveredImageHasTextOverlapRef.current = false;
|
|
7437
|
+
resumeAnimTracks();
|
|
7438
|
+
clearImageHover();
|
|
7439
|
+
}
|
|
9450
7440
|
return;
|
|
9451
7441
|
}
|
|
9452
|
-
hoveredNavContainerRef.current = null;
|
|
9453
|
-
setHoveredNavContainerRect(null);
|
|
9454
7442
|
const toggleEl = document.querySelector("[data-ohw-state-toggle]");
|
|
9455
7443
|
if (toggleEl) {
|
|
7444
|
+
const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
9456
7445
|
const tr = toggleEl.getBoundingClientRect();
|
|
9457
7446
|
if (x >= tr.left && x <= tr.right && y >= tr.top && y <= tr.bottom) {
|
|
9458
|
-
|
|
7447
|
+
if (hoveredImageRef.current) {
|
|
7448
|
+
hoveredImageRef.current = null;
|
|
7449
|
+
resumeAnimTracks();
|
|
7450
|
+
clearImageHover();
|
|
7451
|
+
}
|
|
9459
7452
|
return;
|
|
9460
7453
|
}
|
|
9461
7454
|
}
|
|
9462
7455
|
const imgEl = findImageAtPoint(clientX, clientY, fromParentViewport);
|
|
9463
7456
|
const activeEl = activeElRef.current;
|
|
9464
7457
|
if (activeEl && (!imgEl || imgEl.contains(activeEl))) {
|
|
9465
|
-
|
|
7458
|
+
if (hoveredImageRef.current) {
|
|
7459
|
+
hoveredImageRef.current = null;
|
|
7460
|
+
hoveredImageHasTextOverlapRef.current = false;
|
|
7461
|
+
resumeAnimTracks();
|
|
7462
|
+
clearImageHover();
|
|
7463
|
+
}
|
|
9466
7464
|
return;
|
|
9467
7465
|
}
|
|
9468
7466
|
if (imgEl) {
|
|
7467
|
+
const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
7468
|
+
const overMediaChrome = Array.from(
|
|
7469
|
+
document.querySelectorAll("[data-ohw-media-chrome]")
|
|
7470
|
+
).some((el) => {
|
|
7471
|
+
const r2 = el.getBoundingClientRect();
|
|
7472
|
+
return x >= r2.left && x <= r2.right && y >= r2.top && y <= r2.bottom;
|
|
7473
|
+
});
|
|
7474
|
+
if (overMediaChrome) {
|
|
7475
|
+
if (hoveredImageRef.current) {
|
|
7476
|
+
hoveredImageRef.current = null;
|
|
7477
|
+
hoveredImageHasTextOverlapRef.current = false;
|
|
7478
|
+
resumeAnimTracks();
|
|
7479
|
+
clearImageHover();
|
|
7480
|
+
}
|
|
7481
|
+
return;
|
|
7482
|
+
}
|
|
9469
7483
|
const topEl = document.elementFromPoint(x, y);
|
|
9470
|
-
if (topEl?.closest('[data-ohw-toolbar], [data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]
|
|
7484
|
+
if (topEl?.closest('[data-ohw-toolbar], [data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
|
|
9471
7485
|
if (hoveredImageRef.current) {
|
|
9472
7486
|
hoveredImageRef.current = null;
|
|
9473
7487
|
resumeAnimTracks();
|
|
@@ -9565,12 +7579,12 @@ function OhhwellsBridge() {
|
|
|
9565
7579
|
resumeAnimTracks();
|
|
9566
7580
|
clearImageHover();
|
|
9567
7581
|
}
|
|
9568
|
-
const { x
|
|
7582
|
+
const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
9569
7583
|
const textEl = Array.from(
|
|
9570
7584
|
document.querySelectorAll(NON_MEDIA_SELECTOR)
|
|
9571
7585
|
).find((el) => {
|
|
9572
7586
|
const er = el.getBoundingClientRect();
|
|
9573
|
-
return
|
|
7587
|
+
return x >= er.left && x <= er.right && y >= er.top && y <= er.bottom;
|
|
9574
7588
|
});
|
|
9575
7589
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
9576
7590
|
if (textEl && !textEl.hasAttribute("contenteditable")) {
|
|
@@ -9594,14 +7608,6 @@ function OhhwellsBridge() {
|
|
|
9594
7608
|
}
|
|
9595
7609
|
};
|
|
9596
7610
|
const probeHoverCardsAt = (clientX, clientY, fromParentViewport = false) => {
|
|
9597
|
-
if (linkPopoverOpenRef.current || document.documentElement.hasAttribute("data-ohw-section-picking")) {
|
|
9598
|
-
if (activeStateElRef.current) {
|
|
9599
|
-
activeStateElRef.current.removeAttribute("data-ohw-state-hovered");
|
|
9600
|
-
activeStateElRef.current = null;
|
|
9601
|
-
setToggleState(null);
|
|
9602
|
-
}
|
|
9603
|
-
return;
|
|
9604
|
-
}
|
|
9605
7611
|
const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
9606
7612
|
const toggleEl = document.querySelector("[data-ohw-state-toggle]");
|
|
9607
7613
|
if (toggleEl) {
|
|
@@ -9674,14 +7680,6 @@ function OhhwellsBridge() {
|
|
|
9674
7680
|
probeHoverCardsAt(clientX, clientY);
|
|
9675
7681
|
};
|
|
9676
7682
|
const handleDragOver = (e) => {
|
|
9677
|
-
const footerSession = footerDragRef.current;
|
|
9678
|
-
if (footerSession) {
|
|
9679
|
-
e.preventDefault();
|
|
9680
|
-
if (e.dataTransfer) e.dataTransfer.dropEffect = "move";
|
|
9681
|
-
const slot = footerSession.kind === "link" && footerSession.hrefKey ? hitTestLinkDropSlot(e.clientX, e.clientY, footerSession.hrefKey) : hitTestColumnDropSlot(e.clientX, e.clientY);
|
|
9682
|
-
refreshFooterDragVisualsRef.current(footerSession, slot, e.clientX, e.clientY);
|
|
9683
|
-
return;
|
|
9684
|
-
}
|
|
9685
7683
|
e.preventDefault();
|
|
9686
7684
|
const el = findImageAtPoint(e.clientX, e.clientY, false);
|
|
9687
7685
|
if (!el) {
|
|
@@ -9864,7 +7862,6 @@ function OhhwellsBridge() {
|
|
|
9864
7862
|
continue;
|
|
9865
7863
|
}
|
|
9866
7864
|
if (applyVideoSettingNode(key, val)) continue;
|
|
9867
|
-
if (applyCarouselNode(key, val)) continue;
|
|
9868
7865
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
9869
7866
|
if (el.dataset.ohwEditable === "image") {
|
|
9870
7867
|
const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
|
|
@@ -9887,9 +7884,6 @@ function OhhwellsBridge() {
|
|
|
9887
7884
|
sectionsLoadedRef.current = true;
|
|
9888
7885
|
pendingScheduleConfigRequests.current.splice(0).forEach(processConfigRequest);
|
|
9889
7886
|
}
|
|
9890
|
-
editContentRef.current = { ...editContentRef.current, ...content };
|
|
9891
|
-
reconcileNavbarItemsFromContent(editContentRef.current);
|
|
9892
|
-
reconcileFooterOrderFromContent(editContentRef.current);
|
|
9893
7887
|
enforceLinkHrefs();
|
|
9894
7888
|
postToParentRef.current({ type: "ow:hydrate-done" });
|
|
9895
7889
|
};
|
|
@@ -9897,7 +7891,6 @@ function OhhwellsBridge() {
|
|
|
9897
7891
|
const handleDeactivate = (e) => {
|
|
9898
7892
|
if (e.data?.type !== "ow:deactivate") return;
|
|
9899
7893
|
if (Date.now() < linkPopoverGraceUntilRef.current) return;
|
|
9900
|
-
if (document.querySelector("[data-ohw-section-picker]")) return;
|
|
9901
7894
|
if (linkPopoverOpenRef.current) {
|
|
9902
7895
|
setLinkPopoverRef.current(null);
|
|
9903
7896
|
return;
|
|
@@ -9906,40 +7899,13 @@ function OhhwellsBridge() {
|
|
|
9906
7899
|
deactivateRef.current();
|
|
9907
7900
|
};
|
|
9908
7901
|
window.addEventListener("message", handleDeactivate);
|
|
9909
|
-
const handleUiEscape = (e) => {
|
|
9910
|
-
if (e.data?.type !== "ui:escape") return;
|
|
9911
|
-
if (linkPopoverOpenRef.current) {
|
|
9912
|
-
setLinkPopoverRef.current(null);
|
|
9913
|
-
}
|
|
9914
|
-
};
|
|
9915
|
-
window.addEventListener("message", handleUiEscape);
|
|
9916
7902
|
const handleKeyDown = (e) => {
|
|
9917
|
-
if (e.key === "Escape" && document.querySelector("[data-ohw-section-picker]")) return;
|
|
9918
|
-
if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === "a" && activeElRef.current) {
|
|
9919
|
-
const navAnchor = getNavigationItemAnchor(activeElRef.current);
|
|
9920
|
-
if (navAnchor) {
|
|
9921
|
-
e.preventDefault();
|
|
9922
|
-
selectAllTextInEditable(activeElRef.current);
|
|
9923
|
-
refreshActiveCommandsRef.current();
|
|
9924
|
-
return;
|
|
9925
|
-
}
|
|
9926
|
-
}
|
|
9927
7903
|
if (e.key === "Escape" && linkPopoverOpenRef.current) {
|
|
9928
7904
|
setLinkPopoverRef.current(null);
|
|
9929
7905
|
return;
|
|
9930
7906
|
}
|
|
9931
7907
|
if (e.key === "Escape" && selectedElRef.current && !activeElRef.current) {
|
|
9932
|
-
|
|
9933
|
-
deselectRef.current();
|
|
9934
|
-
return;
|
|
9935
|
-
}
|
|
9936
|
-
const parent = getNavigationSelectionParent(selectedElRef.current);
|
|
9937
|
-
if (parent) {
|
|
9938
|
-
e.preventDefault();
|
|
9939
|
-
selectFrameRef.current(parent);
|
|
9940
|
-
} else {
|
|
9941
|
-
deselectRef.current();
|
|
9942
|
-
}
|
|
7908
|
+
deselectRef.current();
|
|
9943
7909
|
return;
|
|
9944
7910
|
}
|
|
9945
7911
|
if (e.key === "Escape" && activeElRef.current) {
|
|
@@ -9997,23 +7963,9 @@ function OhhwellsBridge() {
|
|
|
9997
7963
|
if (hoveredItemElRef.current) {
|
|
9998
7964
|
setHoveredItemRect(hoveredItemElRef.current.getBoundingClientRect());
|
|
9999
7965
|
}
|
|
10000
|
-
if (hoveredNavContainerRef.current) {
|
|
10001
|
-
setHoveredNavContainerRect(hoveredNavContainerRef.current.getBoundingClientRect());
|
|
10002
|
-
}
|
|
10003
7966
|
if (siblingHintElRef.current) {
|
|
10004
7967
|
setSiblingHintRect(siblingHintElRef.current.getBoundingClientRect());
|
|
10005
7968
|
}
|
|
10006
|
-
const selected = selectedElRef.current;
|
|
10007
|
-
if (selected && !footerDragRef.current && (selected.hasAttribute("data-ohw-footer-col") || Boolean(selected.closest("footer") && isInferredFooterGroup(selected)))) {
|
|
10008
|
-
setSiblingHintRects(
|
|
10009
|
-
listFooterColumns().filter((column) => column !== selected).map((column) => column.getBoundingClientRect())
|
|
10010
|
-
);
|
|
10011
|
-
}
|
|
10012
|
-
if (footerDragRef.current) {
|
|
10013
|
-
const session = footerDragRef.current;
|
|
10014
|
-
const slot = session.kind === "link" && session.hrefKey ? hitTestLinkDropSlot(session.lastClientX, session.lastClientY, session.hrefKey) : hitTestColumnDropSlot(session.lastClientX, session.lastClientY);
|
|
10015
|
-
refreshFooterDragVisualsRef.current(session, slot, session.lastClientX, session.lastClientY);
|
|
10016
|
-
}
|
|
10017
7969
|
if (hoveredImageRef.current) {
|
|
10018
7970
|
const el = hoveredImageRef.current;
|
|
10019
7971
|
const r2 = el.getBoundingClientRect();
|
|
@@ -10024,7 +7976,7 @@ function OhhwellsBridge() {
|
|
|
10024
7976
|
};
|
|
10025
7977
|
const handleSave = (e) => {
|
|
10026
7978
|
if (e.data?.type !== "ow:save") return;
|
|
10027
|
-
const nodes = collectEditableNodes(
|
|
7979
|
+
const nodes = collectEditableNodes();
|
|
10028
7980
|
const tracker = document.querySelector("[data-ohw-sections-tracker]");
|
|
10029
7981
|
if (tracker?.textContent) nodes.push({ key: "__ohw_sections", type: "sections", text: tracker.textContent });
|
|
10030
7982
|
postToParentRef.current({ type: "ow:save-result", nodes });
|
|
@@ -10109,7 +8061,6 @@ function OhhwellsBridge() {
|
|
|
10109
8061
|
const handleDocMouseLeave = () => {
|
|
10110
8062
|
hoveredImageRef.current = null;
|
|
10111
8063
|
setMediaHover(null);
|
|
10112
|
-
setCarouselHover(null);
|
|
10113
8064
|
document.querySelectorAll("[data-ohw-state-hovered]").forEach((el) => el.removeAttribute("data-ohw-state-hovered"));
|
|
10114
8065
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
10115
8066
|
activeStateElRef.current = null;
|
|
@@ -10149,48 +8100,6 @@ function OhhwellsBridge() {
|
|
|
10149
8100
|
if (e.data?.type !== "ow:canvas-height" || typeof e.data.height !== "number") return;
|
|
10150
8101
|
document.documentElement.style.setProperty("--ohw-canvas-h", `${e.data.height}px`);
|
|
10151
8102
|
};
|
|
10152
|
-
const handleCarouselChange = (e) => {
|
|
10153
|
-
if (e.data?.type !== "ow:carousel-change") return;
|
|
10154
|
-
const { key, images } = e.data;
|
|
10155
|
-
if (!key || !Array.isArray(images)) return;
|
|
10156
|
-
const text = JSON.stringify(images);
|
|
10157
|
-
applyCarouselValue(key, images);
|
|
10158
|
-
editContentRef.current = { ...editContentRef.current, [key]: text };
|
|
10159
|
-
postToParentRef.current({ type: "ow:change", nodes: [{ key, text }] });
|
|
10160
|
-
setCarouselHover(null);
|
|
10161
|
-
};
|
|
10162
|
-
const findCarouselAtPoint = (clientX, clientY) => {
|
|
10163
|
-
const containers = Array.from(document.querySelectorAll(`[${CAROUSEL_ATTR}]`));
|
|
10164
|
-
for (let i = containers.length - 1; i >= 0; i--) {
|
|
10165
|
-
const r2 = containers[i].getBoundingClientRect();
|
|
10166
|
-
if (clientX >= r2.left && clientX <= r2.right && clientY >= r2.top && clientY <= r2.bottom) {
|
|
10167
|
-
return containers[i];
|
|
10168
|
-
}
|
|
10169
|
-
}
|
|
10170
|
-
return null;
|
|
10171
|
-
};
|
|
10172
|
-
const isPointOverEditable = (scope, clientX, clientY) => {
|
|
10173
|
-
const editables = scope.querySelectorAll("[data-ohw-editable], [data-ohw-href-key]");
|
|
10174
|
-
for (const el of editables) {
|
|
10175
|
-
const r2 = el.getBoundingClientRect();
|
|
10176
|
-
if (clientX >= r2.left && clientX <= r2.right && clientY >= r2.top && clientY <= r2.bottom) return true;
|
|
10177
|
-
}
|
|
10178
|
-
return false;
|
|
10179
|
-
};
|
|
10180
|
-
const handleCarouselHover = (e) => {
|
|
10181
|
-
const container = findCarouselAtPoint(e.clientX, e.clientY);
|
|
10182
|
-
const scope = container?.closest("[data-ohw-section]") ?? container?.parentElement ?? null;
|
|
10183
|
-
if (!container || !scope || isPointOverEditable(scope, e.clientX, e.clientY)) {
|
|
10184
|
-
setCarouselHover((prev) => prev ? null : prev);
|
|
10185
|
-
return;
|
|
10186
|
-
}
|
|
10187
|
-
const key = container.getAttribute("data-ohw-key") ?? "";
|
|
10188
|
-
if (!key) return;
|
|
10189
|
-
const r2 = getVisibleRect(container);
|
|
10190
|
-
setCarouselHover(
|
|
10191
|
-
(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 } }
|
|
10192
|
-
);
|
|
10193
|
-
};
|
|
10194
8103
|
const applyToolbarPos = (rect) => {
|
|
10195
8104
|
const ps = parentScrollRef.current;
|
|
10196
8105
|
const approxW = 330;
|
|
@@ -10250,45 +8159,9 @@ function OhhwellsBridge() {
|
|
|
10250
8159
|
return clientX >= r2.left && clientX <= r2.right && clientY >= r2.top && clientY <= r2.bottom;
|
|
10251
8160
|
});
|
|
10252
8161
|
if (textEditable) {
|
|
10253
|
-
|
|
10254
|
-
const navAnchor = hrefCtx ? getNavigationItemAnchor(hrefCtx.anchor) : null;
|
|
10255
|
-
if (navAnchor) {
|
|
10256
|
-
if (selectedElRef.current === navAnchor) {
|
|
10257
|
-
activateRef.current(textEditable, { caretX: clientX, caretY: clientY });
|
|
10258
|
-
} else {
|
|
10259
|
-
selectRef.current(navAnchor);
|
|
10260
|
-
}
|
|
10261
|
-
return;
|
|
10262
|
-
}
|
|
10263
|
-
activateRef.current(textEditable, { caretX: clientX, caretY: clientY });
|
|
8162
|
+
activateRef.current(textEditable);
|
|
10264
8163
|
return;
|
|
10265
8164
|
}
|
|
10266
|
-
const navContainer = document.querySelector("[data-ohw-nav-container]");
|
|
10267
|
-
if (navContainer) {
|
|
10268
|
-
const r2 = navContainer.getBoundingClientRect();
|
|
10269
|
-
const pad = 8;
|
|
10270
|
-
const over = clientX >= r2.left - pad && clientX <= r2.right + pad && clientY >= r2.top - pad && clientY <= r2.bottom + pad;
|
|
10271
|
-
if (over && !isPointOverNavItem(navContainer, clientX, clientY)) {
|
|
10272
|
-
selectFrameRef.current(navContainer);
|
|
10273
|
-
return;
|
|
10274
|
-
}
|
|
10275
|
-
}
|
|
10276
|
-
const navRoot = document.querySelector("[data-ohw-nav-root]");
|
|
10277
|
-
if (navRoot && navContainer) {
|
|
10278
|
-
const rr = navRoot.getBoundingClientRect();
|
|
10279
|
-
if (clientX >= rr.left && clientX <= rr.right && clientY >= rr.top && clientY <= rr.bottom && !isPointOverNavItem(navContainer, clientX, clientY)) {
|
|
10280
|
-
const book = navRoot.querySelector('[data-ohw-role="navbar-button"]');
|
|
10281
|
-
if (book) {
|
|
10282
|
-
const br = book.getBoundingClientRect();
|
|
10283
|
-
if (clientX >= br.left && clientX <= br.right && clientY >= br.top && clientY <= br.bottom) {
|
|
10284
|
-
deactivateRef.current();
|
|
10285
|
-
return;
|
|
10286
|
-
}
|
|
10287
|
-
}
|
|
10288
|
-
selectFrameRef.current(navContainer);
|
|
10289
|
-
return;
|
|
10290
|
-
}
|
|
10291
|
-
}
|
|
10292
8165
|
deactivateRef.current();
|
|
10293
8166
|
};
|
|
10294
8167
|
window.addEventListener("message", handleSave);
|
|
@@ -10299,7 +8172,6 @@ function OhhwellsBridge() {
|
|
|
10299
8172
|
window.addEventListener("message", handleRemoveSchedulingSection);
|
|
10300
8173
|
window.addEventListener("message", handleImageUrl);
|
|
10301
8174
|
window.addEventListener("message", handleImageUploading);
|
|
10302
|
-
window.addEventListener("message", handleCarouselChange);
|
|
10303
8175
|
window.addEventListener("message", handleCanvasHeight);
|
|
10304
8176
|
window.addEventListener("message", handleParentScroll);
|
|
10305
8177
|
window.addEventListener("message", handlePointerSync);
|
|
@@ -10311,13 +8183,11 @@ function OhhwellsBridge() {
|
|
|
10311
8183
|
};
|
|
10312
8184
|
window.addEventListener("resize", handleViewportResize, { passive: true });
|
|
10313
8185
|
document.addEventListener("click", handleClick, true);
|
|
10314
|
-
document.addEventListener("dblclick", handleDblClick, true);
|
|
10315
8186
|
document.addEventListener("paste", handlePaste, true);
|
|
10316
8187
|
document.addEventListener("input", handleInput, true);
|
|
10317
8188
|
document.addEventListener("mouseover", handleMouseOver, true);
|
|
10318
8189
|
document.addEventListener("mouseout", handleMouseOut, true);
|
|
10319
8190
|
document.addEventListener("mousemove", handleMouseMove, true);
|
|
10320
|
-
document.addEventListener("mousemove", handleCarouselHover, true);
|
|
10321
8191
|
document.addEventListener("mouseleave", handleDocMouseLeave);
|
|
10322
8192
|
document.addEventListener("dragover", handleDragOver, true);
|
|
10323
8193
|
document.addEventListener("dragleave", handleDragLeave, true);
|
|
@@ -10327,13 +8197,11 @@ function OhhwellsBridge() {
|
|
|
10327
8197
|
window.addEventListener("scroll", handleScroll, true);
|
|
10328
8198
|
return () => {
|
|
10329
8199
|
document.removeEventListener("click", handleClick, true);
|
|
10330
|
-
document.removeEventListener("dblclick", handleDblClick, true);
|
|
10331
8200
|
document.removeEventListener("paste", handlePaste, true);
|
|
10332
8201
|
document.removeEventListener("input", handleInput, true);
|
|
10333
8202
|
document.removeEventListener("mouseover", handleMouseOver, true);
|
|
10334
8203
|
document.removeEventListener("mouseout", handleMouseOut, true);
|
|
10335
8204
|
document.removeEventListener("mousemove", handleMouseMove, true);
|
|
10336
|
-
document.removeEventListener("mousemove", handleCarouselHover, true);
|
|
10337
8205
|
document.removeEventListener("mouseleave", handleDocMouseLeave);
|
|
10338
8206
|
document.removeEventListener("dragover", handleDragOver, true);
|
|
10339
8207
|
document.removeEventListener("dragleave", handleDragLeave, true);
|
|
@@ -10349,7 +8217,6 @@ function OhhwellsBridge() {
|
|
|
10349
8217
|
window.removeEventListener("message", handleRemoveSchedulingSection);
|
|
10350
8218
|
window.removeEventListener("message", handleImageUrl);
|
|
10351
8219
|
window.removeEventListener("message", handleImageUploading);
|
|
10352
|
-
window.removeEventListener("message", handleCarouselChange);
|
|
10353
8220
|
window.removeEventListener("message", handleCanvasHeight);
|
|
10354
8221
|
window.removeEventListener("message", handleParentScroll);
|
|
10355
8222
|
window.removeEventListener("resize", handleViewportResize);
|
|
@@ -10357,162 +8224,13 @@ function OhhwellsBridge() {
|
|
|
10357
8224
|
window.removeEventListener("message", handleClickAt);
|
|
10358
8225
|
window.removeEventListener("message", handleHydrate);
|
|
10359
8226
|
window.removeEventListener("message", handleDeactivate);
|
|
10360
|
-
window.removeEventListener("message", handleUiEscape);
|
|
10361
8227
|
autoSaveTimers.current.forEach(clearTimeout);
|
|
10362
8228
|
autoSaveTimers.current.clear();
|
|
10363
8229
|
if (imageUnhoverTimerRef.current) clearTimeout(imageUnhoverTimerRef.current);
|
|
10364
8230
|
if (imageShowTimerRef.current) clearTimeout(imageShowTimerRef.current);
|
|
10365
8231
|
};
|
|
10366
8232
|
}, [isEditMode, refreshStateRules]);
|
|
10367
|
-
|
|
10368
|
-
if (!isEditMode) return;
|
|
10369
|
-
const THRESHOLD = 10;
|
|
10370
|
-
const resolveWasSelected = (el) => {
|
|
10371
|
-
if (selectedElRef.current === el) return true;
|
|
10372
|
-
const activeAnchor = activeElRef.current ? getNavigationItemAnchor(activeElRef.current) : null;
|
|
10373
|
-
return activeAnchor === el;
|
|
10374
|
-
};
|
|
10375
|
-
const onPointerDown = (e) => {
|
|
10376
|
-
if (e.button !== 0) return;
|
|
10377
|
-
if (footerDragRef.current) return;
|
|
10378
|
-
const target = e.target;
|
|
10379
|
-
if (!target) return;
|
|
10380
|
-
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]')) {
|
|
10381
|
-
return;
|
|
10382
|
-
}
|
|
10383
|
-
if (target.closest("[data-ohw-item-drag-surface]")) return;
|
|
10384
|
-
const anchor = getNavigationItemAnchor(target);
|
|
10385
|
-
const hrefKey = anchor?.getAttribute("data-ohw-href-key") ?? null;
|
|
10386
|
-
if (anchor && isFooterHrefKey(hrefKey)) {
|
|
10387
|
-
armFooterPressDrag();
|
|
10388
|
-
footerPointerDragRef.current = {
|
|
10389
|
-
el: anchor,
|
|
10390
|
-
kind: "link",
|
|
10391
|
-
startX: e.clientX,
|
|
10392
|
-
startY: e.clientY,
|
|
10393
|
-
pointerId: e.pointerId,
|
|
10394
|
-
wasSelected: resolveWasSelected(anchor),
|
|
10395
|
-
started: false
|
|
10396
|
-
};
|
|
10397
|
-
return;
|
|
10398
|
-
}
|
|
10399
|
-
const col = target.closest("[data-ohw-footer-col]");
|
|
10400
|
-
if (col && !getNavigationItemAnchor(target)) {
|
|
10401
|
-
armFooterPressDrag();
|
|
10402
|
-
footerPointerDragRef.current = {
|
|
10403
|
-
el: col,
|
|
10404
|
-
kind: "column",
|
|
10405
|
-
startX: e.clientX,
|
|
10406
|
-
startY: e.clientY,
|
|
10407
|
-
pointerId: e.pointerId,
|
|
10408
|
-
wasSelected: resolveWasSelected(col),
|
|
10409
|
-
started: false
|
|
10410
|
-
};
|
|
10411
|
-
}
|
|
10412
|
-
};
|
|
10413
|
-
const onPointerMove = (e) => {
|
|
10414
|
-
const pending = footerPointerDragRef.current;
|
|
10415
|
-
if (!pending) return;
|
|
10416
|
-
if (pending.started) {
|
|
10417
|
-
e.preventDefault();
|
|
10418
|
-
clearTextSelection();
|
|
10419
|
-
const session = footerDragRef.current;
|
|
10420
|
-
if (!session) return;
|
|
10421
|
-
const slot = session.kind === "link" && session.hrefKey ? hitTestLinkDropSlot(e.clientX, e.clientY, session.hrefKey) : hitTestColumnDropSlot(e.clientX, e.clientY);
|
|
10422
|
-
refreshFooterDragVisualsRef.current(session, slot, e.clientX, e.clientY);
|
|
10423
|
-
return;
|
|
10424
|
-
}
|
|
10425
|
-
const dx = e.clientX - pending.startX;
|
|
10426
|
-
const dy = e.clientY - pending.startY;
|
|
10427
|
-
if (dx * dx + dy * dy < THRESHOLD * THRESHOLD) return;
|
|
10428
|
-
e.preventDefault();
|
|
10429
|
-
pending.started = true;
|
|
10430
|
-
clearTextSelection();
|
|
10431
|
-
try {
|
|
10432
|
-
document.body.setPointerCapture(pending.pointerId);
|
|
10433
|
-
} catch {
|
|
10434
|
-
}
|
|
10435
|
-
if (linkPopoverOpenRef.current) {
|
|
10436
|
-
setLinkPopoverRef.current(null);
|
|
10437
|
-
}
|
|
10438
|
-
if (activeElRef.current) {
|
|
10439
|
-
deactivateRef.current();
|
|
10440
|
-
}
|
|
10441
|
-
if (pending.kind === "link") {
|
|
10442
|
-
const key = pending.el.getAttribute("data-ohw-href-key");
|
|
10443
|
-
if (!key) return;
|
|
10444
|
-
const column = findFooterColumnForLink(pending.el);
|
|
10445
|
-
const columns2 = listFooterColumns();
|
|
10446
|
-
beginFooterDragRef.current({
|
|
10447
|
-
kind: "link",
|
|
10448
|
-
hrefKey: key,
|
|
10449
|
-
columnEl: column,
|
|
10450
|
-
sourceColumnIndex: column ? columns2.indexOf(column) : 0,
|
|
10451
|
-
wasSelected: pending.wasSelected,
|
|
10452
|
-
draggedEl: pending.el,
|
|
10453
|
-
lastClientX: e.clientX,
|
|
10454
|
-
lastClientY: e.clientY,
|
|
10455
|
-
activeSlot: null
|
|
10456
|
-
});
|
|
10457
|
-
return;
|
|
10458
|
-
}
|
|
10459
|
-
const columns = listFooterColumns();
|
|
10460
|
-
const idx = columns.indexOf(pending.el);
|
|
10461
|
-
if (idx < 0) return;
|
|
10462
|
-
beginFooterDragRef.current({
|
|
10463
|
-
kind: "column",
|
|
10464
|
-
hrefKey: null,
|
|
10465
|
-
columnEl: pending.el,
|
|
10466
|
-
sourceColumnIndex: idx,
|
|
10467
|
-
wasSelected: pending.wasSelected,
|
|
10468
|
-
draggedEl: pending.el,
|
|
10469
|
-
lastClientX: e.clientX,
|
|
10470
|
-
lastClientY: e.clientY,
|
|
10471
|
-
activeSlot: null
|
|
10472
|
-
});
|
|
10473
|
-
};
|
|
10474
|
-
const endPointerDrag = (e) => {
|
|
10475
|
-
const pending = footerPointerDragRef.current;
|
|
10476
|
-
footerPointerDragRef.current = null;
|
|
10477
|
-
try {
|
|
10478
|
-
if (document.body.hasPointerCapture(e.pointerId)) {
|
|
10479
|
-
document.body.releasePointerCapture(e.pointerId);
|
|
10480
|
-
}
|
|
10481
|
-
} catch {
|
|
10482
|
-
}
|
|
10483
|
-
if (!pending?.started) {
|
|
10484
|
-
unlockFooterDragInteraction();
|
|
10485
|
-
return;
|
|
10486
|
-
}
|
|
10487
|
-
suppressNextClickRef.current = true;
|
|
10488
|
-
commitFooterDragRef.current(e.clientX, e.clientY);
|
|
10489
|
-
};
|
|
10490
|
-
const blockSelectStart = (e) => {
|
|
10491
|
-
if (footerDragRef.current || footerPointerDragRef.current?.started || document.documentElement.hasAttribute("data-ohw-footer-press-drag")) {
|
|
10492
|
-
e.preventDefault();
|
|
10493
|
-
}
|
|
10494
|
-
};
|
|
10495
|
-
const onDragEnd = (_e) => {
|
|
10496
|
-
if (!footerDragRef.current) return;
|
|
10497
|
-
commitFooterDragRef.current();
|
|
10498
|
-
};
|
|
10499
|
-
document.addEventListener("pointerdown", onPointerDown, true);
|
|
10500
|
-
document.addEventListener("pointermove", onPointerMove, true);
|
|
10501
|
-
document.addEventListener("pointerup", endPointerDrag, true);
|
|
10502
|
-
document.addEventListener("pointercancel", endPointerDrag, true);
|
|
10503
|
-
document.addEventListener("selectstart", blockSelectStart, true);
|
|
10504
|
-
document.addEventListener("dragend", onDragEnd, true);
|
|
10505
|
-
return () => {
|
|
10506
|
-
document.removeEventListener("pointerdown", onPointerDown, true);
|
|
10507
|
-
document.removeEventListener("pointermove", onPointerMove, true);
|
|
10508
|
-
document.removeEventListener("pointerup", endPointerDrag, true);
|
|
10509
|
-
document.removeEventListener("pointercancel", endPointerDrag, true);
|
|
10510
|
-
document.removeEventListener("selectstart", blockSelectStart, true);
|
|
10511
|
-
document.removeEventListener("dragend", onDragEnd, true);
|
|
10512
|
-
unlockFooterDragInteraction();
|
|
10513
|
-
};
|
|
10514
|
-
}, [isEditMode]);
|
|
10515
|
-
useEffect8(() => {
|
|
8233
|
+
useEffect4(() => {
|
|
10516
8234
|
const handler = (e) => {
|
|
10517
8235
|
if (e.data?.type !== "ow:request-schedule-config") return;
|
|
10518
8236
|
const insertAfterVal = e.data.insertAfter;
|
|
@@ -10528,7 +8246,7 @@ function OhhwellsBridge() {
|
|
|
10528
8246
|
window.addEventListener("message", handler);
|
|
10529
8247
|
return () => window.removeEventListener("message", handler);
|
|
10530
8248
|
}, [processConfigRequest]);
|
|
10531
|
-
|
|
8249
|
+
useEffect4(() => {
|
|
10532
8250
|
if (!isEditMode) return;
|
|
10533
8251
|
document.querySelectorAll("[data-ohw-active-state]").forEach((el) => {
|
|
10534
8252
|
el.removeAttribute("data-ohw-active-state");
|
|
@@ -10549,33 +8267,27 @@ function OhhwellsBridge() {
|
|
|
10549
8267
|
const next = { ...prev, [pathKey]: sections };
|
|
10550
8268
|
return shouldUseDevFixtures() ? { ...DEV_SECTIONS_BY_PATH, ...next } : next;
|
|
10551
8269
|
});
|
|
10552
|
-
|
|
10553
|
-
|
|
10554
|
-
version: "1",
|
|
10555
|
-
path: pathname,
|
|
10556
|
-
nodes: collectEditableNodes(editContentRef.current),
|
|
10557
|
-
sections
|
|
10558
|
-
});
|
|
10559
|
-
postToParent2({ type: "ow:request-site-pages" });
|
|
8270
|
+
postToParent({ type: "ow:ready", version: "1", path: pathname, nodes: collectEditableNodes(), sections });
|
|
8271
|
+
postToParent({ type: "ow:request-site-pages" });
|
|
10560
8272
|
}, 150);
|
|
10561
8273
|
return () => {
|
|
10562
8274
|
cancelAnimationFrame(raf);
|
|
10563
8275
|
clearTimeout(timer);
|
|
10564
8276
|
};
|
|
10565
|
-
}, [pathname, isEditMode, refreshStateRules,
|
|
10566
|
-
|
|
8277
|
+
}, [pathname, isEditMode, refreshStateRules, postToParent]);
|
|
8278
|
+
useEffect4(() => {
|
|
10567
8279
|
scrollToHashSectionWhenReady();
|
|
10568
8280
|
const onHashChange = () => scrollToHashSectionWhenReady();
|
|
10569
8281
|
window.addEventListener("hashchange", onHashChange);
|
|
10570
8282
|
return () => window.removeEventListener("hashchange", onHashChange);
|
|
10571
8283
|
}, [pathname]);
|
|
10572
|
-
const handleCommand =
|
|
8284
|
+
const handleCommand = useCallback2((cmd) => {
|
|
10573
8285
|
document.execCommand(cmd, false);
|
|
10574
8286
|
activeElRef.current?.focus();
|
|
10575
8287
|
if (activeElRef.current) setToolbarRect(getEditMeasureEl(activeElRef.current).getBoundingClientRect());
|
|
10576
8288
|
refreshActiveCommandsRef.current();
|
|
10577
8289
|
}, []);
|
|
10578
|
-
const handleStateChange =
|
|
8290
|
+
const handleStateChange = useCallback2((state) => {
|
|
10579
8291
|
if (!activeStateElRef.current) return;
|
|
10580
8292
|
const el = activeStateElRef.current;
|
|
10581
8293
|
if (state === "Default") {
|
|
@@ -10588,22 +8300,18 @@ function OhhwellsBridge() {
|
|
|
10588
8300
|
}
|
|
10589
8301
|
setToggleState((prev) => prev ? { ...prev, activeState: state } : null);
|
|
10590
8302
|
}, [deactivate]);
|
|
10591
|
-
const closeLinkPopover =
|
|
10592
|
-
|
|
10593
|
-
setLinkPopover(null);
|
|
10594
|
-
}, []);
|
|
10595
|
-
const openLinkPopoverForActive = useCallback4(() => {
|
|
8303
|
+
const closeLinkPopover = useCallback2(() => setLinkPopover(null), []);
|
|
8304
|
+
const openLinkPopoverForActive = useCallback2(() => {
|
|
10596
8305
|
const hrefCtx = getHrefKeyFromElement(activeElRef.current);
|
|
10597
8306
|
if (!hrefCtx) return;
|
|
10598
8307
|
bumpLinkPopoverGrace();
|
|
10599
8308
|
setLinkPopover({
|
|
10600
8309
|
key: hrefCtx.key,
|
|
10601
|
-
|
|
10602
|
-
target: getLinkHref2(hrefCtx.anchor)
|
|
8310
|
+
target: getLinkHref(hrefCtx.anchor)
|
|
10603
8311
|
});
|
|
10604
8312
|
deactivate();
|
|
10605
8313
|
}, [deactivate]);
|
|
10606
|
-
const openLinkPopoverForSelected =
|
|
8314
|
+
const openLinkPopoverForSelected = useCallback2(() => {
|
|
10607
8315
|
const anchor = selectedElRef.current;
|
|
10608
8316
|
if (!anchor) return;
|
|
10609
8317
|
const key = anchor.getAttribute("data-ohw-href-key");
|
|
@@ -10611,80 +8319,30 @@ function OhhwellsBridge() {
|
|
|
10611
8319
|
bumpLinkPopoverGrace();
|
|
10612
8320
|
setLinkPopover({
|
|
10613
8321
|
key,
|
|
10614
|
-
|
|
10615
|
-
target: getLinkHref2(anchor)
|
|
8322
|
+
target: getLinkHref(anchor)
|
|
10616
8323
|
});
|
|
10617
8324
|
deselect();
|
|
10618
8325
|
}, [deselect]);
|
|
10619
|
-
const handleLinkPopoverSubmit =
|
|
8326
|
+
const handleLinkPopoverSubmit = useCallback2(
|
|
10620
8327
|
(target) => {
|
|
10621
|
-
|
|
10622
|
-
|
|
10623
|
-
if (session.intent === "add-nav") {
|
|
10624
|
-
const trimmed = target.trim();
|
|
10625
|
-
let href = trimmed;
|
|
10626
|
-
let label = "Untitled";
|
|
10627
|
-
if (trimmed) {
|
|
10628
|
-
const { pageRoute, sectionId } = parseTarget(trimmed);
|
|
10629
|
-
const page = resolvePage(pageRoute, sitePages);
|
|
10630
|
-
const pageSections = getSectionsForPath(sectionsByPath, pageRoute);
|
|
10631
|
-
const section = sectionId ? pageSections.find((s) => s.id === sectionId) : void 0;
|
|
10632
|
-
label = section?.label ?? page.title;
|
|
10633
|
-
href = trimmed;
|
|
10634
|
-
}
|
|
10635
|
-
const afterAnchor = addNavAfterAnchorRef.current;
|
|
10636
|
-
const { anchor, hrefKey, labelKey, index, order } = insertNavbarItem(href, label, afterAnchor);
|
|
10637
|
-
applyLinkByKey(hrefKey, href);
|
|
10638
|
-
document.querySelectorAll(`[data-ohw-key="${labelKey}"]`).forEach((el) => {
|
|
10639
|
-
el.textContent = label;
|
|
10640
|
-
});
|
|
10641
|
-
const navCount = String(index + 1);
|
|
10642
|
-
const orderJson = JSON.stringify(order);
|
|
10643
|
-
editContentRef.current = {
|
|
10644
|
-
...editContentRef.current,
|
|
10645
|
-
[hrefKey]: href,
|
|
10646
|
-
[labelKey]: label,
|
|
10647
|
-
[NAV_COUNT_KEY]: navCount,
|
|
10648
|
-
[NAV_ORDER_KEY]: orderJson
|
|
10649
|
-
};
|
|
10650
|
-
postToParent2({
|
|
10651
|
-
type: "ow:change",
|
|
10652
|
-
nodes: [
|
|
10653
|
-
{ key: hrefKey, text: href },
|
|
10654
|
-
{ key: labelKey, text: label },
|
|
10655
|
-
{ key: NAV_COUNT_KEY, text: navCount },
|
|
10656
|
-
{ key: NAV_ORDER_KEY, text: orderJson }
|
|
10657
|
-
]
|
|
10658
|
-
});
|
|
10659
|
-
postToParent2({ type: "ow:toast", title: "Link added", toastType: "success" });
|
|
10660
|
-
addNavAfterAnchorRef.current = null;
|
|
10661
|
-
setLinkPopover(null);
|
|
10662
|
-
enforceLinkHrefs();
|
|
10663
|
-
requestAnimationFrame(() => {
|
|
10664
|
-
selectRef.current(anchor);
|
|
10665
|
-
});
|
|
10666
|
-
return;
|
|
10667
|
-
}
|
|
10668
|
-
const { key } = session;
|
|
8328
|
+
if (!linkPopover) return;
|
|
8329
|
+
const { key } = linkPopover;
|
|
10669
8330
|
applyLinkByKey(key, target);
|
|
10670
|
-
|
|
8331
|
+
postToParent({ type: "ow:change", nodes: [{ key, text: target }] });
|
|
10671
8332
|
setLinkPopover(null);
|
|
10672
8333
|
},
|
|
10673
|
-
[
|
|
10674
|
-
);
|
|
10675
|
-
const handleMediaReplace = useCallback4(
|
|
10676
|
-
(key) => {
|
|
10677
|
-
postToParent2({ type: "ow:image-pick", key, elementType: mediaHover?.elementType ?? "image" });
|
|
10678
|
-
},
|
|
10679
|
-
[postToParent2, mediaHover?.elementType]
|
|
8334
|
+
[linkPopover, postToParent]
|
|
10680
8335
|
);
|
|
10681
|
-
const
|
|
8336
|
+
const showEditLink = toolbarShowEditLink;
|
|
8337
|
+
const currentSections = sectionsByPath[pathname] ?? [];
|
|
8338
|
+
linkPopoverOpenRef.current = linkPopover !== null;
|
|
8339
|
+
const handleMediaReplace = useCallback2(
|
|
10682
8340
|
(key) => {
|
|
10683
|
-
|
|
8341
|
+
postToParent({ type: "ow:image-pick", key, elementType: mediaHover?.elementType ?? "image" });
|
|
10684
8342
|
},
|
|
10685
|
-
[
|
|
8343
|
+
[postToParent, mediaHover?.elementType]
|
|
10686
8344
|
);
|
|
10687
|
-
const handleMediaFadeOutComplete =
|
|
8345
|
+
const handleMediaFadeOutComplete = useCallback2((key) => {
|
|
10688
8346
|
setUploadingRects((prev) => {
|
|
10689
8347
|
if (!(key in prev)) return prev;
|
|
10690
8348
|
const next = { ...prev };
|
|
@@ -10692,7 +8350,7 @@ function OhhwellsBridge() {
|
|
|
10692
8350
|
return next;
|
|
10693
8351
|
});
|
|
10694
8352
|
}, []);
|
|
10695
|
-
const handleVideoSettingsChange =
|
|
8353
|
+
const handleVideoSettingsChange = useCallback2(
|
|
10696
8354
|
(key, settings) => {
|
|
10697
8355
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
10698
8356
|
const video = getVideoEl(el);
|
|
@@ -10700,7 +8358,7 @@ function OhhwellsBridge() {
|
|
|
10700
8358
|
if (typeof settings.autoplay === "boolean") video.autoplay = settings.autoplay;
|
|
10701
8359
|
if (typeof settings.muted === "boolean") video.muted = settings.muted;
|
|
10702
8360
|
syncVideoPlayback(video);
|
|
10703
|
-
|
|
8361
|
+
postToParent({
|
|
10704
8362
|
type: "ow:change",
|
|
10705
8363
|
nodes: [
|
|
10706
8364
|
{ key: `${key}${VIDEO_AUTOPLAY_SUFFIX}`, text: String(video.autoplay) },
|
|
@@ -10712,15 +8370,12 @@ function OhhwellsBridge() {
|
|
|
10712
8370
|
);
|
|
10713
8371
|
});
|
|
10714
8372
|
},
|
|
10715
|
-
[
|
|
8373
|
+
[postToParent]
|
|
10716
8374
|
);
|
|
10717
|
-
|
|
10718
|
-
|
|
10719
|
-
|
|
10720
|
-
|
|
10721
|
-
/* @__PURE__ */ jsxs14(Fragment5, { children: [
|
|
10722
|
-
/* @__PURE__ */ jsx25("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
|
|
10723
|
-
Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ jsx25(
|
|
8375
|
+
return bridgeRoot ? createPortal(
|
|
8376
|
+
/* @__PURE__ */ jsxs12(Fragment4, { children: [
|
|
8377
|
+
/* @__PURE__ */ jsx22("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
|
|
8378
|
+
Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ jsx22(
|
|
10724
8379
|
MediaOverlay,
|
|
10725
8380
|
{
|
|
10726
8381
|
hover: { key, rect, elementType: "image", isDragOver: false, hasTextOverlap: false },
|
|
@@ -10731,7 +8386,7 @@ function OhhwellsBridge() {
|
|
|
10731
8386
|
},
|
|
10732
8387
|
`uploading-${key}`
|
|
10733
8388
|
)),
|
|
10734
|
-
mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */
|
|
8389
|
+
mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */ jsx22(
|
|
10735
8390
|
MediaOverlay,
|
|
10736
8391
|
{
|
|
10737
8392
|
hover: mediaHover,
|
|
@@ -10740,33 +8395,53 @@ function OhhwellsBridge() {
|
|
|
10740
8395
|
onVideoSettingsChange: handleVideoSettingsChange
|
|
10741
8396
|
}
|
|
10742
8397
|
),
|
|
10743
|
-
|
|
10744
|
-
siblingHintRect && !isItemDragging &&
|
|
10745
|
-
|
|
10746
|
-
|
|
10747
|
-
isItemDragging && footerDropSlots.map((slot, i) => /* @__PURE__ */ jsx25(
|
|
10748
|
-
"div",
|
|
8398
|
+
siblingHintRect && !isItemDragging && /* @__PURE__ */ jsx22(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
|
|
8399
|
+
hoveredItemRect && !siblingHintRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ jsx22(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
|
|
8400
|
+
toolbarRect && toolbarVariant === "link-action" && /* @__PURE__ */ jsx22(
|
|
8401
|
+
ItemInteractionLayer,
|
|
10749
8402
|
{
|
|
10750
|
-
|
|
10751
|
-
|
|
10752
|
-
|
|
10753
|
-
|
|
10754
|
-
|
|
10755
|
-
|
|
10756
|
-
|
|
10757
|
-
|
|
10758
|
-
|
|
10759
|
-
|
|
10760
|
-
|
|
10761
|
-
|
|
10762
|
-
|
|
10763
|
-
|
|
10764
|
-
|
|
10765
|
-
|
|
10766
|
-
|
|
10767
|
-
|
|
8403
|
+
rect: toolbarRect,
|
|
8404
|
+
elRef: glowElRef,
|
|
8405
|
+
state: isItemDragging ? "dragging" : resolveItemInteractionState(toolbarRect, parentScrollRef.current),
|
|
8406
|
+
showHandle: Boolean(reorderHrefKey),
|
|
8407
|
+
dragDisabled: reorderDragDisabled,
|
|
8408
|
+
dragHandleLabel: reorderHrefKey ? `Reorder ${reorderHrefKey}` : "Reorder item",
|
|
8409
|
+
onDragHandleDragStart: handleItemDragStart,
|
|
8410
|
+
onDragHandleDragEnd: handleItemDragEnd,
|
|
8411
|
+
toolbar: isItemDragging ? void 0 : /* @__PURE__ */ jsx22(
|
|
8412
|
+
ItemActionToolbar,
|
|
8413
|
+
{
|
|
8414
|
+
onEditLink: openLinkPopoverForSelected,
|
|
8415
|
+
onAddItem: handleAddNavigationItem,
|
|
8416
|
+
addItemDisabled: false
|
|
8417
|
+
}
|
|
8418
|
+
)
|
|
8419
|
+
}
|
|
8420
|
+
),
|
|
8421
|
+
toolbarRect && toolbarVariant === "rich-text" && /* @__PURE__ */ jsxs12(Fragment4, { children: [
|
|
8422
|
+
/* @__PURE__ */ jsx22(
|
|
8423
|
+
EditGlowChrome,
|
|
8424
|
+
{
|
|
8425
|
+
rect: toolbarRect,
|
|
8426
|
+
elRef: glowElRef,
|
|
8427
|
+
reorderHrefKey,
|
|
8428
|
+
dragDisabled: reorderDragDisabled
|
|
8429
|
+
}
|
|
8430
|
+
),
|
|
8431
|
+
/* @__PURE__ */ jsx22(
|
|
8432
|
+
FloatingToolbar,
|
|
8433
|
+
{
|
|
8434
|
+
rect: toolbarRect,
|
|
8435
|
+
parentScroll: parentScrollRef.current,
|
|
8436
|
+
elRef: toolbarElRef,
|
|
8437
|
+
onCommand: handleCommand,
|
|
8438
|
+
activeCommands,
|
|
8439
|
+
showEditLink,
|
|
8440
|
+
onEditLink: openLinkPopoverForActive
|
|
8441
|
+
}
|
|
8442
|
+
)
|
|
10768
8443
|
] }),
|
|
10769
|
-
maxBadge && /* @__PURE__ */
|
|
8444
|
+
maxBadge && /* @__PURE__ */ jsxs12(
|
|
10770
8445
|
"div",
|
|
10771
8446
|
{
|
|
10772
8447
|
"data-ohw-max-badge": "",
|
|
@@ -10792,29 +8467,56 @@ function OhhwellsBridge() {
|
|
|
10792
8467
|
]
|
|
10793
8468
|
}
|
|
10794
8469
|
),
|
|
10795
|
-
toggleState &&
|
|
10796
|
-
|
|
10797
|
-
|
|
10798
|
-
|
|
10799
|
-
|
|
10800
|
-
|
|
10801
|
-
|
|
10802
|
-
|
|
10803
|
-
|
|
10804
|
-
|
|
10805
|
-
|
|
10806
|
-
|
|
10807
|
-
|
|
8470
|
+
toggleState && /* @__PURE__ */ jsx22(
|
|
8471
|
+
StateToggle,
|
|
8472
|
+
{
|
|
8473
|
+
rect: toggleState.rect,
|
|
8474
|
+
activeState: toggleState.activeState,
|
|
8475
|
+
states: toggleState.states,
|
|
8476
|
+
onStateChange: handleStateChange
|
|
8477
|
+
}
|
|
8478
|
+
),
|
|
8479
|
+
sectionGap && /* @__PURE__ */ jsxs12(
|
|
8480
|
+
"div",
|
|
8481
|
+
{
|
|
8482
|
+
"data-ohw-section-insert-line": "",
|
|
8483
|
+
className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
|
|
8484
|
+
style: { top: sectionGap.y, transform: "translateY(-50%)" },
|
|
8485
|
+
children: [
|
|
8486
|
+
/* @__PURE__ */ jsx22("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
|
|
8487
|
+
/* @__PURE__ */ jsx22(
|
|
8488
|
+
Badge,
|
|
8489
|
+
{
|
|
8490
|
+
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",
|
|
8491
|
+
onClick: () => {
|
|
8492
|
+
window.parent.postMessage(
|
|
8493
|
+
{ type: "ow:add-section", insertAfter: sectionGap.insertAfter, insertBefore: sectionGap.insertBefore },
|
|
8494
|
+
"*"
|
|
8495
|
+
);
|
|
10808
8496
|
},
|
|
10809
|
-
"
|
|
10810
|
-
|
|
10811
|
-
|
|
10812
|
-
|
|
10813
|
-
|
|
10814
|
-
|
|
10815
|
-
|
|
10816
|
-
|
|
10817
|
-
|
|
8497
|
+
children: "Add Section"
|
|
8498
|
+
}
|
|
8499
|
+
),
|
|
8500
|
+
/* @__PURE__ */ jsx22("div", { className: "flex-1 bg-primary", style: { height: 3 } })
|
|
8501
|
+
]
|
|
8502
|
+
}
|
|
8503
|
+
),
|
|
8504
|
+
linkPopover && dialogPortalContainer ? /* @__PURE__ */ jsx22(
|
|
8505
|
+
LinkPopover,
|
|
8506
|
+
{
|
|
8507
|
+
panelRef: linkPopoverPanelRef,
|
|
8508
|
+
portalContainer: dialogPortalContainer,
|
|
8509
|
+
open: true,
|
|
8510
|
+
mode: "edit",
|
|
8511
|
+
pages: sitePages,
|
|
8512
|
+
sections: currentSections,
|
|
8513
|
+
sectionsByPath,
|
|
8514
|
+
initialTarget: linkPopover.target,
|
|
8515
|
+
onClose: closeLinkPopover,
|
|
8516
|
+
onSubmit: handleLinkPopoverSubmit
|
|
8517
|
+
},
|
|
8518
|
+
`${linkPopover.key}-${pathname}`
|
|
8519
|
+
) : null
|
|
10818
8520
|
] }),
|
|
10819
8521
|
bridgeRoot
|
|
10820
8522
|
) : null;
|
|
@@ -10824,7 +8526,6 @@ export {
|
|
|
10824
8526
|
CustomToolbarButton,
|
|
10825
8527
|
CustomToolbarDivider,
|
|
10826
8528
|
DragHandle,
|
|
10827
|
-
DropIndicator,
|
|
10828
8529
|
ItemActionToolbar,
|
|
10829
8530
|
ItemInteractionLayer,
|
|
10830
8531
|
LinkEditorPanel,
|
|
@@ -10839,14 +8540,12 @@ export {
|
|
|
10839
8540
|
TooltipProvider,
|
|
10840
8541
|
TooltipTrigger,
|
|
10841
8542
|
buildTarget,
|
|
10842
|
-
dropIndicatorVariants,
|
|
10843
8543
|
filterAvailablePages,
|
|
10844
8544
|
getEditModeInitialState,
|
|
10845
8545
|
isEditSessionActive,
|
|
10846
8546
|
isValidUrl,
|
|
10847
8547
|
parseTarget,
|
|
10848
8548
|
toggleVariants,
|
|
10849
|
-
useOhwCarousel,
|
|
10850
8549
|
validateUrlInput
|
|
10851
8550
|
};
|
|
10852
8551
|
//# sourceMappingURL=index.js.map
|