@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.cjs
CHANGED
|
@@ -115,6 +115,7 @@ var import_react3 = require("react");
|
|
|
115
115
|
var import_react2 = require("react");
|
|
116
116
|
var import_radix_ui = require("radix-ui");
|
|
117
117
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
118
|
+
var isValidEmail = (value) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value);
|
|
118
119
|
function Spinner() {
|
|
119
120
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
120
121
|
"svg",
|
|
@@ -148,12 +149,17 @@ function EmailCaptureModal({ title, subtitle, onSubmit, onClose }) {
|
|
|
148
149
|
const [error, setError] = (0, import_react2.useState)(null);
|
|
149
150
|
const isBook = title === "Confirm your spot";
|
|
150
151
|
const handleSubmit = async () => {
|
|
151
|
-
|
|
152
|
+
const trimmed = email.trim();
|
|
153
|
+
if (!trimmed) return;
|
|
154
|
+
if (!isValidEmail(trimmed)) {
|
|
155
|
+
setError("Please enter a valid email address.");
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
152
158
|
setLoading(true);
|
|
153
159
|
setError(null);
|
|
154
160
|
try {
|
|
155
|
-
await onSubmit(
|
|
156
|
-
setSubmittedEmail(
|
|
161
|
+
await onSubmit(trimmed);
|
|
162
|
+
setSubmittedEmail(trimmed);
|
|
157
163
|
setSuccess(true);
|
|
158
164
|
} catch (e) {
|
|
159
165
|
setError(e instanceof Error ? e.message : "Something went wrong. Please try again.");
|
|
@@ -228,7 +234,10 @@ function EmailCaptureModal({ title, subtitle, onSubmit, onClose }) {
|
|
|
228
234
|
{
|
|
229
235
|
type: "email",
|
|
230
236
|
value: email,
|
|
231
|
-
onChange: (e) =>
|
|
237
|
+
onChange: (e) => {
|
|
238
|
+
setEmail(e.target.value);
|
|
239
|
+
if (error) setError(null);
|
|
240
|
+
},
|
|
232
241
|
onKeyDown: handleKeyDown,
|
|
233
242
|
placeholder: "hello@gmail.com",
|
|
234
243
|
autoFocus: true,
|
|
@@ -285,12 +294,20 @@ function formatClassTime(cls) {
|
|
|
285
294
|
const em = endTotal % 60;
|
|
286
295
|
return `${h}:${cls.startTime.minutes}-${eh}:${String(em).padStart(2, "0")}`;
|
|
287
296
|
}
|
|
297
|
+
function formatBookingLabel(cls) {
|
|
298
|
+
const price = cls.price;
|
|
299
|
+
const isFree = price === null || price === void 0 || `${price}` === "" || `${price}` === "0";
|
|
300
|
+
return isFree ? "Book for free" : `Book for ${cls.currency ?? ""} ${price}`.trim();
|
|
301
|
+
}
|
|
288
302
|
function getBookingsOnDate(cls, date) {
|
|
289
303
|
if (!cls.bookings?.length) return 0;
|
|
290
|
-
const
|
|
304
|
+
const target = new Date(date);
|
|
305
|
+
target.setHours(0, 0, 0, 0);
|
|
291
306
|
return cls.bookings.filter((b) => {
|
|
292
307
|
try {
|
|
293
|
-
|
|
308
|
+
const bookingDate = new Date(b.classDate);
|
|
309
|
+
bookingDate.setHours(0, 0, 0, 0);
|
|
310
|
+
return bookingDate.getTime() === target.getTime();
|
|
294
311
|
} catch {
|
|
295
312
|
return false;
|
|
296
313
|
}
|
|
@@ -555,7 +572,7 @@ function ScheduleView({ schedule, dates, selectedIdx, onSelectDate, onOpenModal
|
|
|
555
572
|
}
|
|
556
573
|
)
|
|
557
574
|
] }),
|
|
558
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "sm:hidden flex flex-col gap-px", children: isFull ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "font-body text-sm text-(--color-dark,#200C02) opacity-80", children: "Full" }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
575
|
+
cls.showAvailability !== false && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "sm:hidden flex flex-col gap-px", children: isFull ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "font-body text-sm text-(--color-dark,#200C02) opacity-80", children: "Full" }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
559
576
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "font-body text-sm text-(--color-dark,#200C02) opacity-80", children: [
|
|
560
577
|
available,
|
|
561
578
|
"/",
|
|
@@ -567,9 +584,17 @@ function ScheduleView({ schedule, dates, selectedIdx, onSelectDate, onOpenModal
|
|
|
567
584
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex flex-1 flex-col gap-2 min-w-0 sm:contents", children: [
|
|
568
585
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex-1 flex flex-col gap-2 min-w-0", children: [
|
|
569
586
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "font-body text-base font-bold text-(--color-dark,#200C02) block truncate", children: cls.name }),
|
|
570
|
-
cls.hostName && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "font-body text-base font-normal text-(--color-dark,#200C02) opacity-80 block truncate", children: cls.hostName })
|
|
587
|
+
cls.hostName && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "font-body text-base font-normal text-(--color-dark,#200C02) opacity-80 block truncate", children: cls.hostName }),
|
|
588
|
+
cls.description && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
589
|
+
"span",
|
|
590
|
+
{
|
|
591
|
+
className: "font-body text-base font-normal text-(--color-dark,#200C02) opacity-80 block",
|
|
592
|
+
style: { wordBreak: "break-word" },
|
|
593
|
+
children: cls.description
|
|
594
|
+
}
|
|
595
|
+
)
|
|
571
596
|
] }),
|
|
572
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "hidden sm:flex w-14 shrink-0 flex-col gap-px", children: isFull ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "font-body text-sm text-(--color-dark,#200C02) opacity-80", children: "Full" }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
597
|
+
cls.showAvailability !== false && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "hidden sm:flex w-14 shrink-0 flex-col gap-px", children: isFull ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "font-body text-sm text-(--color-dark,#200C02) opacity-80", children: "Full" }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
573
598
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "font-body text-sm text-(--color-dark,#200C02) opacity-80", children: [
|
|
574
599
|
available,
|
|
575
600
|
"/",
|
|
@@ -594,7 +619,7 @@ function ScheduleView({ schedule, dates, selectedIdx, onSelectDate, onOpenModal
|
|
|
594
619
|
if (!cls.id) return;
|
|
595
620
|
onOpenModal?.(isFull ? "waitlist" : "book", cls.id, selectedDate);
|
|
596
621
|
},
|
|
597
|
-
children: isFull ? "Join Waitlist" :
|
|
622
|
+
children: isFull ? "Join Waitlist" : formatBookingLabel(cls)
|
|
598
623
|
}
|
|
599
624
|
)
|
|
600
625
|
] })
|
|
@@ -636,6 +661,17 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
636
661
|
const [isHovered, setIsHovered] = (0, import_react3.useState)(false);
|
|
637
662
|
const [modalState, setModalState] = (0, import_react3.useState)(null);
|
|
638
663
|
const switchScheduleIdRef = (0, import_react3.useRef)(null);
|
|
664
|
+
const liveScheduleIdRef = (0, import_react3.useRef)(null);
|
|
665
|
+
const refetchLiveSchedule = (0, import_react3.useCallback)(async () => {
|
|
666
|
+
const id = liveScheduleIdRef.current;
|
|
667
|
+
if (!id) return;
|
|
668
|
+
try {
|
|
669
|
+
const res = await fetch(`${API_URL}/api/schedule/id/${id}`);
|
|
670
|
+
const data = await res.json();
|
|
671
|
+
if (data?.id) setSchedule(data);
|
|
672
|
+
} catch {
|
|
673
|
+
}
|
|
674
|
+
}, []);
|
|
639
675
|
const dates = (0, import_react3.useMemo)(() => {
|
|
640
676
|
const today = /* @__PURE__ */ new Date();
|
|
641
677
|
today.setHours(0, 0, 0, 0);
|
|
@@ -655,6 +691,18 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
655
691
|
}
|
|
656
692
|
}
|
|
657
693
|
}, [schedule, dates]);
|
|
694
|
+
(0, import_react3.useEffect)(() => {
|
|
695
|
+
if (typeof window === "undefined") return;
|
|
696
|
+
const onVisible = () => {
|
|
697
|
+
if (!document.hidden) void refetchLiveSchedule();
|
|
698
|
+
};
|
|
699
|
+
window.addEventListener("focus", refetchLiveSchedule);
|
|
700
|
+
document.addEventListener("visibilitychange", onVisible);
|
|
701
|
+
return () => {
|
|
702
|
+
window.removeEventListener("focus", refetchLiveSchedule);
|
|
703
|
+
document.removeEventListener("visibilitychange", onVisible);
|
|
704
|
+
};
|
|
705
|
+
}, [refetchLiveSchedule]);
|
|
658
706
|
(0, import_react3.useEffect)(() => {
|
|
659
707
|
if (typeof window === "undefined") return;
|
|
660
708
|
const isInEditor = window.self !== window.top;
|
|
@@ -716,7 +764,7 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
716
764
|
setLoading(false);
|
|
717
765
|
return;
|
|
718
766
|
}
|
|
719
|
-
;
|
|
767
|
+
liveScheduleIdRef.current = effectiveId;
|
|
720
768
|
(async () => {
|
|
721
769
|
try {
|
|
722
770
|
const res = await fetch(`${API_URL}/api/schedule/id/${effectiveId}`);
|
|
@@ -773,18 +821,14 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
773
821
|
const data = await res.json().catch(() => ({}));
|
|
774
822
|
throw new Error(data?.message ?? "Something went wrong. Please try again.");
|
|
775
823
|
}
|
|
824
|
+
await refetchLiveSchedule();
|
|
776
825
|
};
|
|
777
826
|
const handleReplaceSchedule = () => {
|
|
778
827
|
setIsHovered(false);
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
insertAfter
|
|
784
|
-
}, "*");
|
|
785
|
-
} else {
|
|
786
|
-
window.parent.postMessage({ type: "ow:scheduling-not-connected", insertAfter }, "*");
|
|
787
|
-
}
|
|
828
|
+
window.parent.postMessage(
|
|
829
|
+
{ type: "ow:scheduling-not-connected", insertAfter, currentScheduleId: schedule?.id },
|
|
830
|
+
"*"
|
|
831
|
+
);
|
|
788
832
|
};
|
|
789
833
|
if (!inEditor && !loading && !schedule) return null;
|
|
790
834
|
const sectionId = `scheduling-${insertAfter}`;
|
|
@@ -827,7 +871,19 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
827
871
|
),
|
|
828
872
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "max-w-[1280px] mx-auto flex flex-col items-center gap-16", children: [
|
|
829
873
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex flex-col items-center gap-4", children: [
|
|
830
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
874
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
875
|
+
"h2",
|
|
876
|
+
{
|
|
877
|
+
className: "font-display text-center m-0 text-(--color-dark,#200C02)",
|
|
878
|
+
style: {
|
|
879
|
+
fontSize: "var(--fs-section-h2, clamp(40px, 4.4vw, 64px))",
|
|
880
|
+
fontWeight: "var(--font-weight-heading, 400)",
|
|
881
|
+
lineHeight: 1.05,
|
|
882
|
+
letterSpacing: "-0.02em"
|
|
883
|
+
},
|
|
884
|
+
children: schedule?.name ?? "Book an appointment"
|
|
885
|
+
}
|
|
886
|
+
),
|
|
831
887
|
schedule?.description && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "font-body text-body text-center m-0 text-(--color-accent,#A89B83)", children: schedule.description })
|
|
832
888
|
] }),
|
|
833
889
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "w-full flex flex-col items-end gap-3", children: [
|
|
@@ -4887,7 +4943,11 @@ function MediaOverlay({
|
|
|
4887
4943
|
variant: "outline",
|
|
4888
4944
|
size: "sm",
|
|
4889
4945
|
className: "gap-1.5 cursor-pointer hover:bg-background",
|
|
4890
|
-
style:
|
|
4946
|
+
style: {
|
|
4947
|
+
...OVERLAY_BUTTON_STYLE,
|
|
4948
|
+
// Don't let Replace steal clicks when text (e.g. nav) sits on top of this media.
|
|
4949
|
+
pointerEvents: hover.hasTextOverlap ? "none" : "auto"
|
|
4950
|
+
},
|
|
4891
4951
|
onMouseDown: (e) => e.preventDefault(),
|
|
4892
4952
|
onClick: (e) => {
|
|
4893
4953
|
e.stopPropagation();
|
|
@@ -6661,6 +6721,8 @@ function applyNavOrderToContainer(container, order) {
|
|
|
6661
6721
|
if (current.length === expected.length && current.every((key, i) => key === expected[i])) {
|
|
6662
6722
|
return;
|
|
6663
6723
|
}
|
|
6724
|
+
const lastCurrentLinkEl = current.length > 0 ? findCounterpartByHrefKey(current[current.length - 1], container) : null;
|
|
6725
|
+
const anchor = lastCurrentLinkEl?.parentElement === container ? lastCurrentLinkEl.nextElementSibling : null;
|
|
6664
6726
|
const seen = /* @__PURE__ */ new Set();
|
|
6665
6727
|
for (const hrefKey of desired) {
|
|
6666
6728
|
if (seen.has(hrefKey)) continue;
|
|
@@ -6675,7 +6737,9 @@ function applyNavOrderToContainer(container, order) {
|
|
|
6675
6737
|
orderedEls.push(el);
|
|
6676
6738
|
}
|
|
6677
6739
|
for (const el of orderedEls) {
|
|
6678
|
-
if (
|
|
6740
|
+
if (anchor) {
|
|
6741
|
+
if (el.nextSibling !== anchor) container.insertBefore(el, anchor);
|
|
6742
|
+
} else if (container.lastElementChild !== el) {
|
|
6679
6743
|
container.appendChild(el);
|
|
6680
6744
|
}
|
|
6681
6745
|
}
|
|
@@ -7007,7 +7071,195 @@ function parseFooterOrder(content) {
|
|
|
7007
7071
|
return null;
|
|
7008
7072
|
}
|
|
7009
7073
|
}
|
|
7074
|
+
var FOOTER_HEADING_RE = /^footer-(\d+)-heading$/;
|
|
7075
|
+
var FOOTER_LABEL_RE = /^footer-(\d+)-(\d+)-label$/;
|
|
7076
|
+
var DEFAULT_FOOTER_COLUMN_HEADING = "New";
|
|
7077
|
+
var DEFAULT_FOOTER_COLUMN_LINK_LABEL = "New link";
|
|
7078
|
+
var DEFAULT_FOOTER_COLUMN_LINK_HREF = "";
|
|
7079
|
+
function isFooterLinksContainer(el) {
|
|
7080
|
+
return el.hasAttribute("data-ohw-footer-links") || el.classList.contains("rb-footer-links");
|
|
7081
|
+
}
|
|
7082
|
+
function getFooterColumnIndicesInDom() {
|
|
7083
|
+
const indices = /* @__PURE__ */ new Set();
|
|
7084
|
+
for (const col of listFooterColumns()) {
|
|
7085
|
+
const attr = col.getAttribute("data-ohw-footer-col");
|
|
7086
|
+
if (attr != null) {
|
|
7087
|
+
const n = parseInt(attr, 10);
|
|
7088
|
+
if (Number.isFinite(n)) indices.add(n);
|
|
7089
|
+
}
|
|
7090
|
+
for (const link of listFooterLinksInColumn(col)) {
|
|
7091
|
+
const parsed = parseFooterHrefKey(link.getAttribute("data-ohw-href-key"));
|
|
7092
|
+
if (parsed) indices.add(parsed.col);
|
|
7093
|
+
}
|
|
7094
|
+
const heading = col.querySelector('[data-ohw-key^="footer-"][data-ohw-key$="-heading"]');
|
|
7095
|
+
const headingKey = heading?.getAttribute("data-ohw-key");
|
|
7096
|
+
if (headingKey) {
|
|
7097
|
+
const match = headingKey.match(FOOTER_HEADING_RE);
|
|
7098
|
+
if (match) indices.add(parseInt(match[1], 10));
|
|
7099
|
+
}
|
|
7100
|
+
}
|
|
7101
|
+
return [...indices].sort((a, b) => a - b);
|
|
7102
|
+
}
|
|
7103
|
+
function getNextFooterColumnIndex() {
|
|
7104
|
+
const indices = getFooterColumnIndicesInDom();
|
|
7105
|
+
if (indices.length === 0) return 0;
|
|
7106
|
+
return Math.max(...indices) + 1;
|
|
7107
|
+
}
|
|
7108
|
+
function cloneFooterLinkShell(template) {
|
|
7109
|
+
const anchor = document.createElement("a");
|
|
7110
|
+
if (template) {
|
|
7111
|
+
anchor.style.cssText = template.style.cssText;
|
|
7112
|
+
if (template.className) anchor.className = template.className;
|
|
7113
|
+
}
|
|
7114
|
+
anchor.style.cursor = "pointer";
|
|
7115
|
+
anchor.style.textDecoration = "none";
|
|
7116
|
+
return anchor;
|
|
7117
|
+
}
|
|
7118
|
+
function buildFooterHeading(colIndex, text) {
|
|
7119
|
+
const heading = document.createElement("p");
|
|
7120
|
+
heading.setAttribute("data-ohw-editable", "text");
|
|
7121
|
+
heading.setAttribute("data-ohw-key", `footer-${colIndex}-heading`);
|
|
7122
|
+
heading.textContent = text;
|
|
7123
|
+
heading.style.cssText = [
|
|
7124
|
+
"color: var(--espresso, #3d312b)",
|
|
7125
|
+
"font-size: 14px",
|
|
7126
|
+
"font-weight: 800",
|
|
7127
|
+
"opacity: 0.82",
|
|
7128
|
+
"margin: 0 0 6px",
|
|
7129
|
+
"padding: 0",
|
|
7130
|
+
"line-height: 1.2"
|
|
7131
|
+
].join(";");
|
|
7132
|
+
return heading;
|
|
7133
|
+
}
|
|
7134
|
+
function buildFooterLink(colIndex, itemIndex, href, label, template) {
|
|
7135
|
+
const anchor = cloneFooterLinkShell(template);
|
|
7136
|
+
anchor.setAttribute("href", href);
|
|
7137
|
+
anchor.setAttribute("data-ohw-href-key", `footer-${colIndex}-${itemIndex}-href`);
|
|
7138
|
+
const span = document.createElement("span");
|
|
7139
|
+
span.setAttribute("data-ohw-editable", "text");
|
|
7140
|
+
span.setAttribute("data-ohw-key", `footer-${colIndex}-${itemIndex}-label`);
|
|
7141
|
+
span.textContent = label;
|
|
7142
|
+
anchor.appendChild(span);
|
|
7143
|
+
return anchor;
|
|
7144
|
+
}
|
|
7145
|
+
function footerColumnExistsInDom(colIndex) {
|
|
7146
|
+
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;
|
|
7147
|
+
}
|
|
7148
|
+
function getFooterLinkTemplate() {
|
|
7149
|
+
for (const col of listFooterColumns()) {
|
|
7150
|
+
const link = listFooterLinksInColumn(col)[0];
|
|
7151
|
+
if (link) return link;
|
|
7152
|
+
}
|
|
7153
|
+
return null;
|
|
7154
|
+
}
|
|
7155
|
+
function getFooterColumnTemplate() {
|
|
7156
|
+
return listFooterColumns()[0] ?? null;
|
|
7157
|
+
}
|
|
7158
|
+
function insertFooterColumnDom(colIndex, heading, items) {
|
|
7159
|
+
const container = getFooterLinksContainer();
|
|
7160
|
+
if (!container) return null;
|
|
7161
|
+
const colTemplate = getFooterColumnTemplate();
|
|
7162
|
+
const linkTemplate = getFooterLinkTemplate();
|
|
7163
|
+
const column = document.createElement("div");
|
|
7164
|
+
if (colTemplate?.className) column.className = colTemplate.className;
|
|
7165
|
+
else column.className = "rb-footer-link-col";
|
|
7166
|
+
column.setAttribute("data-ohw-footer-col", String(colIndex));
|
|
7167
|
+
if (colTemplate) {
|
|
7168
|
+
const gap = getComputedStyle(colTemplate).gap;
|
|
7169
|
+
if (gap && gap !== "normal") column.style.gap = gap;
|
|
7170
|
+
column.style.display = getComputedStyle(colTemplate).display || "flex";
|
|
7171
|
+
column.style.flexDirection = "column";
|
|
7172
|
+
}
|
|
7173
|
+
column.appendChild(buildFooterHeading(colIndex, heading));
|
|
7174
|
+
let firstLink = null;
|
|
7175
|
+
items.forEach((item, itemIndex) => {
|
|
7176
|
+
const link = buildFooterLink(colIndex, itemIndex, item.href, item.label, linkTemplate);
|
|
7177
|
+
column.appendChild(link);
|
|
7178
|
+
if (!firstLink) firstLink = link;
|
|
7179
|
+
});
|
|
7180
|
+
container.appendChild(column);
|
|
7181
|
+
return { column, firstLink };
|
|
7182
|
+
}
|
|
7183
|
+
function insertFooterColumn(heading = DEFAULT_FOOTER_COLUMN_HEADING, linkLabel = DEFAULT_FOOTER_COLUMN_LINK_LABEL, linkHref = DEFAULT_FOOTER_COLUMN_LINK_HREF) {
|
|
7184
|
+
const colIndex = getNextFooterColumnIndex();
|
|
7185
|
+
const inserted = insertFooterColumnDom(colIndex, heading, [{ href: linkHref, label: linkLabel }]);
|
|
7186
|
+
if (!inserted?.firstLink) throw new Error("Failed to insert footer column");
|
|
7187
|
+
syncFooterColumnIndices(listFooterColumns());
|
|
7188
|
+
return {
|
|
7189
|
+
column: inserted.column,
|
|
7190
|
+
firstLink: inserted.firstLink,
|
|
7191
|
+
colIndex,
|
|
7192
|
+
headingKey: `footer-${colIndex}-heading`,
|
|
7193
|
+
hrefKey: `footer-${colIndex}-0-href`,
|
|
7194
|
+
labelKey: `footer-${colIndex}-0-label`,
|
|
7195
|
+
heading,
|
|
7196
|
+
label: linkLabel,
|
|
7197
|
+
href: linkHref,
|
|
7198
|
+
order: getFooterOrderFromDom()
|
|
7199
|
+
};
|
|
7200
|
+
}
|
|
7201
|
+
function collectFooterColumnIndicesFromContent(content) {
|
|
7202
|
+
const indices = /* @__PURE__ */ new Set();
|
|
7203
|
+
for (const key of Object.keys(content)) {
|
|
7204
|
+
const href = parseFooterHrefKey(key);
|
|
7205
|
+
if (href) indices.add(href.col);
|
|
7206
|
+
const heading = key.match(FOOTER_HEADING_RE);
|
|
7207
|
+
if (heading) indices.add(parseInt(heading[1], 10));
|
|
7208
|
+
const label = key.match(FOOTER_LABEL_RE);
|
|
7209
|
+
if (label) indices.add(parseInt(label[1], 10));
|
|
7210
|
+
}
|
|
7211
|
+
const order = parseFooterOrder(content);
|
|
7212
|
+
if (order) {
|
|
7213
|
+
for (const col of order) {
|
|
7214
|
+
for (const hrefKey of col) {
|
|
7215
|
+
const parsed = parseFooterHrefKey(hrefKey);
|
|
7216
|
+
if (parsed) indices.add(parsed.col);
|
|
7217
|
+
}
|
|
7218
|
+
}
|
|
7219
|
+
}
|
|
7220
|
+
return [...indices].sort((a, b) => a - b);
|
|
7221
|
+
}
|
|
7222
|
+
function collectFooterItemsForColumn(content, colIndex) {
|
|
7223
|
+
const itemIndices = /* @__PURE__ */ new Set();
|
|
7224
|
+
for (const key of Object.keys(content)) {
|
|
7225
|
+
const href = parseFooterHrefKey(key);
|
|
7226
|
+
if (href?.col === colIndex) itemIndices.add(href.item);
|
|
7227
|
+
const label = key.match(FOOTER_LABEL_RE);
|
|
7228
|
+
if (label && parseInt(label[1], 10) === colIndex) {
|
|
7229
|
+
itemIndices.add(parseInt(label[2], 10));
|
|
7230
|
+
}
|
|
7231
|
+
}
|
|
7232
|
+
const sorted = [...itemIndices].sort((a, b) => a - b);
|
|
7233
|
+
if (sorted.length === 0) {
|
|
7234
|
+
return [
|
|
7235
|
+
{
|
|
7236
|
+
href: content[`footer-${colIndex}-0-href`] ?? DEFAULT_FOOTER_COLUMN_LINK_HREF,
|
|
7237
|
+
label: content[`footer-${colIndex}-0-label`] ?? DEFAULT_FOOTER_COLUMN_LINK_LABEL
|
|
7238
|
+
}
|
|
7239
|
+
];
|
|
7240
|
+
}
|
|
7241
|
+
return sorted.map((itemIndex) => ({
|
|
7242
|
+
href: content[`footer-${colIndex}-${itemIndex}-href`] ?? DEFAULT_FOOTER_COLUMN_LINK_HREF,
|
|
7243
|
+
label: content[`footer-${colIndex}-${itemIndex}-label`] ?? DEFAULT_FOOTER_COLUMN_LINK_LABEL
|
|
7244
|
+
}));
|
|
7245
|
+
}
|
|
7246
|
+
function reconcileFooterColumnsFromContent(content) {
|
|
7247
|
+
const indices = collectFooterColumnIndicesFromContent(content);
|
|
7248
|
+
for (const colIndex of indices) {
|
|
7249
|
+
if (footerColumnExistsInDom(colIndex)) continue;
|
|
7250
|
+
const heading = content[`footer-${colIndex}-heading`] ?? DEFAULT_FOOTER_COLUMN_HEADING;
|
|
7251
|
+
const items = collectFooterItemsForColumn(content, colIndex);
|
|
7252
|
+
const hasPayload = Boolean(content[`footer-${colIndex}-heading`]) || items.some(
|
|
7253
|
+
(_, i) => content[`footer-${colIndex}-${i}-href`] !== void 0 || content[`footer-${colIndex}-${i}-label`] !== void 0
|
|
7254
|
+
) || (parseFooterOrder(content)?.some(
|
|
7255
|
+
(col) => col.some((k) => parseFooterHrefKey(k)?.col === colIndex)
|
|
7256
|
+
) ?? false);
|
|
7257
|
+
if (!hasPayload) continue;
|
|
7258
|
+
insertFooterColumnDom(colIndex, heading, items);
|
|
7259
|
+
}
|
|
7260
|
+
}
|
|
7010
7261
|
function reconcileFooterOrderFromContent(content) {
|
|
7262
|
+
reconcileFooterColumnsFromContent(content);
|
|
7011
7263
|
const order = parseFooterOrder(content);
|
|
7012
7264
|
if (!order?.length) return;
|
|
7013
7265
|
const current = getFooterOrderFromDom();
|
|
@@ -7017,6 +7269,31 @@ function reconcileFooterOrderFromContent(content) {
|
|
|
7017
7269
|
}
|
|
7018
7270
|
applyFooterOrder(order);
|
|
7019
7271
|
}
|
|
7272
|
+
function resolveFooterLinksContainerSelectionTarget(target, clientX, clientY, isPointOverItem) {
|
|
7273
|
+
const container = getFooterLinksContainer();
|
|
7274
|
+
if (!container) return null;
|
|
7275
|
+
const inContainer = target === container || container.contains(target) && Boolean(target.closest("[data-ohw-footer-links], .rb-footer-links"));
|
|
7276
|
+
if (!inContainer && target !== container) {
|
|
7277
|
+
const r2 = container.getBoundingClientRect();
|
|
7278
|
+
const over = clientX >= r2.left && clientX <= r2.right && clientY >= r2.top && clientY <= r2.bottom;
|
|
7279
|
+
if (!over) return null;
|
|
7280
|
+
}
|
|
7281
|
+
if (isPointOverItem(container, clientX, clientY)) return null;
|
|
7282
|
+
const column = target.closest("[data-ohw-footer-col], [data-ohw-footer-column]") ?? null;
|
|
7283
|
+
if (column && container.contains(column)) {
|
|
7284
|
+
if (target === column || column.contains(target)) return null;
|
|
7285
|
+
}
|
|
7286
|
+
if (target === container || container.contains(target) || inContainer) {
|
|
7287
|
+
if (target === container || isFooterLinksContainer(target)) return container;
|
|
7288
|
+
if (!column) return container;
|
|
7289
|
+
}
|
|
7290
|
+
return null;
|
|
7291
|
+
}
|
|
7292
|
+
function isRowLayoutColumn(links) {
|
|
7293
|
+
if (links.length < 2) return false;
|
|
7294
|
+
const firstTop = links[0].getBoundingClientRect().top;
|
|
7295
|
+
return links.every((link) => Math.abs(link.getBoundingClientRect().top - firstTop) < 4);
|
|
7296
|
+
}
|
|
7020
7297
|
function buildLinkDropSlots(column, columnIndex) {
|
|
7021
7298
|
const links = listFooterLinksInColumn(column);
|
|
7022
7299
|
const colRect = column.getBoundingClientRect();
|
|
@@ -7034,6 +7311,32 @@ function buildLinkDropSlots(column, columnIndex) {
|
|
|
7034
7311
|
});
|
|
7035
7312
|
return slots;
|
|
7036
7313
|
}
|
|
7314
|
+
if (isRowLayoutColumn(links)) {
|
|
7315
|
+
for (let i = 0; i <= links.length; i++) {
|
|
7316
|
+
let left;
|
|
7317
|
+
if (i === 0) {
|
|
7318
|
+
left = links[0].getBoundingClientRect().left - barThickness / 2;
|
|
7319
|
+
} else if (i === links.length) {
|
|
7320
|
+
const last = links[links.length - 1].getBoundingClientRect();
|
|
7321
|
+
left = last.right - barThickness / 2;
|
|
7322
|
+
} else {
|
|
7323
|
+
const prev = links[i - 1].getBoundingClientRect();
|
|
7324
|
+
const next = links[i].getBoundingClientRect();
|
|
7325
|
+
left = (prev.right + next.left) / 2 - barThickness / 2;
|
|
7326
|
+
}
|
|
7327
|
+
const heightRef = i === 0 ? links[0].getBoundingClientRect() : i === links.length ? links[links.length - 1].getBoundingClientRect() : links[i].getBoundingClientRect();
|
|
7328
|
+
slots.push({
|
|
7329
|
+
insertIndex: i,
|
|
7330
|
+
columnIndex,
|
|
7331
|
+
left,
|
|
7332
|
+
top: heightRef.top,
|
|
7333
|
+
width: barThickness,
|
|
7334
|
+
height: Math.max(heightRef.height, colRect.height * 0.8),
|
|
7335
|
+
direction: "vertical"
|
|
7336
|
+
});
|
|
7337
|
+
}
|
|
7338
|
+
return slots;
|
|
7339
|
+
}
|
|
7037
7340
|
for (let i = 0; i <= links.length; i++) {
|
|
7038
7341
|
let top;
|
|
7039
7342
|
if (i === 0) {
|
|
@@ -7117,8 +7420,7 @@ function hitTestLinkDropSlot(clientX, clientY, draggedHrefKey) {
|
|
|
7117
7420
|
return true;
|
|
7118
7421
|
});
|
|
7119
7422
|
for (const slot of slots) {
|
|
7120
|
-
const
|
|
7121
|
-
const dist = Math.abs(clientY - cy) + (inColX ? 0 : 1e3);
|
|
7423
|
+
const dist = slot.direction === "vertical" ? Math.abs(clientX - (slot.left + slot.width / 2)) : Math.abs(clientY - (slot.top + slot.height / 2));
|
|
7122
7424
|
if (!best || dist < best.dist) best = { slot, dist };
|
|
7123
7425
|
}
|
|
7124
7426
|
}
|
|
@@ -7142,6 +7444,30 @@ function hitTestColumnDropSlot(clientX, _clientY) {
|
|
|
7142
7444
|
return best?.slot ?? null;
|
|
7143
7445
|
}
|
|
7144
7446
|
|
|
7447
|
+
// src/lib/add-footer-column.ts
|
|
7448
|
+
function buildFooterColumnEditContentPatch(result) {
|
|
7449
|
+
return {
|
|
7450
|
+
[result.headingKey]: result.heading,
|
|
7451
|
+
[result.hrefKey]: result.href,
|
|
7452
|
+
[result.labelKey]: result.label,
|
|
7453
|
+
[FOOTER_ORDER_KEY]: JSON.stringify(result.order)
|
|
7454
|
+
};
|
|
7455
|
+
}
|
|
7456
|
+
function addFooterColumnWithPersist({
|
|
7457
|
+
postToParent: postToParent2
|
|
7458
|
+
}) {
|
|
7459
|
+
const result = insertFooterColumn();
|
|
7460
|
+
const patch = buildFooterColumnEditContentPatch(result);
|
|
7461
|
+
setStoredLinkHref(result.hrefKey, result.href);
|
|
7462
|
+
postToParent2({
|
|
7463
|
+
type: "ow:change",
|
|
7464
|
+
nodes: Object.entries(patch).map(([key, text]) => ({ key, text }))
|
|
7465
|
+
});
|
|
7466
|
+
postToParent2({ type: "ow:toast", title: "Item added", toastType: "success" });
|
|
7467
|
+
enforceLinkHrefs();
|
|
7468
|
+
return result;
|
|
7469
|
+
}
|
|
7470
|
+
|
|
7145
7471
|
// src/lib/item-drag-interaction.ts
|
|
7146
7472
|
function disableNativeHrefDrag(el) {
|
|
7147
7473
|
if (el.draggable) el.draggable = false;
|
|
@@ -7162,9 +7488,10 @@ function lockItemDuringDrag() {
|
|
|
7162
7488
|
clearTextSelection();
|
|
7163
7489
|
}
|
|
7164
7490
|
function unlockItemDragInteraction() {
|
|
7491
|
+
const wasDragging = document.documentElement.hasAttribute("data-ohw-item-dragging");
|
|
7165
7492
|
document.documentElement.removeAttribute("data-ohw-footer-press-drag");
|
|
7166
7493
|
document.documentElement.removeAttribute("data-ohw-item-dragging");
|
|
7167
|
-
clearTextSelection();
|
|
7494
|
+
if (wasDragging) clearTextSelection();
|
|
7168
7495
|
}
|
|
7169
7496
|
var armFooterPressDrag = armItemPressDrag;
|
|
7170
7497
|
var lockFooterDuringDrag = lockItemDuringDrag;
|
|
@@ -7541,7 +7868,6 @@ function useNavItemDrag({
|
|
|
7541
7868
|
const hrefKey = anchor?.getAttribute("data-ohw-href-key") ?? null;
|
|
7542
7869
|
if (!anchor || !isNavbarHrefKey(hrefKey)) return;
|
|
7543
7870
|
if (isNavbarButton3(anchor) || isDragHandleDisabled2(anchor)) return;
|
|
7544
|
-
armItemPressDrag();
|
|
7545
7871
|
navPointerDragRef.current = {
|
|
7546
7872
|
el: anchor,
|
|
7547
7873
|
startX: e.clientX,
|
|
@@ -7568,6 +7894,7 @@ function useNavItemDrag({
|
|
|
7568
7894
|
if (dx * dx + dy * dy < THRESHOLD * THRESHOLD) return;
|
|
7569
7895
|
e.preventDefault();
|
|
7570
7896
|
pending.started = true;
|
|
7897
|
+
armItemPressDrag();
|
|
7571
7898
|
clearTextSelection();
|
|
7572
7899
|
try {
|
|
7573
7900
|
document.body.setPointerCapture(pending.pointerId);
|
|
@@ -7595,7 +7922,8 @@ function useNavItemDrag({
|
|
|
7595
7922
|
}
|
|
7596
7923
|
} catch {
|
|
7597
7924
|
}
|
|
7598
|
-
if (!pending
|
|
7925
|
+
if (!pending) return;
|
|
7926
|
+
if (!pending.started) {
|
|
7599
7927
|
unlockItemDragInteraction();
|
|
7600
7928
|
return;
|
|
7601
7929
|
}
|
|
@@ -7647,7 +7975,6 @@ function useNavItemDrag({
|
|
|
7647
7975
|
const hrefKey = selected.getAttribute("data-ohw-href-key");
|
|
7648
7976
|
if (!hrefKey || !isNavbarHrefKey(hrefKey)) return false;
|
|
7649
7977
|
if (isNavbarButton3(selected) || isDragHandleDisabled2(selected)) return false;
|
|
7650
|
-
armItemPressDrag();
|
|
7651
7978
|
navPointerDragRef.current = {
|
|
7652
7979
|
el: selected,
|
|
7653
7980
|
startX: clientX,
|
|
@@ -7673,15 +8000,60 @@ function useNavItemDrag({
|
|
|
7673
8000
|
};
|
|
7674
8001
|
}
|
|
7675
8002
|
|
|
7676
|
-
// src/ui/
|
|
8003
|
+
// src/ui/footer-container-chrome.tsx
|
|
7677
8004
|
var import_lucide_react10 = require("lucide-react");
|
|
7678
8005
|
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
8006
|
+
function FooterContainerChrome({ rect, onAdd }) {
|
|
8007
|
+
const chromeGap = 6;
|
|
8008
|
+
const buttonMargin = 7;
|
|
8009
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
8010
|
+
"div",
|
|
8011
|
+
{
|
|
8012
|
+
"data-ohw-footer-container-chrome": "",
|
|
8013
|
+
"data-ohw-bridge": "",
|
|
8014
|
+
className: "pointer-events-none fixed z-[2147483647]",
|
|
8015
|
+
style: {
|
|
8016
|
+
top: rect.top - chromeGap,
|
|
8017
|
+
left: rect.left - chromeGap,
|
|
8018
|
+
width: rect.width + chromeGap * 2,
|
|
8019
|
+
height: rect.height + chromeGap * 2
|
|
8020
|
+
},
|
|
8021
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(Tooltip, { children: [
|
|
8022
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
8023
|
+
"button",
|
|
8024
|
+
{
|
|
8025
|
+
type: "button",
|
|
8026
|
+
"data-ohw-footer-add-button": "",
|
|
8027
|
+
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",
|
|
8028
|
+
style: { top: chromeGap - buttonMargin },
|
|
8029
|
+
"aria-label": "Add item",
|
|
8030
|
+
onMouseDown: (e) => {
|
|
8031
|
+
e.preventDefault();
|
|
8032
|
+
e.stopPropagation();
|
|
8033
|
+
},
|
|
8034
|
+
onClick: (e) => {
|
|
8035
|
+
e.preventDefault();
|
|
8036
|
+
e.stopPropagation();
|
|
8037
|
+
onAdd();
|
|
8038
|
+
},
|
|
8039
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react10.Plus, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
|
|
8040
|
+
}
|
|
8041
|
+
) }),
|
|
8042
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TooltipContent, { side: "bottom", sideOffset: 9, children: "Add item" })
|
|
8043
|
+
] })
|
|
8044
|
+
}
|
|
8045
|
+
) });
|
|
8046
|
+
}
|
|
8047
|
+
|
|
8048
|
+
// src/ui/navbar-container-chrome.tsx
|
|
8049
|
+
var import_lucide_react11 = require("lucide-react");
|
|
8050
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
7679
8051
|
function NavbarContainerChrome({
|
|
7680
8052
|
rect,
|
|
7681
8053
|
onAdd
|
|
7682
8054
|
}) {
|
|
7683
8055
|
const chromeGap = 6;
|
|
7684
|
-
return /* @__PURE__ */ (0,
|
|
8056
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
7685
8057
|
"div",
|
|
7686
8058
|
{
|
|
7687
8059
|
"data-ohw-navbar-container-chrome": "",
|
|
@@ -7693,7 +8065,7 @@ function NavbarContainerChrome({
|
|
|
7693
8065
|
width: rect.width + chromeGap * 2,
|
|
7694
8066
|
height: rect.height + chromeGap * 2
|
|
7695
8067
|
},
|
|
7696
|
-
children: /* @__PURE__ */ (0,
|
|
8068
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
7697
8069
|
"button",
|
|
7698
8070
|
{
|
|
7699
8071
|
type: "button",
|
|
@@ -7710,7 +8082,7 @@ function NavbarContainerChrome({
|
|
|
7710
8082
|
e.stopPropagation();
|
|
7711
8083
|
onAdd();
|
|
7712
8084
|
},
|
|
7713
|
-
children: /* @__PURE__ */ (0,
|
|
8085
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react11.Plus, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
|
|
7714
8086
|
}
|
|
7715
8087
|
)
|
|
7716
8088
|
}
|
|
@@ -7719,7 +8091,7 @@ function NavbarContainerChrome({
|
|
|
7719
8091
|
|
|
7720
8092
|
// src/ui/drop-indicator.tsx
|
|
7721
8093
|
var React10 = __toESM(require("react"), 1);
|
|
7722
|
-
var
|
|
8094
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
7723
8095
|
var dropIndicatorVariants = cva(
|
|
7724
8096
|
"ov-gap-line pointer-events-none shrink-0 transition-opacity duration-150",
|
|
7725
8097
|
{
|
|
@@ -7743,7 +8115,7 @@ var dropIndicatorVariants = cva(
|
|
|
7743
8115
|
);
|
|
7744
8116
|
var DropIndicator = React10.forwardRef(
|
|
7745
8117
|
({ className, direction, state, ...props }, ref) => {
|
|
7746
|
-
return /* @__PURE__ */ (0,
|
|
8118
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
7747
8119
|
"div",
|
|
7748
8120
|
{
|
|
7749
8121
|
ref,
|
|
@@ -7760,7 +8132,7 @@ var DropIndicator = React10.forwardRef(
|
|
|
7760
8132
|
DropIndicator.displayName = "DropIndicator";
|
|
7761
8133
|
|
|
7762
8134
|
// src/ui/badge.tsx
|
|
7763
|
-
var
|
|
8135
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
7764
8136
|
var badgeVariants = cva(
|
|
7765
8137
|
"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",
|
|
7766
8138
|
{
|
|
@@ -7778,12 +8150,12 @@ var badgeVariants = cva(
|
|
|
7778
8150
|
}
|
|
7779
8151
|
);
|
|
7780
8152
|
function Badge({ className, variant, ...props }) {
|
|
7781
|
-
return /* @__PURE__ */ (0,
|
|
8153
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: cn(badgeVariants({ variant }), className), ...props });
|
|
7782
8154
|
}
|
|
7783
8155
|
|
|
7784
8156
|
// src/OhhwellsBridge.tsx
|
|
7785
|
-
var
|
|
7786
|
-
var
|
|
8157
|
+
var import_lucide_react12 = require("lucide-react");
|
|
8158
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
7787
8159
|
var PRIMARY2 = "#0885FE";
|
|
7788
8160
|
var IMAGE_FADE_MS = 300;
|
|
7789
8161
|
function runOpacityFade(el, onDone) {
|
|
@@ -7962,7 +8334,7 @@ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId,
|
|
|
7962
8334
|
const root = (0, import_client.createRoot)(container);
|
|
7963
8335
|
(0, import_react_dom2.flushSync)(() => {
|
|
7964
8336
|
root.render(
|
|
7965
|
-
/* @__PURE__ */ (0,
|
|
8337
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
7966
8338
|
SchedulingWidget,
|
|
7967
8339
|
{
|
|
7968
8340
|
notifyOnConnect,
|
|
@@ -8163,7 +8535,7 @@ function applyLinkByKey(key, val) {
|
|
|
8163
8535
|
}
|
|
8164
8536
|
function isInsideLinkEditor(target) {
|
|
8165
8537
|
return Boolean(
|
|
8166
|
-
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"]')
|
|
8538
|
+
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"]')
|
|
8167
8539
|
);
|
|
8168
8540
|
}
|
|
8169
8541
|
function getHrefKeyFromElement(el) {
|
|
@@ -8244,7 +8616,7 @@ function isInferredFooterGroup(el) {
|
|
|
8244
8616
|
return countFooterNavItems(el) >= 2;
|
|
8245
8617
|
}
|
|
8246
8618
|
function isNavigationContainer(el) {
|
|
8247
|
-
return el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isNavigationRoot(el) || isInferredFooterGroup(el);
|
|
8619
|
+
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);
|
|
8248
8620
|
}
|
|
8249
8621
|
function isNavbarLinksContainer(el) {
|
|
8250
8622
|
return el.hasAttribute("data-ohw-nav-container");
|
|
@@ -8263,6 +8635,9 @@ function isPointOverNavigation(x, y) {
|
|
|
8263
8635
|
const roots = /* @__PURE__ */ new Set();
|
|
8264
8636
|
const navRoot = document.querySelector("[data-ohw-nav-root]") ?? document.querySelector("nav");
|
|
8265
8637
|
if (navRoot) roots.add(navRoot);
|
|
8638
|
+
document.querySelectorAll("[data-ohw-nav-drawer], [data-ohw-nav-container]").forEach((el) => {
|
|
8639
|
+
roots.add(el);
|
|
8640
|
+
});
|
|
8266
8641
|
const footer = document.querySelector("footer");
|
|
8267
8642
|
if (footer) roots.add(footer);
|
|
8268
8643
|
for (const root of roots) {
|
|
@@ -8291,6 +8666,12 @@ function isPointOverNavItem(container, x, y) {
|
|
|
8291
8666
|
return x >= itemRect.left && x <= itemRect.right && y >= itemRect.top && y <= itemRect.bottom;
|
|
8292
8667
|
});
|
|
8293
8668
|
}
|
|
8669
|
+
function isPointOverFooterColumn(x, y) {
|
|
8670
|
+
return listFooterColumns().some((col) => {
|
|
8671
|
+
const r2 = col.getBoundingClientRect();
|
|
8672
|
+
return x >= r2.left && x <= r2.right && y >= r2.top && y <= r2.bottom;
|
|
8673
|
+
});
|
|
8674
|
+
}
|
|
8294
8675
|
function resolveNavContainerSelectionTarget(target, clientX, clientY) {
|
|
8295
8676
|
if (getNavigationItemAnchor(target)) return null;
|
|
8296
8677
|
if (target.closest('[data-ohw-role="navbar-button"]')) return null;
|
|
@@ -8321,7 +8702,10 @@ function getNavigationSelectionParent(el) {
|
|
|
8321
8702
|
if (footerGroup) return footerGroup;
|
|
8322
8703
|
return getNavigationRoot(el);
|
|
8323
8704
|
}
|
|
8324
|
-
if (el
|
|
8705
|
+
if (!isFooterLinksContainer(el) && (el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isInferredFooterGroup(el))) {
|
|
8706
|
+
return getFooterLinksContainer();
|
|
8707
|
+
}
|
|
8708
|
+
if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isFooterLinksContainer(el) || isInferredFooterGroup(el)) {
|
|
8325
8709
|
return getNavigationRoot(el);
|
|
8326
8710
|
}
|
|
8327
8711
|
return null;
|
|
@@ -8492,9 +8876,16 @@ function sanitizeHtml(html) {
|
|
|
8492
8876
|
if (!SAFE_TAGS.has(el.tagName)) {
|
|
8493
8877
|
parent.replaceChild(document.createTextNode(el.textContent ?? ""), el);
|
|
8494
8878
|
} else {
|
|
8495
|
-
const
|
|
8879
|
+
const htmlEl = el;
|
|
8880
|
+
const textAlign = htmlEl.style?.textAlign || el.getAttribute("align") || "";
|
|
8881
|
+
const fontWeight = htmlEl.style?.fontWeight || "";
|
|
8882
|
+
const fontStyle = htmlEl.style?.fontStyle || "";
|
|
8883
|
+
const textDecorationLine = htmlEl.style?.textDecorationLine || htmlEl.style?.textDecoration || "";
|
|
8496
8884
|
for (const attr of Array.from(el.attributes)) el.removeAttribute(attr.name);
|
|
8497
|
-
if (textAlign)
|
|
8885
|
+
if (textAlign) htmlEl.style.textAlign = textAlign;
|
|
8886
|
+
if (fontWeight) htmlEl.style.fontWeight = fontWeight;
|
|
8887
|
+
if (fontStyle) htmlEl.style.fontStyle = fontStyle;
|
|
8888
|
+
if (textDecorationLine) htmlEl.style.textDecorationLine = textDecorationLine;
|
|
8498
8889
|
walk(el);
|
|
8499
8890
|
}
|
|
8500
8891
|
}
|
|
@@ -8541,7 +8932,7 @@ function EditGlowChrome({
|
|
|
8541
8932
|
hideHandle = false
|
|
8542
8933
|
}) {
|
|
8543
8934
|
const GAP = SELECTION_CHROME_GAP2;
|
|
8544
|
-
return /* @__PURE__ */ (0,
|
|
8935
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
8545
8936
|
"div",
|
|
8546
8937
|
{
|
|
8547
8938
|
ref: elRef,
|
|
@@ -8556,7 +8947,7 @@ function EditGlowChrome({
|
|
|
8556
8947
|
zIndex: 2147483646
|
|
8557
8948
|
},
|
|
8558
8949
|
children: [
|
|
8559
|
-
/* @__PURE__ */ (0,
|
|
8950
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
8560
8951
|
"div",
|
|
8561
8952
|
{
|
|
8562
8953
|
style: {
|
|
@@ -8569,7 +8960,7 @@ function EditGlowChrome({
|
|
|
8569
8960
|
}
|
|
8570
8961
|
}
|
|
8571
8962
|
),
|
|
8572
|
-
reorderHrefKey && !hideHandle && /* @__PURE__ */ (0,
|
|
8963
|
+
reorderHrefKey && !hideHandle && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
8573
8964
|
"div",
|
|
8574
8965
|
{
|
|
8575
8966
|
"data-ohw-drag-handle-container": "",
|
|
@@ -8581,7 +8972,7 @@ function EditGlowChrome({
|
|
|
8581
8972
|
transform: "translate(calc(-100% - 7px), -50%)",
|
|
8582
8973
|
pointerEvents: dragDisabled ? "none" : "auto"
|
|
8583
8974
|
},
|
|
8584
|
-
children: /* @__PURE__ */ (0,
|
|
8975
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
8585
8976
|
DragHandle,
|
|
8586
8977
|
{
|
|
8587
8978
|
"aria-label": `Reorder ${reorderHrefKey}`,
|
|
@@ -8682,6 +9073,79 @@ function resolveItemInteractionState(rect, parentScroll) {
|
|
|
8682
9073
|
const { transform } = calcToolbarPos(rect, parentScroll, 120);
|
|
8683
9074
|
return transform.includes("translateY(-100%)") ? "active-top" : "active-bottom";
|
|
8684
9075
|
}
|
|
9076
|
+
function resolveSelectionStartElement(sel) {
|
|
9077
|
+
if (!sel || sel.rangeCount === 0) return null;
|
|
9078
|
+
const range = sel.getRangeAt(0);
|
|
9079
|
+
let startNode = range.startContainer;
|
|
9080
|
+
if (startNode.nodeType === Node.ELEMENT_NODE) {
|
|
9081
|
+
const el = startNode;
|
|
9082
|
+
startNode = el.childNodes[range.startOffset] ?? el.childNodes[range.startOffset - 1] ?? el;
|
|
9083
|
+
}
|
|
9084
|
+
return startNode.nodeType === Node.TEXT_NODE ? startNode.parentElement : startNode;
|
|
9085
|
+
}
|
|
9086
|
+
function detectActiveFormats(startEl, activeRoot) {
|
|
9087
|
+
const formats = /* @__PURE__ */ new Set();
|
|
9088
|
+
const cs = getComputedStyle(startEl);
|
|
9089
|
+
const weight = parseInt(cs.fontWeight, 10);
|
|
9090
|
+
let hasBold = cs.fontWeight === "bold" || !Number.isNaN(weight) && weight >= 600;
|
|
9091
|
+
let hasItalic = cs.fontStyle === "italic" || cs.fontStyle === "oblique";
|
|
9092
|
+
let hasUnderline = false;
|
|
9093
|
+
let hasStrike = false;
|
|
9094
|
+
let hasUl = false;
|
|
9095
|
+
let hasOl = false;
|
|
9096
|
+
for (let el = startEl; el; el = el.parentElement) {
|
|
9097
|
+
if (el.tagName === "B" || el.tagName === "STRONG") hasBold = true;
|
|
9098
|
+
if (el.tagName === "I" || el.tagName === "EM") hasItalic = true;
|
|
9099
|
+
const decoration = getComputedStyle(el).textDecorationLine;
|
|
9100
|
+
if (decoration.includes("underline") || el.tagName === "U" || el.tagName === "INS") hasUnderline = true;
|
|
9101
|
+
if (decoration.includes("line-through") || el.tagName === "S" || el.tagName === "STRIKE" || el.tagName === "DEL") hasStrike = true;
|
|
9102
|
+
if (el.tagName === "UL") hasUl = true;
|
|
9103
|
+
if (el.tagName === "OL") hasOl = true;
|
|
9104
|
+
if (el === activeRoot) break;
|
|
9105
|
+
}
|
|
9106
|
+
if (hasBold) formats.add("bold");
|
|
9107
|
+
if (hasItalic) formats.add("italic");
|
|
9108
|
+
if (hasUnderline) formats.add("underline");
|
|
9109
|
+
if (hasStrike) formats.add("strikeThrough");
|
|
9110
|
+
if (hasUl) formats.add("insertUnorderedList");
|
|
9111
|
+
if (hasOl) formats.add("insertOrderedList");
|
|
9112
|
+
const block = startEl.closest("div, p, h1, h2, h3, h4, h5, h6, li, td, th") ?? startEl;
|
|
9113
|
+
const align = getComputedStyle(block).textAlign;
|
|
9114
|
+
if (align === "center") formats.add("justifyCenter");
|
|
9115
|
+
else if (align === "right" || align === "end") formats.add("justifyRight");
|
|
9116
|
+
else formats.add("justifyLeft");
|
|
9117
|
+
return formats;
|
|
9118
|
+
}
|
|
9119
|
+
function setsEqual(a, b) {
|
|
9120
|
+
if (a.size !== b.size) return false;
|
|
9121
|
+
for (const item of a) {
|
|
9122
|
+
if (!b.has(item)) return false;
|
|
9123
|
+
}
|
|
9124
|
+
return true;
|
|
9125
|
+
}
|
|
9126
|
+
function textOffsetInRoot(root, node, offset) {
|
|
9127
|
+
const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT);
|
|
9128
|
+
let total = 0;
|
|
9129
|
+
let current;
|
|
9130
|
+
while (current = walker.nextNode()) {
|
|
9131
|
+
if (current === node) return total + offset;
|
|
9132
|
+
total += (current.textContent ?? "").length;
|
|
9133
|
+
}
|
|
9134
|
+
return total;
|
|
9135
|
+
}
|
|
9136
|
+
function pointAtTextOffset(root, targetOffset) {
|
|
9137
|
+
const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT);
|
|
9138
|
+
let total = 0;
|
|
9139
|
+
let current;
|
|
9140
|
+
let last = null;
|
|
9141
|
+
while (current = walker.nextNode()) {
|
|
9142
|
+
const len = (current.textContent ?? "").length;
|
|
9143
|
+
if (total + len >= targetOffset) return { node: current, offset: targetOffset - total };
|
|
9144
|
+
total += len;
|
|
9145
|
+
last = current;
|
|
9146
|
+
}
|
|
9147
|
+
return last ? { node: last, offset: (last.textContent ?? "").length } : null;
|
|
9148
|
+
}
|
|
8685
9149
|
function FloatingToolbar({
|
|
8686
9150
|
rect,
|
|
8687
9151
|
parentScroll,
|
|
@@ -8718,7 +9182,7 @@ function FloatingToolbar({
|
|
|
8718
9182
|
return () => ro.disconnect();
|
|
8719
9183
|
}, [showEditLink, activeCommands]);
|
|
8720
9184
|
const { top, left, transform } = calcToolbarPos(rect, parentScroll, measuredW);
|
|
8721
|
-
return /* @__PURE__ */ (0,
|
|
9185
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
8722
9186
|
"div",
|
|
8723
9187
|
{
|
|
8724
9188
|
ref: setRefs,
|
|
@@ -8730,12 +9194,12 @@ function FloatingToolbar({
|
|
|
8730
9194
|
zIndex: 2147483647,
|
|
8731
9195
|
pointerEvents: "auto"
|
|
8732
9196
|
},
|
|
8733
|
-
children: /* @__PURE__ */ (0,
|
|
8734
|
-
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ (0,
|
|
8735
|
-
gi > 0 && /* @__PURE__ */ (0,
|
|
9197
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(CustomToolbar, { children: [
|
|
9198
|
+
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_react9.default.Fragment, { children: [
|
|
9199
|
+
gi > 0 && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(CustomToolbarDivider, {}),
|
|
8736
9200
|
btns.map((btn) => {
|
|
8737
9201
|
const isActive = activeCommands.has(btn.cmd);
|
|
8738
|
-
return /* @__PURE__ */ (0,
|
|
9202
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
8739
9203
|
CustomToolbarButton,
|
|
8740
9204
|
{
|
|
8741
9205
|
title: btn.title,
|
|
@@ -8744,7 +9208,7 @@ function FloatingToolbar({
|
|
|
8744
9208
|
e.preventDefault();
|
|
8745
9209
|
onCommand(btn.cmd);
|
|
8746
9210
|
},
|
|
8747
|
-
children: /* @__PURE__ */ (0,
|
|
9211
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
8748
9212
|
"svg",
|
|
8749
9213
|
{
|
|
8750
9214
|
width: "16",
|
|
@@ -8765,7 +9229,7 @@ function FloatingToolbar({
|
|
|
8765
9229
|
);
|
|
8766
9230
|
})
|
|
8767
9231
|
] }, gi)),
|
|
8768
|
-
showEditLink ? /* @__PURE__ */ (0,
|
|
9232
|
+
showEditLink ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
8769
9233
|
CustomToolbarButton,
|
|
8770
9234
|
{
|
|
8771
9235
|
type: "button",
|
|
@@ -8779,7 +9243,7 @@ function FloatingToolbar({
|
|
|
8779
9243
|
e.preventDefault();
|
|
8780
9244
|
e.stopPropagation();
|
|
8781
9245
|
},
|
|
8782
|
-
children: /* @__PURE__ */ (0,
|
|
9246
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Link, { className: "size-4 shrink-0", "aria-hidden": true })
|
|
8783
9247
|
}
|
|
8784
9248
|
) : null
|
|
8785
9249
|
] })
|
|
@@ -8796,7 +9260,7 @@ function StateToggle({
|
|
|
8796
9260
|
states,
|
|
8797
9261
|
onStateChange
|
|
8798
9262
|
}) {
|
|
8799
|
-
return /* @__PURE__ */ (0,
|
|
9263
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
8800
9264
|
ToggleGroup,
|
|
8801
9265
|
{
|
|
8802
9266
|
"data-ohw-state-toggle": "",
|
|
@@ -8810,7 +9274,7 @@ function StateToggle({
|
|
|
8810
9274
|
left: rect.right - 8,
|
|
8811
9275
|
transform: "translateX(-100%)"
|
|
8812
9276
|
},
|
|
8813
|
-
children: states.map((state) => /* @__PURE__ */ (0,
|
|
9277
|
+
children: states.map((state) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ToggleGroupItem, { value: state, size: "sm", children: state }, state))
|
|
8814
9278
|
}
|
|
8815
9279
|
);
|
|
8816
9280
|
}
|
|
@@ -8874,6 +9338,7 @@ function OhhwellsBridge() {
|
|
|
8874
9338
|
const [fetchState, setFetchState] = (0, import_react9.useState)("idle");
|
|
8875
9339
|
const autoSaveTimers = (0, import_react9.useRef)(/* @__PURE__ */ new Map());
|
|
8876
9340
|
const activeElRef = (0, import_react9.useRef)(null);
|
|
9341
|
+
const pointerHeldRef = (0, import_react9.useRef)(false);
|
|
8877
9342
|
const selectedElRef = (0, import_react9.useRef)(null);
|
|
8878
9343
|
const selectedHrefKeyRef = (0, import_react9.useRef)(null);
|
|
8879
9344
|
const selectedFooterColAttrRef = (0, import_react9.useRef)(null);
|
|
@@ -9058,6 +9523,7 @@ function OhhwellsBridge() {
|
|
|
9058
9523
|
document.addEventListener("touchmove", preventBackgroundScroll, scrollOpts);
|
|
9059
9524
|
postToParent2({ type: "ow:image-unhover" });
|
|
9060
9525
|
return () => {
|
|
9526
|
+
document.documentElement.removeAttribute("data-ohw-link-popover-open");
|
|
9061
9527
|
postToParent2({ type: "ow:link-modal-lock", locked: false });
|
|
9062
9528
|
html.style.overflow = prevHtmlOverflow;
|
|
9063
9529
|
body.style.overflow = prevBodyOverflow;
|
|
@@ -9304,6 +9770,18 @@ function OhhwellsBridge() {
|
|
|
9304
9770
|
intent: "add-nav"
|
|
9305
9771
|
});
|
|
9306
9772
|
}, []);
|
|
9773
|
+
const handleAddFooterColumn = (0, import_react9.useCallback)(() => {
|
|
9774
|
+
deselectRef.current();
|
|
9775
|
+
deactivateRef.current();
|
|
9776
|
+
const result = addFooterColumnWithPersist({ postToParent: postToParent2 });
|
|
9777
|
+
editContentRef.current = {
|
|
9778
|
+
...editContentRef.current,
|
|
9779
|
+
...buildFooterColumnEditContentPatch(result)
|
|
9780
|
+
};
|
|
9781
|
+
requestAnimationFrame(() => {
|
|
9782
|
+
selectRef.current(result.firstLink);
|
|
9783
|
+
});
|
|
9784
|
+
}, [postToParent2]);
|
|
9307
9785
|
const clearFooterDragVisuals = (0, import_react9.useCallback)(() => {
|
|
9308
9786
|
footerDragRef.current = null;
|
|
9309
9787
|
setSiblingHintRects([]);
|
|
@@ -9559,7 +10037,6 @@ function OhhwellsBridge() {
|
|
|
9559
10037
|
if (e.button !== 0) return;
|
|
9560
10038
|
const selected = selectedElRef.current;
|
|
9561
10039
|
if (!selected) return;
|
|
9562
|
-
armFooterPressDrag();
|
|
9563
10040
|
const hrefKey = selected.getAttribute("data-ohw-href-key");
|
|
9564
10041
|
if (hrefKey && isFooterHrefKey(hrefKey)) {
|
|
9565
10042
|
footerPointerDragRef.current = {
|
|
@@ -9629,7 +10106,7 @@ function OhhwellsBridge() {
|
|
|
9629
10106
|
const selectFrame = (0, import_react9.useCallback)((el) => {
|
|
9630
10107
|
if (!isNavigationContainer(el)) return;
|
|
9631
10108
|
if (activeElRef.current) deactivate();
|
|
9632
|
-
const isFooterColumn = el.hasAttribute("data-ohw-footer-col") || Boolean(el.closest("footer") && isInferredFooterGroup(el));
|
|
10109
|
+
const isFooterColumn = !isFooterLinksContainer(el) && (el.hasAttribute("data-ohw-footer-col") || Boolean(el.closest("footer") && isInferredFooterGroup(el)));
|
|
9633
10110
|
selectedElRef.current = el;
|
|
9634
10111
|
selectedHrefKeyRef.current = null;
|
|
9635
10112
|
selectedFooterColAttrRef.current = isFooterColumn ? el.getAttribute("data-ohw-footer-col") ?? String(listFooterColumns().indexOf(el)) : null;
|
|
@@ -9669,7 +10146,10 @@ function OhhwellsBridge() {
|
|
|
9669
10146
|
setToolbarVariant("rich-text");
|
|
9670
10147
|
siblingHintElRef.current = null;
|
|
9671
10148
|
setSiblingHintRect(null);
|
|
10149
|
+
setSiblingHintRects([]);
|
|
9672
10150
|
setIsItemDragging(false);
|
|
10151
|
+
const preActivationSelection = window.getSelection();
|
|
10152
|
+
const preservedRange = preActivationSelection && preActivationSelection.rangeCount > 0 && !preActivationSelection.isCollapsed && el.contains(preActivationSelection.getRangeAt(0).commonAncestorContainer) ? preActivationSelection.getRangeAt(0).cloneRange() : null;
|
|
9673
10153
|
el.setAttribute("contenteditable", "true");
|
|
9674
10154
|
el.setAttribute("data-ohw-editing", "");
|
|
9675
10155
|
el.removeAttribute("data-ohw-hovered");
|
|
@@ -9677,7 +10157,11 @@ function OhhwellsBridge() {
|
|
|
9677
10157
|
activeElRef.current = el;
|
|
9678
10158
|
originalContentRef.current = el.innerHTML;
|
|
9679
10159
|
el.focus({ preventScroll: true });
|
|
9680
|
-
if (
|
|
10160
|
+
if (preservedRange) {
|
|
10161
|
+
const selection = window.getSelection();
|
|
10162
|
+
selection?.removeAllRanges();
|
|
10163
|
+
selection?.addRange(preservedRange);
|
|
10164
|
+
} else if (options?.caretX !== void 0 && options?.caretY !== void 0) {
|
|
9681
10165
|
const { caretX, caretY } = options;
|
|
9682
10166
|
placeCaretAtPoint(el, caretX, caretY);
|
|
9683
10167
|
requestAnimationFrame(() => {
|
|
@@ -10133,7 +10617,9 @@ function OhhwellsBridge() {
|
|
|
10133
10617
|
if (inActive || inActiveNav) {
|
|
10134
10618
|
e.preventDefault();
|
|
10135
10619
|
e.stopPropagation();
|
|
10136
|
-
|
|
10620
|
+
const selection = window.getSelection();
|
|
10621
|
+
const hasRangeSelection = Boolean(selection && !selection.isCollapsed);
|
|
10622
|
+
if (e.detail < 2 && !hasRangeSelection) {
|
|
10137
10623
|
placeCaretAtPoint(active, e.clientX, e.clientY);
|
|
10138
10624
|
refreshActiveCommandsRef.current();
|
|
10139
10625
|
}
|
|
@@ -10176,7 +10662,7 @@ function OhhwellsBridge() {
|
|
|
10176
10662
|
}
|
|
10177
10663
|
e.preventDefault();
|
|
10178
10664
|
e.stopPropagation();
|
|
10179
|
-
activateRef.current(editable);
|
|
10665
|
+
activateRef.current(editable, { caretX: e.clientX, caretY: e.clientY });
|
|
10180
10666
|
return;
|
|
10181
10667
|
}
|
|
10182
10668
|
const hrefAnchor = getNavigationItemAnchor(target);
|
|
@@ -10203,6 +10689,18 @@ function OhhwellsBridge() {
|
|
|
10203
10689
|
selectFrameRef.current(footerColClick);
|
|
10204
10690
|
return;
|
|
10205
10691
|
}
|
|
10692
|
+
const footerLinksToSelect = resolveFooterLinksContainerSelectionTarget(
|
|
10693
|
+
target,
|
|
10694
|
+
e.clientX,
|
|
10695
|
+
e.clientY,
|
|
10696
|
+
isPointOverNavItem
|
|
10697
|
+
);
|
|
10698
|
+
if (footerLinksToSelect) {
|
|
10699
|
+
e.preventDefault();
|
|
10700
|
+
e.stopPropagation();
|
|
10701
|
+
selectFrameRef.current(footerLinksToSelect);
|
|
10702
|
+
return;
|
|
10703
|
+
}
|
|
10206
10704
|
const navContainerToSelect = resolveNavContainerSelectionTarget(target, e.clientX, e.clientY);
|
|
10207
10705
|
if (navContainerToSelect) {
|
|
10208
10706
|
e.preventDefault();
|
|
@@ -10261,8 +10759,8 @@ function OhhwellsBridge() {
|
|
|
10261
10759
|
return;
|
|
10262
10760
|
}
|
|
10263
10761
|
const navLabel = getNavigationLabelEditable(target);
|
|
10264
|
-
|
|
10265
|
-
|
|
10762
|
+
const editable = navLabel?.editable ?? target.closest('[data-ohw-editable="text"], [data-ohw-editable="plain"]');
|
|
10763
|
+
if (!editable || isMediaEditable(editable) || editable.dataset.ohwEditable === "link") return;
|
|
10266
10764
|
e.preventDefault();
|
|
10267
10765
|
e.stopPropagation();
|
|
10268
10766
|
if (activeElRef.current !== editable) {
|
|
@@ -10283,16 +10781,38 @@ function OhhwellsBridge() {
|
|
|
10283
10781
|
setHoveredNavContainerRect(null);
|
|
10284
10782
|
return;
|
|
10285
10783
|
}
|
|
10286
|
-
|
|
10287
|
-
const
|
|
10288
|
-
|
|
10289
|
-
|
|
10290
|
-
|
|
10291
|
-
|
|
10292
|
-
|
|
10293
|
-
|
|
10784
|
+
{
|
|
10785
|
+
const selected2 = selectedElRef.current;
|
|
10786
|
+
const selectedIsFooterColumn = Boolean(selected2) && !isFooterLinksContainer(selected2) && (selected2.hasAttribute("data-ohw-footer-col") || selected2.hasAttribute("data-ohw-footer-column") || Boolean(selected2.closest("footer") && isInferredFooterGroup(selected2)));
|
|
10787
|
+
const allowNavContainerHover = toolbarVariantRef.current !== "select-frame";
|
|
10788
|
+
const allowFooterLinksHover = toolbarVariantRef.current !== "select-frame" || selectedIsFooterColumn;
|
|
10789
|
+
if (allowNavContainerHover) {
|
|
10790
|
+
const navContainer = target.closest("[data-ohw-nav-container]");
|
|
10791
|
+
if (navContainer && !getNavigationItemAnchor(target)) {
|
|
10792
|
+
hoveredNavContainerRef.current = navContainer;
|
|
10793
|
+
setHoveredNavContainerRect(navContainer.getBoundingClientRect());
|
|
10794
|
+
hoveredItemElRef.current = null;
|
|
10795
|
+
setHoveredItemRect(null);
|
|
10796
|
+
return;
|
|
10797
|
+
}
|
|
10294
10798
|
}
|
|
10295
|
-
if (
|
|
10799
|
+
if (allowFooterLinksHover) {
|
|
10800
|
+
const navContainer = target.closest("[data-ohw-nav-container]");
|
|
10801
|
+
if (!navContainer) {
|
|
10802
|
+
const footerLinks = target.closest("[data-ohw-footer-links], .rb-footer-links") ?? null;
|
|
10803
|
+
if (footerLinks && selected2 !== footerLinks && !getNavigationItemAnchor(target) && !target.closest("[data-ohw-footer-col], [data-ohw-footer-column]")) {
|
|
10804
|
+
hoveredNavContainerRef.current = footerLinks;
|
|
10805
|
+
setHoveredNavContainerRect(footerLinks.getBoundingClientRect());
|
|
10806
|
+
hoveredItemElRef.current = null;
|
|
10807
|
+
setHoveredItemRect(null);
|
|
10808
|
+
return;
|
|
10809
|
+
}
|
|
10810
|
+
if (!footerLinks) {
|
|
10811
|
+
hoveredNavContainerRef.current = null;
|
|
10812
|
+
setHoveredNavContainerRect(null);
|
|
10813
|
+
}
|
|
10814
|
+
}
|
|
10815
|
+
} else if (toolbarVariantRef.current === "select-frame") {
|
|
10296
10816
|
hoveredNavContainerRef.current = null;
|
|
10297
10817
|
setHoveredNavContainerRect(null);
|
|
10298
10818
|
}
|
|
@@ -10334,9 +10854,9 @@ function OhhwellsBridge() {
|
|
|
10334
10854
|
};
|
|
10335
10855
|
const handleMouseOut = (e) => {
|
|
10336
10856
|
const target = e.target;
|
|
10337
|
-
if (target.closest("[data-ohw-nav-container], [data-ohw-footer-col], [data-ohw-footer-column]")) {
|
|
10857
|
+
if (target.closest("[data-ohw-nav-container], [data-ohw-footer-col], [data-ohw-footer-column], [data-ohw-footer-links], .rb-footer-links")) {
|
|
10338
10858
|
const related2 = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
10339
|
-
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]")) {
|
|
10859
|
+
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]")) {
|
|
10340
10860
|
return;
|
|
10341
10861
|
}
|
|
10342
10862
|
hoveredNavContainerRef.current = null;
|
|
@@ -10431,6 +10951,15 @@ function OhhwellsBridge() {
|
|
|
10431
10951
|
if (track) track.setAttribute("data-ohw-hover-paused", "");
|
|
10432
10952
|
};
|
|
10433
10953
|
const clearImageHover = () => setMediaHover(null);
|
|
10954
|
+
const dismissImageHover = () => {
|
|
10955
|
+
if (hoveredImageRef.current) {
|
|
10956
|
+
hoveredImageRef.current = null;
|
|
10957
|
+
hoveredImageHasTextOverlapRef.current = false;
|
|
10958
|
+
resumeAnimTracks();
|
|
10959
|
+
postToParentRef.current({ type: "ow:image-unhover" });
|
|
10960
|
+
}
|
|
10961
|
+
clearImageHover();
|
|
10962
|
+
};
|
|
10434
10963
|
const findImageAtPoint = (clientX, clientY, fromParentViewport) => {
|
|
10435
10964
|
const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
10436
10965
|
const images = Array.from(document.querySelectorAll(MEDIA_SELECTOR));
|
|
@@ -10474,16 +11003,13 @@ function OhhwellsBridge() {
|
|
|
10474
11003
|
}
|
|
10475
11004
|
return smallest;
|
|
10476
11005
|
};
|
|
10477
|
-
const dismissImageHover = () => {
|
|
10478
|
-
if (hoveredImageRef.current) {
|
|
10479
|
-
hoveredImageRef.current = null;
|
|
10480
|
-
hoveredImageHasTextOverlapRef.current = false;
|
|
10481
|
-
resumeAnimTracks();
|
|
10482
|
-
postToParentRef.current({ type: "ow:image-unhover" });
|
|
10483
|
-
}
|
|
10484
|
-
};
|
|
10485
11006
|
const probeNavigationHoverAt = (x, y) => {
|
|
10486
|
-
|
|
11007
|
+
const selected = selectedElRef.current;
|
|
11008
|
+
const selectedIsFooterColumn = Boolean(selected) && !isFooterLinksContainer(selected) && (selected.hasAttribute("data-ohw-footer-col") || selected.hasAttribute("data-ohw-footer-column") || Boolean(selected.closest("footer") && isInferredFooterGroup(selected)));
|
|
11009
|
+
const selectedIsFooterLinks = Boolean(selected && isFooterLinksContainer(selected));
|
|
11010
|
+
const allowNavContainerHover = toolbarVariantRef.current !== "select-frame";
|
|
11011
|
+
const allowFooterLinksHover = (toolbarVariantRef.current !== "select-frame" || selectedIsFooterColumn) && !selectedIsFooterLinks;
|
|
11012
|
+
if (toolbarVariantRef.current === "select-frame" && !allowFooterLinksHover) {
|
|
10487
11013
|
hoveredNavContainerRef.current = null;
|
|
10488
11014
|
setHoveredNavContainerRect(null);
|
|
10489
11015
|
}
|
|
@@ -10505,7 +11031,6 @@ function OhhwellsBridge() {
|
|
|
10505
11031
|
if (navItemHit) {
|
|
10506
11032
|
hoveredNavContainerRef.current = null;
|
|
10507
11033
|
setHoveredNavContainerRect(null);
|
|
10508
|
-
const selected = selectedElRef.current;
|
|
10509
11034
|
if (selected !== navItemHit) {
|
|
10510
11035
|
clearHrefKeyHover(navItemHit);
|
|
10511
11036
|
hoveredItemElRef.current = navItemHit;
|
|
@@ -10517,7 +11042,7 @@ function OhhwellsBridge() {
|
|
|
10517
11042
|
return;
|
|
10518
11043
|
}
|
|
10519
11044
|
}
|
|
10520
|
-
if (
|
|
11045
|
+
if (allowNavContainerHover) {
|
|
10521
11046
|
for (const container of navContainers) {
|
|
10522
11047
|
const containerRect = container.getBoundingClientRect();
|
|
10523
11048
|
const overContainer = x >= containerRect.left && x <= containerRect.right && y >= containerRect.top && y <= containerRect.bottom;
|
|
@@ -10529,12 +11054,23 @@ function OhhwellsBridge() {
|
|
|
10529
11054
|
setHoveredItemRect(null);
|
|
10530
11055
|
return;
|
|
10531
11056
|
}
|
|
10532
|
-
hoveredNavContainerRef.current = null;
|
|
10533
|
-
setHoveredNavContainerRect(null);
|
|
10534
|
-
} else {
|
|
10535
|
-
hoveredNavContainerRef.current = null;
|
|
10536
|
-
setHoveredNavContainerRect(null);
|
|
10537
11057
|
}
|
|
11058
|
+
if (allowFooterLinksHover) {
|
|
11059
|
+
const footerLinks = getFooterLinksContainer();
|
|
11060
|
+
if (footerLinks) {
|
|
11061
|
+
const containerRect = footerLinks.getBoundingClientRect();
|
|
11062
|
+
const overContainer = x >= containerRect.left && x <= containerRect.right && y >= containerRect.top && y <= containerRect.bottom;
|
|
11063
|
+
if (overContainer && !isPointOverNavItem(footerLinks, x, y) && !isPointOverFooterColumn(x, y)) {
|
|
11064
|
+
hoveredNavContainerRef.current = footerLinks;
|
|
11065
|
+
setHoveredNavContainerRect(footerLinks.getBoundingClientRect());
|
|
11066
|
+
hoveredItemElRef.current = null;
|
|
11067
|
+
setHoveredItemRect(null);
|
|
11068
|
+
return;
|
|
11069
|
+
}
|
|
11070
|
+
}
|
|
11071
|
+
}
|
|
11072
|
+
hoveredNavContainerRef.current = null;
|
|
11073
|
+
setHoveredNavContainerRect(null);
|
|
10538
11074
|
for (const column of footerColumns) {
|
|
10539
11075
|
const containerRect = column.getBoundingClientRect();
|
|
10540
11076
|
const overContainer = x >= containerRect.left && x <= containerRect.right && y >= containerRect.top && y <= containerRect.bottom;
|
|
@@ -11041,6 +11577,7 @@ function OhhwellsBridge() {
|
|
|
11041
11577
|
}
|
|
11042
11578
|
editContentRef.current = { ...editContentRef.current, ...content };
|
|
11043
11579
|
reconcileNavbarItemsFromContent(editContentRef.current);
|
|
11580
|
+
reconcileFooterOrderFromContent(editContentRef.current);
|
|
11044
11581
|
syncNavigationDragCursorAttrs();
|
|
11045
11582
|
enforceLinkHrefs();
|
|
11046
11583
|
postToParentRef.current({ type: "ow:hydrate-done" });
|
|
@@ -11095,6 +11632,11 @@ function OhhwellsBridge() {
|
|
|
11095
11632
|
}
|
|
11096
11633
|
if (selectedElRef.current) {
|
|
11097
11634
|
if (toolbarVariantRef.current === "select-frame") {
|
|
11635
|
+
const parent2 = getNavigationSelectionParent(selectedElRef.current);
|
|
11636
|
+
if (parent2 && isNavigationContainer(parent2) && isFooterLinksContainer(parent2) && !isFooterLinksContainer(selectedElRef.current)) {
|
|
11637
|
+
selectFrameRef.current(parent2);
|
|
11638
|
+
return;
|
|
11639
|
+
}
|
|
11098
11640
|
deselectRef.current();
|
|
11099
11641
|
return;
|
|
11100
11642
|
}
|
|
@@ -11110,13 +11652,10 @@ function OhhwellsBridge() {
|
|
|
11110
11652
|
const handleKeyDown = (e) => {
|
|
11111
11653
|
if (e.key === "Escape" && document.querySelector("[data-ohw-section-picker]")) return;
|
|
11112
11654
|
if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === "a" && activeElRef.current) {
|
|
11113
|
-
|
|
11114
|
-
|
|
11115
|
-
|
|
11116
|
-
|
|
11117
|
-
refreshActiveCommandsRef.current();
|
|
11118
|
-
return;
|
|
11119
|
-
}
|
|
11655
|
+
e.preventDefault();
|
|
11656
|
+
selectAllTextInEditable(activeElRef.current);
|
|
11657
|
+
refreshActiveCommandsRef.current();
|
|
11658
|
+
return;
|
|
11120
11659
|
}
|
|
11121
11660
|
if (e.key === "Escape" && linkPopoverOpenRef.current) {
|
|
11122
11661
|
setLinkPopoverRef.current(null);
|
|
@@ -11124,6 +11663,12 @@ function OhhwellsBridge() {
|
|
|
11124
11663
|
}
|
|
11125
11664
|
if (e.key === "Escape" && selectedElRef.current && !activeElRef.current) {
|
|
11126
11665
|
if (toolbarVariantRef.current === "select-frame") {
|
|
11666
|
+
const parent2 = getNavigationSelectionParent(selectedElRef.current);
|
|
11667
|
+
if (parent2 && isNavigationContainer(parent2) && isFooterLinksContainer(parent2) && !isFooterLinksContainer(selectedElRef.current)) {
|
|
11668
|
+
e.preventDefault();
|
|
11669
|
+
selectFrameRef.current(parent2);
|
|
11670
|
+
return;
|
|
11671
|
+
}
|
|
11127
11672
|
deselectRef.current();
|
|
11128
11673
|
return;
|
|
11129
11674
|
}
|
|
@@ -11286,30 +11831,30 @@ function OhhwellsBridge() {
|
|
|
11286
11831
|
const h = document.documentElement.scrollHeight;
|
|
11287
11832
|
if (h > 50) postToParentRef.current({ type: "ow:height", height: h });
|
|
11288
11833
|
};
|
|
11834
|
+
let selectionChangeRaf = null;
|
|
11835
|
+
const runSelectionChange = () => {
|
|
11836
|
+
selectionChangeRaf = null;
|
|
11837
|
+
const activeRoot = activeElRef.current;
|
|
11838
|
+
if (!activeRoot) return;
|
|
11839
|
+
const startEl = resolveSelectionStartElement(window.getSelection());
|
|
11840
|
+
const next = startEl ? detectActiveFormats(startEl, activeRoot) : /* @__PURE__ */ new Set();
|
|
11841
|
+
setActiveCommands((prev) => setsEqual(prev, next) ? prev : next);
|
|
11842
|
+
};
|
|
11289
11843
|
const handleSelectionChange = () => {
|
|
11290
|
-
if (
|
|
11291
|
-
|
|
11292
|
-
|
|
11293
|
-
|
|
11294
|
-
|
|
11295
|
-
|
|
11296
|
-
|
|
11297
|
-
}
|
|
11298
|
-
const sel = window.getSelection();
|
|
11299
|
-
const anchor = sel?.anchorNode;
|
|
11300
|
-
if (anchor) {
|
|
11301
|
-
const el = anchor.nodeType === Node.TEXT_NODE ? anchor.parentElement : anchor;
|
|
11302
|
-
const block = el?.closest("div, p, h1, h2, h3, h4, h5, h6, li, td, th") ?? el;
|
|
11303
|
-
if (block) {
|
|
11304
|
-
const align = getComputedStyle(block).textAlign;
|
|
11305
|
-
if (align === "center") next.add("justifyCenter");
|
|
11306
|
-
else if (align === "right" || align === "end") next.add("justifyRight");
|
|
11307
|
-
else next.add("justifyLeft");
|
|
11308
|
-
}
|
|
11309
|
-
}
|
|
11310
|
-
setActiveCommands(next);
|
|
11844
|
+
if (pointerHeldRef.current) return;
|
|
11845
|
+
if (selectionChangeRaf !== null) return;
|
|
11846
|
+
selectionChangeRaf = requestAnimationFrame(runSelectionChange);
|
|
11847
|
+
};
|
|
11848
|
+
const markPointerHeld = (e) => {
|
|
11849
|
+
if (e.button !== 0) return;
|
|
11850
|
+
pointerHeldRef.current = true;
|
|
11311
11851
|
};
|
|
11312
|
-
|
|
11852
|
+
const markPointerReleased = () => {
|
|
11853
|
+
if (!pointerHeldRef.current) return;
|
|
11854
|
+
pointerHeldRef.current = false;
|
|
11855
|
+
handleSelectionChange();
|
|
11856
|
+
};
|
|
11857
|
+
refreshActiveCommandsRef.current = runSelectionChange;
|
|
11313
11858
|
const handleDocMouseLeave = () => {
|
|
11314
11859
|
hoveredImageRef.current = null;
|
|
11315
11860
|
setMediaHover(null);
|
|
@@ -11549,7 +12094,6 @@ function OhhwellsBridge() {
|
|
|
11549
12094
|
const anchor = getNavigationItemAnchor(target);
|
|
11550
12095
|
const hrefKey = anchor?.getAttribute("data-ohw-href-key") ?? null;
|
|
11551
12096
|
if (anchor && isFooterHrefKey(hrefKey)) {
|
|
11552
|
-
armFooterPressDrag();
|
|
11553
12097
|
footerPointerDragRef.current = {
|
|
11554
12098
|
el: anchor,
|
|
11555
12099
|
kind: "link",
|
|
@@ -11563,7 +12107,6 @@ function OhhwellsBridge() {
|
|
|
11563
12107
|
}
|
|
11564
12108
|
const col = target.closest("[data-ohw-footer-col]");
|
|
11565
12109
|
if (col && !getNavigationItemAnchor(target)) {
|
|
11566
|
-
armFooterPressDrag();
|
|
11567
12110
|
footerPointerDragRef.current = {
|
|
11568
12111
|
el: col,
|
|
11569
12112
|
kind: "column",
|
|
@@ -11592,6 +12135,7 @@ function OhhwellsBridge() {
|
|
|
11592
12135
|
if (dx * dx + dy * dy < THRESHOLD * THRESHOLD) return;
|
|
11593
12136
|
e.preventDefault();
|
|
11594
12137
|
pending.started = true;
|
|
12138
|
+
armFooterPressDrag();
|
|
11595
12139
|
clearTextSelection();
|
|
11596
12140
|
try {
|
|
11597
12141
|
document.body.setPointerCapture(pending.pointerId);
|
|
@@ -11645,7 +12189,8 @@ function OhhwellsBridge() {
|
|
|
11645
12189
|
}
|
|
11646
12190
|
} catch {
|
|
11647
12191
|
}
|
|
11648
|
-
if (!pending
|
|
12192
|
+
if (!pending) return;
|
|
12193
|
+
if (!pending.started) {
|
|
11649
12194
|
unlockFooterDragInteraction();
|
|
11650
12195
|
return;
|
|
11651
12196
|
}
|
|
@@ -11738,9 +12283,39 @@ function OhhwellsBridge() {
|
|
|
11738
12283
|
return () => window.removeEventListener("hashchange", onHashChange);
|
|
11739
12284
|
}, [pathname]);
|
|
11740
12285
|
const handleCommand = (0, import_react9.useCallback)((cmd) => {
|
|
12286
|
+
const el = activeElRef.current;
|
|
12287
|
+
const selBefore = window.getSelection();
|
|
12288
|
+
let savedOffsets = null;
|
|
12289
|
+
if (el && selBefore && selBefore.rangeCount > 0 && !selBefore.isCollapsed) {
|
|
12290
|
+
const r2 = selBefore.getRangeAt(0);
|
|
12291
|
+
if (el.contains(r2.commonAncestorContainer)) {
|
|
12292
|
+
savedOffsets = {
|
|
12293
|
+
start: textOffsetInRoot(el, r2.startContainer, r2.startOffset),
|
|
12294
|
+
end: textOffsetInRoot(el, r2.endContainer, r2.endOffset)
|
|
12295
|
+
};
|
|
12296
|
+
}
|
|
12297
|
+
}
|
|
12298
|
+
document.execCommand("styleWithCSS", false, true);
|
|
11741
12299
|
document.execCommand(cmd, false);
|
|
11742
|
-
|
|
11743
|
-
|
|
12300
|
+
if (el && document.activeElement !== el) {
|
|
12301
|
+
el.focus();
|
|
12302
|
+
}
|
|
12303
|
+
const selAfter = window.getSelection();
|
|
12304
|
+
if (el && savedOffsets && selAfter?.isCollapsed) {
|
|
12305
|
+
const start = pointAtTextOffset(el, savedOffsets.start);
|
|
12306
|
+
const end = pointAtTextOffset(el, savedOffsets.end);
|
|
12307
|
+
if (start && end) {
|
|
12308
|
+
try {
|
|
12309
|
+
const range = document.createRange();
|
|
12310
|
+
range.setStart(start.node, start.offset);
|
|
12311
|
+
range.setEnd(end.node, end.offset);
|
|
12312
|
+
selAfter.removeAllRanges();
|
|
12313
|
+
selAfter.addRange(range);
|
|
12314
|
+
} catch {
|
|
12315
|
+
}
|
|
12316
|
+
}
|
|
12317
|
+
}
|
|
12318
|
+
if (el) setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
|
|
11744
12319
|
refreshActiveCommandsRef.current();
|
|
11745
12320
|
}, []);
|
|
11746
12321
|
const handleStateChange = (0, import_react9.useCallback)((state) => {
|
|
@@ -11880,9 +12455,9 @@ function OhhwellsBridge() {
|
|
|
11880
12455
|
[postToParent2]
|
|
11881
12456
|
);
|
|
11882
12457
|
return bridgeRoot ? (0, import_react_dom3.createPortal)(
|
|
11883
|
-
/* @__PURE__ */ (0,
|
|
11884
|
-
/* @__PURE__ */ (0,
|
|
11885
|
-
Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ (0,
|
|
12458
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_jsx_runtime25.Fragment, { children: [
|
|
12459
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
|
|
12460
|
+
Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
11886
12461
|
MediaOverlay,
|
|
11887
12462
|
{
|
|
11888
12463
|
hover: { key, rect, elementType: "image", isDragOver: false, hasTextOverlap: false },
|
|
@@ -11893,7 +12468,7 @@ function OhhwellsBridge() {
|
|
|
11893
12468
|
},
|
|
11894
12469
|
`uploading-${key}`
|
|
11895
12470
|
)),
|
|
11896
|
-
mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */ (0,
|
|
12471
|
+
mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
11897
12472
|
MediaOverlay,
|
|
11898
12473
|
{
|
|
11899
12474
|
hover: mediaHover,
|
|
@@ -11902,10 +12477,10 @@ function OhhwellsBridge() {
|
|
|
11902
12477
|
onVideoSettingsChange: handleVideoSettingsChange
|
|
11903
12478
|
}
|
|
11904
12479
|
),
|
|
11905
|
-
siblingHintRect && !linkPopover && !isItemDragging && siblingHintRects.length === 0 && /* @__PURE__ */ (0,
|
|
11906
|
-
siblingHintRects.length > 0 && !linkPopover && !isItemDragging && siblingHintRects.map((rect, i) => /* @__PURE__ */ (0,
|
|
11907
|
-
isItemDragging && draggedItemRect && selectedElRef.current !== footerDragRef.current?.draggedEl && selectedElRef.current !== navDragRef.current?.draggedEl && /* @__PURE__ */ (0,
|
|
11908
|
-
isItemDragging && footerDropSlots.map((slot, i) => /* @__PURE__ */ (0,
|
|
12480
|
+
siblingHintRect && !linkPopover && !isItemDragging && siblingHintRects.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
|
|
12481
|
+
siblingHintRects.length > 0 && !linkPopover && !isItemDragging && siblingHintRects.map((rect, i) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ItemInteractionLayer, { rect, state: "sibling-hint" }, `sibling-hint-${i}`)),
|
|
12482
|
+
isItemDragging && draggedItemRect && selectedElRef.current !== footerDragRef.current?.draggedEl && selectedElRef.current !== navDragRef.current?.draggedEl && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ItemInteractionLayer, { rect: draggedItemRect, state: "dragging" }),
|
|
12483
|
+
isItemDragging && footerDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
11909
12484
|
"div",
|
|
11910
12485
|
{
|
|
11911
12486
|
className: "pointer-events-none fixed z-2147483646",
|
|
@@ -11915,7 +12490,7 @@ function OhhwellsBridge() {
|
|
|
11915
12490
|
width: slot.width,
|
|
11916
12491
|
height: slot.height
|
|
11917
12492
|
},
|
|
11918
|
-
children: /* @__PURE__ */ (0,
|
|
12493
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
11919
12494
|
DropIndicator,
|
|
11920
12495
|
{
|
|
11921
12496
|
direction: slot.direction,
|
|
@@ -11926,7 +12501,7 @@ function OhhwellsBridge() {
|
|
|
11926
12501
|
},
|
|
11927
12502
|
`footer-drop-${slot.direction}-${slot.columnIndex}-${slot.insertIndex}-${i}`
|
|
11928
12503
|
)),
|
|
11929
|
-
isItemDragging && navDropSlots.map((slot, i) => /* @__PURE__ */ (0,
|
|
12504
|
+
isItemDragging && navDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
11930
12505
|
"div",
|
|
11931
12506
|
{
|
|
11932
12507
|
className: "pointer-events-none fixed z-2147483646",
|
|
@@ -11936,7 +12511,7 @@ function OhhwellsBridge() {
|
|
|
11936
12511
|
width: slot.width,
|
|
11937
12512
|
height: slot.height
|
|
11938
12513
|
},
|
|
11939
|
-
children: /* @__PURE__ */ (0,
|
|
12514
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
11940
12515
|
DropIndicator,
|
|
11941
12516
|
{
|
|
11942
12517
|
direction: slot.direction,
|
|
@@ -11947,10 +12522,11 @@ function OhhwellsBridge() {
|
|
|
11947
12522
|
},
|
|
11948
12523
|
`nav-drop-${slot.direction}-${slot.parentId ?? "root"}-${slot.insertIndex}-${i}`
|
|
11949
12524
|
)),
|
|
11950
|
-
hoveredNavContainerRect && toolbarVariant !== "select-frame" && !linkPopover && !isItemDragging && /* @__PURE__ */ (0,
|
|
11951
|
-
hoveredItemRect && !linkPopover && !hoveredNavContainerRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ (0,
|
|
11952
|
-
toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isNavbarLinksContainer(selectedElRef.current) && /* @__PURE__ */ (0,
|
|
11953
|
-
toolbarRect && !linkPopover &&
|
|
12525
|
+
hoveredNavContainerRect && (toolbarVariant !== "select-frame" || isFooterFrameSelection) && !linkPopover && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ItemInteractionLayer, { rect: hoveredNavContainerRect, state: "hover" }),
|
|
12526
|
+
hoveredItemRect && !linkPopover && !hoveredNavContainerRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
|
|
12527
|
+
toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isNavbarLinksContainer(selectedElRef.current) && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(NavbarContainerChrome, { rect: toolbarRect, onAdd: handleAddTopLevelNavItem }),
|
|
12528
|
+
toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isFooterLinksContainer(selectedElRef.current) && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(FooterContainerChrome, { rect: toolbarRect, onAdd: handleAddFooterColumn }),
|
|
12529
|
+
toolbarRect && !linkPopover && (toolbarVariant === "link-action" || toolbarVariant === "select-frame") && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
11954
12530
|
ItemInteractionLayer,
|
|
11955
12531
|
{
|
|
11956
12532
|
rect: isItemDragging && draggedItemRect && (footerDragRef.current?.wasSelected || navDragRef.current?.wasSelected) ? draggedItemRect : toolbarRect,
|
|
@@ -11964,7 +12540,7 @@ function OhhwellsBridge() {
|
|
|
11964
12540
|
onItemPointerDown: handleItemChromePointerDown,
|
|
11965
12541
|
onItemClick: handleItemChromeClick,
|
|
11966
12542
|
itemDragSurface: !isFooterFrameSelection,
|
|
11967
|
-
toolbar: toolbarVariant === "link-action" && !isItemDragging ? /* @__PURE__ */ (0,
|
|
12543
|
+
toolbar: toolbarVariant === "link-action" && !isItemDragging ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
11968
12544
|
ItemActionToolbar,
|
|
11969
12545
|
{
|
|
11970
12546
|
onEditLink: openLinkPopoverForSelected,
|
|
@@ -11977,8 +12553,8 @@ function OhhwellsBridge() {
|
|
|
11977
12553
|
) : void 0
|
|
11978
12554
|
}
|
|
11979
12555
|
),
|
|
11980
|
-
toolbarRect && toolbarVariant === "rich-text" && !linkPopover && /* @__PURE__ */ (0,
|
|
11981
|
-
/* @__PURE__ */ (0,
|
|
12556
|
+
toolbarRect && toolbarVariant === "rich-text" && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_jsx_runtime25.Fragment, { children: [
|
|
12557
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
11982
12558
|
EditGlowChrome,
|
|
11983
12559
|
{
|
|
11984
12560
|
rect: toolbarRect,
|
|
@@ -11988,7 +12564,7 @@ function OhhwellsBridge() {
|
|
|
11988
12564
|
hideHandle: isItemDragging
|
|
11989
12565
|
}
|
|
11990
12566
|
),
|
|
11991
|
-
/* @__PURE__ */ (0,
|
|
12567
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
11992
12568
|
FloatingToolbar,
|
|
11993
12569
|
{
|
|
11994
12570
|
rect: toolbarRect,
|
|
@@ -12001,7 +12577,7 @@ function OhhwellsBridge() {
|
|
|
12001
12577
|
}
|
|
12002
12578
|
)
|
|
12003
12579
|
] }),
|
|
12004
|
-
maxBadge && /* @__PURE__ */ (0,
|
|
12580
|
+
maxBadge && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
12005
12581
|
"div",
|
|
12006
12582
|
{
|
|
12007
12583
|
"data-ohw-max-badge": "",
|
|
@@ -12027,7 +12603,7 @@ function OhhwellsBridge() {
|
|
|
12027
12603
|
]
|
|
12028
12604
|
}
|
|
12029
12605
|
),
|
|
12030
|
-
toggleState && !linkPopover && /* @__PURE__ */ (0,
|
|
12606
|
+
toggleState && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
12031
12607
|
StateToggle,
|
|
12032
12608
|
{
|
|
12033
12609
|
rect: toggleState.rect,
|
|
@@ -12036,15 +12612,15 @@ function OhhwellsBridge() {
|
|
|
12036
12612
|
onStateChange: handleStateChange
|
|
12037
12613
|
}
|
|
12038
12614
|
),
|
|
12039
|
-
sectionGap && !linkPopover && /* @__PURE__ */ (0,
|
|
12615
|
+
sectionGap && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
12040
12616
|
"div",
|
|
12041
12617
|
{
|
|
12042
12618
|
"data-ohw-section-insert-line": "",
|
|
12043
12619
|
className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
|
|
12044
12620
|
style: { top: sectionGap.y, transform: "translateY(-50%)" },
|
|
12045
12621
|
children: [
|
|
12046
|
-
/* @__PURE__ */ (0,
|
|
12047
|
-
/* @__PURE__ */ (0,
|
|
12622
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
|
|
12623
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
12048
12624
|
Badge,
|
|
12049
12625
|
{
|
|
12050
12626
|
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",
|
|
@@ -12061,11 +12637,11 @@ function OhhwellsBridge() {
|
|
|
12061
12637
|
children: "Add Section"
|
|
12062
12638
|
}
|
|
12063
12639
|
),
|
|
12064
|
-
/* @__PURE__ */ (0,
|
|
12640
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } })
|
|
12065
12641
|
]
|
|
12066
12642
|
}
|
|
12067
12643
|
),
|
|
12068
|
-
linkPopover && dialogPortalContainer ? /* @__PURE__ */ (0,
|
|
12644
|
+
linkPopover && dialogPortalContainer ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
12069
12645
|
LinkPopover,
|
|
12070
12646
|
{
|
|
12071
12647
|
panelRef: linkPopoverPanelRef,
|