@ohhwells/bridge 0.1.45 → 0.1.46-next.109
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 +12 -0
- package/dist/index.cjs +729 -153
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +780 -204
- package/dist/index.js.map +1 -1
- package/dist/styles.css +16 -18
- 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 React11, { useCallback as
|
|
4
|
+
import React11, { useCallback as useCallback5, useEffect as useEffect8, useLayoutEffect as useLayoutEffect3, useRef as useRef7, useState as useState7 } from "react";
|
|
5
5
|
import { createRoot } from "react-dom/client";
|
|
6
6
|
import { flushSync } from "react-dom";
|
|
7
7
|
|
|
@@ -48,12 +48,13 @@ function useLinkHrefGuardian(...deps) {
|
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
// src/ui/SchedulingWidget.tsx
|
|
51
|
-
import { useEffect, useId, useMemo, useRef, useState as useState2 } from "react";
|
|
51
|
+
import { useCallback, useEffect, useId, useMemo, useRef, useState as useState2 } from "react";
|
|
52
52
|
|
|
53
53
|
// src/ui/EmailCaptureModal.tsx
|
|
54
54
|
import { useState } from "react";
|
|
55
55
|
import { Dialog } from "radix-ui";
|
|
56
56
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
57
|
+
var isValidEmail = (value) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value);
|
|
57
58
|
function Spinner() {
|
|
58
59
|
return /* @__PURE__ */ jsxs(
|
|
59
60
|
"svg",
|
|
@@ -87,12 +88,17 @@ function EmailCaptureModal({ title, subtitle, onSubmit, onClose }) {
|
|
|
87
88
|
const [error, setError] = useState(null);
|
|
88
89
|
const isBook = title === "Confirm your spot";
|
|
89
90
|
const handleSubmit = async () => {
|
|
90
|
-
|
|
91
|
+
const trimmed = email.trim();
|
|
92
|
+
if (!trimmed) return;
|
|
93
|
+
if (!isValidEmail(trimmed)) {
|
|
94
|
+
setError("Please enter a valid email address.");
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
91
97
|
setLoading(true);
|
|
92
98
|
setError(null);
|
|
93
99
|
try {
|
|
94
|
-
await onSubmit(
|
|
95
|
-
setSubmittedEmail(
|
|
100
|
+
await onSubmit(trimmed);
|
|
101
|
+
setSubmittedEmail(trimmed);
|
|
96
102
|
setSuccess(true);
|
|
97
103
|
} catch (e) {
|
|
98
104
|
setError(e instanceof Error ? e.message : "Something went wrong. Please try again.");
|
|
@@ -167,7 +173,10 @@ function EmailCaptureModal({ title, subtitle, onSubmit, onClose }) {
|
|
|
167
173
|
{
|
|
168
174
|
type: "email",
|
|
169
175
|
value: email,
|
|
170
|
-
onChange: (e) =>
|
|
176
|
+
onChange: (e) => {
|
|
177
|
+
setEmail(e.target.value);
|
|
178
|
+
if (error) setError(null);
|
|
179
|
+
},
|
|
171
180
|
onKeyDown: handleKeyDown,
|
|
172
181
|
placeholder: "hello@gmail.com",
|
|
173
182
|
autoFocus: true,
|
|
@@ -224,12 +233,20 @@ function formatClassTime(cls) {
|
|
|
224
233
|
const em = endTotal % 60;
|
|
225
234
|
return `${h}:${cls.startTime.minutes}-${eh}:${String(em).padStart(2, "0")}`;
|
|
226
235
|
}
|
|
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
|
+
}
|
|
227
241
|
function getBookingsOnDate(cls, date) {
|
|
228
242
|
if (!cls.bookings?.length) return 0;
|
|
229
|
-
const
|
|
243
|
+
const target = new Date(date);
|
|
244
|
+
target.setHours(0, 0, 0, 0);
|
|
230
245
|
return cls.bookings.filter((b) => {
|
|
231
246
|
try {
|
|
232
|
-
|
|
247
|
+
const bookingDate = new Date(b.classDate);
|
|
248
|
+
bookingDate.setHours(0, 0, 0, 0);
|
|
249
|
+
return bookingDate.getTime() === target.getTime();
|
|
233
250
|
} catch {
|
|
234
251
|
return false;
|
|
235
252
|
}
|
|
@@ -494,7 +511,7 @@ function ScheduleView({ schedule, dates, selectedIdx, onSelectDate, onOpenModal
|
|
|
494
511
|
}
|
|
495
512
|
)
|
|
496
513
|
] }),
|
|
497
|
-
/* @__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: [
|
|
514
|
+
cls.showAvailability !== false && /* @__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: [
|
|
498
515
|
/* @__PURE__ */ jsxs2("span", { className: "font-body text-sm text-(--color-dark,#200C02) opacity-80", children: [
|
|
499
516
|
available,
|
|
500
517
|
"/",
|
|
@@ -506,9 +523,17 @@ function ScheduleView({ schedule, dates, selectedIdx, onSelectDate, onOpenModal
|
|
|
506
523
|
/* @__PURE__ */ jsxs2("div", { className: "flex flex-1 flex-col gap-2 min-w-0 sm:contents", children: [
|
|
507
524
|
/* @__PURE__ */ jsxs2("div", { className: "flex-1 flex flex-col gap-2 min-w-0", children: [
|
|
508
525
|
/* @__PURE__ */ jsx2("span", { className: "font-body text-base font-bold text-(--color-dark,#200C02) block truncate", children: cls.name }),
|
|
509
|
-
cls.hostName && /* @__PURE__ */ jsx2("span", { className: "font-body text-base font-normal text-(--color-dark,#200C02) opacity-80 block truncate", children: cls.hostName })
|
|
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(
|
|
528
|
+
"span",
|
|
529
|
+
{
|
|
530
|
+
className: "font-body text-base font-normal text-(--color-dark,#200C02) opacity-80 block",
|
|
531
|
+
style: { wordBreak: "break-word" },
|
|
532
|
+
children: cls.description
|
|
533
|
+
}
|
|
534
|
+
)
|
|
510
535
|
] }),
|
|
511
|
-
/* @__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: [
|
|
536
|
+
cls.showAvailability !== false && /* @__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: [
|
|
512
537
|
/* @__PURE__ */ jsxs2("span", { className: "font-body text-sm text-(--color-dark,#200C02) opacity-80", children: [
|
|
513
538
|
available,
|
|
514
539
|
"/",
|
|
@@ -533,7 +558,7 @@ function ScheduleView({ schedule, dates, selectedIdx, onSelectDate, onOpenModal
|
|
|
533
558
|
if (!cls.id) return;
|
|
534
559
|
onOpenModal?.(isFull ? "waitlist" : "book", cls.id, selectedDate);
|
|
535
560
|
},
|
|
536
|
-
children: isFull ? "Join Waitlist" :
|
|
561
|
+
children: isFull ? "Join Waitlist" : formatBookingLabel(cls)
|
|
537
562
|
}
|
|
538
563
|
)
|
|
539
564
|
] })
|
|
@@ -575,6 +600,17 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
575
600
|
const [isHovered, setIsHovered] = useState2(false);
|
|
576
601
|
const [modalState, setModalState] = useState2(null);
|
|
577
602
|
const switchScheduleIdRef = useRef(null);
|
|
603
|
+
const liveScheduleIdRef = useRef(null);
|
|
604
|
+
const refetchLiveSchedule = useCallback(async () => {
|
|
605
|
+
const id = liveScheduleIdRef.current;
|
|
606
|
+
if (!id) return;
|
|
607
|
+
try {
|
|
608
|
+
const res = await fetch(`${API_URL}/api/schedule/id/${id}`);
|
|
609
|
+
const data = await res.json();
|
|
610
|
+
if (data?.id) setSchedule(data);
|
|
611
|
+
} catch {
|
|
612
|
+
}
|
|
613
|
+
}, []);
|
|
578
614
|
const dates = useMemo(() => {
|
|
579
615
|
const today = /* @__PURE__ */ new Date();
|
|
580
616
|
today.setHours(0, 0, 0, 0);
|
|
@@ -594,6 +630,18 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
594
630
|
}
|
|
595
631
|
}
|
|
596
632
|
}, [schedule, dates]);
|
|
633
|
+
useEffect(() => {
|
|
634
|
+
if (typeof window === "undefined") return;
|
|
635
|
+
const onVisible = () => {
|
|
636
|
+
if (!document.hidden) void refetchLiveSchedule();
|
|
637
|
+
};
|
|
638
|
+
window.addEventListener("focus", refetchLiveSchedule);
|
|
639
|
+
document.addEventListener("visibilitychange", onVisible);
|
|
640
|
+
return () => {
|
|
641
|
+
window.removeEventListener("focus", refetchLiveSchedule);
|
|
642
|
+
document.removeEventListener("visibilitychange", onVisible);
|
|
643
|
+
};
|
|
644
|
+
}, [refetchLiveSchedule]);
|
|
597
645
|
useEffect(() => {
|
|
598
646
|
if (typeof window === "undefined") return;
|
|
599
647
|
const isInEditor = window.self !== window.top;
|
|
@@ -655,7 +703,7 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
655
703
|
setLoading(false);
|
|
656
704
|
return;
|
|
657
705
|
}
|
|
658
|
-
;
|
|
706
|
+
liveScheduleIdRef.current = effectiveId;
|
|
659
707
|
(async () => {
|
|
660
708
|
try {
|
|
661
709
|
const res = await fetch(`${API_URL}/api/schedule/id/${effectiveId}`);
|
|
@@ -712,18 +760,14 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
712
760
|
const data = await res.json().catch(() => ({}));
|
|
713
761
|
throw new Error(data?.message ?? "Something went wrong. Please try again.");
|
|
714
762
|
}
|
|
763
|
+
await refetchLiveSchedule();
|
|
715
764
|
};
|
|
716
765
|
const handleReplaceSchedule = () => {
|
|
717
766
|
setIsHovered(false);
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
insertAfter
|
|
723
|
-
}, "*");
|
|
724
|
-
} else {
|
|
725
|
-
window.parent.postMessage({ type: "ow:scheduling-not-connected", insertAfter }, "*");
|
|
726
|
-
}
|
|
767
|
+
window.parent.postMessage(
|
|
768
|
+
{ type: "ow:scheduling-not-connected", insertAfter, currentScheduleId: schedule?.id },
|
|
769
|
+
"*"
|
|
770
|
+
);
|
|
727
771
|
};
|
|
728
772
|
if (!inEditor && !loading && !schedule) return null;
|
|
729
773
|
const sectionId = `scheduling-${insertAfter}`;
|
|
@@ -766,7 +810,19 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
766
810
|
),
|
|
767
811
|
/* @__PURE__ */ jsxs2("div", { className: "max-w-[1280px] mx-auto flex flex-col items-center gap-16", children: [
|
|
768
812
|
/* @__PURE__ */ jsxs2("div", { className: "flex flex-col items-center gap-4", children: [
|
|
769
|
-
/* @__PURE__ */ jsx2(
|
|
813
|
+
/* @__PURE__ */ jsx2(
|
|
814
|
+
"h2",
|
|
815
|
+
{
|
|
816
|
+
className: "font-display text-center m-0 text-(--color-dark,#200C02)",
|
|
817
|
+
style: {
|
|
818
|
+
fontSize: "var(--fs-section-h2, clamp(40px, 4.4vw, 64px))",
|
|
819
|
+
fontWeight: "var(--font-weight-heading, 400)",
|
|
820
|
+
lineHeight: 1.05,
|
|
821
|
+
letterSpacing: "-0.02em"
|
|
822
|
+
},
|
|
823
|
+
children: schedule?.name ?? "Book an appointment"
|
|
824
|
+
}
|
|
825
|
+
),
|
|
770
826
|
schedule?.description && /* @__PURE__ */ jsx2("p", { className: "font-body text-body text-center m-0 text-(--color-accent,#A89B83)", children: schedule.description })
|
|
771
827
|
] }),
|
|
772
828
|
/* @__PURE__ */ jsxs2("div", { className: "w-full flex flex-col items-end gap-3", children: [
|
|
@@ -4826,7 +4882,11 @@ function MediaOverlay({
|
|
|
4826
4882
|
variant: "outline",
|
|
4827
4883
|
size: "sm",
|
|
4828
4884
|
className: "gap-1.5 cursor-pointer hover:bg-background",
|
|
4829
|
-
style:
|
|
4885
|
+
style: {
|
|
4886
|
+
...OVERLAY_BUTTON_STYLE,
|
|
4887
|
+
// Don't let Replace steal clicks when text (e.g. nav) sits on top of this media.
|
|
4888
|
+
pointerEvents: hover.hasTextOverlap ? "none" : "auto"
|
|
4889
|
+
},
|
|
4830
4890
|
onMouseDown: (e) => e.preventDefault(),
|
|
4831
4891
|
onClick: (e) => {
|
|
4832
4892
|
e.stopPropagation();
|
|
@@ -5603,7 +5663,7 @@ function LinkEditorPanel({ state, onClose }) {
|
|
|
5603
5663
|
}
|
|
5604
5664
|
|
|
5605
5665
|
// src/ui/link-modal/SectionPickerOverlay.tsx
|
|
5606
|
-
import { useCallback, useEffect as useEffect4, useMemo as useMemo2, useRef as useRef5, useState as useState4 } from "react";
|
|
5666
|
+
import { useCallback as useCallback2, useEffect as useEffect4, useMemo as useMemo2, useRef as useRef5, useState as useState4 } from "react";
|
|
5607
5667
|
import { createPortal } from "react-dom";
|
|
5608
5668
|
import { ArrowLeft, Check } from "lucide-react";
|
|
5609
5669
|
import { usePathname, useRouter } from "next/navigation";
|
|
@@ -5734,7 +5794,7 @@ function SectionPickerOverlay({
|
|
|
5734
5794
|
);
|
|
5735
5795
|
sectionIdsRef.current = sectionIds;
|
|
5736
5796
|
const rects = useSectionRects(sectionIdsKey, isOnTargetPage);
|
|
5737
|
-
const applyHoverAt =
|
|
5797
|
+
const applyHoverAt = useCallback2(
|
|
5738
5798
|
(x, y, liveRects) => {
|
|
5739
5799
|
const ids = sectionIdsRef.current;
|
|
5740
5800
|
const map = liveRects ?? readSectionRects(ids);
|
|
@@ -5814,7 +5874,7 @@ function SectionPickerOverlay({
|
|
|
5814
5874
|
window.removeEventListener("message", onPointerSync);
|
|
5815
5875
|
};
|
|
5816
5876
|
}, [rects, applyHoverAt]);
|
|
5817
|
-
const handleSelect =
|
|
5877
|
+
const handleSelect = useCallback2(
|
|
5818
5878
|
(section) => {
|
|
5819
5879
|
if (selectedId) return;
|
|
5820
5880
|
setSelectedId(section.id);
|
|
@@ -5945,7 +6005,7 @@ function SectionPickerOverlay({
|
|
|
5945
6005
|
}
|
|
5946
6006
|
|
|
5947
6007
|
// src/ui/link-modal/useLinkModalState.ts
|
|
5948
|
-
import { useCallback as
|
|
6008
|
+
import { useCallback as useCallback3, useEffect as useEffect5, useMemo as useMemo3, useState as useState5 } from "react";
|
|
5949
6009
|
function useLinkModalState({
|
|
5950
6010
|
open,
|
|
5951
6011
|
mode,
|
|
@@ -5964,7 +6024,7 @@ function useLinkModalState({
|
|
|
5964
6024
|
const [step, setStep] = useState5("input");
|
|
5965
6025
|
const [dropdownOpen, setDropdownOpen] = useState5(false);
|
|
5966
6026
|
const [urlError, setUrlError] = useState5("");
|
|
5967
|
-
const reset =
|
|
6027
|
+
const reset = useCallback3(() => {
|
|
5968
6028
|
setSearchValue("");
|
|
5969
6029
|
setSelectedPage(null);
|
|
5970
6030
|
setSelectedSection(null);
|
|
@@ -6600,6 +6660,8 @@ function applyNavOrderToContainer(container, order) {
|
|
|
6600
6660
|
if (current.length === expected.length && current.every((key, i) => key === expected[i])) {
|
|
6601
6661
|
return;
|
|
6602
6662
|
}
|
|
6663
|
+
const lastCurrentLinkEl = current.length > 0 ? findCounterpartByHrefKey(current[current.length - 1], container) : null;
|
|
6664
|
+
const anchor = lastCurrentLinkEl?.parentElement === container ? lastCurrentLinkEl.nextElementSibling : null;
|
|
6603
6665
|
const seen = /* @__PURE__ */ new Set();
|
|
6604
6666
|
for (const hrefKey of desired) {
|
|
6605
6667
|
if (seen.has(hrefKey)) continue;
|
|
@@ -6614,7 +6676,9 @@ function applyNavOrderToContainer(container, order) {
|
|
|
6614
6676
|
orderedEls.push(el);
|
|
6615
6677
|
}
|
|
6616
6678
|
for (const el of orderedEls) {
|
|
6617
|
-
if (
|
|
6679
|
+
if (anchor) {
|
|
6680
|
+
if (el.nextSibling !== anchor) container.insertBefore(el, anchor);
|
|
6681
|
+
} else if (container.lastElementChild !== el) {
|
|
6618
6682
|
container.appendChild(el);
|
|
6619
6683
|
}
|
|
6620
6684
|
}
|
|
@@ -6946,7 +7010,195 @@ function parseFooterOrder(content) {
|
|
|
6946
7010
|
return null;
|
|
6947
7011
|
}
|
|
6948
7012
|
}
|
|
7013
|
+
var FOOTER_HEADING_RE = /^footer-(\d+)-heading$/;
|
|
7014
|
+
var FOOTER_LABEL_RE = /^footer-(\d+)-(\d+)-label$/;
|
|
7015
|
+
var DEFAULT_FOOTER_COLUMN_HEADING = "New";
|
|
7016
|
+
var DEFAULT_FOOTER_COLUMN_LINK_LABEL = "New link";
|
|
7017
|
+
var DEFAULT_FOOTER_COLUMN_LINK_HREF = "";
|
|
7018
|
+
function isFooterLinksContainer(el) {
|
|
7019
|
+
return el.hasAttribute("data-ohw-footer-links") || el.classList.contains("rb-footer-links");
|
|
7020
|
+
}
|
|
7021
|
+
function getFooterColumnIndicesInDom() {
|
|
7022
|
+
const indices = /* @__PURE__ */ new Set();
|
|
7023
|
+
for (const col of listFooterColumns()) {
|
|
7024
|
+
const attr = col.getAttribute("data-ohw-footer-col");
|
|
7025
|
+
if (attr != null) {
|
|
7026
|
+
const n = parseInt(attr, 10);
|
|
7027
|
+
if (Number.isFinite(n)) indices.add(n);
|
|
7028
|
+
}
|
|
7029
|
+
for (const link of listFooterLinksInColumn(col)) {
|
|
7030
|
+
const parsed = parseFooterHrefKey(link.getAttribute("data-ohw-href-key"));
|
|
7031
|
+
if (parsed) indices.add(parsed.col);
|
|
7032
|
+
}
|
|
7033
|
+
const heading = col.querySelector('[data-ohw-key^="footer-"][data-ohw-key$="-heading"]');
|
|
7034
|
+
const headingKey = heading?.getAttribute("data-ohw-key");
|
|
7035
|
+
if (headingKey) {
|
|
7036
|
+
const match = headingKey.match(FOOTER_HEADING_RE);
|
|
7037
|
+
if (match) indices.add(parseInt(match[1], 10));
|
|
7038
|
+
}
|
|
7039
|
+
}
|
|
7040
|
+
return [...indices].sort((a, b) => a - b);
|
|
7041
|
+
}
|
|
7042
|
+
function getNextFooterColumnIndex() {
|
|
7043
|
+
const indices = getFooterColumnIndicesInDom();
|
|
7044
|
+
if (indices.length === 0) return 0;
|
|
7045
|
+
return Math.max(...indices) + 1;
|
|
7046
|
+
}
|
|
7047
|
+
function cloneFooterLinkShell(template) {
|
|
7048
|
+
const anchor = document.createElement("a");
|
|
7049
|
+
if (template) {
|
|
7050
|
+
anchor.style.cssText = template.style.cssText;
|
|
7051
|
+
if (template.className) anchor.className = template.className;
|
|
7052
|
+
}
|
|
7053
|
+
anchor.style.cursor = "pointer";
|
|
7054
|
+
anchor.style.textDecoration = "none";
|
|
7055
|
+
return anchor;
|
|
7056
|
+
}
|
|
7057
|
+
function buildFooterHeading(colIndex, text) {
|
|
7058
|
+
const heading = document.createElement("p");
|
|
7059
|
+
heading.setAttribute("data-ohw-editable", "text");
|
|
7060
|
+
heading.setAttribute("data-ohw-key", `footer-${colIndex}-heading`);
|
|
7061
|
+
heading.textContent = text;
|
|
7062
|
+
heading.style.cssText = [
|
|
7063
|
+
"color: var(--espresso, #3d312b)",
|
|
7064
|
+
"font-size: 14px",
|
|
7065
|
+
"font-weight: 800",
|
|
7066
|
+
"opacity: 0.82",
|
|
7067
|
+
"margin: 0 0 6px",
|
|
7068
|
+
"padding: 0",
|
|
7069
|
+
"line-height: 1.2"
|
|
7070
|
+
].join(";");
|
|
7071
|
+
return heading;
|
|
7072
|
+
}
|
|
7073
|
+
function buildFooterLink(colIndex, itemIndex, href, label, template) {
|
|
7074
|
+
const anchor = cloneFooterLinkShell(template);
|
|
7075
|
+
anchor.setAttribute("href", href);
|
|
7076
|
+
anchor.setAttribute("data-ohw-href-key", `footer-${colIndex}-${itemIndex}-href`);
|
|
7077
|
+
const span = document.createElement("span");
|
|
7078
|
+
span.setAttribute("data-ohw-editable", "text");
|
|
7079
|
+
span.setAttribute("data-ohw-key", `footer-${colIndex}-${itemIndex}-label`);
|
|
7080
|
+
span.textContent = label;
|
|
7081
|
+
anchor.appendChild(span);
|
|
7082
|
+
return anchor;
|
|
7083
|
+
}
|
|
7084
|
+
function footerColumnExistsInDom(colIndex) {
|
|
7085
|
+
return document.querySelector(`[data-ohw-footer-col="${colIndex}"]`) !== null || document.querySelector(`[data-ohw-href-key^="footer-${colIndex}-"]`) !== null || document.querySelector(`[data-ohw-key="footer-${colIndex}-heading"]`) !== null;
|
|
7086
|
+
}
|
|
7087
|
+
function getFooterLinkTemplate() {
|
|
7088
|
+
for (const col of listFooterColumns()) {
|
|
7089
|
+
const link = listFooterLinksInColumn(col)[0];
|
|
7090
|
+
if (link) return link;
|
|
7091
|
+
}
|
|
7092
|
+
return null;
|
|
7093
|
+
}
|
|
7094
|
+
function getFooterColumnTemplate() {
|
|
7095
|
+
return listFooterColumns()[0] ?? null;
|
|
7096
|
+
}
|
|
7097
|
+
function insertFooterColumnDom(colIndex, heading, items) {
|
|
7098
|
+
const container = getFooterLinksContainer();
|
|
7099
|
+
if (!container) return null;
|
|
7100
|
+
const colTemplate = getFooterColumnTemplate();
|
|
7101
|
+
const linkTemplate = getFooterLinkTemplate();
|
|
7102
|
+
const column = document.createElement("div");
|
|
7103
|
+
if (colTemplate?.className) column.className = colTemplate.className;
|
|
7104
|
+
else column.className = "rb-footer-link-col";
|
|
7105
|
+
column.setAttribute("data-ohw-footer-col", String(colIndex));
|
|
7106
|
+
if (colTemplate) {
|
|
7107
|
+
const gap = getComputedStyle(colTemplate).gap;
|
|
7108
|
+
if (gap && gap !== "normal") column.style.gap = gap;
|
|
7109
|
+
column.style.display = getComputedStyle(colTemplate).display || "flex";
|
|
7110
|
+
column.style.flexDirection = "column";
|
|
7111
|
+
}
|
|
7112
|
+
column.appendChild(buildFooterHeading(colIndex, heading));
|
|
7113
|
+
let firstLink = null;
|
|
7114
|
+
items.forEach((item, itemIndex) => {
|
|
7115
|
+
const link = buildFooterLink(colIndex, itemIndex, item.href, item.label, linkTemplate);
|
|
7116
|
+
column.appendChild(link);
|
|
7117
|
+
if (!firstLink) firstLink = link;
|
|
7118
|
+
});
|
|
7119
|
+
container.appendChild(column);
|
|
7120
|
+
return { column, firstLink };
|
|
7121
|
+
}
|
|
7122
|
+
function insertFooterColumn(heading = DEFAULT_FOOTER_COLUMN_HEADING, linkLabel = DEFAULT_FOOTER_COLUMN_LINK_LABEL, linkHref = DEFAULT_FOOTER_COLUMN_LINK_HREF) {
|
|
7123
|
+
const colIndex = getNextFooterColumnIndex();
|
|
7124
|
+
const inserted = insertFooterColumnDom(colIndex, heading, [{ href: linkHref, label: linkLabel }]);
|
|
7125
|
+
if (!inserted?.firstLink) throw new Error("Failed to insert footer column");
|
|
7126
|
+
syncFooterColumnIndices(listFooterColumns());
|
|
7127
|
+
return {
|
|
7128
|
+
column: inserted.column,
|
|
7129
|
+
firstLink: inserted.firstLink,
|
|
7130
|
+
colIndex,
|
|
7131
|
+
headingKey: `footer-${colIndex}-heading`,
|
|
7132
|
+
hrefKey: `footer-${colIndex}-0-href`,
|
|
7133
|
+
labelKey: `footer-${colIndex}-0-label`,
|
|
7134
|
+
heading,
|
|
7135
|
+
label: linkLabel,
|
|
7136
|
+
href: linkHref,
|
|
7137
|
+
order: getFooterOrderFromDom()
|
|
7138
|
+
};
|
|
7139
|
+
}
|
|
7140
|
+
function collectFooterColumnIndicesFromContent(content) {
|
|
7141
|
+
const indices = /* @__PURE__ */ new Set();
|
|
7142
|
+
for (const key of Object.keys(content)) {
|
|
7143
|
+
const href = parseFooterHrefKey(key);
|
|
7144
|
+
if (href) indices.add(href.col);
|
|
7145
|
+
const heading = key.match(FOOTER_HEADING_RE);
|
|
7146
|
+
if (heading) indices.add(parseInt(heading[1], 10));
|
|
7147
|
+
const label = key.match(FOOTER_LABEL_RE);
|
|
7148
|
+
if (label) indices.add(parseInt(label[1], 10));
|
|
7149
|
+
}
|
|
7150
|
+
const order = parseFooterOrder(content);
|
|
7151
|
+
if (order) {
|
|
7152
|
+
for (const col of order) {
|
|
7153
|
+
for (const hrefKey of col) {
|
|
7154
|
+
const parsed = parseFooterHrefKey(hrefKey);
|
|
7155
|
+
if (parsed) indices.add(parsed.col);
|
|
7156
|
+
}
|
|
7157
|
+
}
|
|
7158
|
+
}
|
|
7159
|
+
return [...indices].sort((a, b) => a - b);
|
|
7160
|
+
}
|
|
7161
|
+
function collectFooterItemsForColumn(content, colIndex) {
|
|
7162
|
+
const itemIndices = /* @__PURE__ */ new Set();
|
|
7163
|
+
for (const key of Object.keys(content)) {
|
|
7164
|
+
const href = parseFooterHrefKey(key);
|
|
7165
|
+
if (href?.col === colIndex) itemIndices.add(href.item);
|
|
7166
|
+
const label = key.match(FOOTER_LABEL_RE);
|
|
7167
|
+
if (label && parseInt(label[1], 10) === colIndex) {
|
|
7168
|
+
itemIndices.add(parseInt(label[2], 10));
|
|
7169
|
+
}
|
|
7170
|
+
}
|
|
7171
|
+
const sorted = [...itemIndices].sort((a, b) => a - b);
|
|
7172
|
+
if (sorted.length === 0) {
|
|
7173
|
+
return [
|
|
7174
|
+
{
|
|
7175
|
+
href: content[`footer-${colIndex}-0-href`] ?? DEFAULT_FOOTER_COLUMN_LINK_HREF,
|
|
7176
|
+
label: content[`footer-${colIndex}-0-label`] ?? DEFAULT_FOOTER_COLUMN_LINK_LABEL
|
|
7177
|
+
}
|
|
7178
|
+
];
|
|
7179
|
+
}
|
|
7180
|
+
return sorted.map((itemIndex) => ({
|
|
7181
|
+
href: content[`footer-${colIndex}-${itemIndex}-href`] ?? DEFAULT_FOOTER_COLUMN_LINK_HREF,
|
|
7182
|
+
label: content[`footer-${colIndex}-${itemIndex}-label`] ?? DEFAULT_FOOTER_COLUMN_LINK_LABEL
|
|
7183
|
+
}));
|
|
7184
|
+
}
|
|
7185
|
+
function reconcileFooterColumnsFromContent(content) {
|
|
7186
|
+
const indices = collectFooterColumnIndicesFromContent(content);
|
|
7187
|
+
for (const colIndex of indices) {
|
|
7188
|
+
if (footerColumnExistsInDom(colIndex)) continue;
|
|
7189
|
+
const heading = content[`footer-${colIndex}-heading`] ?? DEFAULT_FOOTER_COLUMN_HEADING;
|
|
7190
|
+
const items = collectFooterItemsForColumn(content, colIndex);
|
|
7191
|
+
const hasPayload = Boolean(content[`footer-${colIndex}-heading`]) || items.some(
|
|
7192
|
+
(_, i) => content[`footer-${colIndex}-${i}-href`] !== void 0 || content[`footer-${colIndex}-${i}-label`] !== void 0
|
|
7193
|
+
) || (parseFooterOrder(content)?.some(
|
|
7194
|
+
(col) => col.some((k) => parseFooterHrefKey(k)?.col === colIndex)
|
|
7195
|
+
) ?? false);
|
|
7196
|
+
if (!hasPayload) continue;
|
|
7197
|
+
insertFooterColumnDom(colIndex, heading, items);
|
|
7198
|
+
}
|
|
7199
|
+
}
|
|
6949
7200
|
function reconcileFooterOrderFromContent(content) {
|
|
7201
|
+
reconcileFooterColumnsFromContent(content);
|
|
6950
7202
|
const order = parseFooterOrder(content);
|
|
6951
7203
|
if (!order?.length) return;
|
|
6952
7204
|
const current = getFooterOrderFromDom();
|
|
@@ -6956,6 +7208,31 @@ function reconcileFooterOrderFromContent(content) {
|
|
|
6956
7208
|
}
|
|
6957
7209
|
applyFooterOrder(order);
|
|
6958
7210
|
}
|
|
7211
|
+
function resolveFooterLinksContainerSelectionTarget(target, clientX, clientY, isPointOverItem) {
|
|
7212
|
+
const container = getFooterLinksContainer();
|
|
7213
|
+
if (!container) return null;
|
|
7214
|
+
const inContainer = target === container || container.contains(target) && Boolean(target.closest("[data-ohw-footer-links], .rb-footer-links"));
|
|
7215
|
+
if (!inContainer && target !== container) {
|
|
7216
|
+
const r2 = container.getBoundingClientRect();
|
|
7217
|
+
const over = clientX >= r2.left && clientX <= r2.right && clientY >= r2.top && clientY <= r2.bottom;
|
|
7218
|
+
if (!over) return null;
|
|
7219
|
+
}
|
|
7220
|
+
if (isPointOverItem(container, clientX, clientY)) return null;
|
|
7221
|
+
const column = target.closest("[data-ohw-footer-col], [data-ohw-footer-column]") ?? null;
|
|
7222
|
+
if (column && container.contains(column)) {
|
|
7223
|
+
if (target === column || column.contains(target)) return null;
|
|
7224
|
+
}
|
|
7225
|
+
if (target === container || container.contains(target) || inContainer) {
|
|
7226
|
+
if (target === container || isFooterLinksContainer(target)) return container;
|
|
7227
|
+
if (!column) return container;
|
|
7228
|
+
}
|
|
7229
|
+
return null;
|
|
7230
|
+
}
|
|
7231
|
+
function isRowLayoutColumn(links) {
|
|
7232
|
+
if (links.length < 2) return false;
|
|
7233
|
+
const firstTop = links[0].getBoundingClientRect().top;
|
|
7234
|
+
return links.every((link) => Math.abs(link.getBoundingClientRect().top - firstTop) < 4);
|
|
7235
|
+
}
|
|
6959
7236
|
function buildLinkDropSlots(column, columnIndex) {
|
|
6960
7237
|
const links = listFooterLinksInColumn(column);
|
|
6961
7238
|
const colRect = column.getBoundingClientRect();
|
|
@@ -6973,6 +7250,32 @@ function buildLinkDropSlots(column, columnIndex) {
|
|
|
6973
7250
|
});
|
|
6974
7251
|
return slots;
|
|
6975
7252
|
}
|
|
7253
|
+
if (isRowLayoutColumn(links)) {
|
|
7254
|
+
for (let i = 0; i <= links.length; i++) {
|
|
7255
|
+
let left;
|
|
7256
|
+
if (i === 0) {
|
|
7257
|
+
left = links[0].getBoundingClientRect().left - barThickness / 2;
|
|
7258
|
+
} else if (i === links.length) {
|
|
7259
|
+
const last = links[links.length - 1].getBoundingClientRect();
|
|
7260
|
+
left = last.right - barThickness / 2;
|
|
7261
|
+
} else {
|
|
7262
|
+
const prev = links[i - 1].getBoundingClientRect();
|
|
7263
|
+
const next = links[i].getBoundingClientRect();
|
|
7264
|
+
left = (prev.right + next.left) / 2 - barThickness / 2;
|
|
7265
|
+
}
|
|
7266
|
+
const heightRef = i === 0 ? links[0].getBoundingClientRect() : i === links.length ? links[links.length - 1].getBoundingClientRect() : links[i].getBoundingClientRect();
|
|
7267
|
+
slots.push({
|
|
7268
|
+
insertIndex: i,
|
|
7269
|
+
columnIndex,
|
|
7270
|
+
left,
|
|
7271
|
+
top: heightRef.top,
|
|
7272
|
+
width: barThickness,
|
|
7273
|
+
height: Math.max(heightRef.height, colRect.height * 0.8),
|
|
7274
|
+
direction: "vertical"
|
|
7275
|
+
});
|
|
7276
|
+
}
|
|
7277
|
+
return slots;
|
|
7278
|
+
}
|
|
6976
7279
|
for (let i = 0; i <= links.length; i++) {
|
|
6977
7280
|
let top;
|
|
6978
7281
|
if (i === 0) {
|
|
@@ -7056,8 +7359,7 @@ function hitTestLinkDropSlot(clientX, clientY, draggedHrefKey) {
|
|
|
7056
7359
|
return true;
|
|
7057
7360
|
});
|
|
7058
7361
|
for (const slot of slots) {
|
|
7059
|
-
const
|
|
7060
|
-
const dist = Math.abs(clientY - cy) + (inColX ? 0 : 1e3);
|
|
7362
|
+
const dist = slot.direction === "vertical" ? Math.abs(clientX - (slot.left + slot.width / 2)) : Math.abs(clientY - (slot.top + slot.height / 2));
|
|
7061
7363
|
if (!best || dist < best.dist) best = { slot, dist };
|
|
7062
7364
|
}
|
|
7063
7365
|
}
|
|
@@ -7081,6 +7383,30 @@ function hitTestColumnDropSlot(clientX, _clientY) {
|
|
|
7081
7383
|
return best?.slot ?? null;
|
|
7082
7384
|
}
|
|
7083
7385
|
|
|
7386
|
+
// src/lib/add-footer-column.ts
|
|
7387
|
+
function buildFooterColumnEditContentPatch(result) {
|
|
7388
|
+
return {
|
|
7389
|
+
[result.headingKey]: result.heading,
|
|
7390
|
+
[result.hrefKey]: result.href,
|
|
7391
|
+
[result.labelKey]: result.label,
|
|
7392
|
+
[FOOTER_ORDER_KEY]: JSON.stringify(result.order)
|
|
7393
|
+
};
|
|
7394
|
+
}
|
|
7395
|
+
function addFooterColumnWithPersist({
|
|
7396
|
+
postToParent: postToParent2
|
|
7397
|
+
}) {
|
|
7398
|
+
const result = insertFooterColumn();
|
|
7399
|
+
const patch = buildFooterColumnEditContentPatch(result);
|
|
7400
|
+
setStoredLinkHref(result.hrefKey, result.href);
|
|
7401
|
+
postToParent2({
|
|
7402
|
+
type: "ow:change",
|
|
7403
|
+
nodes: Object.entries(patch).map(([key, text]) => ({ key, text }))
|
|
7404
|
+
});
|
|
7405
|
+
postToParent2({ type: "ow:toast", title: "Item added", toastType: "success" });
|
|
7406
|
+
enforceLinkHrefs();
|
|
7407
|
+
return result;
|
|
7408
|
+
}
|
|
7409
|
+
|
|
7084
7410
|
// src/lib/item-drag-interaction.ts
|
|
7085
7411
|
function disableNativeHrefDrag(el) {
|
|
7086
7412
|
if (el.draggable) el.draggable = false;
|
|
@@ -7101,9 +7427,10 @@ function lockItemDuringDrag() {
|
|
|
7101
7427
|
clearTextSelection();
|
|
7102
7428
|
}
|
|
7103
7429
|
function unlockItemDragInteraction() {
|
|
7430
|
+
const wasDragging = document.documentElement.hasAttribute("data-ohw-item-dragging");
|
|
7104
7431
|
document.documentElement.removeAttribute("data-ohw-footer-press-drag");
|
|
7105
7432
|
document.documentElement.removeAttribute("data-ohw-item-dragging");
|
|
7106
|
-
clearTextSelection();
|
|
7433
|
+
if (wasDragging) clearTextSelection();
|
|
7107
7434
|
}
|
|
7108
7435
|
var armFooterPressDrag = armItemPressDrag;
|
|
7109
7436
|
var lockFooterDuringDrag = lockItemDuringDrag;
|
|
@@ -7277,7 +7604,7 @@ function hitTestNavDropSlot(clientX, clientY, draggedHrefKey) {
|
|
|
7277
7604
|
}
|
|
7278
7605
|
|
|
7279
7606
|
// src/useNavItemDrag.ts
|
|
7280
|
-
import { useCallback as
|
|
7607
|
+
import { useCallback as useCallback4, useEffect as useEffect7, useRef as useRef6, useState as useState6 } from "react";
|
|
7281
7608
|
function useNavItemDrag({
|
|
7282
7609
|
isEditMode,
|
|
7283
7610
|
editContentRef,
|
|
@@ -7306,7 +7633,7 @@ function useNavItemDrag({
|
|
|
7306
7633
|
const [navDropSlots, setNavDropSlots] = useState6([]);
|
|
7307
7634
|
const [activeNavDropIndex, setActiveNavDropIndex] = useState6(null);
|
|
7308
7635
|
const navPointerDragRef = useRef6(null);
|
|
7309
|
-
const clearNavDragVisuals =
|
|
7636
|
+
const clearNavDragVisuals = useCallback4(() => {
|
|
7310
7637
|
navDragRef.current = null;
|
|
7311
7638
|
setNavDropSlots([]);
|
|
7312
7639
|
setActiveNavDropIndex(null);
|
|
@@ -7315,7 +7642,7 @@ function useNavItemDrag({
|
|
|
7315
7642
|
setIsItemDragging(false);
|
|
7316
7643
|
unlockItemDragInteraction();
|
|
7317
7644
|
}, [setDraggedItemRect, setIsItemDragging, setSiblingHintRects]);
|
|
7318
|
-
const refreshNavDragVisuals =
|
|
7645
|
+
const refreshNavDragVisuals = useCallback4(
|
|
7319
7646
|
(session, activeSlot, clientX, clientY) => {
|
|
7320
7647
|
setDraggedItemRect(session.draggedEl.getBoundingClientRect());
|
|
7321
7648
|
if (typeof clientX === "number" && typeof clientY === "number") {
|
|
@@ -7339,7 +7666,7 @@ function useNavItemDrag({
|
|
|
7339
7666
|
});
|
|
7340
7667
|
const beginNavDragRef = useRef6(() => {
|
|
7341
7668
|
});
|
|
7342
|
-
const beginNavDrag =
|
|
7669
|
+
const beginNavDrag = useCallback4(
|
|
7343
7670
|
(session) => {
|
|
7344
7671
|
const rect = session.draggedEl.getBoundingClientRect();
|
|
7345
7672
|
session.lastClientX = session.lastClientX || rect.left + rect.width / 2;
|
|
@@ -7366,7 +7693,7 @@ function useNavItemDrag({
|
|
|
7366
7693
|
]
|
|
7367
7694
|
);
|
|
7368
7695
|
beginNavDragRef.current = beginNavDrag;
|
|
7369
|
-
const commitNavDrag =
|
|
7696
|
+
const commitNavDrag = useCallback4(
|
|
7370
7697
|
(clientX, clientY) => {
|
|
7371
7698
|
const session = navDragRef.current;
|
|
7372
7699
|
if (!session) {
|
|
@@ -7427,7 +7754,7 @@ function useNavItemDrag({
|
|
|
7427
7754
|
[clearNavDragVisuals, deselectRef, editContentRef, postToParentRef, selectRef]
|
|
7428
7755
|
);
|
|
7429
7756
|
commitNavDragRef.current = commitNavDrag;
|
|
7430
|
-
const startNavLinkDrag =
|
|
7757
|
+
const startNavLinkDrag = useCallback4(
|
|
7431
7758
|
(anchor, clientX, clientY, wasSelected) => {
|
|
7432
7759
|
if (footerDragRef.current) return false;
|
|
7433
7760
|
const hrefKey = anchor.getAttribute("data-ohw-href-key");
|
|
@@ -7445,7 +7772,7 @@ function useNavItemDrag({
|
|
|
7445
7772
|
},
|
|
7446
7773
|
[beginNavDrag, footerDragRef, isDragHandleDisabled2, isNavbarButton3]
|
|
7447
7774
|
);
|
|
7448
|
-
const onNavDragOver =
|
|
7775
|
+
const onNavDragOver = useCallback4(
|
|
7449
7776
|
(e) => {
|
|
7450
7777
|
const session = navDragRef.current;
|
|
7451
7778
|
if (!session) return false;
|
|
@@ -7480,7 +7807,6 @@ function useNavItemDrag({
|
|
|
7480
7807
|
const hrefKey = anchor?.getAttribute("data-ohw-href-key") ?? null;
|
|
7481
7808
|
if (!anchor || !isNavbarHrefKey(hrefKey)) return;
|
|
7482
7809
|
if (isNavbarButton3(anchor) || isDragHandleDisabled2(anchor)) return;
|
|
7483
|
-
armItemPressDrag();
|
|
7484
7810
|
navPointerDragRef.current = {
|
|
7485
7811
|
el: anchor,
|
|
7486
7812
|
startX: e.clientX,
|
|
@@ -7507,6 +7833,7 @@ function useNavItemDrag({
|
|
|
7507
7833
|
if (dx * dx + dy * dy < THRESHOLD * THRESHOLD) return;
|
|
7508
7834
|
e.preventDefault();
|
|
7509
7835
|
pending.started = true;
|
|
7836
|
+
armItemPressDrag();
|
|
7510
7837
|
clearTextSelection();
|
|
7511
7838
|
try {
|
|
7512
7839
|
document.body.setPointerCapture(pending.pointerId);
|
|
@@ -7534,7 +7861,8 @@ function useNavItemDrag({
|
|
|
7534
7861
|
}
|
|
7535
7862
|
} catch {
|
|
7536
7863
|
}
|
|
7537
|
-
if (!pending
|
|
7864
|
+
if (!pending) return;
|
|
7865
|
+
if (!pending.started) {
|
|
7538
7866
|
unlockItemDragInteraction();
|
|
7539
7867
|
return;
|
|
7540
7868
|
}
|
|
@@ -7581,12 +7909,11 @@ function useNavItemDrag({
|
|
|
7581
7909
|
setLinkPopover,
|
|
7582
7910
|
suppressNextClickRef
|
|
7583
7911
|
]);
|
|
7584
|
-
const armNavPressFromChrome =
|
|
7912
|
+
const armNavPressFromChrome = useCallback4(
|
|
7585
7913
|
(selected, clientX, clientY, pointerId) => {
|
|
7586
7914
|
const hrefKey = selected.getAttribute("data-ohw-href-key");
|
|
7587
7915
|
if (!hrefKey || !isNavbarHrefKey(hrefKey)) return false;
|
|
7588
7916
|
if (isNavbarButton3(selected) || isDragHandleDisabled2(selected)) return false;
|
|
7589
|
-
armItemPressDrag();
|
|
7590
7917
|
navPointerDragRef.current = {
|
|
7591
7918
|
el: selected,
|
|
7592
7919
|
startX: clientX,
|
|
@@ -7612,15 +7939,60 @@ function useNavItemDrag({
|
|
|
7612
7939
|
};
|
|
7613
7940
|
}
|
|
7614
7941
|
|
|
7615
|
-
// src/ui/
|
|
7942
|
+
// src/ui/footer-container-chrome.tsx
|
|
7616
7943
|
import { Plus as Plus2 } from "lucide-react";
|
|
7617
|
-
import { jsx as jsx21 } from "react/jsx-runtime";
|
|
7944
|
+
import { jsx as jsx21, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
7945
|
+
function FooterContainerChrome({ rect, onAdd }) {
|
|
7946
|
+
const chromeGap = 6;
|
|
7947
|
+
const buttonMargin = 7;
|
|
7948
|
+
return /* @__PURE__ */ jsx21(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ jsx21(
|
|
7949
|
+
"div",
|
|
7950
|
+
{
|
|
7951
|
+
"data-ohw-footer-container-chrome": "",
|
|
7952
|
+
"data-ohw-bridge": "",
|
|
7953
|
+
className: "pointer-events-none fixed z-[2147483647]",
|
|
7954
|
+
style: {
|
|
7955
|
+
top: rect.top - chromeGap,
|
|
7956
|
+
left: rect.left - chromeGap,
|
|
7957
|
+
width: rect.width + chromeGap * 2,
|
|
7958
|
+
height: rect.height + chromeGap * 2
|
|
7959
|
+
},
|
|
7960
|
+
children: /* @__PURE__ */ jsxs13(Tooltip, { children: [
|
|
7961
|
+
/* @__PURE__ */ jsx21(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx21(
|
|
7962
|
+
"button",
|
|
7963
|
+
{
|
|
7964
|
+
type: "button",
|
|
7965
|
+
"data-ohw-footer-add-button": "",
|
|
7966
|
+
className: "pointer-events-auto absolute left-1/2 flex size-7 -translate-x-1/2 -translate-y-full items-center justify-center rounded-[10px] border border-border bg-background p-0.5 shadow-sm transition-colors hover:bg-muted/80",
|
|
7967
|
+
style: { top: chromeGap - buttonMargin },
|
|
7968
|
+
"aria-label": "Add item",
|
|
7969
|
+
onMouseDown: (e) => {
|
|
7970
|
+
e.preventDefault();
|
|
7971
|
+
e.stopPropagation();
|
|
7972
|
+
},
|
|
7973
|
+
onClick: (e) => {
|
|
7974
|
+
e.preventDefault();
|
|
7975
|
+
e.stopPropagation();
|
|
7976
|
+
onAdd();
|
|
7977
|
+
},
|
|
7978
|
+
children: /* @__PURE__ */ jsx21(Plus2, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
|
|
7979
|
+
}
|
|
7980
|
+
) }),
|
|
7981
|
+
/* @__PURE__ */ jsx21(TooltipContent, { side: "bottom", sideOffset: 9, children: "Add item" })
|
|
7982
|
+
] })
|
|
7983
|
+
}
|
|
7984
|
+
) });
|
|
7985
|
+
}
|
|
7986
|
+
|
|
7987
|
+
// src/ui/navbar-container-chrome.tsx
|
|
7988
|
+
import { Plus as Plus3 } from "lucide-react";
|
|
7989
|
+
import { jsx as jsx22 } from "react/jsx-runtime";
|
|
7618
7990
|
function NavbarContainerChrome({
|
|
7619
7991
|
rect,
|
|
7620
7992
|
onAdd
|
|
7621
7993
|
}) {
|
|
7622
7994
|
const chromeGap = 6;
|
|
7623
|
-
return /* @__PURE__ */
|
|
7995
|
+
return /* @__PURE__ */ jsx22(
|
|
7624
7996
|
"div",
|
|
7625
7997
|
{
|
|
7626
7998
|
"data-ohw-navbar-container-chrome": "",
|
|
@@ -7632,7 +8004,7 @@ function NavbarContainerChrome({
|
|
|
7632
8004
|
width: rect.width + chromeGap * 2,
|
|
7633
8005
|
height: rect.height + chromeGap * 2
|
|
7634
8006
|
},
|
|
7635
|
-
children: /* @__PURE__ */
|
|
8007
|
+
children: /* @__PURE__ */ jsx22(
|
|
7636
8008
|
"button",
|
|
7637
8009
|
{
|
|
7638
8010
|
type: "button",
|
|
@@ -7649,7 +8021,7 @@ function NavbarContainerChrome({
|
|
|
7649
8021
|
e.stopPropagation();
|
|
7650
8022
|
onAdd();
|
|
7651
8023
|
},
|
|
7652
|
-
children: /* @__PURE__ */
|
|
8024
|
+
children: /* @__PURE__ */ jsx22(Plus3, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
|
|
7653
8025
|
}
|
|
7654
8026
|
)
|
|
7655
8027
|
}
|
|
@@ -7658,7 +8030,7 @@ function NavbarContainerChrome({
|
|
|
7658
8030
|
|
|
7659
8031
|
// src/ui/drop-indicator.tsx
|
|
7660
8032
|
import * as React10 from "react";
|
|
7661
|
-
import { jsx as
|
|
8033
|
+
import { jsx as jsx23 } from "react/jsx-runtime";
|
|
7662
8034
|
var dropIndicatorVariants = cva(
|
|
7663
8035
|
"ov-gap-line pointer-events-none shrink-0 transition-opacity duration-150",
|
|
7664
8036
|
{
|
|
@@ -7682,7 +8054,7 @@ var dropIndicatorVariants = cva(
|
|
|
7682
8054
|
);
|
|
7683
8055
|
var DropIndicator = React10.forwardRef(
|
|
7684
8056
|
({ className, direction, state, ...props }, ref) => {
|
|
7685
|
-
return /* @__PURE__ */
|
|
8057
|
+
return /* @__PURE__ */ jsx23(
|
|
7686
8058
|
"div",
|
|
7687
8059
|
{
|
|
7688
8060
|
ref,
|
|
@@ -7699,7 +8071,7 @@ var DropIndicator = React10.forwardRef(
|
|
|
7699
8071
|
DropIndicator.displayName = "DropIndicator";
|
|
7700
8072
|
|
|
7701
8073
|
// src/ui/badge.tsx
|
|
7702
|
-
import { jsx as
|
|
8074
|
+
import { jsx as jsx24 } from "react/jsx-runtime";
|
|
7703
8075
|
var badgeVariants = cva(
|
|
7704
8076
|
"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",
|
|
7705
8077
|
{
|
|
@@ -7717,12 +8089,12 @@ var badgeVariants = cva(
|
|
|
7717
8089
|
}
|
|
7718
8090
|
);
|
|
7719
8091
|
function Badge({ className, variant, ...props }) {
|
|
7720
|
-
return /* @__PURE__ */
|
|
8092
|
+
return /* @__PURE__ */ jsx24("div", { className: cn(badgeVariants({ variant }), className), ...props });
|
|
7721
8093
|
}
|
|
7722
8094
|
|
|
7723
8095
|
// src/OhhwellsBridge.tsx
|
|
7724
8096
|
import { Link as Link2 } from "lucide-react";
|
|
7725
|
-
import { Fragment as Fragment5, jsx as
|
|
8097
|
+
import { Fragment as Fragment5, jsx as jsx25, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
7726
8098
|
var PRIMARY2 = "#0885FE";
|
|
7727
8099
|
var IMAGE_FADE_MS = 300;
|
|
7728
8100
|
function runOpacityFade(el, onDone) {
|
|
@@ -7901,7 +8273,7 @@ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId,
|
|
|
7901
8273
|
const root = createRoot(container);
|
|
7902
8274
|
flushSync(() => {
|
|
7903
8275
|
root.render(
|
|
7904
|
-
/* @__PURE__ */
|
|
8276
|
+
/* @__PURE__ */ jsx25(
|
|
7905
8277
|
SchedulingWidget,
|
|
7906
8278
|
{
|
|
7907
8279
|
notifyOnConnect,
|
|
@@ -8102,7 +8474,7 @@ function applyLinkByKey(key, val) {
|
|
|
8102
8474
|
}
|
|
8103
8475
|
function isInsideLinkEditor(target) {
|
|
8104
8476
|
return Boolean(
|
|
8105
|
-
target.closest("[data-ohw-link-popover-root]") || target.closest("[data-ohw-link-modal-root]") || target.closest("[data-ohw-link-page-dropdown]") || target.closest("[data-ohw-section-picker]") || target.closest("[data-ohw-navbar-container-chrome]") || target.closest("[data-ohw-navbar-add-button]") || target.closest('[data-slot="popover-content"]') || target.closest('[data-slot="dialog-content"]') || target.closest('[data-slot="dialog-overlay"]')
|
|
8477
|
+
target.closest("[data-ohw-link-popover-root]") || target.closest("[data-ohw-link-modal-root]") || target.closest("[data-ohw-link-page-dropdown]") || target.closest("[data-ohw-section-picker]") || target.closest("[data-ohw-navbar-container-chrome]") || target.closest("[data-ohw-navbar-add-button]") || target.closest("[data-ohw-footer-container-chrome]") || target.closest("[data-ohw-footer-add-button]") || target.closest('[data-slot="popover-content"]') || target.closest('[data-slot="dialog-content"]') || target.closest('[data-slot="dialog-overlay"]')
|
|
8106
8478
|
);
|
|
8107
8479
|
}
|
|
8108
8480
|
function getHrefKeyFromElement(el) {
|
|
@@ -8183,7 +8555,7 @@ function isInferredFooterGroup(el) {
|
|
|
8183
8555
|
return countFooterNavItems(el) >= 2;
|
|
8184
8556
|
}
|
|
8185
8557
|
function isNavigationContainer(el) {
|
|
8186
|
-
return el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isNavigationRoot(el) || isInferredFooterGroup(el);
|
|
8558
|
+
return el.hasAttribute("data-ohw-nav-container") || isFooterLinksContainer(el) || el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isNavigationRoot(el) || isInferredFooterGroup(el);
|
|
8187
8559
|
}
|
|
8188
8560
|
function isNavbarLinksContainer(el) {
|
|
8189
8561
|
return el.hasAttribute("data-ohw-nav-container");
|
|
@@ -8202,6 +8574,9 @@ function isPointOverNavigation(x, y) {
|
|
|
8202
8574
|
const roots = /* @__PURE__ */ new Set();
|
|
8203
8575
|
const navRoot = document.querySelector("[data-ohw-nav-root]") ?? document.querySelector("nav");
|
|
8204
8576
|
if (navRoot) roots.add(navRoot);
|
|
8577
|
+
document.querySelectorAll("[data-ohw-nav-drawer], [data-ohw-nav-container]").forEach((el) => {
|
|
8578
|
+
roots.add(el);
|
|
8579
|
+
});
|
|
8205
8580
|
const footer = document.querySelector("footer");
|
|
8206
8581
|
if (footer) roots.add(footer);
|
|
8207
8582
|
for (const root of roots) {
|
|
@@ -8230,6 +8605,12 @@ function isPointOverNavItem(container, x, y) {
|
|
|
8230
8605
|
return x >= itemRect.left && x <= itemRect.right && y >= itemRect.top && y <= itemRect.bottom;
|
|
8231
8606
|
});
|
|
8232
8607
|
}
|
|
8608
|
+
function isPointOverFooterColumn(x, y) {
|
|
8609
|
+
return listFooterColumns().some((col) => {
|
|
8610
|
+
const r2 = col.getBoundingClientRect();
|
|
8611
|
+
return x >= r2.left && x <= r2.right && y >= r2.top && y <= r2.bottom;
|
|
8612
|
+
});
|
|
8613
|
+
}
|
|
8233
8614
|
function resolveNavContainerSelectionTarget(target, clientX, clientY) {
|
|
8234
8615
|
if (getNavigationItemAnchor(target)) return null;
|
|
8235
8616
|
if (target.closest('[data-ohw-role="navbar-button"]')) return null;
|
|
@@ -8260,7 +8641,10 @@ function getNavigationSelectionParent(el) {
|
|
|
8260
8641
|
if (footerGroup) return footerGroup;
|
|
8261
8642
|
return getNavigationRoot(el);
|
|
8262
8643
|
}
|
|
8263
|
-
if (el
|
|
8644
|
+
if (!isFooterLinksContainer(el) && (el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isInferredFooterGroup(el))) {
|
|
8645
|
+
return getFooterLinksContainer();
|
|
8646
|
+
}
|
|
8647
|
+
if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isFooterLinksContainer(el) || isInferredFooterGroup(el)) {
|
|
8264
8648
|
return getNavigationRoot(el);
|
|
8265
8649
|
}
|
|
8266
8650
|
return null;
|
|
@@ -8431,9 +8815,16 @@ function sanitizeHtml(html) {
|
|
|
8431
8815
|
if (!SAFE_TAGS.has(el.tagName)) {
|
|
8432
8816
|
parent.replaceChild(document.createTextNode(el.textContent ?? ""), el);
|
|
8433
8817
|
} else {
|
|
8434
|
-
const
|
|
8818
|
+
const htmlEl = el;
|
|
8819
|
+
const textAlign = htmlEl.style?.textAlign || el.getAttribute("align") || "";
|
|
8820
|
+
const fontWeight = htmlEl.style?.fontWeight || "";
|
|
8821
|
+
const fontStyle = htmlEl.style?.fontStyle || "";
|
|
8822
|
+
const textDecorationLine = htmlEl.style?.textDecorationLine || htmlEl.style?.textDecoration || "";
|
|
8435
8823
|
for (const attr of Array.from(el.attributes)) el.removeAttribute(attr.name);
|
|
8436
|
-
if (textAlign)
|
|
8824
|
+
if (textAlign) htmlEl.style.textAlign = textAlign;
|
|
8825
|
+
if (fontWeight) htmlEl.style.fontWeight = fontWeight;
|
|
8826
|
+
if (fontStyle) htmlEl.style.fontStyle = fontStyle;
|
|
8827
|
+
if (textDecorationLine) htmlEl.style.textDecorationLine = textDecorationLine;
|
|
8437
8828
|
walk(el);
|
|
8438
8829
|
}
|
|
8439
8830
|
}
|
|
@@ -8480,7 +8871,7 @@ function EditGlowChrome({
|
|
|
8480
8871
|
hideHandle = false
|
|
8481
8872
|
}) {
|
|
8482
8873
|
const GAP = SELECTION_CHROME_GAP2;
|
|
8483
|
-
return /* @__PURE__ */
|
|
8874
|
+
return /* @__PURE__ */ jsxs14(
|
|
8484
8875
|
"div",
|
|
8485
8876
|
{
|
|
8486
8877
|
ref: elRef,
|
|
@@ -8495,7 +8886,7 @@ function EditGlowChrome({
|
|
|
8495
8886
|
zIndex: 2147483646
|
|
8496
8887
|
},
|
|
8497
8888
|
children: [
|
|
8498
|
-
/* @__PURE__ */
|
|
8889
|
+
/* @__PURE__ */ jsx25(
|
|
8499
8890
|
"div",
|
|
8500
8891
|
{
|
|
8501
8892
|
style: {
|
|
@@ -8508,7 +8899,7 @@ function EditGlowChrome({
|
|
|
8508
8899
|
}
|
|
8509
8900
|
}
|
|
8510
8901
|
),
|
|
8511
|
-
reorderHrefKey && !hideHandle && /* @__PURE__ */
|
|
8902
|
+
reorderHrefKey && !hideHandle && /* @__PURE__ */ jsx25(
|
|
8512
8903
|
"div",
|
|
8513
8904
|
{
|
|
8514
8905
|
"data-ohw-drag-handle-container": "",
|
|
@@ -8520,7 +8911,7 @@ function EditGlowChrome({
|
|
|
8520
8911
|
transform: "translate(calc(-100% - 7px), -50%)",
|
|
8521
8912
|
pointerEvents: dragDisabled ? "none" : "auto"
|
|
8522
8913
|
},
|
|
8523
|
-
children: /* @__PURE__ */
|
|
8914
|
+
children: /* @__PURE__ */ jsx25(
|
|
8524
8915
|
DragHandle,
|
|
8525
8916
|
{
|
|
8526
8917
|
"aria-label": `Reorder ${reorderHrefKey}`,
|
|
@@ -8621,6 +9012,79 @@ function resolveItemInteractionState(rect, parentScroll) {
|
|
|
8621
9012
|
const { transform } = calcToolbarPos(rect, parentScroll, 120);
|
|
8622
9013
|
return transform.includes("translateY(-100%)") ? "active-top" : "active-bottom";
|
|
8623
9014
|
}
|
|
9015
|
+
function resolveSelectionStartElement(sel) {
|
|
9016
|
+
if (!sel || sel.rangeCount === 0) return null;
|
|
9017
|
+
const range = sel.getRangeAt(0);
|
|
9018
|
+
let startNode = range.startContainer;
|
|
9019
|
+
if (startNode.nodeType === Node.ELEMENT_NODE) {
|
|
9020
|
+
const el = startNode;
|
|
9021
|
+
startNode = el.childNodes[range.startOffset] ?? el.childNodes[range.startOffset - 1] ?? el;
|
|
9022
|
+
}
|
|
9023
|
+
return startNode.nodeType === Node.TEXT_NODE ? startNode.parentElement : startNode;
|
|
9024
|
+
}
|
|
9025
|
+
function detectActiveFormats(startEl, activeRoot) {
|
|
9026
|
+
const formats = /* @__PURE__ */ new Set();
|
|
9027
|
+
const cs = getComputedStyle(startEl);
|
|
9028
|
+
const weight = parseInt(cs.fontWeight, 10);
|
|
9029
|
+
let hasBold = cs.fontWeight === "bold" || !Number.isNaN(weight) && weight >= 600;
|
|
9030
|
+
let hasItalic = cs.fontStyle === "italic" || cs.fontStyle === "oblique";
|
|
9031
|
+
let hasUnderline = false;
|
|
9032
|
+
let hasStrike = false;
|
|
9033
|
+
let hasUl = false;
|
|
9034
|
+
let hasOl = false;
|
|
9035
|
+
for (let el = startEl; el; el = el.parentElement) {
|
|
9036
|
+
if (el.tagName === "B" || el.tagName === "STRONG") hasBold = true;
|
|
9037
|
+
if (el.tagName === "I" || el.tagName === "EM") hasItalic = true;
|
|
9038
|
+
const decoration = getComputedStyle(el).textDecorationLine;
|
|
9039
|
+
if (decoration.includes("underline") || el.tagName === "U" || el.tagName === "INS") hasUnderline = true;
|
|
9040
|
+
if (decoration.includes("line-through") || el.tagName === "S" || el.tagName === "STRIKE" || el.tagName === "DEL") hasStrike = true;
|
|
9041
|
+
if (el.tagName === "UL") hasUl = true;
|
|
9042
|
+
if (el.tagName === "OL") hasOl = true;
|
|
9043
|
+
if (el === activeRoot) break;
|
|
9044
|
+
}
|
|
9045
|
+
if (hasBold) formats.add("bold");
|
|
9046
|
+
if (hasItalic) formats.add("italic");
|
|
9047
|
+
if (hasUnderline) formats.add("underline");
|
|
9048
|
+
if (hasStrike) formats.add("strikeThrough");
|
|
9049
|
+
if (hasUl) formats.add("insertUnorderedList");
|
|
9050
|
+
if (hasOl) formats.add("insertOrderedList");
|
|
9051
|
+
const block = startEl.closest("div, p, h1, h2, h3, h4, h5, h6, li, td, th") ?? startEl;
|
|
9052
|
+
const align = getComputedStyle(block).textAlign;
|
|
9053
|
+
if (align === "center") formats.add("justifyCenter");
|
|
9054
|
+
else if (align === "right" || align === "end") formats.add("justifyRight");
|
|
9055
|
+
else formats.add("justifyLeft");
|
|
9056
|
+
return formats;
|
|
9057
|
+
}
|
|
9058
|
+
function setsEqual(a, b) {
|
|
9059
|
+
if (a.size !== b.size) return false;
|
|
9060
|
+
for (const item of a) {
|
|
9061
|
+
if (!b.has(item)) return false;
|
|
9062
|
+
}
|
|
9063
|
+
return true;
|
|
9064
|
+
}
|
|
9065
|
+
function textOffsetInRoot(root, node, offset) {
|
|
9066
|
+
const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT);
|
|
9067
|
+
let total = 0;
|
|
9068
|
+
let current;
|
|
9069
|
+
while (current = walker.nextNode()) {
|
|
9070
|
+
if (current === node) return total + offset;
|
|
9071
|
+
total += (current.textContent ?? "").length;
|
|
9072
|
+
}
|
|
9073
|
+
return total;
|
|
9074
|
+
}
|
|
9075
|
+
function pointAtTextOffset(root, targetOffset) {
|
|
9076
|
+
const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT);
|
|
9077
|
+
let total = 0;
|
|
9078
|
+
let current;
|
|
9079
|
+
let last = null;
|
|
9080
|
+
while (current = walker.nextNode()) {
|
|
9081
|
+
const len = (current.textContent ?? "").length;
|
|
9082
|
+
if (total + len >= targetOffset) return { node: current, offset: targetOffset - total };
|
|
9083
|
+
total += len;
|
|
9084
|
+
last = current;
|
|
9085
|
+
}
|
|
9086
|
+
return last ? { node: last, offset: (last.textContent ?? "").length } : null;
|
|
9087
|
+
}
|
|
8624
9088
|
function FloatingToolbar({
|
|
8625
9089
|
rect,
|
|
8626
9090
|
parentScroll,
|
|
@@ -8657,7 +9121,7 @@ function FloatingToolbar({
|
|
|
8657
9121
|
return () => ro.disconnect();
|
|
8658
9122
|
}, [showEditLink, activeCommands]);
|
|
8659
9123
|
const { top, left, transform } = calcToolbarPos(rect, parentScroll, measuredW);
|
|
8660
|
-
return /* @__PURE__ */
|
|
9124
|
+
return /* @__PURE__ */ jsx25(
|
|
8661
9125
|
"div",
|
|
8662
9126
|
{
|
|
8663
9127
|
ref: setRefs,
|
|
@@ -8669,12 +9133,12 @@ function FloatingToolbar({
|
|
|
8669
9133
|
zIndex: 2147483647,
|
|
8670
9134
|
pointerEvents: "auto"
|
|
8671
9135
|
},
|
|
8672
|
-
children: /* @__PURE__ */
|
|
8673
|
-
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */
|
|
8674
|
-
gi > 0 && /* @__PURE__ */
|
|
9136
|
+
children: /* @__PURE__ */ jsxs14(CustomToolbar, { children: [
|
|
9137
|
+
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ jsxs14(React11.Fragment, { children: [
|
|
9138
|
+
gi > 0 && /* @__PURE__ */ jsx25(CustomToolbarDivider, {}),
|
|
8675
9139
|
btns.map((btn) => {
|
|
8676
9140
|
const isActive = activeCommands.has(btn.cmd);
|
|
8677
|
-
return /* @__PURE__ */
|
|
9141
|
+
return /* @__PURE__ */ jsx25(
|
|
8678
9142
|
CustomToolbarButton,
|
|
8679
9143
|
{
|
|
8680
9144
|
title: btn.title,
|
|
@@ -8683,7 +9147,7 @@ function FloatingToolbar({
|
|
|
8683
9147
|
e.preventDefault();
|
|
8684
9148
|
onCommand(btn.cmd);
|
|
8685
9149
|
},
|
|
8686
|
-
children: /* @__PURE__ */
|
|
9150
|
+
children: /* @__PURE__ */ jsx25(
|
|
8687
9151
|
"svg",
|
|
8688
9152
|
{
|
|
8689
9153
|
width: "16",
|
|
@@ -8704,7 +9168,7 @@ function FloatingToolbar({
|
|
|
8704
9168
|
);
|
|
8705
9169
|
})
|
|
8706
9170
|
] }, gi)),
|
|
8707
|
-
showEditLink ? /* @__PURE__ */
|
|
9171
|
+
showEditLink ? /* @__PURE__ */ jsx25(
|
|
8708
9172
|
CustomToolbarButton,
|
|
8709
9173
|
{
|
|
8710
9174
|
type: "button",
|
|
@@ -8718,7 +9182,7 @@ function FloatingToolbar({
|
|
|
8718
9182
|
e.preventDefault();
|
|
8719
9183
|
e.stopPropagation();
|
|
8720
9184
|
},
|
|
8721
|
-
children: /* @__PURE__ */
|
|
9185
|
+
children: /* @__PURE__ */ jsx25(Link2, { className: "size-4 shrink-0", "aria-hidden": true })
|
|
8722
9186
|
}
|
|
8723
9187
|
) : null
|
|
8724
9188
|
] })
|
|
@@ -8735,7 +9199,7 @@ function StateToggle({
|
|
|
8735
9199
|
states,
|
|
8736
9200
|
onStateChange
|
|
8737
9201
|
}) {
|
|
8738
|
-
return /* @__PURE__ */
|
|
9202
|
+
return /* @__PURE__ */ jsx25(
|
|
8739
9203
|
ToggleGroup,
|
|
8740
9204
|
{
|
|
8741
9205
|
"data-ohw-state-toggle": "",
|
|
@@ -8749,7 +9213,7 @@ function StateToggle({
|
|
|
8749
9213
|
left: rect.right - 8,
|
|
8750
9214
|
transform: "translateX(-100%)"
|
|
8751
9215
|
},
|
|
8752
|
-
children: states.map((state) => /* @__PURE__ */
|
|
9216
|
+
children: states.map((state) => /* @__PURE__ */ jsx25(ToggleGroupItem, { value: state, size: "sm", children: state }, state))
|
|
8753
9217
|
}
|
|
8754
9218
|
);
|
|
8755
9219
|
}
|
|
@@ -8805,7 +9269,7 @@ function OhhwellsBridge() {
|
|
|
8805
9269
|
const subdomainFromQuery = searchParams.get("subdomain");
|
|
8806
9270
|
const subdomain = resolveSubdomain(subdomainFromQuery);
|
|
8807
9271
|
useLinkHrefGuardian(pathname, subdomain, isEditMode);
|
|
8808
|
-
const postToParent2 =
|
|
9272
|
+
const postToParent2 = useCallback5((data) => {
|
|
8809
9273
|
if (typeof window !== "undefined" && window.parent !== window) {
|
|
8810
9274
|
window.parent.postMessage(data, "*");
|
|
8811
9275
|
}
|
|
@@ -8813,6 +9277,7 @@ function OhhwellsBridge() {
|
|
|
8813
9277
|
const [fetchState, setFetchState] = useState7("idle");
|
|
8814
9278
|
const autoSaveTimers = useRef7(/* @__PURE__ */ new Map());
|
|
8815
9279
|
const activeElRef = useRef7(null);
|
|
9280
|
+
const pointerHeldRef = useRef7(false);
|
|
8816
9281
|
const selectedElRef = useRef7(null);
|
|
8817
9282
|
const selectedHrefKeyRef = useRef7(null);
|
|
8818
9283
|
const selectedFooterColAttrRef = useRef7(null);
|
|
@@ -8821,7 +9286,7 @@ function OhhwellsBridge() {
|
|
|
8821
9286
|
const parentScrollRef = useRef7(null);
|
|
8822
9287
|
const visibleViewportRef = useRef7(null);
|
|
8823
9288
|
const [dialogPortalContainer, setDialogPortalContainer] = useState7(null);
|
|
8824
|
-
const attachVisibleViewport =
|
|
9289
|
+
const attachVisibleViewport = useCallback5((node) => {
|
|
8825
9290
|
visibleViewportRef.current = node;
|
|
8826
9291
|
setDialogPortalContainer(node);
|
|
8827
9292
|
if (node) applyVisibleViewport(node, parentScrollRef.current);
|
|
@@ -8934,7 +9399,7 @@ function OhhwellsBridge() {
|
|
|
8934
9399
|
const bumpLinkPopoverGrace = () => {
|
|
8935
9400
|
linkPopoverGraceUntilRef.current = Date.now() + 350;
|
|
8936
9401
|
};
|
|
8937
|
-
const runSectionsPrefetch =
|
|
9402
|
+
const runSectionsPrefetch = useCallback5((pages) => {
|
|
8938
9403
|
if (!isEditMode || shouldUseDevFixtures() || pages.length === 0) return;
|
|
8939
9404
|
const gen = ++sectionsPrefetchGenRef.current;
|
|
8940
9405
|
const paths = pages.map((p) => p.path);
|
|
@@ -8997,6 +9462,7 @@ function OhhwellsBridge() {
|
|
|
8997
9462
|
document.addEventListener("touchmove", preventBackgroundScroll, scrollOpts);
|
|
8998
9463
|
postToParent2({ type: "ow:image-unhover" });
|
|
8999
9464
|
return () => {
|
|
9465
|
+
document.documentElement.removeAttribute("data-ohw-link-popover-open");
|
|
9000
9466
|
postToParent2({ type: "ow:link-modal-lock", locked: false });
|
|
9001
9467
|
html.style.overflow = prevHtmlOverflow;
|
|
9002
9468
|
body.style.overflow = prevBodyOverflow;
|
|
@@ -9059,10 +9525,10 @@ function OhhwellsBridge() {
|
|
|
9059
9525
|
vvp.removeEventListener("resize", update);
|
|
9060
9526
|
};
|
|
9061
9527
|
}, []);
|
|
9062
|
-
const refreshStateRules =
|
|
9528
|
+
const refreshStateRules = useCallback5(() => {
|
|
9063
9529
|
editStylesRef.current?.forceHover && (editStylesRef.current.forceHover.textContent = collectStateRules());
|
|
9064
9530
|
}, []);
|
|
9065
|
-
const processConfigRequest =
|
|
9531
|
+
const processConfigRequest = useCallback5((insertAfterVal) => {
|
|
9066
9532
|
const tracker = getSectionsTracker();
|
|
9067
9533
|
let entries = [];
|
|
9068
9534
|
try {
|
|
@@ -9085,7 +9551,7 @@ function OhhwellsBridge() {
|
|
|
9085
9551
|
}
|
|
9086
9552
|
window.postMessage({ type: "ow:schedule-config", insertAfter: insertAfterVal, scheduleId: null }, "*");
|
|
9087
9553
|
}, [isEditMode]);
|
|
9088
|
-
const deactivate =
|
|
9554
|
+
const deactivate = useCallback5(() => {
|
|
9089
9555
|
const el = activeElRef.current;
|
|
9090
9556
|
if (!el) return;
|
|
9091
9557
|
const key = el.dataset.ohwKey;
|
|
@@ -9117,12 +9583,12 @@ function OhhwellsBridge() {
|
|
|
9117
9583
|
setToolbarShowEditLink(false);
|
|
9118
9584
|
postToParent2({ type: "ow:exit-edit" });
|
|
9119
9585
|
}, [postToParent2]);
|
|
9120
|
-
const clearSelectedAttr =
|
|
9586
|
+
const clearSelectedAttr = useCallback5(() => {
|
|
9121
9587
|
document.querySelectorAll("[data-ohw-selected]").forEach((el) => {
|
|
9122
9588
|
el.removeAttribute("data-ohw-selected");
|
|
9123
9589
|
});
|
|
9124
9590
|
}, []);
|
|
9125
|
-
const deselect =
|
|
9591
|
+
const deselect = useCallback5(() => {
|
|
9126
9592
|
clearSelectedAttr();
|
|
9127
9593
|
selectedElRef.current = null;
|
|
9128
9594
|
selectedHrefKeyRef.current = null;
|
|
@@ -9142,11 +9608,11 @@ function OhhwellsBridge() {
|
|
|
9142
9608
|
setToolbarVariant("none");
|
|
9143
9609
|
}
|
|
9144
9610
|
}, [clearSelectedAttr]);
|
|
9145
|
-
const markSelected =
|
|
9611
|
+
const markSelected = useCallback5((el) => {
|
|
9146
9612
|
clearSelectedAttr();
|
|
9147
9613
|
el.setAttribute("data-ohw-selected", "");
|
|
9148
9614
|
}, [clearSelectedAttr]);
|
|
9149
|
-
const resolveHrefKeyElement =
|
|
9615
|
+
const resolveHrefKeyElement = useCallback5((hrefKey) => {
|
|
9150
9616
|
if (isFooterHrefKey(hrefKey)) {
|
|
9151
9617
|
return document.querySelector(
|
|
9152
9618
|
`footer [data-ohw-href-key="${CSS.escape(hrefKey)}"]`
|
|
@@ -9161,7 +9627,7 @@ function OhhwellsBridge() {
|
|
|
9161
9627
|
`[data-ohw-href-key="${CSS.escape(hrefKey)}"]`
|
|
9162
9628
|
);
|
|
9163
9629
|
}, []);
|
|
9164
|
-
const resyncSelectedNavigationItem =
|
|
9630
|
+
const resyncSelectedNavigationItem = useCallback5(() => {
|
|
9165
9631
|
const hrefKey = selectedHrefKeyRef.current;
|
|
9166
9632
|
if (hrefKey) {
|
|
9167
9633
|
const link = resolveHrefKeyElement(hrefKey);
|
|
@@ -9189,7 +9655,7 @@ function OhhwellsBridge() {
|
|
|
9189
9655
|
);
|
|
9190
9656
|
}
|
|
9191
9657
|
}, [resolveHrefKeyElement]);
|
|
9192
|
-
const reselectNavigationItem =
|
|
9658
|
+
const reselectNavigationItem = useCallback5((navAnchor) => {
|
|
9193
9659
|
selectedElRef.current = navAnchor;
|
|
9194
9660
|
selectedHrefKeyRef.current = navAnchor.getAttribute("data-ohw-href-key");
|
|
9195
9661
|
selectedFooterColAttrRef.current = null;
|
|
@@ -9204,7 +9670,7 @@ function OhhwellsBridge() {
|
|
|
9204
9670
|
setToolbarShowEditLink(false);
|
|
9205
9671
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
9206
9672
|
}, [markSelected]);
|
|
9207
|
-
const commitNavigationTextEdit =
|
|
9673
|
+
const commitNavigationTextEdit = useCallback5((navAnchor) => {
|
|
9208
9674
|
const el = activeElRef.current;
|
|
9209
9675
|
if (!el) return;
|
|
9210
9676
|
const key = el.dataset.ohwKey;
|
|
@@ -9231,7 +9697,7 @@ function OhhwellsBridge() {
|
|
|
9231
9697
|
postToParent2({ type: "ow:exit-edit" });
|
|
9232
9698
|
reselectNavigationItem(navAnchor);
|
|
9233
9699
|
}, [postToParent2, reselectNavigationItem]);
|
|
9234
|
-
const handleAddTopLevelNavItem =
|
|
9700
|
+
const handleAddTopLevelNavItem = useCallback5(() => {
|
|
9235
9701
|
const items = listNavbarItems();
|
|
9236
9702
|
addNavAfterAnchorRef.current = items[items.length - 1] ?? null;
|
|
9237
9703
|
deselectRef.current();
|
|
@@ -9243,7 +9709,19 @@ function OhhwellsBridge() {
|
|
|
9243
9709
|
intent: "add-nav"
|
|
9244
9710
|
});
|
|
9245
9711
|
}, []);
|
|
9246
|
-
const
|
|
9712
|
+
const handleAddFooterColumn = useCallback5(() => {
|
|
9713
|
+
deselectRef.current();
|
|
9714
|
+
deactivateRef.current();
|
|
9715
|
+
const result = addFooterColumnWithPersist({ postToParent: postToParent2 });
|
|
9716
|
+
editContentRef.current = {
|
|
9717
|
+
...editContentRef.current,
|
|
9718
|
+
...buildFooterColumnEditContentPatch(result)
|
|
9719
|
+
};
|
|
9720
|
+
requestAnimationFrame(() => {
|
|
9721
|
+
selectRef.current(result.firstLink);
|
|
9722
|
+
});
|
|
9723
|
+
}, [postToParent2]);
|
|
9724
|
+
const clearFooterDragVisuals = useCallback5(() => {
|
|
9247
9725
|
footerDragRef.current = null;
|
|
9248
9726
|
setSiblingHintRects([]);
|
|
9249
9727
|
setFooterDropSlots([]);
|
|
@@ -9252,7 +9730,7 @@ function OhhwellsBridge() {
|
|
|
9252
9730
|
setIsItemDragging(false);
|
|
9253
9731
|
unlockFooterDragInteraction();
|
|
9254
9732
|
}, []);
|
|
9255
|
-
const refreshFooterDragVisuals =
|
|
9733
|
+
const refreshFooterDragVisuals = useCallback5((session, activeSlot, clientX, clientY) => {
|
|
9256
9734
|
const dragged = session.draggedEl;
|
|
9257
9735
|
setDraggedItemRect(dragged.getBoundingClientRect());
|
|
9258
9736
|
if (typeof clientX === "number" && typeof clientY === "number") {
|
|
@@ -9283,7 +9761,7 @@ function OhhwellsBridge() {
|
|
|
9283
9761
|
});
|
|
9284
9762
|
const beginFooterDragRef = useRef7(() => {
|
|
9285
9763
|
});
|
|
9286
|
-
const beginFooterDrag =
|
|
9764
|
+
const beginFooterDrag = useCallback5(
|
|
9287
9765
|
(session) => {
|
|
9288
9766
|
const rect = session.draggedEl.getBoundingClientRect();
|
|
9289
9767
|
session.lastClientX = session.lastClientX || rect.left + rect.width / 2;
|
|
@@ -9303,7 +9781,7 @@ function OhhwellsBridge() {
|
|
|
9303
9781
|
[refreshFooterDragVisuals]
|
|
9304
9782
|
);
|
|
9305
9783
|
beginFooterDragRef.current = beginFooterDrag;
|
|
9306
|
-
const commitFooterDrag =
|
|
9784
|
+
const commitFooterDrag = useCallback5(
|
|
9307
9785
|
(clientX, clientY) => {
|
|
9308
9786
|
const session = footerDragRef.current;
|
|
9309
9787
|
if (!session) {
|
|
@@ -9407,7 +9885,7 @@ function OhhwellsBridge() {
|
|
|
9407
9885
|
[clearFooterDragVisuals, resolveHrefKeyElement, resyncSelectedNavigationItem]
|
|
9408
9886
|
);
|
|
9409
9887
|
commitFooterDragRef.current = commitFooterDrag;
|
|
9410
|
-
const startFooterLinkDrag =
|
|
9888
|
+
const startFooterLinkDrag = useCallback5(
|
|
9411
9889
|
(anchor, clientX, clientY, wasSelected) => {
|
|
9412
9890
|
const hrefKey = anchor.getAttribute("data-ohw-href-key");
|
|
9413
9891
|
if (!hrefKey || !isFooterHrefKey(hrefKey)) return false;
|
|
@@ -9428,7 +9906,7 @@ function OhhwellsBridge() {
|
|
|
9428
9906
|
},
|
|
9429
9907
|
[beginFooterDrag]
|
|
9430
9908
|
);
|
|
9431
|
-
const startFooterColumnDrag =
|
|
9909
|
+
const startFooterColumnDrag = useCallback5(
|
|
9432
9910
|
(columnEl, clientX, clientY, wasSelected) => {
|
|
9433
9911
|
const columns = listFooterColumns();
|
|
9434
9912
|
const idx = columns.indexOf(columnEl);
|
|
@@ -9448,7 +9926,7 @@ function OhhwellsBridge() {
|
|
|
9448
9926
|
},
|
|
9449
9927
|
[beginFooterDrag]
|
|
9450
9928
|
);
|
|
9451
|
-
const handleItemDragStart =
|
|
9929
|
+
const handleItemDragStart = useCallback5(
|
|
9452
9930
|
(e) => {
|
|
9453
9931
|
const selected = selectedElRef.current;
|
|
9454
9932
|
if (!selected) {
|
|
@@ -9468,7 +9946,7 @@ function OhhwellsBridge() {
|
|
|
9468
9946
|
},
|
|
9469
9947
|
[startFooterColumnDrag, startFooterLinkDrag, startNavLinkDrag]
|
|
9470
9948
|
);
|
|
9471
|
-
const handleItemDragEnd =
|
|
9949
|
+
const handleItemDragEnd = useCallback5(
|
|
9472
9950
|
(e) => {
|
|
9473
9951
|
if (footerDragRef.current) {
|
|
9474
9952
|
const x = e?.clientX;
|
|
@@ -9494,11 +9972,10 @@ function OhhwellsBridge() {
|
|
|
9494
9972
|
},
|
|
9495
9973
|
[commitFooterDrag, commitNavDrag, navDragRef]
|
|
9496
9974
|
);
|
|
9497
|
-
const handleItemChromePointerDown =
|
|
9975
|
+
const handleItemChromePointerDown = useCallback5((e) => {
|
|
9498
9976
|
if (e.button !== 0) return;
|
|
9499
9977
|
const selected = selectedElRef.current;
|
|
9500
9978
|
if (!selected) return;
|
|
9501
|
-
armFooterPressDrag();
|
|
9502
9979
|
const hrefKey = selected.getAttribute("data-ohw-href-key");
|
|
9503
9980
|
if (hrefKey && isFooterHrefKey(hrefKey)) {
|
|
9504
9981
|
footerPointerDragRef.current = {
|
|
@@ -9526,7 +10003,7 @@ function OhhwellsBridge() {
|
|
|
9526
10003
|
}
|
|
9527
10004
|
if (armNavPressFromChrome(selected, e.clientX, e.clientY, e.pointerId)) return;
|
|
9528
10005
|
}, [armNavPressFromChrome]);
|
|
9529
|
-
const handleItemChromeClick =
|
|
10006
|
+
const handleItemChromeClick = useCallback5((clientX, clientY) => {
|
|
9530
10007
|
if (suppressNextClickRef.current || Date.now() < suppressClickUntilRef.current) {
|
|
9531
10008
|
suppressNextClickRef.current = false;
|
|
9532
10009
|
return;
|
|
@@ -9539,7 +10016,7 @@ function OhhwellsBridge() {
|
|
|
9539
10016
|
}, []);
|
|
9540
10017
|
reselectNavigationItemRef.current = reselectNavigationItem;
|
|
9541
10018
|
commitNavigationTextEditRef.current = commitNavigationTextEdit;
|
|
9542
|
-
const select =
|
|
10019
|
+
const select = useCallback5((anchor) => {
|
|
9543
10020
|
if (!isNavigationItem(anchor)) return;
|
|
9544
10021
|
if (activeElRef.current) deactivate();
|
|
9545
10022
|
selectedElRef.current = anchor;
|
|
@@ -9565,10 +10042,10 @@ function OhhwellsBridge() {
|
|
|
9565
10042
|
setToolbarShowEditLink(false);
|
|
9566
10043
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
9567
10044
|
}, [deactivate, markSelected]);
|
|
9568
|
-
const selectFrame =
|
|
10045
|
+
const selectFrame = useCallback5((el) => {
|
|
9569
10046
|
if (!isNavigationContainer(el)) return;
|
|
9570
10047
|
if (activeElRef.current) deactivate();
|
|
9571
|
-
const isFooterColumn = el.hasAttribute("data-ohw-footer-col") || Boolean(el.closest("footer") && isInferredFooterGroup(el));
|
|
10048
|
+
const isFooterColumn = !isFooterLinksContainer(el) && (el.hasAttribute("data-ohw-footer-col") || Boolean(el.closest("footer") && isInferredFooterGroup(el)));
|
|
9572
10049
|
selectedElRef.current = el;
|
|
9573
10050
|
selectedHrefKeyRef.current = null;
|
|
9574
10051
|
selectedFooterColAttrRef.current = isFooterColumn ? el.getAttribute("data-ohw-footer-col") ?? String(listFooterColumns().indexOf(el)) : null;
|
|
@@ -9593,7 +10070,7 @@ function OhhwellsBridge() {
|
|
|
9593
10070
|
setToolbarShowEditLink(false);
|
|
9594
10071
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
9595
10072
|
}, [deactivate, markSelected]);
|
|
9596
|
-
const activate =
|
|
10073
|
+
const activate = useCallback5((el, options) => {
|
|
9597
10074
|
if (activeElRef.current === el) return;
|
|
9598
10075
|
clearSelectedAttr();
|
|
9599
10076
|
selectedElRef.current = null;
|
|
@@ -9608,7 +10085,10 @@ function OhhwellsBridge() {
|
|
|
9608
10085
|
setToolbarVariant("rich-text");
|
|
9609
10086
|
siblingHintElRef.current = null;
|
|
9610
10087
|
setSiblingHintRect(null);
|
|
10088
|
+
setSiblingHintRects([]);
|
|
9611
10089
|
setIsItemDragging(false);
|
|
10090
|
+
const preActivationSelection = window.getSelection();
|
|
10091
|
+
const preservedRange = preActivationSelection && preActivationSelection.rangeCount > 0 && !preActivationSelection.isCollapsed && el.contains(preActivationSelection.getRangeAt(0).commonAncestorContainer) ? preActivationSelection.getRangeAt(0).cloneRange() : null;
|
|
9612
10092
|
el.setAttribute("contenteditable", "true");
|
|
9613
10093
|
el.setAttribute("data-ohw-editing", "");
|
|
9614
10094
|
el.removeAttribute("data-ohw-hovered");
|
|
@@ -9616,7 +10096,11 @@ function OhhwellsBridge() {
|
|
|
9616
10096
|
activeElRef.current = el;
|
|
9617
10097
|
originalContentRef.current = el.innerHTML;
|
|
9618
10098
|
el.focus({ preventScroll: true });
|
|
9619
|
-
if (
|
|
10099
|
+
if (preservedRange) {
|
|
10100
|
+
const selection = window.getSelection();
|
|
10101
|
+
selection?.removeAllRanges();
|
|
10102
|
+
selection?.addRange(preservedRange);
|
|
10103
|
+
} else if (options?.caretX !== void 0 && options?.caretY !== void 0) {
|
|
9620
10104
|
const { caretX, caretY } = options;
|
|
9621
10105
|
placeCaretAtPoint(el, caretX, caretY);
|
|
9622
10106
|
requestAnimationFrame(() => {
|
|
@@ -10072,7 +10556,9 @@ function OhhwellsBridge() {
|
|
|
10072
10556
|
if (inActive || inActiveNav) {
|
|
10073
10557
|
e.preventDefault();
|
|
10074
10558
|
e.stopPropagation();
|
|
10075
|
-
|
|
10559
|
+
const selection = window.getSelection();
|
|
10560
|
+
const hasRangeSelection = Boolean(selection && !selection.isCollapsed);
|
|
10561
|
+
if (e.detail < 2 && !hasRangeSelection) {
|
|
10076
10562
|
placeCaretAtPoint(active, e.clientX, e.clientY);
|
|
10077
10563
|
refreshActiveCommandsRef.current();
|
|
10078
10564
|
}
|
|
@@ -10115,7 +10601,7 @@ function OhhwellsBridge() {
|
|
|
10115
10601
|
}
|
|
10116
10602
|
e.preventDefault();
|
|
10117
10603
|
e.stopPropagation();
|
|
10118
|
-
activateRef.current(editable);
|
|
10604
|
+
activateRef.current(editable, { caretX: e.clientX, caretY: e.clientY });
|
|
10119
10605
|
return;
|
|
10120
10606
|
}
|
|
10121
10607
|
const hrefAnchor = getNavigationItemAnchor(target);
|
|
@@ -10142,6 +10628,18 @@ function OhhwellsBridge() {
|
|
|
10142
10628
|
selectFrameRef.current(footerColClick);
|
|
10143
10629
|
return;
|
|
10144
10630
|
}
|
|
10631
|
+
const footerLinksToSelect = resolveFooterLinksContainerSelectionTarget(
|
|
10632
|
+
target,
|
|
10633
|
+
e.clientX,
|
|
10634
|
+
e.clientY,
|
|
10635
|
+
isPointOverNavItem
|
|
10636
|
+
);
|
|
10637
|
+
if (footerLinksToSelect) {
|
|
10638
|
+
e.preventDefault();
|
|
10639
|
+
e.stopPropagation();
|
|
10640
|
+
selectFrameRef.current(footerLinksToSelect);
|
|
10641
|
+
return;
|
|
10642
|
+
}
|
|
10145
10643
|
const navContainerToSelect = resolveNavContainerSelectionTarget(target, e.clientX, e.clientY);
|
|
10146
10644
|
if (navContainerToSelect) {
|
|
10147
10645
|
e.preventDefault();
|
|
@@ -10200,8 +10698,8 @@ function OhhwellsBridge() {
|
|
|
10200
10698
|
return;
|
|
10201
10699
|
}
|
|
10202
10700
|
const navLabel = getNavigationLabelEditable(target);
|
|
10203
|
-
|
|
10204
|
-
|
|
10701
|
+
const editable = navLabel?.editable ?? target.closest('[data-ohw-editable="text"], [data-ohw-editable="plain"]');
|
|
10702
|
+
if (!editable || isMediaEditable(editable) || editable.dataset.ohwEditable === "link") return;
|
|
10205
10703
|
e.preventDefault();
|
|
10206
10704
|
e.stopPropagation();
|
|
10207
10705
|
if (activeElRef.current !== editable) {
|
|
@@ -10222,16 +10720,38 @@ function OhhwellsBridge() {
|
|
|
10222
10720
|
setHoveredNavContainerRect(null);
|
|
10223
10721
|
return;
|
|
10224
10722
|
}
|
|
10225
|
-
|
|
10226
|
-
const
|
|
10227
|
-
|
|
10228
|
-
|
|
10229
|
-
|
|
10230
|
-
|
|
10231
|
-
|
|
10232
|
-
|
|
10723
|
+
{
|
|
10724
|
+
const selected2 = selectedElRef.current;
|
|
10725
|
+
const selectedIsFooterColumn = Boolean(selected2) && !isFooterLinksContainer(selected2) && (selected2.hasAttribute("data-ohw-footer-col") || selected2.hasAttribute("data-ohw-footer-column") || Boolean(selected2.closest("footer") && isInferredFooterGroup(selected2)));
|
|
10726
|
+
const allowNavContainerHover = toolbarVariantRef.current !== "select-frame";
|
|
10727
|
+
const allowFooterLinksHover = toolbarVariantRef.current !== "select-frame" || selectedIsFooterColumn;
|
|
10728
|
+
if (allowNavContainerHover) {
|
|
10729
|
+
const navContainer = target.closest("[data-ohw-nav-container]");
|
|
10730
|
+
if (navContainer && !getNavigationItemAnchor(target)) {
|
|
10731
|
+
hoveredNavContainerRef.current = navContainer;
|
|
10732
|
+
setHoveredNavContainerRect(navContainer.getBoundingClientRect());
|
|
10733
|
+
hoveredItemElRef.current = null;
|
|
10734
|
+
setHoveredItemRect(null);
|
|
10735
|
+
return;
|
|
10736
|
+
}
|
|
10233
10737
|
}
|
|
10234
|
-
if (
|
|
10738
|
+
if (allowFooterLinksHover) {
|
|
10739
|
+
const navContainer = target.closest("[data-ohw-nav-container]");
|
|
10740
|
+
if (!navContainer) {
|
|
10741
|
+
const footerLinks = target.closest("[data-ohw-footer-links], .rb-footer-links") ?? null;
|
|
10742
|
+
if (footerLinks && selected2 !== footerLinks && !getNavigationItemAnchor(target) && !target.closest("[data-ohw-footer-col], [data-ohw-footer-column]")) {
|
|
10743
|
+
hoveredNavContainerRef.current = footerLinks;
|
|
10744
|
+
setHoveredNavContainerRect(footerLinks.getBoundingClientRect());
|
|
10745
|
+
hoveredItemElRef.current = null;
|
|
10746
|
+
setHoveredItemRect(null);
|
|
10747
|
+
return;
|
|
10748
|
+
}
|
|
10749
|
+
if (!footerLinks) {
|
|
10750
|
+
hoveredNavContainerRef.current = null;
|
|
10751
|
+
setHoveredNavContainerRect(null);
|
|
10752
|
+
}
|
|
10753
|
+
}
|
|
10754
|
+
} else if (toolbarVariantRef.current === "select-frame") {
|
|
10235
10755
|
hoveredNavContainerRef.current = null;
|
|
10236
10756
|
setHoveredNavContainerRect(null);
|
|
10237
10757
|
}
|
|
@@ -10273,9 +10793,9 @@ function OhhwellsBridge() {
|
|
|
10273
10793
|
};
|
|
10274
10794
|
const handleMouseOut = (e) => {
|
|
10275
10795
|
const target = e.target;
|
|
10276
|
-
if (target.closest("[data-ohw-nav-container], [data-ohw-footer-col], [data-ohw-footer-column]")) {
|
|
10796
|
+
if (target.closest("[data-ohw-nav-container], [data-ohw-footer-col], [data-ohw-footer-column], [data-ohw-footer-links], .rb-footer-links")) {
|
|
10277
10797
|
const related2 = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
10278
|
-
if (related2?.closest("[data-ohw-nav-container], [data-ohw-footer-col], [data-ohw-footer-column], [data-ohw-navbar-container-chrome], [data-ohw-navbar-add-button]")) {
|
|
10798
|
+
if (related2?.closest("[data-ohw-nav-container], [data-ohw-footer-col], [data-ohw-footer-column], [data-ohw-footer-links], .rb-footer-links, [data-ohw-navbar-container-chrome], [data-ohw-navbar-add-button], [data-ohw-footer-container-chrome], [data-ohw-footer-add-button]")) {
|
|
10279
10799
|
return;
|
|
10280
10800
|
}
|
|
10281
10801
|
hoveredNavContainerRef.current = null;
|
|
@@ -10370,6 +10890,15 @@ function OhhwellsBridge() {
|
|
|
10370
10890
|
if (track) track.setAttribute("data-ohw-hover-paused", "");
|
|
10371
10891
|
};
|
|
10372
10892
|
const clearImageHover = () => setMediaHover(null);
|
|
10893
|
+
const dismissImageHover = () => {
|
|
10894
|
+
if (hoveredImageRef.current) {
|
|
10895
|
+
hoveredImageRef.current = null;
|
|
10896
|
+
hoveredImageHasTextOverlapRef.current = false;
|
|
10897
|
+
resumeAnimTracks();
|
|
10898
|
+
postToParentRef.current({ type: "ow:image-unhover" });
|
|
10899
|
+
}
|
|
10900
|
+
clearImageHover();
|
|
10901
|
+
};
|
|
10373
10902
|
const findImageAtPoint = (clientX, clientY, fromParentViewport) => {
|
|
10374
10903
|
const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
10375
10904
|
const images = Array.from(document.querySelectorAll(MEDIA_SELECTOR));
|
|
@@ -10413,16 +10942,13 @@ function OhhwellsBridge() {
|
|
|
10413
10942
|
}
|
|
10414
10943
|
return smallest;
|
|
10415
10944
|
};
|
|
10416
|
-
const dismissImageHover = () => {
|
|
10417
|
-
if (hoveredImageRef.current) {
|
|
10418
|
-
hoveredImageRef.current = null;
|
|
10419
|
-
hoveredImageHasTextOverlapRef.current = false;
|
|
10420
|
-
resumeAnimTracks();
|
|
10421
|
-
postToParentRef.current({ type: "ow:image-unhover" });
|
|
10422
|
-
}
|
|
10423
|
-
};
|
|
10424
10945
|
const probeNavigationHoverAt = (x, y) => {
|
|
10425
|
-
|
|
10946
|
+
const selected = selectedElRef.current;
|
|
10947
|
+
const selectedIsFooterColumn = Boolean(selected) && !isFooterLinksContainer(selected) && (selected.hasAttribute("data-ohw-footer-col") || selected.hasAttribute("data-ohw-footer-column") || Boolean(selected.closest("footer") && isInferredFooterGroup(selected)));
|
|
10948
|
+
const selectedIsFooterLinks = Boolean(selected && isFooterLinksContainer(selected));
|
|
10949
|
+
const allowNavContainerHover = toolbarVariantRef.current !== "select-frame";
|
|
10950
|
+
const allowFooterLinksHover = (toolbarVariantRef.current !== "select-frame" || selectedIsFooterColumn) && !selectedIsFooterLinks;
|
|
10951
|
+
if (toolbarVariantRef.current === "select-frame" && !allowFooterLinksHover) {
|
|
10426
10952
|
hoveredNavContainerRef.current = null;
|
|
10427
10953
|
setHoveredNavContainerRect(null);
|
|
10428
10954
|
}
|
|
@@ -10444,7 +10970,6 @@ function OhhwellsBridge() {
|
|
|
10444
10970
|
if (navItemHit) {
|
|
10445
10971
|
hoveredNavContainerRef.current = null;
|
|
10446
10972
|
setHoveredNavContainerRect(null);
|
|
10447
|
-
const selected = selectedElRef.current;
|
|
10448
10973
|
if (selected !== navItemHit) {
|
|
10449
10974
|
clearHrefKeyHover(navItemHit);
|
|
10450
10975
|
hoveredItemElRef.current = navItemHit;
|
|
@@ -10456,7 +10981,7 @@ function OhhwellsBridge() {
|
|
|
10456
10981
|
return;
|
|
10457
10982
|
}
|
|
10458
10983
|
}
|
|
10459
|
-
if (
|
|
10984
|
+
if (allowNavContainerHover) {
|
|
10460
10985
|
for (const container of navContainers) {
|
|
10461
10986
|
const containerRect = container.getBoundingClientRect();
|
|
10462
10987
|
const overContainer = x >= containerRect.left && x <= containerRect.right && y >= containerRect.top && y <= containerRect.bottom;
|
|
@@ -10468,12 +10993,23 @@ function OhhwellsBridge() {
|
|
|
10468
10993
|
setHoveredItemRect(null);
|
|
10469
10994
|
return;
|
|
10470
10995
|
}
|
|
10471
|
-
hoveredNavContainerRef.current = null;
|
|
10472
|
-
setHoveredNavContainerRect(null);
|
|
10473
|
-
} else {
|
|
10474
|
-
hoveredNavContainerRef.current = null;
|
|
10475
|
-
setHoveredNavContainerRect(null);
|
|
10476
10996
|
}
|
|
10997
|
+
if (allowFooterLinksHover) {
|
|
10998
|
+
const footerLinks = getFooterLinksContainer();
|
|
10999
|
+
if (footerLinks) {
|
|
11000
|
+
const containerRect = footerLinks.getBoundingClientRect();
|
|
11001
|
+
const overContainer = x >= containerRect.left && x <= containerRect.right && y >= containerRect.top && y <= containerRect.bottom;
|
|
11002
|
+
if (overContainer && !isPointOverNavItem(footerLinks, x, y) && !isPointOverFooterColumn(x, y)) {
|
|
11003
|
+
hoveredNavContainerRef.current = footerLinks;
|
|
11004
|
+
setHoveredNavContainerRect(footerLinks.getBoundingClientRect());
|
|
11005
|
+
hoveredItemElRef.current = null;
|
|
11006
|
+
setHoveredItemRect(null);
|
|
11007
|
+
return;
|
|
11008
|
+
}
|
|
11009
|
+
}
|
|
11010
|
+
}
|
|
11011
|
+
hoveredNavContainerRef.current = null;
|
|
11012
|
+
setHoveredNavContainerRect(null);
|
|
10477
11013
|
for (const column of footerColumns) {
|
|
10478
11014
|
const containerRect = column.getBoundingClientRect();
|
|
10479
11015
|
const overContainer = x >= containerRect.left && x <= containerRect.right && y >= containerRect.top && y <= containerRect.bottom;
|
|
@@ -10980,6 +11516,7 @@ function OhhwellsBridge() {
|
|
|
10980
11516
|
}
|
|
10981
11517
|
editContentRef.current = { ...editContentRef.current, ...content };
|
|
10982
11518
|
reconcileNavbarItemsFromContent(editContentRef.current);
|
|
11519
|
+
reconcileFooterOrderFromContent(editContentRef.current);
|
|
10983
11520
|
syncNavigationDragCursorAttrs();
|
|
10984
11521
|
enforceLinkHrefs();
|
|
10985
11522
|
postToParentRef.current({ type: "ow:hydrate-done" });
|
|
@@ -11034,6 +11571,11 @@ function OhhwellsBridge() {
|
|
|
11034
11571
|
}
|
|
11035
11572
|
if (selectedElRef.current) {
|
|
11036
11573
|
if (toolbarVariantRef.current === "select-frame") {
|
|
11574
|
+
const parent2 = getNavigationSelectionParent(selectedElRef.current);
|
|
11575
|
+
if (parent2 && isNavigationContainer(parent2) && isFooterLinksContainer(parent2) && !isFooterLinksContainer(selectedElRef.current)) {
|
|
11576
|
+
selectFrameRef.current(parent2);
|
|
11577
|
+
return;
|
|
11578
|
+
}
|
|
11037
11579
|
deselectRef.current();
|
|
11038
11580
|
return;
|
|
11039
11581
|
}
|
|
@@ -11049,13 +11591,10 @@ function OhhwellsBridge() {
|
|
|
11049
11591
|
const handleKeyDown = (e) => {
|
|
11050
11592
|
if (e.key === "Escape" && document.querySelector("[data-ohw-section-picker]")) return;
|
|
11051
11593
|
if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === "a" && activeElRef.current) {
|
|
11052
|
-
|
|
11053
|
-
|
|
11054
|
-
|
|
11055
|
-
|
|
11056
|
-
refreshActiveCommandsRef.current();
|
|
11057
|
-
return;
|
|
11058
|
-
}
|
|
11594
|
+
e.preventDefault();
|
|
11595
|
+
selectAllTextInEditable(activeElRef.current);
|
|
11596
|
+
refreshActiveCommandsRef.current();
|
|
11597
|
+
return;
|
|
11059
11598
|
}
|
|
11060
11599
|
if (e.key === "Escape" && linkPopoverOpenRef.current) {
|
|
11061
11600
|
setLinkPopoverRef.current(null);
|
|
@@ -11063,6 +11602,12 @@ function OhhwellsBridge() {
|
|
|
11063
11602
|
}
|
|
11064
11603
|
if (e.key === "Escape" && selectedElRef.current && !activeElRef.current) {
|
|
11065
11604
|
if (toolbarVariantRef.current === "select-frame") {
|
|
11605
|
+
const parent2 = getNavigationSelectionParent(selectedElRef.current);
|
|
11606
|
+
if (parent2 && isNavigationContainer(parent2) && isFooterLinksContainer(parent2) && !isFooterLinksContainer(selectedElRef.current)) {
|
|
11607
|
+
e.preventDefault();
|
|
11608
|
+
selectFrameRef.current(parent2);
|
|
11609
|
+
return;
|
|
11610
|
+
}
|
|
11066
11611
|
deselectRef.current();
|
|
11067
11612
|
return;
|
|
11068
11613
|
}
|
|
@@ -11225,30 +11770,30 @@ function OhhwellsBridge() {
|
|
|
11225
11770
|
const h = document.documentElement.scrollHeight;
|
|
11226
11771
|
if (h > 50) postToParentRef.current({ type: "ow:height", height: h });
|
|
11227
11772
|
};
|
|
11773
|
+
let selectionChangeRaf = null;
|
|
11774
|
+
const runSelectionChange = () => {
|
|
11775
|
+
selectionChangeRaf = null;
|
|
11776
|
+
const activeRoot = activeElRef.current;
|
|
11777
|
+
if (!activeRoot) return;
|
|
11778
|
+
const startEl = resolveSelectionStartElement(window.getSelection());
|
|
11779
|
+
const next = startEl ? detectActiveFormats(startEl, activeRoot) : /* @__PURE__ */ new Set();
|
|
11780
|
+
setActiveCommands((prev) => setsEqual(prev, next) ? prev : next);
|
|
11781
|
+
};
|
|
11228
11782
|
const handleSelectionChange = () => {
|
|
11229
|
-
if (
|
|
11230
|
-
|
|
11231
|
-
|
|
11232
|
-
|
|
11233
|
-
|
|
11234
|
-
|
|
11235
|
-
|
|
11236
|
-
}
|
|
11237
|
-
const sel = window.getSelection();
|
|
11238
|
-
const anchor = sel?.anchorNode;
|
|
11239
|
-
if (anchor) {
|
|
11240
|
-
const el = anchor.nodeType === Node.TEXT_NODE ? anchor.parentElement : anchor;
|
|
11241
|
-
const block = el?.closest("div, p, h1, h2, h3, h4, h5, h6, li, td, th") ?? el;
|
|
11242
|
-
if (block) {
|
|
11243
|
-
const align = getComputedStyle(block).textAlign;
|
|
11244
|
-
if (align === "center") next.add("justifyCenter");
|
|
11245
|
-
else if (align === "right" || align === "end") next.add("justifyRight");
|
|
11246
|
-
else next.add("justifyLeft");
|
|
11247
|
-
}
|
|
11248
|
-
}
|
|
11249
|
-
setActiveCommands(next);
|
|
11783
|
+
if (pointerHeldRef.current) return;
|
|
11784
|
+
if (selectionChangeRaf !== null) return;
|
|
11785
|
+
selectionChangeRaf = requestAnimationFrame(runSelectionChange);
|
|
11786
|
+
};
|
|
11787
|
+
const markPointerHeld = (e) => {
|
|
11788
|
+
if (e.button !== 0) return;
|
|
11789
|
+
pointerHeldRef.current = true;
|
|
11250
11790
|
};
|
|
11251
|
-
|
|
11791
|
+
const markPointerReleased = () => {
|
|
11792
|
+
if (!pointerHeldRef.current) return;
|
|
11793
|
+
pointerHeldRef.current = false;
|
|
11794
|
+
handleSelectionChange();
|
|
11795
|
+
};
|
|
11796
|
+
refreshActiveCommandsRef.current = runSelectionChange;
|
|
11252
11797
|
const handleDocMouseLeave = () => {
|
|
11253
11798
|
hoveredImageRef.current = null;
|
|
11254
11799
|
setMediaHover(null);
|
|
@@ -11488,7 +12033,6 @@ function OhhwellsBridge() {
|
|
|
11488
12033
|
const anchor = getNavigationItemAnchor(target);
|
|
11489
12034
|
const hrefKey = anchor?.getAttribute("data-ohw-href-key") ?? null;
|
|
11490
12035
|
if (anchor && isFooterHrefKey(hrefKey)) {
|
|
11491
|
-
armFooterPressDrag();
|
|
11492
12036
|
footerPointerDragRef.current = {
|
|
11493
12037
|
el: anchor,
|
|
11494
12038
|
kind: "link",
|
|
@@ -11502,7 +12046,6 @@ function OhhwellsBridge() {
|
|
|
11502
12046
|
}
|
|
11503
12047
|
const col = target.closest("[data-ohw-footer-col]");
|
|
11504
12048
|
if (col && !getNavigationItemAnchor(target)) {
|
|
11505
|
-
armFooterPressDrag();
|
|
11506
12049
|
footerPointerDragRef.current = {
|
|
11507
12050
|
el: col,
|
|
11508
12051
|
kind: "column",
|
|
@@ -11531,6 +12074,7 @@ function OhhwellsBridge() {
|
|
|
11531
12074
|
if (dx * dx + dy * dy < THRESHOLD * THRESHOLD) return;
|
|
11532
12075
|
e.preventDefault();
|
|
11533
12076
|
pending.started = true;
|
|
12077
|
+
armFooterPressDrag();
|
|
11534
12078
|
clearTextSelection();
|
|
11535
12079
|
try {
|
|
11536
12080
|
document.body.setPointerCapture(pending.pointerId);
|
|
@@ -11584,7 +12128,8 @@ function OhhwellsBridge() {
|
|
|
11584
12128
|
}
|
|
11585
12129
|
} catch {
|
|
11586
12130
|
}
|
|
11587
|
-
if (!pending
|
|
12131
|
+
if (!pending) return;
|
|
12132
|
+
if (!pending.started) {
|
|
11588
12133
|
unlockFooterDragInteraction();
|
|
11589
12134
|
return;
|
|
11590
12135
|
}
|
|
@@ -11676,13 +12221,43 @@ function OhhwellsBridge() {
|
|
|
11676
12221
|
window.addEventListener("hashchange", onHashChange);
|
|
11677
12222
|
return () => window.removeEventListener("hashchange", onHashChange);
|
|
11678
12223
|
}, [pathname]);
|
|
11679
|
-
const handleCommand =
|
|
12224
|
+
const handleCommand = useCallback5((cmd) => {
|
|
12225
|
+
const el = activeElRef.current;
|
|
12226
|
+
const selBefore = window.getSelection();
|
|
12227
|
+
let savedOffsets = null;
|
|
12228
|
+
if (el && selBefore && selBefore.rangeCount > 0 && !selBefore.isCollapsed) {
|
|
12229
|
+
const r2 = selBefore.getRangeAt(0);
|
|
12230
|
+
if (el.contains(r2.commonAncestorContainer)) {
|
|
12231
|
+
savedOffsets = {
|
|
12232
|
+
start: textOffsetInRoot(el, r2.startContainer, r2.startOffset),
|
|
12233
|
+
end: textOffsetInRoot(el, r2.endContainer, r2.endOffset)
|
|
12234
|
+
};
|
|
12235
|
+
}
|
|
12236
|
+
}
|
|
12237
|
+
document.execCommand("styleWithCSS", false, true);
|
|
11680
12238
|
document.execCommand(cmd, false);
|
|
11681
|
-
|
|
11682
|
-
|
|
12239
|
+
if (el && document.activeElement !== el) {
|
|
12240
|
+
el.focus();
|
|
12241
|
+
}
|
|
12242
|
+
const selAfter = window.getSelection();
|
|
12243
|
+
if (el && savedOffsets && selAfter?.isCollapsed) {
|
|
12244
|
+
const start = pointAtTextOffset(el, savedOffsets.start);
|
|
12245
|
+
const end = pointAtTextOffset(el, savedOffsets.end);
|
|
12246
|
+
if (start && end) {
|
|
12247
|
+
try {
|
|
12248
|
+
const range = document.createRange();
|
|
12249
|
+
range.setStart(start.node, start.offset);
|
|
12250
|
+
range.setEnd(end.node, end.offset);
|
|
12251
|
+
selAfter.removeAllRanges();
|
|
12252
|
+
selAfter.addRange(range);
|
|
12253
|
+
} catch {
|
|
12254
|
+
}
|
|
12255
|
+
}
|
|
12256
|
+
}
|
|
12257
|
+
if (el) setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
|
|
11683
12258
|
refreshActiveCommandsRef.current();
|
|
11684
12259
|
}, []);
|
|
11685
|
-
const handleStateChange =
|
|
12260
|
+
const handleStateChange = useCallback5((state) => {
|
|
11686
12261
|
if (!activeStateElRef.current) return;
|
|
11687
12262
|
const el = activeStateElRef.current;
|
|
11688
12263
|
if (state === "Default") {
|
|
@@ -11695,11 +12270,11 @@ function OhhwellsBridge() {
|
|
|
11695
12270
|
}
|
|
11696
12271
|
setToggleState((prev) => prev ? { ...prev, activeState: state } : null);
|
|
11697
12272
|
}, [deactivate]);
|
|
11698
|
-
const closeLinkPopover =
|
|
12273
|
+
const closeLinkPopover = useCallback5(() => {
|
|
11699
12274
|
addNavAfterAnchorRef.current = null;
|
|
11700
12275
|
setLinkPopover(null);
|
|
11701
12276
|
}, []);
|
|
11702
|
-
const openLinkPopoverForActive =
|
|
12277
|
+
const openLinkPopoverForActive = useCallback5(() => {
|
|
11703
12278
|
const hrefCtx = getHrefKeyFromElement(activeElRef.current);
|
|
11704
12279
|
if (!hrefCtx) return;
|
|
11705
12280
|
bumpLinkPopoverGrace();
|
|
@@ -11710,7 +12285,7 @@ function OhhwellsBridge() {
|
|
|
11710
12285
|
});
|
|
11711
12286
|
deactivate();
|
|
11712
12287
|
}, [deactivate]);
|
|
11713
|
-
const openLinkPopoverForSelected =
|
|
12288
|
+
const openLinkPopoverForSelected = useCallback5(() => {
|
|
11714
12289
|
const anchor = selectedElRef.current;
|
|
11715
12290
|
if (!anchor) return;
|
|
11716
12291
|
const key = anchor.getAttribute("data-ohw-href-key");
|
|
@@ -11723,7 +12298,7 @@ function OhhwellsBridge() {
|
|
|
11723
12298
|
});
|
|
11724
12299
|
deselect();
|
|
11725
12300
|
}, [deselect]);
|
|
11726
|
-
const handleLinkPopoverSubmit =
|
|
12301
|
+
const handleLinkPopoverSubmit = useCallback5(
|
|
11727
12302
|
(target) => {
|
|
11728
12303
|
const session = linkPopoverSessionRef.current;
|
|
11729
12304
|
if (!session) return;
|
|
@@ -11782,13 +12357,13 @@ function OhhwellsBridge() {
|
|
|
11782
12357
|
const showEditLink = toolbarShowEditLink;
|
|
11783
12358
|
const currentSections = sectionsByPath[pathname] ?? [];
|
|
11784
12359
|
linkPopoverOpenRef.current = linkPopover !== null;
|
|
11785
|
-
const handleMediaReplace =
|
|
12360
|
+
const handleMediaReplace = useCallback5(
|
|
11786
12361
|
(key) => {
|
|
11787
12362
|
postToParent2({ type: "ow:image-pick", key, elementType: mediaHover?.elementType ?? "image" });
|
|
11788
12363
|
},
|
|
11789
12364
|
[postToParent2, mediaHover?.elementType]
|
|
11790
12365
|
);
|
|
11791
|
-
const handleMediaFadeOutComplete =
|
|
12366
|
+
const handleMediaFadeOutComplete = useCallback5((key) => {
|
|
11792
12367
|
setUploadingRects((prev) => {
|
|
11793
12368
|
if (!(key in prev)) return prev;
|
|
11794
12369
|
const next = { ...prev };
|
|
@@ -11796,7 +12371,7 @@ function OhhwellsBridge() {
|
|
|
11796
12371
|
return next;
|
|
11797
12372
|
});
|
|
11798
12373
|
}, []);
|
|
11799
|
-
const handleVideoSettingsChange =
|
|
12374
|
+
const handleVideoSettingsChange = useCallback5(
|
|
11800
12375
|
(key, settings) => {
|
|
11801
12376
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
11802
12377
|
const video = getVideoEl(el);
|
|
@@ -11819,9 +12394,9 @@ function OhhwellsBridge() {
|
|
|
11819
12394
|
[postToParent2]
|
|
11820
12395
|
);
|
|
11821
12396
|
return bridgeRoot ? createPortal2(
|
|
11822
|
-
/* @__PURE__ */
|
|
11823
|
-
/* @__PURE__ */
|
|
11824
|
-
Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */
|
|
12397
|
+
/* @__PURE__ */ jsxs14(Fragment5, { children: [
|
|
12398
|
+
/* @__PURE__ */ jsx25("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
|
|
12399
|
+
Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ jsx25(
|
|
11825
12400
|
MediaOverlay,
|
|
11826
12401
|
{
|
|
11827
12402
|
hover: { key, rect, elementType: "image", isDragOver: false, hasTextOverlap: false },
|
|
@@ -11832,7 +12407,7 @@ function OhhwellsBridge() {
|
|
|
11832
12407
|
},
|
|
11833
12408
|
`uploading-${key}`
|
|
11834
12409
|
)),
|
|
11835
|
-
mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */
|
|
12410
|
+
mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */ jsx25(
|
|
11836
12411
|
MediaOverlay,
|
|
11837
12412
|
{
|
|
11838
12413
|
hover: mediaHover,
|
|
@@ -11841,10 +12416,10 @@ function OhhwellsBridge() {
|
|
|
11841
12416
|
onVideoSettingsChange: handleVideoSettingsChange
|
|
11842
12417
|
}
|
|
11843
12418
|
),
|
|
11844
|
-
siblingHintRect && !linkPopover && !isItemDragging && siblingHintRects.length === 0 && /* @__PURE__ */
|
|
11845
|
-
siblingHintRects.length > 0 && !linkPopover && !isItemDragging && siblingHintRects.map((rect, i) => /* @__PURE__ */
|
|
11846
|
-
isItemDragging && draggedItemRect && selectedElRef.current !== footerDragRef.current?.draggedEl && selectedElRef.current !== navDragRef.current?.draggedEl && /* @__PURE__ */
|
|
11847
|
-
isItemDragging && footerDropSlots.map((slot, i) => /* @__PURE__ */
|
|
12419
|
+
siblingHintRect && !linkPopover && !isItemDragging && siblingHintRects.length === 0 && /* @__PURE__ */ jsx25(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
|
|
12420
|
+
siblingHintRects.length > 0 && !linkPopover && !isItemDragging && siblingHintRects.map((rect, i) => /* @__PURE__ */ jsx25(ItemInteractionLayer, { rect, state: "sibling-hint" }, `sibling-hint-${i}`)),
|
|
12421
|
+
isItemDragging && draggedItemRect && selectedElRef.current !== footerDragRef.current?.draggedEl && selectedElRef.current !== navDragRef.current?.draggedEl && /* @__PURE__ */ jsx25(ItemInteractionLayer, { rect: draggedItemRect, state: "dragging" }),
|
|
12422
|
+
isItemDragging && footerDropSlots.map((slot, i) => /* @__PURE__ */ jsx25(
|
|
11848
12423
|
"div",
|
|
11849
12424
|
{
|
|
11850
12425
|
className: "pointer-events-none fixed z-2147483646",
|
|
@@ -11854,7 +12429,7 @@ function OhhwellsBridge() {
|
|
|
11854
12429
|
width: slot.width,
|
|
11855
12430
|
height: slot.height
|
|
11856
12431
|
},
|
|
11857
|
-
children: /* @__PURE__ */
|
|
12432
|
+
children: /* @__PURE__ */ jsx25(
|
|
11858
12433
|
DropIndicator,
|
|
11859
12434
|
{
|
|
11860
12435
|
direction: slot.direction,
|
|
@@ -11865,7 +12440,7 @@ function OhhwellsBridge() {
|
|
|
11865
12440
|
},
|
|
11866
12441
|
`footer-drop-${slot.direction}-${slot.columnIndex}-${slot.insertIndex}-${i}`
|
|
11867
12442
|
)),
|
|
11868
|
-
isItemDragging && navDropSlots.map((slot, i) => /* @__PURE__ */
|
|
12443
|
+
isItemDragging && navDropSlots.map((slot, i) => /* @__PURE__ */ jsx25(
|
|
11869
12444
|
"div",
|
|
11870
12445
|
{
|
|
11871
12446
|
className: "pointer-events-none fixed z-2147483646",
|
|
@@ -11875,7 +12450,7 @@ function OhhwellsBridge() {
|
|
|
11875
12450
|
width: slot.width,
|
|
11876
12451
|
height: slot.height
|
|
11877
12452
|
},
|
|
11878
|
-
children: /* @__PURE__ */
|
|
12453
|
+
children: /* @__PURE__ */ jsx25(
|
|
11879
12454
|
DropIndicator,
|
|
11880
12455
|
{
|
|
11881
12456
|
direction: slot.direction,
|
|
@@ -11886,10 +12461,11 @@ function OhhwellsBridge() {
|
|
|
11886
12461
|
},
|
|
11887
12462
|
`nav-drop-${slot.direction}-${slot.parentId ?? "root"}-${slot.insertIndex}-${i}`
|
|
11888
12463
|
)),
|
|
11889
|
-
hoveredNavContainerRect && toolbarVariant !== "select-frame" && !linkPopover && !isItemDragging && /* @__PURE__ */
|
|
11890
|
-
hoveredItemRect && !linkPopover && !hoveredNavContainerRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */
|
|
11891
|
-
toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isNavbarLinksContainer(selectedElRef.current) && /* @__PURE__ */
|
|
11892
|
-
toolbarRect && !linkPopover &&
|
|
12464
|
+
hoveredNavContainerRect && (toolbarVariant !== "select-frame" || isFooterFrameSelection) && !linkPopover && !isItemDragging && /* @__PURE__ */ jsx25(ItemInteractionLayer, { rect: hoveredNavContainerRect, state: "hover" }),
|
|
12465
|
+
hoveredItemRect && !linkPopover && !hoveredNavContainerRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ jsx25(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
|
|
12466
|
+
toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isNavbarLinksContainer(selectedElRef.current) && /* @__PURE__ */ jsx25(NavbarContainerChrome, { rect: toolbarRect, onAdd: handleAddTopLevelNavItem }),
|
|
12467
|
+
toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isFooterLinksContainer(selectedElRef.current) && /* @__PURE__ */ jsx25(FooterContainerChrome, { rect: toolbarRect, onAdd: handleAddFooterColumn }),
|
|
12468
|
+
toolbarRect && !linkPopover && (toolbarVariant === "link-action" || toolbarVariant === "select-frame") && /* @__PURE__ */ jsx25(
|
|
11893
12469
|
ItemInteractionLayer,
|
|
11894
12470
|
{
|
|
11895
12471
|
rect: isItemDragging && draggedItemRect && (footerDragRef.current?.wasSelected || navDragRef.current?.wasSelected) ? draggedItemRect : toolbarRect,
|
|
@@ -11903,7 +12479,7 @@ function OhhwellsBridge() {
|
|
|
11903
12479
|
onItemPointerDown: handleItemChromePointerDown,
|
|
11904
12480
|
onItemClick: handleItemChromeClick,
|
|
11905
12481
|
itemDragSurface: !isFooterFrameSelection,
|
|
11906
|
-
toolbar: toolbarVariant === "link-action" && !isItemDragging ? /* @__PURE__ */
|
|
12482
|
+
toolbar: toolbarVariant === "link-action" && !isItemDragging ? /* @__PURE__ */ jsx25(
|
|
11907
12483
|
ItemActionToolbar,
|
|
11908
12484
|
{
|
|
11909
12485
|
onEditLink: openLinkPopoverForSelected,
|
|
@@ -11916,8 +12492,8 @@ function OhhwellsBridge() {
|
|
|
11916
12492
|
) : void 0
|
|
11917
12493
|
}
|
|
11918
12494
|
),
|
|
11919
|
-
toolbarRect && toolbarVariant === "rich-text" && !linkPopover && /* @__PURE__ */
|
|
11920
|
-
/* @__PURE__ */
|
|
12495
|
+
toolbarRect && toolbarVariant === "rich-text" && !linkPopover && /* @__PURE__ */ jsxs14(Fragment5, { children: [
|
|
12496
|
+
/* @__PURE__ */ jsx25(
|
|
11921
12497
|
EditGlowChrome,
|
|
11922
12498
|
{
|
|
11923
12499
|
rect: toolbarRect,
|
|
@@ -11927,7 +12503,7 @@ function OhhwellsBridge() {
|
|
|
11927
12503
|
hideHandle: isItemDragging
|
|
11928
12504
|
}
|
|
11929
12505
|
),
|
|
11930
|
-
/* @__PURE__ */
|
|
12506
|
+
/* @__PURE__ */ jsx25(
|
|
11931
12507
|
FloatingToolbar,
|
|
11932
12508
|
{
|
|
11933
12509
|
rect: toolbarRect,
|
|
@@ -11940,7 +12516,7 @@ function OhhwellsBridge() {
|
|
|
11940
12516
|
}
|
|
11941
12517
|
)
|
|
11942
12518
|
] }),
|
|
11943
|
-
maxBadge && /* @__PURE__ */
|
|
12519
|
+
maxBadge && /* @__PURE__ */ jsxs14(
|
|
11944
12520
|
"div",
|
|
11945
12521
|
{
|
|
11946
12522
|
"data-ohw-max-badge": "",
|
|
@@ -11966,7 +12542,7 @@ function OhhwellsBridge() {
|
|
|
11966
12542
|
]
|
|
11967
12543
|
}
|
|
11968
12544
|
),
|
|
11969
|
-
toggleState && !linkPopover && /* @__PURE__ */
|
|
12545
|
+
toggleState && !linkPopover && /* @__PURE__ */ jsx25(
|
|
11970
12546
|
StateToggle,
|
|
11971
12547
|
{
|
|
11972
12548
|
rect: toggleState.rect,
|
|
@@ -11975,15 +12551,15 @@ function OhhwellsBridge() {
|
|
|
11975
12551
|
onStateChange: handleStateChange
|
|
11976
12552
|
}
|
|
11977
12553
|
),
|
|
11978
|
-
sectionGap && !linkPopover && /* @__PURE__ */
|
|
12554
|
+
sectionGap && !linkPopover && /* @__PURE__ */ jsxs14(
|
|
11979
12555
|
"div",
|
|
11980
12556
|
{
|
|
11981
12557
|
"data-ohw-section-insert-line": "",
|
|
11982
12558
|
className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
|
|
11983
12559
|
style: { top: sectionGap.y, transform: "translateY(-50%)" },
|
|
11984
12560
|
children: [
|
|
11985
|
-
/* @__PURE__ */
|
|
11986
|
-
/* @__PURE__ */
|
|
12561
|
+
/* @__PURE__ */ jsx25("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
|
|
12562
|
+
/* @__PURE__ */ jsx25(
|
|
11987
12563
|
Badge,
|
|
11988
12564
|
{
|
|
11989
12565
|
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",
|
|
@@ -12000,11 +12576,11 @@ function OhhwellsBridge() {
|
|
|
12000
12576
|
children: "Add Section"
|
|
12001
12577
|
}
|
|
12002
12578
|
),
|
|
12003
|
-
/* @__PURE__ */
|
|
12579
|
+
/* @__PURE__ */ jsx25("div", { className: "flex-1 bg-primary", style: { height: 3 } })
|
|
12004
12580
|
]
|
|
12005
12581
|
}
|
|
12006
12582
|
),
|
|
12007
|
-
linkPopover && dialogPortalContainer ? /* @__PURE__ */
|
|
12583
|
+
linkPopover && dialogPortalContainer ? /* @__PURE__ */ jsx25(
|
|
12008
12584
|
LinkPopover,
|
|
12009
12585
|
{
|
|
12010
12586
|
panelRef: linkPopoverPanelRef,
|