@ohhwells/bridge 0.1.42-next.97 → 0.1.43
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 +0 -12
- package/dist/index.cjs +467 -2914
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -30
- package/dist/index.d.ts +4 -30
- package/dist/index.js +470 -2917
- package/dist/index.js.map +1 -1
- package/dist/styles.css +67 -68
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -62,7 +62,7 @@ __export(index_exports, {
|
|
|
62
62
|
module.exports = __toCommonJS(index_exports);
|
|
63
63
|
|
|
64
64
|
// src/OhhwellsBridge.tsx
|
|
65
|
-
var
|
|
65
|
+
var import_react8 = __toESM(require("react"), 1);
|
|
66
66
|
var import_client = require("react-dom/client");
|
|
67
67
|
var import_react_dom2 = require("react-dom");
|
|
68
68
|
|
|
@@ -115,7 +115,6 @@ 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);
|
|
119
118
|
function Spinner() {
|
|
120
119
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
121
120
|
"svg",
|
|
@@ -149,17 +148,12 @@ function EmailCaptureModal({ title, subtitle, onSubmit, onClose }) {
|
|
|
149
148
|
const [error, setError] = (0, import_react2.useState)(null);
|
|
150
149
|
const isBook = title === "Confirm your spot";
|
|
151
150
|
const handleSubmit = async () => {
|
|
152
|
-
|
|
153
|
-
if (!trimmed) return;
|
|
154
|
-
if (!isValidEmail(trimmed)) {
|
|
155
|
-
setError("Please enter a valid email address.");
|
|
156
|
-
return;
|
|
157
|
-
}
|
|
151
|
+
if (!email.trim()) return;
|
|
158
152
|
setLoading(true);
|
|
159
153
|
setError(null);
|
|
160
154
|
try {
|
|
161
|
-
await onSubmit(
|
|
162
|
-
setSubmittedEmail(
|
|
155
|
+
await onSubmit(email.trim());
|
|
156
|
+
setSubmittedEmail(email.trim());
|
|
163
157
|
setSuccess(true);
|
|
164
158
|
} catch (e) {
|
|
165
159
|
setError(e instanceof Error ? e.message : "Something went wrong. Please try again.");
|
|
@@ -234,10 +228,7 @@ function EmailCaptureModal({ title, subtitle, onSubmit, onClose }) {
|
|
|
234
228
|
{
|
|
235
229
|
type: "email",
|
|
236
230
|
value: email,
|
|
237
|
-
onChange: (e) =>
|
|
238
|
-
setEmail(e.target.value);
|
|
239
|
-
if (error) setError(null);
|
|
240
|
-
},
|
|
231
|
+
onChange: (e) => setEmail(e.target.value),
|
|
241
232
|
onKeyDown: handleKeyDown,
|
|
242
233
|
placeholder: "hello@gmail.com",
|
|
243
234
|
autoFocus: true,
|
|
@@ -294,20 +285,12 @@ function formatClassTime(cls) {
|
|
|
294
285
|
const em = endTotal % 60;
|
|
295
286
|
return `${h}:${cls.startTime.minutes}-${eh}:${String(em).padStart(2, "0")}`;
|
|
296
287
|
}
|
|
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
|
-
}
|
|
302
288
|
function getBookingsOnDate(cls, date) {
|
|
303
289
|
if (!cls.bookings?.length) return 0;
|
|
304
|
-
const
|
|
305
|
-
target.setHours(0, 0, 0, 0);
|
|
290
|
+
const ds = date.toISOString().split("T")[0];
|
|
306
291
|
return cls.bookings.filter((b) => {
|
|
307
292
|
try {
|
|
308
|
-
|
|
309
|
-
bookingDate.setHours(0, 0, 0, 0);
|
|
310
|
-
return bookingDate.getTime() === target.getTime();
|
|
293
|
+
return new Date(b.classDate).toISOString().split("T")[0] === ds;
|
|
311
294
|
} catch {
|
|
312
295
|
return false;
|
|
313
296
|
}
|
|
@@ -572,7 +555,7 @@ function ScheduleView({ schedule, dates, selectedIdx, onSelectDate, onOpenModal
|
|
|
572
555
|
}
|
|
573
556
|
)
|
|
574
557
|
] }),
|
|
575
|
-
|
|
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: [
|
|
576
559
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "font-body text-sm text-(--color-dark,#200C02) opacity-80", children: [
|
|
577
560
|
available,
|
|
578
561
|
"/",
|
|
@@ -584,17 +567,9 @@ function ScheduleView({ schedule, dates, selectedIdx, onSelectDate, onOpenModal
|
|
|
584
567
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex flex-1 flex-col gap-2 min-w-0 sm:contents", children: [
|
|
585
568
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex-1 flex flex-col gap-2 min-w-0", children: [
|
|
586
569
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "font-body text-base font-bold text-(--color-dark,#200C02) block truncate", children: cls.name }),
|
|
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
|
-
)
|
|
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 })
|
|
596
571
|
] }),
|
|
597
|
-
|
|
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: [
|
|
598
573
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "font-body text-sm text-(--color-dark,#200C02) opacity-80", children: [
|
|
599
574
|
available,
|
|
600
575
|
"/",
|
|
@@ -619,7 +594,7 @@ function ScheduleView({ schedule, dates, selectedIdx, onSelectDate, onOpenModal
|
|
|
619
594
|
if (!cls.id) return;
|
|
620
595
|
onOpenModal?.(isFull ? "waitlist" : "book", cls.id, selectedDate);
|
|
621
596
|
},
|
|
622
|
-
children: isFull ? "Join Waitlist" :
|
|
597
|
+
children: isFull ? "Join Waitlist" : "Book Now"
|
|
623
598
|
}
|
|
624
599
|
)
|
|
625
600
|
] })
|
|
@@ -661,17 +636,6 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
661
636
|
const [isHovered, setIsHovered] = (0, import_react3.useState)(false);
|
|
662
637
|
const [modalState, setModalState] = (0, import_react3.useState)(null);
|
|
663
638
|
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
|
-
}, []);
|
|
675
639
|
const dates = (0, import_react3.useMemo)(() => {
|
|
676
640
|
const today = /* @__PURE__ */ new Date();
|
|
677
641
|
today.setHours(0, 0, 0, 0);
|
|
@@ -691,18 +655,6 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
691
655
|
}
|
|
692
656
|
}
|
|
693
657
|
}, [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]);
|
|
706
658
|
(0, import_react3.useEffect)(() => {
|
|
707
659
|
if (typeof window === "undefined") return;
|
|
708
660
|
const isInEditor = window.self !== window.top;
|
|
@@ -764,7 +716,7 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
764
716
|
setLoading(false);
|
|
765
717
|
return;
|
|
766
718
|
}
|
|
767
|
-
|
|
719
|
+
;
|
|
768
720
|
(async () => {
|
|
769
721
|
try {
|
|
770
722
|
const res = await fetch(`${API_URL}/api/schedule/id/${effectiveId}`);
|
|
@@ -821,14 +773,18 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
821
773
|
const data = await res.json().catch(() => ({}));
|
|
822
774
|
throw new Error(data?.message ?? "Something went wrong. Please try again.");
|
|
823
775
|
}
|
|
824
|
-
await refetchLiveSchedule();
|
|
825
776
|
};
|
|
826
777
|
const handleReplaceSchedule = () => {
|
|
827
778
|
setIsHovered(false);
|
|
828
|
-
|
|
829
|
-
{
|
|
830
|
-
|
|
831
|
-
|
|
779
|
+
if (schedule) {
|
|
780
|
+
window.parent.postMessage({
|
|
781
|
+
type: "ow:schedule-connected",
|
|
782
|
+
schedule: { id: schedule.id, name: schedule.name },
|
|
783
|
+
insertAfter
|
|
784
|
+
}, "*");
|
|
785
|
+
} else {
|
|
786
|
+
window.parent.postMessage({ type: "ow:scheduling-not-connected", insertAfter }, "*");
|
|
787
|
+
}
|
|
832
788
|
};
|
|
833
789
|
if (!inEditor && !loading && !schedule) return null;
|
|
834
790
|
const sectionId = `scheduling-${insertAfter}`;
|
|
@@ -871,19 +827,7 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
871
827
|
),
|
|
872
828
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "max-w-[1280px] mx-auto flex flex-col items-center gap-16", children: [
|
|
873
829
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex flex-col items-center gap-4", children: [
|
|
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
|
-
),
|
|
830
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h2", { className: "font-display text-4xl sm:text-5xl font-bold text-center m-0 text-(--color-dark,#200C02)", children: schedule?.name ?? "Book an appointment" }),
|
|
887
831
|
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 })
|
|
888
832
|
] }),
|
|
889
833
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "w-full flex flex-col items-end gap-3", children: [
|
|
@@ -4359,8 +4303,7 @@ var CustomToolbar = React4.forwardRef(({ className, onMouseDown, ...props }, ref
|
|
|
4359
4303
|
ref,
|
|
4360
4304
|
"data-ohw-toolbar": "",
|
|
4361
4305
|
className: cn(
|
|
4362
|
-
|
|
4363
|
-
"inline-flex h-8 items-center gap-1 rounded-[var(--radius,0.5rem)] bg-background p-0.5 font-sans whitespace-nowrap shadow-md",
|
|
4306
|
+
"inline-flex items-center gap-1 rounded-lg border border-border bg-background p-0.5 font-sans whitespace-nowrap shadow-[0px_2px_4px_-2px_rgba(0,0,0,0.1),0px_4px_6px_-1px_rgba(0,0,0,0.1)]",
|
|
4364
4307
|
className
|
|
4365
4308
|
),
|
|
4366
4309
|
onMouseDown: (e) => {
|
|
@@ -4388,8 +4331,8 @@ var CustomToolbarButton = React4.forwardRef(
|
|
|
4388
4331
|
ref,
|
|
4389
4332
|
type,
|
|
4390
4333
|
className: cn(
|
|
4391
|
-
"inline-flex
|
|
4392
|
-
active ? "bg-primary text-primary-foreground" : "bg-transparent hover:bg-muted disabled:cursor-not-allowed disabled:text-muted-foreground disabled:opacity-60",
|
|
4334
|
+
"inline-flex shrink-0 items-center justify-center rounded p-1.5 transition-colors",
|
|
4335
|
+
active ? "bg-primary text-primary-foreground" : "bg-transparent text-foreground hover:bg-muted disabled:cursor-not-allowed disabled:text-muted-foreground disabled:opacity-60",
|
|
4393
4336
|
className
|
|
4394
4337
|
),
|
|
4395
4338
|
...props
|
|
@@ -4424,10 +4367,9 @@ var arrowClassBySide = {
|
|
|
4424
4367
|
};
|
|
4425
4368
|
function TooltipContent({
|
|
4426
4369
|
className,
|
|
4427
|
-
sideOffset =
|
|
4370
|
+
sideOffset = 6,
|
|
4428
4371
|
side = "bottom",
|
|
4429
4372
|
children,
|
|
4430
|
-
hideArrow,
|
|
4431
4373
|
...props
|
|
4432
4374
|
}) {
|
|
4433
4375
|
const resolvedSide = side ?? "bottom";
|
|
@@ -4438,13 +4380,12 @@ function TooltipContent({
|
|
|
4438
4380
|
side,
|
|
4439
4381
|
sideOffset,
|
|
4440
4382
|
className: cn(
|
|
4441
|
-
"relative z-[2147483647]
|
|
4442
|
-
|
|
4443
|
-
|
|
4383
|
+
"relative z-[2147483647] w-fit max-w-xs rounded-md bg-foreground px-3 py-1.5 text-xs text-background shadow-md",
|
|
4384
|
+
'before:pointer-events-none before:absolute before:size-2 before:rotate-45 before:bg-foreground before:content-[""]',
|
|
4385
|
+
arrowClassBySide[resolvedSide],
|
|
4386
|
+
"animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
|
|
4444
4387
|
"data-[side=bottom]:slide-in-from-top-2 data-[side=top]:slide-in-from-bottom-2",
|
|
4445
4388
|
"data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2",
|
|
4446
|
-
!hideArrow && 'before:pointer-events-none before:absolute before:size-2 before:rotate-45 before:bg-foreground before:content-[""]',
|
|
4447
|
-
!hideArrow && arrowClassBySide[resolvedSide],
|
|
4448
4389
|
className
|
|
4449
4390
|
),
|
|
4450
4391
|
...props,
|
|
@@ -4465,7 +4406,7 @@ function ToolbarActionTooltip({
|
|
|
4465
4406
|
const button = /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(CustomToolbarButton, { type: "button", "aria-label": label, disabled, ...buttonProps, children });
|
|
4466
4407
|
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Tooltip, { children: [
|
|
4467
4408
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(TooltipTrigger, { asChild: true, children: disabled ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "inline-flex", children: button }) : button }),
|
|
4468
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(TooltipContent, { side,
|
|
4409
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(TooltipContent, { side, children: label })
|
|
4469
4410
|
] });
|
|
4470
4411
|
}
|
|
4471
4412
|
function ItemActionToolbar({
|
|
@@ -4475,8 +4416,6 @@ function ItemActionToolbar({
|
|
|
4475
4416
|
editLinkDisabled = false,
|
|
4476
4417
|
addItemDisabled = true,
|
|
4477
4418
|
moreDisabled = true,
|
|
4478
|
-
showAddItem = true,
|
|
4479
|
-
showMore = true,
|
|
4480
4419
|
tooltipSide = "bottom"
|
|
4481
4420
|
}) {
|
|
4482
4421
|
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(CustomToolbar, { children: [
|
|
@@ -4501,7 +4440,8 @@ function ItemActionToolbar({
|
|
|
4501
4440
|
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react2.Link, { className: "size-4 shrink-0", "aria-hidden": true })
|
|
4502
4441
|
}
|
|
4503
4442
|
),
|
|
4504
|
-
|
|
4443
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(CustomToolbarDivider, {}),
|
|
4444
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
4505
4445
|
ToolbarActionTooltip,
|
|
4506
4446
|
{
|
|
4507
4447
|
label: "Add item",
|
|
@@ -4517,8 +4457,9 @@ function ItemActionToolbar({
|
|
|
4517
4457
|
},
|
|
4518
4458
|
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react2.Plus, { className: "size-4 shrink-0", "aria-hidden": true })
|
|
4519
4459
|
}
|
|
4520
|
-
)
|
|
4521
|
-
|
|
4460
|
+
),
|
|
4461
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(CustomToolbarDivider, {}),
|
|
4462
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
4522
4463
|
ToolbarActionTooltip,
|
|
4523
4464
|
{
|
|
4524
4465
|
label: "More",
|
|
@@ -4534,32 +4475,15 @@ function ItemActionToolbar({
|
|
|
4534
4475
|
},
|
|
4535
4476
|
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react2.MoreHorizontal, { className: "size-4 shrink-0", "aria-hidden": true })
|
|
4536
4477
|
}
|
|
4537
|
-
)
|
|
4478
|
+
)
|
|
4538
4479
|
] }) });
|
|
4539
4480
|
}
|
|
4540
4481
|
|
|
4541
4482
|
// src/ui/item-interaction-layer.tsx
|
|
4542
|
-
var React5 = __toESM(require("react"), 1);
|
|
4543
4483
|
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
4544
4484
|
var PRIMARY = "var(--ohw-primary, #0885FE)";
|
|
4545
|
-
var FOCUS_RING =
|
|
4485
|
+
var FOCUS_RING = "0 0 0 4px rgba(8, 133, 254, 0.12)";
|
|
4546
4486
|
var DRAG_SHADOW = "0px 4px 6px -1px rgba(0, 0, 0, 0.1), 0px 2px 4px -2px rgba(0, 0, 0, 0.1)";
|
|
4547
|
-
var TOOLBAR_EDGE_MARGIN = 4;
|
|
4548
|
-
var SELECTION_CHROME_GAP = 4;
|
|
4549
|
-
var TOOLBAR_STROKE_GAP = 4;
|
|
4550
|
-
function getChromeZIndex(state) {
|
|
4551
|
-
switch (state) {
|
|
4552
|
-
case "active-top":
|
|
4553
|
-
case "active-bottom":
|
|
4554
|
-
case "dragging":
|
|
4555
|
-
return 2147483644;
|
|
4556
|
-
case "hover":
|
|
4557
|
-
case "sibling-hint":
|
|
4558
|
-
return 2147483643;
|
|
4559
|
-
default:
|
|
4560
|
-
return 2147483642;
|
|
4561
|
-
}
|
|
4562
|
-
}
|
|
4563
4487
|
function getChromeStyle(state) {
|
|
4564
4488
|
switch (state) {
|
|
4565
4489
|
case "hover":
|
|
@@ -4581,65 +4505,12 @@ function getChromeStyle(state) {
|
|
|
4581
4505
|
case "dragging":
|
|
4582
4506
|
return {
|
|
4583
4507
|
border: `2px solid ${PRIMARY}`,
|
|
4584
|
-
boxShadow:
|
|
4508
|
+
boxShadow: DRAG_SHADOW
|
|
4585
4509
|
};
|
|
4586
4510
|
default:
|
|
4587
4511
|
return {};
|
|
4588
4512
|
}
|
|
4589
4513
|
}
|
|
4590
|
-
function ClampedToolbarSlot({
|
|
4591
|
-
placement,
|
|
4592
|
-
children
|
|
4593
|
-
}) {
|
|
4594
|
-
const slotRef = React5.useRef(null);
|
|
4595
|
-
React5.useLayoutEffect(() => {
|
|
4596
|
-
const slot = slotRef.current;
|
|
4597
|
-
if (!slot) return;
|
|
4598
|
-
const clamp = () => {
|
|
4599
|
-
const toolbar = slot.firstElementChild;
|
|
4600
|
-
if (!toolbar) return;
|
|
4601
|
-
const w = toolbar.offsetWidth;
|
|
4602
|
-
if (w <= 0) return;
|
|
4603
|
-
const parent = slot.offsetParent;
|
|
4604
|
-
if (!parent) return;
|
|
4605
|
-
const parentRect = parent.getBoundingClientRect();
|
|
4606
|
-
const centerX = parentRect.left + parentRect.width / 2;
|
|
4607
|
-
const half = w / 2;
|
|
4608
|
-
const clampedCenter = Math.max(
|
|
4609
|
-
TOOLBAR_EDGE_MARGIN + half,
|
|
4610
|
-
Math.min(centerX, window.innerWidth - TOOLBAR_EDGE_MARGIN - half)
|
|
4611
|
-
);
|
|
4612
|
-
const offsetX = clampedCenter - centerX;
|
|
4613
|
-
slot.style.transform = `translateX(calc(-50% + ${offsetX}px))`;
|
|
4614
|
-
};
|
|
4615
|
-
clamp();
|
|
4616
|
-
const ro = new ResizeObserver(clamp);
|
|
4617
|
-
ro.observe(slot);
|
|
4618
|
-
if (slot.firstElementChild) ro.observe(slot.firstElementChild);
|
|
4619
|
-
window.addEventListener("resize", clamp);
|
|
4620
|
-
return () => {
|
|
4621
|
-
ro.disconnect();
|
|
4622
|
-
window.removeEventListener("resize", clamp);
|
|
4623
|
-
};
|
|
4624
|
-
}, [placement, children]);
|
|
4625
|
-
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
4626
|
-
"div",
|
|
4627
|
-
{
|
|
4628
|
-
ref: slotRef,
|
|
4629
|
-
className: cn(
|
|
4630
|
-
"pointer-events-auto absolute left-1/2",
|
|
4631
|
-
placement === "top" ? "bottom-full" : "top-full"
|
|
4632
|
-
),
|
|
4633
|
-
style: {
|
|
4634
|
-
marginBottom: placement === "top" ? TOOLBAR_STROKE_GAP : void 0,
|
|
4635
|
-
marginTop: placement === "bottom" ? TOOLBAR_STROKE_GAP : void 0,
|
|
4636
|
-
transform: "translateX(-50%)"
|
|
4637
|
-
},
|
|
4638
|
-
"data-ohw-item-toolbar-anchor": placement,
|
|
4639
|
-
children
|
|
4640
|
-
}
|
|
4641
|
-
);
|
|
4642
|
-
}
|
|
4643
4514
|
function ItemInteractionLayer({
|
|
4644
4515
|
rect,
|
|
4645
4516
|
state,
|
|
@@ -4650,18 +4521,14 @@ function ItemInteractionLayer({
|
|
|
4650
4521
|
dragHandleLabel = "Reorder item",
|
|
4651
4522
|
onDragHandleDragStart,
|
|
4652
4523
|
onDragHandleDragEnd,
|
|
4653
|
-
|
|
4654
|
-
onItemClick,
|
|
4655
|
-
itemDragSurface = true,
|
|
4656
|
-
chromeGap = SELECTION_CHROME_GAP,
|
|
4524
|
+
chromeGap = 6,
|
|
4657
4525
|
className
|
|
4658
4526
|
}) {
|
|
4659
4527
|
if (state === "default") return null;
|
|
4660
4528
|
const isActive = state === "active-top" || state === "active-bottom";
|
|
4661
4529
|
const isDragging = state === "dragging";
|
|
4662
4530
|
const showToolbar = isActive && toolbar;
|
|
4663
|
-
const showDragHandle =
|
|
4664
|
-
const itemDragEnabled = itemDragSurface && isActive && showHandle && !isDragging && !dragDisabled;
|
|
4531
|
+
const showDragHandle = isActive && showHandle && !isDragging;
|
|
4665
4532
|
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
4666
4533
|
"div",
|
|
4667
4534
|
{
|
|
@@ -4675,7 +4542,7 @@ function ItemInteractionLayer({
|
|
|
4675
4542
|
left: rect.left - chromeGap,
|
|
4676
4543
|
width: rect.width + chromeGap * 2,
|
|
4677
4544
|
height: rect.height + chromeGap * 2,
|
|
4678
|
-
zIndex:
|
|
4545
|
+
zIndex: 2147483646
|
|
4679
4546
|
},
|
|
4680
4547
|
children: [
|
|
4681
4548
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
@@ -4686,29 +4553,11 @@ function ItemInteractionLayer({
|
|
|
4686
4553
|
style: getChromeStyle(state)
|
|
4687
4554
|
}
|
|
4688
4555
|
),
|
|
4689
|
-
itemDragEnabled && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
4690
|
-
"div",
|
|
4691
|
-
{
|
|
4692
|
-
"data-ohw-item-drag-surface": "",
|
|
4693
|
-
className: "pointer-events-auto absolute inset-0 cursor-text rounded-lg",
|
|
4694
|
-
onPointerDown: (e) => {
|
|
4695
|
-
if (e.button !== 0) return;
|
|
4696
|
-
onItemPointerDown?.(e);
|
|
4697
|
-
},
|
|
4698
|
-
onClick: (e) => {
|
|
4699
|
-
e.preventDefault();
|
|
4700
|
-
e.stopPropagation();
|
|
4701
|
-
onItemClick?.(e.clientX, e.clientY);
|
|
4702
|
-
}
|
|
4703
|
-
}
|
|
4704
|
-
),
|
|
4705
4556
|
showDragHandle && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
4706
4557
|
"div",
|
|
4707
4558
|
{
|
|
4708
4559
|
"data-ohw-drag-handle-container": "",
|
|
4709
|
-
className: "pointer-events-auto absolute left-0 top-1/2
|
|
4710
|
-
style: isDragging ? { opacity: 0 } : void 0,
|
|
4711
|
-
"aria-hidden": isDragging || void 0,
|
|
4560
|
+
className: "pointer-events-auto absolute left-0 top-1/2 -translate-x-[calc(100%+7px)] -translate-y-1/2",
|
|
4712
4561
|
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
4713
4562
|
DragHandle,
|
|
4714
4563
|
{
|
|
@@ -4720,17 +4569,7 @@ function ItemInteractionLayer({
|
|
|
4720
4569
|
e.preventDefault();
|
|
4721
4570
|
return;
|
|
4722
4571
|
}
|
|
4723
|
-
|
|
4724
|
-
blank.width = 1;
|
|
4725
|
-
blank.height = 1;
|
|
4726
|
-
blank.style.cssText = "position:fixed;left:-9999px;top:-9999px;width:1px;height:1px;pointer-events:none";
|
|
4727
|
-
document.body.appendChild(blank);
|
|
4728
|
-
try {
|
|
4729
|
-
e.dataTransfer.setDragImage(blank, 0, 0);
|
|
4730
|
-
} finally {
|
|
4731
|
-
requestAnimationFrame(() => blank.remove());
|
|
4732
|
-
}
|
|
4733
|
-
e.dataTransfer.setData("text/plain", dragHandleLabel);
|
|
4572
|
+
e.dataTransfer?.setData("text/plain", dragHandleLabel);
|
|
4734
4573
|
e.dataTransfer.effectAllowed = "move";
|
|
4735
4574
|
onDragHandleDragStart?.(e);
|
|
4736
4575
|
},
|
|
@@ -4739,19 +4578,33 @@ function ItemInteractionLayer({
|
|
|
4739
4578
|
)
|
|
4740
4579
|
}
|
|
4741
4580
|
),
|
|
4742
|
-
showToolbar && state === "active-top" && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
4743
|
-
|
|
4581
|
+
showToolbar && state === "active-top" && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
4582
|
+
"div",
|
|
4583
|
+
{
|
|
4584
|
+
className: "pointer-events-auto absolute bottom-full left-1/2 mb-2 -translate-x-1/2",
|
|
4585
|
+
"data-ohw-item-toolbar-anchor": "top",
|
|
4586
|
+
children: toolbar
|
|
4587
|
+
}
|
|
4588
|
+
),
|
|
4589
|
+
showToolbar && state === "active-bottom" && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
4590
|
+
"div",
|
|
4591
|
+
{
|
|
4592
|
+
className: "pointer-events-auto absolute left-1/2 top-full mt-2 -translate-x-1/2",
|
|
4593
|
+
"data-ohw-item-toolbar-anchor": "bottom",
|
|
4594
|
+
children: toolbar
|
|
4595
|
+
}
|
|
4596
|
+
)
|
|
4744
4597
|
]
|
|
4745
4598
|
}
|
|
4746
4599
|
);
|
|
4747
4600
|
}
|
|
4748
4601
|
|
|
4749
4602
|
// src/ui/MediaOverlay.tsx
|
|
4750
|
-
var
|
|
4603
|
+
var React6 = __toESM(require("react"), 1);
|
|
4751
4604
|
var import_lucide_react3 = require("lucide-react");
|
|
4752
4605
|
|
|
4753
4606
|
// src/ui/button.tsx
|
|
4754
|
-
var
|
|
4607
|
+
var React5 = __toESM(require("react"), 1);
|
|
4755
4608
|
var import_radix_ui4 = require("radix-ui");
|
|
4756
4609
|
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
4757
4610
|
var buttonVariants = cva(
|
|
@@ -4774,7 +4627,7 @@ var buttonVariants = cva(
|
|
|
4774
4627
|
}
|
|
4775
4628
|
}
|
|
4776
4629
|
);
|
|
4777
|
-
var Button =
|
|
4630
|
+
var Button = React5.forwardRef(
|
|
4778
4631
|
({ className, variant, size, asChild = false, ...props }, ref) => {
|
|
4779
4632
|
const Comp = asChild ? import_radix_ui4.Slot.Root : "button";
|
|
4780
4633
|
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
@@ -4826,7 +4679,7 @@ function MediaOverlay({
|
|
|
4826
4679
|
onVideoSettingsChange
|
|
4827
4680
|
}) {
|
|
4828
4681
|
const { rect } = hover;
|
|
4829
|
-
const skeletonRef =
|
|
4682
|
+
const skeletonRef = React6.useRef(null);
|
|
4830
4683
|
const isVideo = hover.elementType === "video";
|
|
4831
4684
|
const autoplay = hover.videoAutoplay ?? true;
|
|
4832
4685
|
const muted = hover.videoMuted ?? true;
|
|
@@ -4838,7 +4691,7 @@ function MediaOverlay({
|
|
|
4838
4691
|
height: rect.height,
|
|
4839
4692
|
zIndex: 2147483646
|
|
4840
4693
|
};
|
|
4841
|
-
|
|
4694
|
+
React6.useEffect(() => {
|
|
4842
4695
|
if (!isUploading || !fadingOut || !skeletonRef.current) return;
|
|
4843
4696
|
const anim = skeletonRef.current.animate([{ opacity: 1 }, { opacity: 0 }], {
|
|
4844
4697
|
duration: MEDIA_UPLOAD_FADE_MS,
|
|
@@ -5243,7 +5096,7 @@ function scrollToHashSectionWhenReady(behavior = "smooth") {
|
|
|
5243
5096
|
var import_react7 = require("react");
|
|
5244
5097
|
|
|
5245
5098
|
// src/ui/dialog.tsx
|
|
5246
|
-
var
|
|
5099
|
+
var React7 = __toESM(require("react"), 1);
|
|
5247
5100
|
var import_radix_ui5 = require("radix-ui");
|
|
5248
5101
|
var import_lucide_react4 = require("lucide-react");
|
|
5249
5102
|
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
@@ -5271,7 +5124,7 @@ function DialogOverlay({
|
|
|
5271
5124
|
}
|
|
5272
5125
|
);
|
|
5273
5126
|
}
|
|
5274
|
-
var DialogContent =
|
|
5127
|
+
var DialogContent = React7.forwardRef(
|
|
5275
5128
|
({ className, children, showCloseButton = true, container, ...props }, ref) => {
|
|
5276
5129
|
const positionMode = container ? "absolute" : "fixed";
|
|
5277
5130
|
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(DialogPortal, { container: container ?? void 0, children: [
|
|
@@ -5326,7 +5179,7 @@ function DialogFooter({
|
|
|
5326
5179
|
}
|
|
5327
5180
|
);
|
|
5328
5181
|
}
|
|
5329
|
-
var DialogTitle =
|
|
5182
|
+
var DialogTitle = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
5330
5183
|
import_radix_ui5.Dialog.Title,
|
|
5331
5184
|
{
|
|
5332
5185
|
ref,
|
|
@@ -5338,7 +5191,7 @@ var DialogTitle = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE
|
|
|
5338
5191
|
}
|
|
5339
5192
|
));
|
|
5340
5193
|
DialogTitle.displayName = import_radix_ui5.Dialog.Title.displayName;
|
|
5341
|
-
var DialogDescription =
|
|
5194
|
+
var DialogDescription = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
5342
5195
|
import_radix_ui5.Dialog.Description,
|
|
5343
5196
|
{
|
|
5344
5197
|
ref,
|
|
@@ -5443,9 +5296,9 @@ function SectionTreeItem({
|
|
|
5443
5296
|
var import_react4 = require("react");
|
|
5444
5297
|
|
|
5445
5298
|
// src/ui/input.tsx
|
|
5446
|
-
var
|
|
5299
|
+
var React8 = __toESM(require("react"), 1);
|
|
5447
5300
|
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
5448
|
-
var Input =
|
|
5301
|
+
var Input = React8.forwardRef(
|
|
5449
5302
|
({ className, type, ...props }, ref) => {
|
|
5450
5303
|
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
5451
5304
|
"input",
|
|
@@ -6426,155 +6279,9 @@ function shouldUseDevFixtures() {
|
|
|
6426
6279
|
return new URLSearchParams(q).get("ohw-fixtures") === "1";
|
|
6427
6280
|
}
|
|
6428
6281
|
|
|
6429
|
-
// src/lib/nav-tree.ts
|
|
6430
|
-
var MAX_LEVEL = { nav: 1 };
|
|
6431
|
-
var ROOT = null;
|
|
6432
|
-
function cloneForest(nodes) {
|
|
6433
|
-
return nodes.map((n) => ({ id: n.id, children: cloneForest(n.children) }));
|
|
6434
|
-
}
|
|
6435
|
-
function findNode(nodes, id, parentId = ROOT) {
|
|
6436
|
-
for (let i = 0; i < nodes.length; i++) {
|
|
6437
|
-
const node = nodes[i];
|
|
6438
|
-
if (node.id === id) return { node, parentId, index: i, siblings: nodes };
|
|
6439
|
-
const nested = findNode(node.children, id, node.id);
|
|
6440
|
-
if (nested) return nested;
|
|
6441
|
-
}
|
|
6442
|
-
return null;
|
|
6443
|
-
}
|
|
6444
|
-
function getChildrenOf(nodes, parentId) {
|
|
6445
|
-
if (parentId === ROOT) return nodes;
|
|
6446
|
-
const found = findNode(nodes, parentId);
|
|
6447
|
-
return found ? found.node.children : null;
|
|
6448
|
-
}
|
|
6449
|
-
function isDescendant(nodes, ancestorId, maybeDescendantId) {
|
|
6450
|
-
const found = findNode(nodes, ancestorId);
|
|
6451
|
-
if (!found) return false;
|
|
6452
|
-
return findNode(found.node.children, maybeDescendantId) !== null;
|
|
6453
|
-
}
|
|
6454
|
-
function levelOf(nodes, id) {
|
|
6455
|
-
const loc = findNode(nodes, id);
|
|
6456
|
-
if (!loc) return -1;
|
|
6457
|
-
if (loc.parentId === ROOT) return 0;
|
|
6458
|
-
return 1 + Math.max(0, levelOf(nodes, loc.parentId));
|
|
6459
|
-
}
|
|
6460
|
-
function insertedLevel(nodes, parentId) {
|
|
6461
|
-
if (parentId === ROOT) return 0;
|
|
6462
|
-
const parentLevel = levelOf(nodes, parentId);
|
|
6463
|
-
if (parentLevel < 0) return -1;
|
|
6464
|
-
return parentLevel + 1;
|
|
6465
|
-
}
|
|
6466
|
-
function takeNode(nodes, id) {
|
|
6467
|
-
const forest = cloneForest(nodes);
|
|
6468
|
-
const loc = findNode(forest, id);
|
|
6469
|
-
if (!loc) return null;
|
|
6470
|
-
const [taken] = loc.siblings.splice(loc.index, 1);
|
|
6471
|
-
if (!taken) return null;
|
|
6472
|
-
return { forest, taken };
|
|
6473
|
-
}
|
|
6474
|
-
function insertInto(forest, node, parentId, index) {
|
|
6475
|
-
const siblings = getChildrenOf(forest, parentId);
|
|
6476
|
-
if (!siblings) return false;
|
|
6477
|
-
const clamped = Math.max(0, Math.min(index, siblings.length));
|
|
6478
|
-
siblings.splice(clamped, 0, node);
|
|
6479
|
-
return true;
|
|
6480
|
-
}
|
|
6481
|
-
function normalize(nodes) {
|
|
6482
|
-
const walk = (list) => list.map((n) => {
|
|
6483
|
-
const children = walk(n.children);
|
|
6484
|
-
return { id: n.id, children };
|
|
6485
|
-
});
|
|
6486
|
-
return walk(nodes);
|
|
6487
|
-
}
|
|
6488
|
-
function moveNode(model, draggedId, target) {
|
|
6489
|
-
const { parentId, index: targetIndex } = target;
|
|
6490
|
-
if (parentId === draggedId) return null;
|
|
6491
|
-
if (parentId !== ROOT && isDescendant(model, draggedId, parentId)) return null;
|
|
6492
|
-
const nextLevel = insertedLevel(model, parentId);
|
|
6493
|
-
if (nextLevel < 0 || nextLevel > MAX_LEVEL.nav) return null;
|
|
6494
|
-
const draggedLoc = findNode(model, draggedId);
|
|
6495
|
-
if (!draggedLoc) return null;
|
|
6496
|
-
if (parentId !== ROOT && draggedLoc.node.children.length > 0) return null;
|
|
6497
|
-
const taken = takeNode(model, draggedId);
|
|
6498
|
-
if (!taken) return null;
|
|
6499
|
-
let insertIndex = targetIndex;
|
|
6500
|
-
if (draggedLoc.parentId === parentId && draggedLoc.index < targetIndex) {
|
|
6501
|
-
insertIndex -= 1;
|
|
6502
|
-
}
|
|
6503
|
-
if (!insertInto(taken.forest, taken.taken, parentId, insertIndex)) return null;
|
|
6504
|
-
const next = normalize(taken.forest);
|
|
6505
|
-
if (forestsEqual(model, next)) return null;
|
|
6506
|
-
return next;
|
|
6507
|
-
}
|
|
6508
|
-
function forestsEqual(a, b) {
|
|
6509
|
-
if (a.length !== b.length) return false;
|
|
6510
|
-
for (let i = 0; i < a.length; i++) {
|
|
6511
|
-
const left = a[i];
|
|
6512
|
-
const right = b[i];
|
|
6513
|
-
if (left.id !== right.id) return false;
|
|
6514
|
-
if (!forestsEqual(left.children, right.children)) return false;
|
|
6515
|
-
}
|
|
6516
|
-
return true;
|
|
6517
|
-
}
|
|
6518
|
-
function forestFromFlatOrder(order) {
|
|
6519
|
-
return order.map((id) => ({ id, children: [] }));
|
|
6520
|
-
}
|
|
6521
|
-
function serializeNavOrder(nodes) {
|
|
6522
|
-
const hasNesting = nodes.some((n) => n.children.length > 0);
|
|
6523
|
-
if (!hasNesting) {
|
|
6524
|
-
return JSON.stringify(nodes.map((n) => n.id));
|
|
6525
|
-
}
|
|
6526
|
-
return JSON.stringify(nodes);
|
|
6527
|
-
}
|
|
6528
|
-
function parseNavOrderJson(raw) {
|
|
6529
|
-
if (!raw) return null;
|
|
6530
|
-
try {
|
|
6531
|
-
const parsed = JSON.parse(raw);
|
|
6532
|
-
if (!Array.isArray(parsed)) return null;
|
|
6533
|
-
if (parsed.every((x) => typeof x === "string")) {
|
|
6534
|
-
return forestFromFlatOrder(parsed.filter((x) => typeof x === "string" && x.length > 0));
|
|
6535
|
-
}
|
|
6536
|
-
return parseNavNodeList(parsed);
|
|
6537
|
-
} catch {
|
|
6538
|
-
return null;
|
|
6539
|
-
}
|
|
6540
|
-
}
|
|
6541
|
-
function parseNavNodeList(raw) {
|
|
6542
|
-
const out = [];
|
|
6543
|
-
for (const item of raw) {
|
|
6544
|
-
if (typeof item === "string" && item.length > 0) {
|
|
6545
|
-
out.push({ id: item, children: [] });
|
|
6546
|
-
continue;
|
|
6547
|
-
}
|
|
6548
|
-
if (!item || typeof item !== "object") return null;
|
|
6549
|
-
const rec = item;
|
|
6550
|
-
if (typeof rec.id !== "string" || !rec.id) return null;
|
|
6551
|
-
const children = Array.isArray(rec.children) ? parseNavNodeList(rec.children) : [];
|
|
6552
|
-
if (!children) return null;
|
|
6553
|
-
out.push({ id: rec.id, children });
|
|
6554
|
-
}
|
|
6555
|
-
return out;
|
|
6556
|
-
}
|
|
6557
|
-
function flattenNavOrder(nodes) {
|
|
6558
|
-
const out = [];
|
|
6559
|
-
const walk = (list) => {
|
|
6560
|
-
for (const n of list) {
|
|
6561
|
-
out.push(n.id);
|
|
6562
|
-
walk(n.children);
|
|
6563
|
-
}
|
|
6564
|
-
};
|
|
6565
|
-
walk(nodes);
|
|
6566
|
-
return out;
|
|
6567
|
-
}
|
|
6568
|
-
|
|
6569
6282
|
// src/lib/nav-items.ts
|
|
6570
6283
|
var NAV_COUNT_KEY = "__ohw_nav_count";
|
|
6571
6284
|
var NAV_ORDER_KEY = "__ohw_nav_order";
|
|
6572
|
-
var NAV_HREF_RE = /^nav-(\d+)-href$/;
|
|
6573
|
-
function isNavbarHrefKey(key) {
|
|
6574
|
-
if (!key) return false;
|
|
6575
|
-
if (key === "nav-book-href") return false;
|
|
6576
|
-
return NAV_HREF_RE.test(key);
|
|
6577
|
-
}
|
|
6578
6285
|
function getLinkHref(el) {
|
|
6579
6286
|
const key = el.getAttribute("data-ohw-href-key");
|
|
6580
6287
|
if (key) {
|
|
@@ -6611,7 +6318,7 @@ function listNavbarItems() {
|
|
|
6611
6318
|
}
|
|
6612
6319
|
function parseNavIndexFromKey(key) {
|
|
6613
6320
|
if (!key) return null;
|
|
6614
|
-
const match = key.match(
|
|
6321
|
+
const match = key.match(/^nav-(\d+)-href$/);
|
|
6615
6322
|
if (!match) return null;
|
|
6616
6323
|
return parseInt(match[1], 10);
|
|
6617
6324
|
}
|
|
@@ -6634,6 +6341,17 @@ function getNavbarExistingTargets() {
|
|
|
6634
6341
|
function getNavOrderFromDom() {
|
|
6635
6342
|
return listNavbarItems().map((el) => el.getAttribute("data-ohw-href-key")).filter((key) => Boolean(key));
|
|
6636
6343
|
}
|
|
6344
|
+
function parseNavOrder(content) {
|
|
6345
|
+
const raw = content[NAV_ORDER_KEY];
|
|
6346
|
+
if (!raw) return null;
|
|
6347
|
+
try {
|
|
6348
|
+
const parsed = JSON.parse(raw);
|
|
6349
|
+
if (!Array.isArray(parsed)) return null;
|
|
6350
|
+
return parsed.filter((key) => typeof key === "string" && key.length > 0);
|
|
6351
|
+
} catch {
|
|
6352
|
+
return null;
|
|
6353
|
+
}
|
|
6354
|
+
}
|
|
6637
6355
|
function findCounterpartByHrefKey(hrefKey, root) {
|
|
6638
6356
|
return root.querySelector(`[data-ohw-href-key="${CSS.escape(hrefKey)}"]`);
|
|
6639
6357
|
}
|
|
@@ -6697,47 +6415,19 @@ function insertNavbarItemDom(index, href, label, afterAnchor) {
|
|
|
6697
6415
|
}
|
|
6698
6416
|
return primary;
|
|
6699
6417
|
}
|
|
6700
|
-
function navOrderKeysEqual(a, b) {
|
|
6701
|
-
if (a.length !== b.length) return false;
|
|
6702
|
-
for (let i = 0; i < a.length; i++) {
|
|
6703
|
-
if (a[i] !== b[i]) return false;
|
|
6704
|
-
}
|
|
6705
|
-
return true;
|
|
6706
|
-
}
|
|
6707
|
-
function getNavbarLinkKeysInContainer(container) {
|
|
6708
|
-
return Array.from(container.querySelectorAll("[data-ohw-href-key]")).filter(isNavbarLinkItem).map((el) => el.getAttribute("data-ohw-href-key")).filter((key) => Boolean(key));
|
|
6709
|
-
}
|
|
6710
6418
|
function applyNavOrderToContainer(container, order) {
|
|
6711
|
-
const desired = order.filter((key, i) => order.indexOf(key) === i);
|
|
6712
|
-
const current = getNavbarLinkKeysInContainer(container);
|
|
6713
|
-
const extras = current.filter((key) => !desired.includes(key));
|
|
6714
|
-
const expected = [...desired.filter((key) => current.includes(key)), ...extras];
|
|
6715
|
-
const orderedEls = [];
|
|
6716
|
-
if (navOrderKeysEqual(current, expected)) return;
|
|
6717
|
-
if (current.length === expected.length && current.every((key, i) => key === expected[i])) {
|
|
6718
|
-
return;
|
|
6719
|
-
}
|
|
6720
|
-
const lastCurrentLinkEl = current.length > 0 ? findCounterpartByHrefKey(current[current.length - 1], container) : null;
|
|
6721
|
-
const anchor = lastCurrentLinkEl?.parentElement === container ? lastCurrentLinkEl.nextElementSibling : null;
|
|
6722
6419
|
const seen = /* @__PURE__ */ new Set();
|
|
6723
|
-
for (const hrefKey of
|
|
6420
|
+
for (const hrefKey of order) {
|
|
6724
6421
|
if (seen.has(hrefKey)) continue;
|
|
6725
6422
|
seen.add(hrefKey);
|
|
6726
6423
|
const el = findCounterpartByHrefKey(hrefKey, container);
|
|
6727
|
-
if (el
|
|
6424
|
+
if (el) container.appendChild(el);
|
|
6728
6425
|
}
|
|
6729
6426
|
for (const el of container.querySelectorAll("[data-ohw-href-key]")) {
|
|
6730
6427
|
if (!isNavbarLinkItem(el)) continue;
|
|
6731
6428
|
const key = el.getAttribute("data-ohw-href-key");
|
|
6732
6429
|
if (!key || seen.has(key)) continue;
|
|
6733
|
-
|
|
6734
|
-
}
|
|
6735
|
-
for (const el of orderedEls) {
|
|
6736
|
-
if (anchor) {
|
|
6737
|
-
if (el.nextSibling !== anchor) container.insertBefore(el, anchor);
|
|
6738
|
-
} else if (container.lastElementChild !== el) {
|
|
6739
|
-
container.appendChild(el);
|
|
6740
|
-
}
|
|
6430
|
+
container.appendChild(el);
|
|
6741
6431
|
}
|
|
6742
6432
|
}
|
|
6743
6433
|
function applyNavOrder(order) {
|
|
@@ -6746,75 +6436,6 @@ function applyNavOrder(order) {
|
|
|
6746
6436
|
const drawer = getNavbarDrawerContainer();
|
|
6747
6437
|
if (drawer) applyNavOrderToContainer(drawer, order);
|
|
6748
6438
|
}
|
|
6749
|
-
function applyChildrenOrder(parentHrefKey, childKeys, root) {
|
|
6750
|
-
const parent = findCounterpartByHrefKey(parentHrefKey, root);
|
|
6751
|
-
if (!parent) return;
|
|
6752
|
-
const group = parent.closest("[data-ohw-nav-group]");
|
|
6753
|
-
const childrenRoot = group?.querySelector(":scope > [data-ohw-nav-children]");
|
|
6754
|
-
if (!childrenRoot) return;
|
|
6755
|
-
const current = Array.from(childrenRoot.querySelectorAll(":scope > [data-ohw-href-key]")).map((el) => el.getAttribute("data-ohw-href-key")).filter((key) => Boolean(key));
|
|
6756
|
-
if (navOrderKeysEqual(current, childKeys)) return;
|
|
6757
|
-
for (const key of childKeys) {
|
|
6758
|
-
const el = findCounterpartByHrefKey(key, root);
|
|
6759
|
-
if (!el) continue;
|
|
6760
|
-
if (childrenRoot.lastElementChild !== el) {
|
|
6761
|
-
childrenRoot.appendChild(el);
|
|
6762
|
-
}
|
|
6763
|
-
}
|
|
6764
|
-
}
|
|
6765
|
-
function applyNavForest(forest) {
|
|
6766
|
-
if (forestsEqual(forest, getNavForestFromDom())) return;
|
|
6767
|
-
const rootKeys = forest.map((n) => n.id);
|
|
6768
|
-
applyNavOrder(rootKeys);
|
|
6769
|
-
const desktop = getNavbarDesktopContainer();
|
|
6770
|
-
const drawer = getNavbarDrawerContainer();
|
|
6771
|
-
for (const node of forest) {
|
|
6772
|
-
if (node.children.length === 0) continue;
|
|
6773
|
-
const childKeys = node.children.map((c) => c.id);
|
|
6774
|
-
if (desktop) applyChildrenOrder(node.id, childKeys, desktop);
|
|
6775
|
-
if (drawer) applyChildrenOrder(node.id, childKeys, drawer);
|
|
6776
|
-
}
|
|
6777
|
-
}
|
|
6778
|
-
function getNavForestFromDom() {
|
|
6779
|
-
const items = listNavbarItems();
|
|
6780
|
-
const nestedChildKeys = /* @__PURE__ */ new Set();
|
|
6781
|
-
const roots = [];
|
|
6782
|
-
for (const item of items) {
|
|
6783
|
-
const key = item.getAttribute("data-ohw-href-key");
|
|
6784
|
-
if (!key || !isNavbarHrefKey(key)) continue;
|
|
6785
|
-
if (item.closest("[data-ohw-nav-children]")) continue;
|
|
6786
|
-
const group = item.closest("[data-ohw-nav-group]");
|
|
6787
|
-
const childrenRoot = group?.querySelector(":scope > [data-ohw-nav-children]");
|
|
6788
|
-
const children = [];
|
|
6789
|
-
if (childrenRoot) {
|
|
6790
|
-
for (const child of childrenRoot.querySelectorAll(":scope > [data-ohw-href-key]")) {
|
|
6791
|
-
if (!isNavbarLinkItem(child)) continue;
|
|
6792
|
-
const childKey = child.getAttribute("data-ohw-href-key");
|
|
6793
|
-
if (!childKey || !isNavbarHrefKey(childKey)) continue;
|
|
6794
|
-
nestedChildKeys.add(childKey);
|
|
6795
|
-
children.push({ id: childKey, children: [] });
|
|
6796
|
-
}
|
|
6797
|
-
}
|
|
6798
|
-
roots.push({ id: key, children });
|
|
6799
|
-
}
|
|
6800
|
-
if (roots.length === 0) {
|
|
6801
|
-
return forestFromFlatOrder(
|
|
6802
|
-
getNavOrderFromDom().filter((k) => isNavbarHrefKey(k) && !nestedChildKeys.has(k))
|
|
6803
|
-
);
|
|
6804
|
-
}
|
|
6805
|
-
return roots;
|
|
6806
|
-
}
|
|
6807
|
-
function planNavItemMove(hrefKey, parentId, insertIndex) {
|
|
6808
|
-
const model = getNavForestFromDom();
|
|
6809
|
-
const next = moveNode(model, hrefKey, { parentId, index: insertIndex });
|
|
6810
|
-
if (!next) return null;
|
|
6811
|
-
if (forestsEqual(model, next)) return null;
|
|
6812
|
-
return {
|
|
6813
|
-
forest: next,
|
|
6814
|
-
orderJson: serializeNavOrder(next),
|
|
6815
|
-
flatOrder: flattenNavOrder(next)
|
|
6816
|
-
};
|
|
6817
|
-
}
|
|
6818
6439
|
function collectNavbarIndicesFromContent(content) {
|
|
6819
6440
|
const indices = /* @__PURE__ */ new Set();
|
|
6820
6441
|
for (const key of Object.keys(content)) {
|
|
@@ -6842,10 +6463,8 @@ function reconcileNavbarItemsFromContent(content) {
|
|
|
6842
6463
|
if (!href && !label) continue;
|
|
6843
6464
|
insertNavbarItemDom(index, href ?? "/", label ?? "Untitled", null);
|
|
6844
6465
|
}
|
|
6845
|
-
const
|
|
6846
|
-
if (
|
|
6847
|
-
applyNavForest(orderForest);
|
|
6848
|
-
}
|
|
6466
|
+
const order = parseNavOrder(content);
|
|
6467
|
+
if (order?.length) applyNavOrder(order);
|
|
6849
6468
|
}
|
|
6850
6469
|
function buildNavOrderAfterInsert(afterAnchor, newHrefKey) {
|
|
6851
6470
|
const order = getNavOrderFromDom();
|
|
@@ -6885,982 +6504,75 @@ function insertNavbarItem(href, label, afterAnchor = null) {
|
|
|
6885
6504
|
};
|
|
6886
6505
|
}
|
|
6887
6506
|
|
|
6888
|
-
// src/
|
|
6889
|
-
var
|
|
6890
|
-
var
|
|
6891
|
-
function
|
|
6892
|
-
|
|
6893
|
-
|
|
6894
|
-
|
|
6895
|
-
|
|
6896
|
-
|
|
6897
|
-
|
|
6898
|
-
|
|
6899
|
-
|
|
6900
|
-
|
|
6901
|
-
|
|
6902
|
-
|
|
6903
|
-
|
|
6904
|
-
|
|
6905
|
-
|
|
6906
|
-
|
|
6907
|
-
|
|
6908
|
-
|
|
6909
|
-
|
|
6910
|
-
|
|
6911
|
-
|
|
6912
|
-
|
|
6913
|
-
|
|
6914
|
-
|
|
6915
|
-
|
|
6916
|
-
|
|
6917
|
-
|
|
6918
|
-
|
|
6919
|
-
|
|
6920
|
-
|
|
6921
|
-
|
|
6922
|
-
|
|
6923
|
-
|
|
6924
|
-
|
|
6925
|
-
|
|
6926
|
-
|
|
6927
|
-
|
|
6928
|
-
function findFooterColumnForLink(anchor) {
|
|
6929
|
-
const columns = listFooterColumns();
|
|
6930
|
-
return columns.find((col) => col.contains(anchor)) ?? null;
|
|
6931
|
-
}
|
|
6932
|
-
function getFooterOrderFromDom() {
|
|
6933
|
-
return listFooterColumns().map(
|
|
6934
|
-
(col) => listFooterLinksInColumn(col).map((el) => el.getAttribute("data-ohw-href-key")).filter((key) => Boolean(key))
|
|
6935
|
-
);
|
|
6936
|
-
}
|
|
6937
|
-
function findFooterLinkByKey(hrefKey) {
|
|
6938
|
-
return document.querySelector(
|
|
6939
|
-
`footer [data-ohw-href-key="${CSS.escape(hrefKey)}"]`
|
|
6940
|
-
);
|
|
6941
|
-
}
|
|
6942
|
-
function syncFooterColumnIndices(columns) {
|
|
6943
|
-
columns.forEach((col, index) => {
|
|
6944
|
-
const next = String(index);
|
|
6945
|
-
if (col.getAttribute("data-ohw-footer-col") !== next) {
|
|
6946
|
-
col.setAttribute("data-ohw-footer-col", next);
|
|
6507
|
+
// src/ui/navbar-container-chrome.tsx
|
|
6508
|
+
var import_lucide_react10 = require("lucide-react");
|
|
6509
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
6510
|
+
function NavbarContainerChrome({
|
|
6511
|
+
rect,
|
|
6512
|
+
onAdd
|
|
6513
|
+
}) {
|
|
6514
|
+
const chromeGap = 6;
|
|
6515
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
6516
|
+
"div",
|
|
6517
|
+
{
|
|
6518
|
+
"data-ohw-navbar-container-chrome": "",
|
|
6519
|
+
"data-ohw-bridge": "",
|
|
6520
|
+
className: "pointer-events-none fixed z-[2147483647]",
|
|
6521
|
+
style: {
|
|
6522
|
+
top: rect.top - chromeGap,
|
|
6523
|
+
left: rect.left - chromeGap,
|
|
6524
|
+
width: rect.width + chromeGap * 2,
|
|
6525
|
+
height: rect.height + chromeGap * 2
|
|
6526
|
+
},
|
|
6527
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
6528
|
+
"button",
|
|
6529
|
+
{
|
|
6530
|
+
type: "button",
|
|
6531
|
+
"data-ohw-navbar-add-button": "",
|
|
6532
|
+
className: "pointer-events-auto absolute left-1/2 flex p-0.5 rounded-[10px] size-7 -translate-x-1/2 translate-y-1/2 items-center justify-center border border-border bg-background shadow-sm transition-colors hover:bg-muted/80",
|
|
6533
|
+
style: { top: "70%" },
|
|
6534
|
+
"aria-label": "Add item",
|
|
6535
|
+
onMouseDown: (e) => {
|
|
6536
|
+
e.preventDefault();
|
|
6537
|
+
e.stopPropagation();
|
|
6538
|
+
},
|
|
6539
|
+
onClick: (e) => {
|
|
6540
|
+
e.preventDefault();
|
|
6541
|
+
e.stopPropagation();
|
|
6542
|
+
onAdd();
|
|
6543
|
+
},
|
|
6544
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react10.Plus, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
|
|
6545
|
+
}
|
|
6546
|
+
)
|
|
6947
6547
|
}
|
|
6948
|
-
|
|
6949
|
-
}
|
|
6950
|
-
function appendChildIfNeeded(parent, child) {
|
|
6951
|
-
if (parent.lastElementChild !== child) {
|
|
6952
|
-
parent.appendChild(child);
|
|
6953
|
-
}
|
|
6548
|
+
);
|
|
6954
6549
|
}
|
|
6955
|
-
|
|
6956
|
-
|
|
6957
|
-
|
|
6958
|
-
|
|
6959
|
-
|
|
6960
|
-
|
|
6961
|
-
|
|
6962
|
-
|
|
6963
|
-
|
|
6964
|
-
|
|
6965
|
-
|
|
6966
|
-
|
|
6967
|
-
for (const colOrder of order) {
|
|
6968
|
-
let matched = null;
|
|
6969
|
-
for (const hrefKey of colOrder) {
|
|
6970
|
-
const link = findFooterLinkByKey(hrefKey);
|
|
6971
|
-
if (!link) continue;
|
|
6972
|
-
const owner = findFooterColumnForLink(link);
|
|
6973
|
-
if (owner && !used.has(owner)) {
|
|
6974
|
-
matched = owner;
|
|
6975
|
-
break;
|
|
6976
|
-
}
|
|
6977
|
-
}
|
|
6978
|
-
if (!matched) {
|
|
6979
|
-
matched = columns.find((col) => !used.has(col)) ?? null;
|
|
6980
|
-
}
|
|
6981
|
-
if (matched) {
|
|
6982
|
-
used.add(matched);
|
|
6983
|
-
orderedCols.push(matched);
|
|
6984
|
-
}
|
|
6985
|
-
}
|
|
6986
|
-
for (const col of columns) {
|
|
6987
|
-
if (!used.has(col)) orderedCols.push(col);
|
|
6988
|
-
}
|
|
6989
|
-
for (const col of orderedCols) {
|
|
6990
|
-
appendChildIfNeeded(container, col);
|
|
6991
|
-
}
|
|
6992
|
-
const freshColumns = listFooterColumns();
|
|
6993
|
-
syncFooterColumnIndices(freshColumns);
|
|
6994
|
-
for (let c = 0; c < order.length; c++) {
|
|
6995
|
-
const col = freshColumns[c];
|
|
6996
|
-
if (!col) continue;
|
|
6997
|
-
const colOrder = order[c];
|
|
6998
|
-
for (const hrefKey of colOrder) {
|
|
6999
|
-
const el = findFooterLinkByKey(hrefKey);
|
|
7000
|
-
if (!el) continue;
|
|
7001
|
-
if (el.parentElement !== col || col.lastElementChild !== el) {
|
|
7002
|
-
col.appendChild(el);
|
|
6550
|
+
|
|
6551
|
+
// src/ui/badge.tsx
|
|
6552
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
6553
|
+
var badgeVariants = cva(
|
|
6554
|
+
"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",
|
|
6555
|
+
{
|
|
6556
|
+
variants: {
|
|
6557
|
+
variant: {
|
|
6558
|
+
default: "border-transparent bg-primary text-primary-foreground",
|
|
6559
|
+
secondary: "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
6560
|
+
destructive: "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",
|
|
6561
|
+
outline: "text-foreground"
|
|
7003
6562
|
}
|
|
6563
|
+
},
|
|
6564
|
+
defaultVariants: {
|
|
6565
|
+
variant: "default"
|
|
7004
6566
|
}
|
|
7005
6567
|
}
|
|
7006
|
-
|
|
7007
|
-
function
|
|
7008
|
-
|
|
7009
|
-
for (let i = 0; i < a.length; i++) {
|
|
7010
|
-
const left = a[i];
|
|
7011
|
-
const right = b[i];
|
|
7012
|
-
if (left.length !== right.length) return false;
|
|
7013
|
-
for (let j = 0; j < left.length; j++) {
|
|
7014
|
-
if (left[j] !== right[j]) return false;
|
|
7015
|
-
}
|
|
7016
|
-
}
|
|
7017
|
-
return true;
|
|
7018
|
-
}
|
|
7019
|
-
function planFooterLinkMove(hrefKey, targetColIndex, insertIndex) {
|
|
7020
|
-
const order = getFooterOrderFromDom();
|
|
7021
|
-
if (targetColIndex < 0 || targetColIndex >= order.length) return null;
|
|
7022
|
-
let fromCol = -1;
|
|
7023
|
-
let fromIdx = -1;
|
|
7024
|
-
for (let c = 0; c < order.length; c++) {
|
|
7025
|
-
const idx = order[c].indexOf(hrefKey);
|
|
7026
|
-
if (idx >= 0) {
|
|
7027
|
-
fromCol = c;
|
|
7028
|
-
fromIdx = idx;
|
|
7029
|
-
break;
|
|
7030
|
-
}
|
|
7031
|
-
}
|
|
7032
|
-
if (fromCol < 0) return null;
|
|
7033
|
-
const next = order.map((col) => [...col]);
|
|
7034
|
-
next[fromCol].splice(fromIdx, 1);
|
|
7035
|
-
let adjusted = insertIndex;
|
|
7036
|
-
if (fromCol === targetColIndex && fromIdx < insertIndex) adjusted -= 1;
|
|
7037
|
-
adjusted = Math.max(0, Math.min(adjusted, next[targetColIndex].length));
|
|
7038
|
-
next[targetColIndex].splice(adjusted, 0, hrefKey);
|
|
7039
|
-
if (ordersEqual(next, order)) return null;
|
|
7040
|
-
return next;
|
|
7041
|
-
}
|
|
7042
|
-
function planFooterColumnMove(fromIndex, toIndex) {
|
|
7043
|
-
const order = getFooterOrderFromDom();
|
|
7044
|
-
const columns = listFooterColumns();
|
|
7045
|
-
if (fromIndex < 0 || fromIndex >= columns.length || toIndex < 0 || toIndex > columns.length) {
|
|
7046
|
-
return null;
|
|
7047
|
-
}
|
|
7048
|
-
if (toIndex === fromIndex || toIndex === fromIndex + 1) return null;
|
|
7049
|
-
const nextOrder = order.map((col) => [...col]);
|
|
7050
|
-
const [movedOrder] = nextOrder.splice(fromIndex, 1);
|
|
7051
|
-
if (!movedOrder) return null;
|
|
7052
|
-
let adjusted = toIndex;
|
|
7053
|
-
if (fromIndex < toIndex) adjusted -= 1;
|
|
7054
|
-
adjusted = Math.max(0, Math.min(adjusted, nextOrder.length));
|
|
7055
|
-
nextOrder.splice(adjusted, 0, movedOrder);
|
|
7056
|
-
if (ordersEqual(nextOrder, order)) return null;
|
|
7057
|
-
return nextOrder;
|
|
7058
|
-
}
|
|
7059
|
-
function parseFooterOrder(content) {
|
|
7060
|
-
const raw = content[FOOTER_ORDER_KEY];
|
|
7061
|
-
if (!raw) return null;
|
|
7062
|
-
try {
|
|
7063
|
-
const parsed = JSON.parse(raw);
|
|
7064
|
-
if (!Array.isArray(parsed)) return null;
|
|
7065
|
-
return parsed.filter((col) => Array.isArray(col)).map((col) => col.filter((key) => typeof key === "string" && key.length > 0));
|
|
7066
|
-
} catch {
|
|
7067
|
-
return null;
|
|
7068
|
-
}
|
|
7069
|
-
}
|
|
7070
|
-
function reconcileFooterOrderFromContent(content) {
|
|
7071
|
-
const order = parseFooterOrder(content);
|
|
7072
|
-
if (!order?.length) return;
|
|
7073
|
-
const current = getFooterOrderFromDom();
|
|
7074
|
-
if (ordersEqual(order, current)) {
|
|
7075
|
-
syncFooterColumnIndices(listFooterColumns());
|
|
7076
|
-
return;
|
|
7077
|
-
}
|
|
7078
|
-
applyFooterOrder(order);
|
|
7079
|
-
}
|
|
7080
|
-
function isRowLayoutColumn(links) {
|
|
7081
|
-
if (links.length < 2) return false;
|
|
7082
|
-
const firstTop = links[0].getBoundingClientRect().top;
|
|
7083
|
-
return links.every((link) => Math.abs(link.getBoundingClientRect().top - firstTop) < 4);
|
|
7084
|
-
}
|
|
7085
|
-
function buildLinkDropSlots(column, columnIndex) {
|
|
7086
|
-
const links = listFooterLinksInColumn(column);
|
|
7087
|
-
const colRect = column.getBoundingClientRect();
|
|
7088
|
-
const slots = [];
|
|
7089
|
-
const barThickness = 3;
|
|
7090
|
-
if (links.length === 0) {
|
|
7091
|
-
slots.push({
|
|
7092
|
-
insertIndex: 0,
|
|
7093
|
-
columnIndex,
|
|
7094
|
-
left: colRect.left,
|
|
7095
|
-
top: colRect.top + colRect.height / 2 - barThickness / 2,
|
|
7096
|
-
width: colRect.width,
|
|
7097
|
-
height: barThickness,
|
|
7098
|
-
direction: "horizontal"
|
|
7099
|
-
});
|
|
7100
|
-
return slots;
|
|
7101
|
-
}
|
|
7102
|
-
if (isRowLayoutColumn(links)) {
|
|
7103
|
-
for (let i = 0; i <= links.length; i++) {
|
|
7104
|
-
let left;
|
|
7105
|
-
if (i === 0) {
|
|
7106
|
-
left = links[0].getBoundingClientRect().left - barThickness / 2;
|
|
7107
|
-
} else if (i === links.length) {
|
|
7108
|
-
const last = links[links.length - 1].getBoundingClientRect();
|
|
7109
|
-
left = last.right - barThickness / 2;
|
|
7110
|
-
} else {
|
|
7111
|
-
const prev = links[i - 1].getBoundingClientRect();
|
|
7112
|
-
const next = links[i].getBoundingClientRect();
|
|
7113
|
-
left = (prev.right + next.left) / 2 - barThickness / 2;
|
|
7114
|
-
}
|
|
7115
|
-
const heightRef = i === 0 ? links[0].getBoundingClientRect() : i === links.length ? links[links.length - 1].getBoundingClientRect() : links[i].getBoundingClientRect();
|
|
7116
|
-
slots.push({
|
|
7117
|
-
insertIndex: i,
|
|
7118
|
-
columnIndex,
|
|
7119
|
-
left,
|
|
7120
|
-
top: heightRef.top,
|
|
7121
|
-
width: barThickness,
|
|
7122
|
-
height: Math.max(heightRef.height, colRect.height * 0.8),
|
|
7123
|
-
direction: "vertical"
|
|
7124
|
-
});
|
|
7125
|
-
}
|
|
7126
|
-
return slots;
|
|
7127
|
-
}
|
|
7128
|
-
for (let i = 0; i <= links.length; i++) {
|
|
7129
|
-
let top;
|
|
7130
|
-
if (i === 0) {
|
|
7131
|
-
top = links[0].getBoundingClientRect().top - barThickness / 2;
|
|
7132
|
-
} else if (i === links.length) {
|
|
7133
|
-
const last = links[links.length - 1].getBoundingClientRect();
|
|
7134
|
-
top = last.bottom - barThickness / 2;
|
|
7135
|
-
} else {
|
|
7136
|
-
const prev = links[i - 1].getBoundingClientRect();
|
|
7137
|
-
const next = links[i].getBoundingClientRect();
|
|
7138
|
-
top = (prev.bottom + next.top) / 2 - barThickness / 2;
|
|
7139
|
-
}
|
|
7140
|
-
const widthRef = i === 0 ? links[0].getBoundingClientRect() : i === links.length ? links[links.length - 1].getBoundingClientRect() : links[i].getBoundingClientRect();
|
|
7141
|
-
slots.push({
|
|
7142
|
-
insertIndex: i,
|
|
7143
|
-
columnIndex,
|
|
7144
|
-
left: widthRef.left,
|
|
7145
|
-
top,
|
|
7146
|
-
width: Math.max(widthRef.width, colRect.width * 0.8),
|
|
7147
|
-
height: barThickness,
|
|
7148
|
-
direction: "horizontal"
|
|
7149
|
-
});
|
|
7150
|
-
}
|
|
7151
|
-
return slots;
|
|
7152
|
-
}
|
|
7153
|
-
function buildColumnDropSlots() {
|
|
7154
|
-
const columns = listFooterColumns();
|
|
7155
|
-
const slots = [];
|
|
7156
|
-
const barThickness = 3;
|
|
7157
|
-
if (columns.length === 0) return slots;
|
|
7158
|
-
for (let i = 0; i <= columns.length; i++) {
|
|
7159
|
-
let left;
|
|
7160
|
-
let height;
|
|
7161
|
-
let top;
|
|
7162
|
-
if (i === 0) {
|
|
7163
|
-
const first = columns[0].getBoundingClientRect();
|
|
7164
|
-
left = first.left - barThickness / 2;
|
|
7165
|
-
top = first.top;
|
|
7166
|
-
height = first.height;
|
|
7167
|
-
} else if (i === columns.length) {
|
|
7168
|
-
const last = columns[columns.length - 1].getBoundingClientRect();
|
|
7169
|
-
left = last.right - barThickness / 2;
|
|
7170
|
-
top = last.top;
|
|
7171
|
-
height = last.height;
|
|
7172
|
-
} else {
|
|
7173
|
-
const prev = columns[i - 1].getBoundingClientRect();
|
|
7174
|
-
const next = columns[i].getBoundingClientRect();
|
|
7175
|
-
left = (prev.right + next.left) / 2 - barThickness / 2;
|
|
7176
|
-
top = Math.min(prev.top, next.top);
|
|
7177
|
-
height = Math.max(prev.bottom, next.bottom) - top;
|
|
7178
|
-
}
|
|
7179
|
-
slots.push({
|
|
7180
|
-
insertIndex: i,
|
|
7181
|
-
columnIndex: i,
|
|
7182
|
-
left,
|
|
7183
|
-
top,
|
|
7184
|
-
width: barThickness,
|
|
7185
|
-
height: Math.max(height, 24),
|
|
7186
|
-
direction: "vertical"
|
|
7187
|
-
});
|
|
7188
|
-
}
|
|
7189
|
-
return slots;
|
|
7190
|
-
}
|
|
7191
|
-
function hitTestLinkDropSlot(clientX, clientY, draggedHrefKey) {
|
|
7192
|
-
const columns = listFooterColumns();
|
|
7193
|
-
let best = null;
|
|
7194
|
-
for (let c = 0; c < columns.length; c++) {
|
|
7195
|
-
const col = columns[c];
|
|
7196
|
-
const colRect = col.getBoundingClientRect();
|
|
7197
|
-
const inColX = clientX >= colRect.left - 24 && clientX <= colRect.right + 24;
|
|
7198
|
-
if (!inColX) continue;
|
|
7199
|
-
const slots = buildLinkDropSlots(col, c).filter((slot) => {
|
|
7200
|
-
const links = listFooterLinksInColumn(col);
|
|
7201
|
-
const fromIdx = links.findIndex(
|
|
7202
|
-
(el) => el.getAttribute("data-ohw-href-key") === draggedHrefKey
|
|
7203
|
-
);
|
|
7204
|
-
if (fromIdx < 0) return true;
|
|
7205
|
-
if (c === findColumnIndexForKey(draggedHrefKey) && (slot.insertIndex === fromIdx || slot.insertIndex === fromIdx + 1)) {
|
|
7206
|
-
return true;
|
|
7207
|
-
}
|
|
7208
|
-
return true;
|
|
7209
|
-
});
|
|
7210
|
-
for (const slot of slots) {
|
|
7211
|
-
const dist = slot.direction === "vertical" ? Math.abs(clientX - (slot.left + slot.width / 2)) : Math.abs(clientY - (slot.top + slot.height / 2));
|
|
7212
|
-
if (!best || dist < best.dist) best = { slot, dist };
|
|
7213
|
-
}
|
|
7214
|
-
}
|
|
7215
|
-
return best?.slot ?? null;
|
|
7216
|
-
}
|
|
7217
|
-
function findColumnIndexForKey(hrefKey) {
|
|
7218
|
-
const order = getFooterOrderFromDom();
|
|
7219
|
-
for (let c = 0; c < order.length; c++) {
|
|
7220
|
-
if (order[c].includes(hrefKey)) return c;
|
|
7221
|
-
}
|
|
7222
|
-
return -1;
|
|
7223
|
-
}
|
|
7224
|
-
function hitTestColumnDropSlot(clientX, _clientY) {
|
|
7225
|
-
const slots = buildColumnDropSlots();
|
|
7226
|
-
let best = null;
|
|
7227
|
-
for (const slot of slots) {
|
|
7228
|
-
const cx2 = slot.left + slot.width / 2;
|
|
7229
|
-
const dist = Math.abs(clientX - cx2);
|
|
7230
|
-
if (!best || dist < best.dist) best = { slot, dist };
|
|
7231
|
-
}
|
|
7232
|
-
return best?.slot ?? null;
|
|
7233
|
-
}
|
|
7234
|
-
|
|
7235
|
-
// src/lib/item-drag-interaction.ts
|
|
7236
|
-
function disableNativeHrefDrag(el) {
|
|
7237
|
-
if (el.draggable) el.draggable = false;
|
|
7238
|
-
if (el.getAttribute("draggable") !== "false") {
|
|
7239
|
-
el.setAttribute("draggable", "false");
|
|
7240
|
-
}
|
|
7241
|
-
}
|
|
7242
|
-
function clearTextSelection() {
|
|
7243
|
-
const sel = window.getSelection();
|
|
7244
|
-
if (sel && !sel.isCollapsed) sel.removeAllRanges();
|
|
7245
|
-
}
|
|
7246
|
-
function armItemPressDrag() {
|
|
7247
|
-
document.documentElement.setAttribute("data-ohw-footer-press-drag", "");
|
|
7248
|
-
}
|
|
7249
|
-
function lockItemDuringDrag() {
|
|
7250
|
-
document.documentElement.removeAttribute("data-ohw-footer-press-drag");
|
|
7251
|
-
document.documentElement.setAttribute("data-ohw-item-dragging", "");
|
|
7252
|
-
clearTextSelection();
|
|
7253
|
-
}
|
|
7254
|
-
function unlockItemDragInteraction() {
|
|
7255
|
-
document.documentElement.removeAttribute("data-ohw-footer-press-drag");
|
|
7256
|
-
document.documentElement.removeAttribute("data-ohw-item-dragging");
|
|
7257
|
-
clearTextSelection();
|
|
7258
|
-
}
|
|
7259
|
-
var armFooterPressDrag = armItemPressDrag;
|
|
7260
|
-
var lockFooterDuringDrag = lockItemDuringDrag;
|
|
7261
|
-
var unlockFooterDragInteraction = unlockItemDragInteraction;
|
|
7262
|
-
|
|
7263
|
-
// src/lib/nav-dnd.ts
|
|
7264
|
-
function listReorderableNavItems() {
|
|
7265
|
-
return listNavbarItems().filter((el) => {
|
|
7266
|
-
const key = el.getAttribute("data-ohw-href-key");
|
|
7267
|
-
return isNavbarHrefKey(key) && !el.closest("[data-ohw-nav-children]");
|
|
7268
|
-
});
|
|
7269
|
-
}
|
|
7270
|
-
function listNavChildren(parentHrefKey) {
|
|
7271
|
-
const items = listNavbarItems();
|
|
7272
|
-
const parent = items.find((el) => el.getAttribute("data-ohw-href-key") === parentHrefKey);
|
|
7273
|
-
if (!parent) return [];
|
|
7274
|
-
const group = parent.closest("[data-ohw-nav-group]");
|
|
7275
|
-
const childrenRoot = group?.querySelector(":scope > [data-ohw-nav-children]");
|
|
7276
|
-
if (!childrenRoot) return [];
|
|
7277
|
-
return Array.from(childrenRoot.querySelectorAll(":scope > [data-ohw-href-key]")).filter(
|
|
7278
|
-
(el) => isNavbarHrefKey(el.getAttribute("data-ohw-href-key"))
|
|
7279
|
-
);
|
|
7280
|
-
}
|
|
7281
|
-
function activeNavListContainer() {
|
|
7282
|
-
const desktop = getNavbarDesktopContainer();
|
|
7283
|
-
if (desktop && desktop.getClientRects().length > 0) {
|
|
7284
|
-
const style = window.getComputedStyle(desktop);
|
|
7285
|
-
if (style.display !== "none" && style.visibility !== "hidden") return desktop;
|
|
7286
|
-
}
|
|
7287
|
-
return getNavbarDrawerContainer();
|
|
7288
|
-
}
|
|
7289
|
-
function buildRootNavDropSlots() {
|
|
7290
|
-
const items = listReorderableNavItems();
|
|
7291
|
-
const slots = [];
|
|
7292
|
-
const barThickness = 3;
|
|
7293
|
-
if (items.length === 0) {
|
|
7294
|
-
const container = activeNavListContainer();
|
|
7295
|
-
if (!container) return slots;
|
|
7296
|
-
const rect = container.getBoundingClientRect();
|
|
7297
|
-
slots.push({
|
|
7298
|
-
insertIndex: 0,
|
|
7299
|
-
parentId: null,
|
|
7300
|
-
left: rect.left + rect.width / 2 - barThickness / 2,
|
|
7301
|
-
top: rect.top,
|
|
7302
|
-
width: barThickness,
|
|
7303
|
-
height: Math.max(rect.height, 24),
|
|
7304
|
-
direction: "vertical"
|
|
7305
|
-
});
|
|
7306
|
-
return slots;
|
|
7307
|
-
}
|
|
7308
|
-
for (let i = 0; i <= items.length; i++) {
|
|
7309
|
-
let left;
|
|
7310
|
-
let top;
|
|
7311
|
-
let height;
|
|
7312
|
-
if (i === 0) {
|
|
7313
|
-
const first = items[0].getBoundingClientRect();
|
|
7314
|
-
left = first.left - barThickness / 2;
|
|
7315
|
-
top = first.top;
|
|
7316
|
-
height = first.height;
|
|
7317
|
-
} else if (i === items.length) {
|
|
7318
|
-
const last = items[items.length - 1].getBoundingClientRect();
|
|
7319
|
-
left = last.right - barThickness / 2;
|
|
7320
|
-
top = last.top;
|
|
7321
|
-
height = last.height;
|
|
7322
|
-
} else {
|
|
7323
|
-
const prev = items[i - 1].getBoundingClientRect();
|
|
7324
|
-
const next = items[i].getBoundingClientRect();
|
|
7325
|
-
left = (prev.right + next.left) / 2 - barThickness / 2;
|
|
7326
|
-
top = Math.min(prev.top, next.top);
|
|
7327
|
-
height = Math.max(prev.bottom, next.bottom) - top;
|
|
7328
|
-
}
|
|
7329
|
-
slots.push({
|
|
7330
|
-
insertIndex: i,
|
|
7331
|
-
parentId: null,
|
|
7332
|
-
left,
|
|
7333
|
-
top,
|
|
7334
|
-
width: barThickness,
|
|
7335
|
-
height: Math.max(height, 24),
|
|
7336
|
-
direction: "vertical"
|
|
7337
|
-
});
|
|
7338
|
-
}
|
|
7339
|
-
return slots;
|
|
7340
|
-
}
|
|
7341
|
-
function buildChildNavDropSlots(parentHrefKey) {
|
|
7342
|
-
const children = listNavChildren(parentHrefKey);
|
|
7343
|
-
const slots = [];
|
|
7344
|
-
const barThickness = 3;
|
|
7345
|
-
if (children.length === 0) return slots;
|
|
7346
|
-
for (let i = 0; i <= children.length; i++) {
|
|
7347
|
-
let top;
|
|
7348
|
-
let width;
|
|
7349
|
-
let left;
|
|
7350
|
-
if (i === 0) {
|
|
7351
|
-
const first = children[0].getBoundingClientRect();
|
|
7352
|
-
top = first.top - barThickness / 2;
|
|
7353
|
-
left = first.left;
|
|
7354
|
-
width = first.width;
|
|
7355
|
-
} else if (i === children.length) {
|
|
7356
|
-
const last = children[children.length - 1].getBoundingClientRect();
|
|
7357
|
-
top = last.bottom - barThickness / 2;
|
|
7358
|
-
left = last.left;
|
|
7359
|
-
width = last.width;
|
|
7360
|
-
} else {
|
|
7361
|
-
const prev = children[i - 1].getBoundingClientRect();
|
|
7362
|
-
const next = children[i].getBoundingClientRect();
|
|
7363
|
-
top = (prev.bottom + next.top) / 2 - barThickness / 2;
|
|
7364
|
-
left = Math.min(prev.left, next.left);
|
|
7365
|
-
width = Math.max(prev.right, next.right) - left;
|
|
7366
|
-
}
|
|
7367
|
-
slots.push({
|
|
7368
|
-
insertIndex: i,
|
|
7369
|
-
parentId: parentHrefKey,
|
|
7370
|
-
left,
|
|
7371
|
-
top,
|
|
7372
|
-
width: Math.max(width, 40),
|
|
7373
|
-
height: barThickness,
|
|
7374
|
-
direction: "horizontal"
|
|
7375
|
-
});
|
|
7376
|
-
}
|
|
7377
|
-
return slots;
|
|
7378
|
-
}
|
|
7379
|
-
function buildAllNavDropSlots(draggedHrefKey) {
|
|
7380
|
-
const slots = [...buildRootNavDropSlots()];
|
|
7381
|
-
for (const item of listReorderableNavItems()) {
|
|
7382
|
-
const key = item.getAttribute("data-ohw-href-key");
|
|
7383
|
-
if (!key || key === draggedHrefKey) continue;
|
|
7384
|
-
const group = item.closest("[data-ohw-nav-group]");
|
|
7385
|
-
if (!group?.querySelector(":scope > [data-ohw-nav-children]")) continue;
|
|
7386
|
-
slots.push(...buildChildNavDropSlots(key));
|
|
7387
|
-
}
|
|
7388
|
-
const dragged = listNavbarItems().find((el) => el.getAttribute("data-ohw-href-key") === draggedHrefKey);
|
|
7389
|
-
const parentGroup = dragged?.closest("[data-ohw-nav-children]")?.closest("[data-ohw-nav-group]");
|
|
7390
|
-
const parentTrigger = parentGroup?.querySelector(":scope > [data-ohw-href-key]");
|
|
7391
|
-
const parentKey = parentTrigger?.getAttribute("data-ohw-href-key");
|
|
7392
|
-
if (parentKey && isNavbarHrefKey(parentKey)) {
|
|
7393
|
-
const existing = slots.some((s) => s.parentId === parentKey);
|
|
7394
|
-
if (!existing) slots.push(...buildChildNavDropSlots(parentKey));
|
|
7395
|
-
}
|
|
7396
|
-
return slots;
|
|
7397
|
-
}
|
|
7398
|
-
function hitTestNavDropSlot(clientX, clientY, draggedHrefKey) {
|
|
7399
|
-
const slots = buildAllNavDropSlots(draggedHrefKey);
|
|
7400
|
-
let best = null;
|
|
7401
|
-
for (const slot of slots) {
|
|
7402
|
-
const cx2 = slot.left + slot.width / 2;
|
|
7403
|
-
const cy = slot.top + slot.height / 2;
|
|
7404
|
-
const dist = slot.direction === "vertical" ? Math.abs(clientX - cx2) + Math.abs(clientY - cy) * 0.25 : Math.abs(clientY - cy) + Math.abs(clientX - cx2) * 0.25;
|
|
7405
|
-
if (!best || dist < best.dist) best = { slot, dist };
|
|
7406
|
-
}
|
|
7407
|
-
return best?.slot ?? null;
|
|
7408
|
-
}
|
|
7409
|
-
function siblingRectsForNavDrag(draggedEl, activeParentId) {
|
|
7410
|
-
if (activeParentId) {
|
|
7411
|
-
return listNavChildren(activeParentId).filter((el) => el !== draggedEl).map((el) => el.getBoundingClientRect());
|
|
7412
|
-
}
|
|
7413
|
-
return listReorderableNavItems().filter((el) => el !== draggedEl).map((el) => el.getBoundingClientRect());
|
|
7414
|
-
}
|
|
7415
|
-
|
|
7416
|
-
// src/useNavItemDrag.ts
|
|
7417
|
-
var import_react8 = require("react");
|
|
7418
|
-
function useNavItemDrag({
|
|
7419
|
-
isEditMode,
|
|
7420
|
-
editContentRef,
|
|
7421
|
-
selectedElRef,
|
|
7422
|
-
activeElRef,
|
|
7423
|
-
footerDragRef,
|
|
7424
|
-
suppressNextClickRef,
|
|
7425
|
-
suppressClickUntilRef,
|
|
7426
|
-
siblingHintElRef,
|
|
7427
|
-
postToParentRef,
|
|
7428
|
-
deselectRef,
|
|
7429
|
-
selectRef,
|
|
7430
|
-
deactivateRef,
|
|
7431
|
-
setLinkPopover,
|
|
7432
|
-
linkPopoverOpenRef,
|
|
7433
|
-
setIsItemDragging,
|
|
7434
|
-
setDraggedItemRect,
|
|
7435
|
-
setSiblingHintRect,
|
|
7436
|
-
setSiblingHintRects,
|
|
7437
|
-
setToolbarRect,
|
|
7438
|
-
getNavigationItemAnchor: getNavigationItemAnchor2,
|
|
7439
|
-
isDragHandleDisabled: isDragHandleDisabled2,
|
|
7440
|
-
isNavbarButton: isNavbarButton3
|
|
7441
|
-
}) {
|
|
7442
|
-
const navDragRef = (0, import_react8.useRef)(null);
|
|
7443
|
-
const [navDropSlots, setNavDropSlots] = (0, import_react8.useState)([]);
|
|
7444
|
-
const [activeNavDropIndex, setActiveNavDropIndex] = (0, import_react8.useState)(null);
|
|
7445
|
-
const navPointerDragRef = (0, import_react8.useRef)(null);
|
|
7446
|
-
const clearNavDragVisuals = (0, import_react8.useCallback)(() => {
|
|
7447
|
-
navDragRef.current = null;
|
|
7448
|
-
setNavDropSlots([]);
|
|
7449
|
-
setActiveNavDropIndex(null);
|
|
7450
|
-
setDraggedItemRect(null);
|
|
7451
|
-
setSiblingHintRects([]);
|
|
7452
|
-
setIsItemDragging(false);
|
|
7453
|
-
unlockItemDragInteraction();
|
|
7454
|
-
}, [setDraggedItemRect, setIsItemDragging, setSiblingHintRects]);
|
|
7455
|
-
const refreshNavDragVisuals = (0, import_react8.useCallback)(
|
|
7456
|
-
(session, activeSlot, clientX, clientY) => {
|
|
7457
|
-
setDraggedItemRect(session.draggedEl.getBoundingClientRect());
|
|
7458
|
-
if (typeof clientX === "number" && typeof clientY === "number") {
|
|
7459
|
-
session.lastClientX = clientX;
|
|
7460
|
-
session.lastClientY = clientY;
|
|
7461
|
-
}
|
|
7462
|
-
session.activeSlot = activeSlot;
|
|
7463
|
-
const parentId = activeSlot?.parentId ?? null;
|
|
7464
|
-
setSiblingHintRects(siblingRectsForNavDrag(session.draggedEl, parentId));
|
|
7465
|
-
const slots = buildAllNavDropSlots(session.hrefKey);
|
|
7466
|
-
setNavDropSlots(slots);
|
|
7467
|
-
const activeIdx = activeSlot ? slots.findIndex(
|
|
7468
|
-
(s) => s.parentId === activeSlot.parentId && s.insertIndex === activeSlot.insertIndex
|
|
7469
|
-
) : -1;
|
|
7470
|
-
setActiveNavDropIndex(activeIdx >= 0 ? activeIdx : null);
|
|
7471
|
-
},
|
|
7472
|
-
[setDraggedItemRect, setSiblingHintRects]
|
|
7473
|
-
);
|
|
7474
|
-
const refreshNavDragVisualsRef = (0, import_react8.useRef)(refreshNavDragVisuals);
|
|
7475
|
-
refreshNavDragVisualsRef.current = refreshNavDragVisuals;
|
|
7476
|
-
const commitNavDragRef = (0, import_react8.useRef)(() => {
|
|
7477
|
-
});
|
|
7478
|
-
const beginNavDragRef = (0, import_react8.useRef)(() => {
|
|
7479
|
-
});
|
|
7480
|
-
const beginNavDrag = (0, import_react8.useCallback)(
|
|
7481
|
-
(session) => {
|
|
7482
|
-
const rect = session.draggedEl.getBoundingClientRect();
|
|
7483
|
-
session.lastClientX = session.lastClientX || rect.left + rect.width / 2;
|
|
7484
|
-
session.lastClientY = session.lastClientY || rect.top + rect.height / 2;
|
|
7485
|
-
session.activeSlot = session.activeSlot ?? null;
|
|
7486
|
-
navDragRef.current = session;
|
|
7487
|
-
setIsItemDragging(true);
|
|
7488
|
-
lockItemDuringDrag();
|
|
7489
|
-
siblingHintElRef.current = null;
|
|
7490
|
-
setSiblingHintRect(null);
|
|
7491
|
-
if (session.wasSelected && selectedElRef.current === session.draggedEl) {
|
|
7492
|
-
setToolbarRect(rect);
|
|
7493
|
-
}
|
|
7494
|
-
const initialSlot = hitTestNavDropSlot(session.lastClientX, session.lastClientY, session.hrefKey);
|
|
7495
|
-
refreshNavDragVisuals(session, initialSlot, session.lastClientX, session.lastClientY);
|
|
7496
|
-
},
|
|
7497
|
-
[
|
|
7498
|
-
refreshNavDragVisuals,
|
|
7499
|
-
selectedElRef,
|
|
7500
|
-
setIsItemDragging,
|
|
7501
|
-
setSiblingHintRect,
|
|
7502
|
-
setToolbarRect,
|
|
7503
|
-
siblingHintElRef
|
|
7504
|
-
]
|
|
7505
|
-
);
|
|
7506
|
-
beginNavDragRef.current = beginNavDrag;
|
|
7507
|
-
const commitNavDrag = (0, import_react8.useCallback)(
|
|
7508
|
-
(clientX, clientY) => {
|
|
7509
|
-
const session = navDragRef.current;
|
|
7510
|
-
if (!session) {
|
|
7511
|
-
clearNavDragVisuals();
|
|
7512
|
-
return;
|
|
7513
|
-
}
|
|
7514
|
-
const x = typeof clientX === "number" && (clientX !== 0 || clientY !== 0) ? clientX : session.lastClientX;
|
|
7515
|
-
const y = typeof clientY === "number" && (clientX !== 0 || clientY !== 0) ? clientY : session.lastClientY;
|
|
7516
|
-
const slot = session.activeSlot ?? hitTestNavDropSlot(x, y, session.hrefKey);
|
|
7517
|
-
const planned = slot != null ? planNavItemMove(session.hrefKey, slot.parentId, slot.insertIndex) : null;
|
|
7518
|
-
const wasSelected = session.wasSelected;
|
|
7519
|
-
const hrefKey = session.hrefKey;
|
|
7520
|
-
const applySelectionAfterDrop = () => {
|
|
7521
|
-
if (!wasSelected) {
|
|
7522
|
-
deselectRef.current();
|
|
7523
|
-
return;
|
|
7524
|
-
}
|
|
7525
|
-
const desktop = document.querySelector("[data-ohw-nav-container]");
|
|
7526
|
-
const drawer = document.querySelector("[data-ohw-nav-drawer]");
|
|
7527
|
-
const link = desktop?.querySelector(`[data-ohw-href-key="${CSS.escape(hrefKey)}"]`) ?? drawer?.querySelector(`[data-ohw-href-key="${CSS.escape(hrefKey)}"]`) ?? document.querySelector(`[data-ohw-href-key="${CSS.escape(hrefKey)}"]`);
|
|
7528
|
-
if (link) {
|
|
7529
|
-
selectRef.current(link);
|
|
7530
|
-
return;
|
|
7531
|
-
}
|
|
7532
|
-
deselectRef.current();
|
|
7533
|
-
};
|
|
7534
|
-
if (planned) {
|
|
7535
|
-
editContentRef.current = {
|
|
7536
|
-
...editContentRef.current,
|
|
7537
|
-
[NAV_ORDER_KEY]: planned.orderJson
|
|
7538
|
-
};
|
|
7539
|
-
applyNavForest(planned.forest);
|
|
7540
|
-
document.querySelectorAll(
|
|
7541
|
-
"nav [data-ohw-href-key], [data-ohw-nav-container] [data-ohw-href-key], [data-ohw-nav-drawer] [data-ohw-href-key]"
|
|
7542
|
-
).forEach((el) => {
|
|
7543
|
-
if (isNavbarHrefKey(el.getAttribute("data-ohw-href-key"))) {
|
|
7544
|
-
disableNativeHrefDrag(el);
|
|
7545
|
-
}
|
|
7546
|
-
});
|
|
7547
|
-
postToParentRef.current({
|
|
7548
|
-
type: "ow:change",
|
|
7549
|
-
nodes: [{ key: NAV_ORDER_KEY, text: planned.orderJson }]
|
|
7550
|
-
});
|
|
7551
|
-
applySelectionAfterDrop();
|
|
7552
|
-
clearNavDragVisuals();
|
|
7553
|
-
requestAnimationFrame(() => {
|
|
7554
|
-
if (editContentRef.current[NAV_ORDER_KEY] === planned.orderJson) {
|
|
7555
|
-
applyNavForest(planned.forest);
|
|
7556
|
-
}
|
|
7557
|
-
applySelectionAfterDrop();
|
|
7558
|
-
requestAnimationFrame(applySelectionAfterDrop);
|
|
7559
|
-
});
|
|
7560
|
-
return;
|
|
7561
|
-
}
|
|
7562
|
-
applySelectionAfterDrop();
|
|
7563
|
-
clearNavDragVisuals();
|
|
7564
|
-
},
|
|
7565
|
-
[clearNavDragVisuals, deselectRef, editContentRef, postToParentRef, selectRef]
|
|
7566
|
-
);
|
|
7567
|
-
commitNavDragRef.current = commitNavDrag;
|
|
7568
|
-
const startNavLinkDrag = (0, import_react8.useCallback)(
|
|
7569
|
-
(anchor, clientX, clientY, wasSelected) => {
|
|
7570
|
-
if (footerDragRef.current) return false;
|
|
7571
|
-
const hrefKey = anchor.getAttribute("data-ohw-href-key");
|
|
7572
|
-
if (!hrefKey || !isNavbarHrefKey(hrefKey)) return false;
|
|
7573
|
-
if (isNavbarButton3(anchor) || isDragHandleDisabled2(anchor)) return false;
|
|
7574
|
-
beginNavDrag({
|
|
7575
|
-
hrefKey,
|
|
7576
|
-
wasSelected,
|
|
7577
|
-
draggedEl: anchor,
|
|
7578
|
-
lastClientX: clientX,
|
|
7579
|
-
lastClientY: clientY,
|
|
7580
|
-
activeSlot: null
|
|
7581
|
-
});
|
|
7582
|
-
return true;
|
|
7583
|
-
},
|
|
7584
|
-
[beginNavDrag, footerDragRef, isDragHandleDisabled2, isNavbarButton3]
|
|
7585
|
-
);
|
|
7586
|
-
const onNavDragOver = (0, import_react8.useCallback)(
|
|
7587
|
-
(e) => {
|
|
7588
|
-
const session = navDragRef.current;
|
|
7589
|
-
if (!session) return false;
|
|
7590
|
-
e.preventDefault();
|
|
7591
|
-
if (e.dataTransfer) e.dataTransfer.dropEffect = "move";
|
|
7592
|
-
const slot = hitTestNavDropSlot(e.clientX, e.clientY, session.hrefKey);
|
|
7593
|
-
refreshNavDragVisualsRef.current(session, slot, e.clientX, e.clientY);
|
|
7594
|
-
return true;
|
|
7595
|
-
},
|
|
7596
|
-
[]
|
|
7597
|
-
);
|
|
7598
|
-
(0, import_react8.useEffect)(() => {
|
|
7599
|
-
if (!isEditMode) return;
|
|
7600
|
-
const THRESHOLD = 10;
|
|
7601
|
-
const resolveWasSelected = (el) => {
|
|
7602
|
-
if (selectedElRef.current === el) return true;
|
|
7603
|
-
const activeAnchor = activeElRef.current ? getNavigationItemAnchor2(activeElRef.current) : null;
|
|
7604
|
-
return activeAnchor === el;
|
|
7605
|
-
};
|
|
7606
|
-
const onPointerDown = (e) => {
|
|
7607
|
-
if (e.button !== 0) return;
|
|
7608
|
-
if (navDragRef.current || footerDragRef.current) return;
|
|
7609
|
-
const target = e.target;
|
|
7610
|
-
if (!target) return;
|
|
7611
|
-
if (target.closest(
|
|
7612
|
-
'[data-ohw-drag-handle-container], [data-slot="drag-handle"], [data-ohw-toolbar], [data-ohw-item-toolbar-anchor], [data-ohw-link-popover-root]'
|
|
7613
|
-
)) {
|
|
7614
|
-
return;
|
|
7615
|
-
}
|
|
7616
|
-
if (target.closest("[data-ohw-item-drag-surface]")) return;
|
|
7617
|
-
const anchor = getNavigationItemAnchor2(target);
|
|
7618
|
-
const hrefKey = anchor?.getAttribute("data-ohw-href-key") ?? null;
|
|
7619
|
-
if (!anchor || !isNavbarHrefKey(hrefKey)) return;
|
|
7620
|
-
if (isNavbarButton3(anchor) || isDragHandleDisabled2(anchor)) return;
|
|
7621
|
-
navPointerDragRef.current = {
|
|
7622
|
-
el: anchor,
|
|
7623
|
-
startX: e.clientX,
|
|
7624
|
-
startY: e.clientY,
|
|
7625
|
-
pointerId: e.pointerId,
|
|
7626
|
-
wasSelected: resolveWasSelected(anchor),
|
|
7627
|
-
started: false
|
|
7628
|
-
};
|
|
7629
|
-
};
|
|
7630
|
-
const onPointerMove = (e) => {
|
|
7631
|
-
const pending = navPointerDragRef.current;
|
|
7632
|
-
if (!pending) return;
|
|
7633
|
-
if (pending.started) {
|
|
7634
|
-
e.preventDefault();
|
|
7635
|
-
clearTextSelection();
|
|
7636
|
-
const session = navDragRef.current;
|
|
7637
|
-
if (!session) return;
|
|
7638
|
-
const slot = hitTestNavDropSlot(e.clientX, e.clientY, session.hrefKey);
|
|
7639
|
-
refreshNavDragVisualsRef.current(session, slot, e.clientX, e.clientY);
|
|
7640
|
-
return;
|
|
7641
|
-
}
|
|
7642
|
-
const dx = e.clientX - pending.startX;
|
|
7643
|
-
const dy = e.clientY - pending.startY;
|
|
7644
|
-
if (dx * dx + dy * dy < THRESHOLD * THRESHOLD) return;
|
|
7645
|
-
e.preventDefault();
|
|
7646
|
-
pending.started = true;
|
|
7647
|
-
armItemPressDrag();
|
|
7648
|
-
clearTextSelection();
|
|
7649
|
-
try {
|
|
7650
|
-
document.body.setPointerCapture(pending.pointerId);
|
|
7651
|
-
} catch {
|
|
7652
|
-
}
|
|
7653
|
-
if (linkPopoverOpenRef.current) setLinkPopover(null);
|
|
7654
|
-
if (activeElRef.current) deactivateRef.current();
|
|
7655
|
-
const key = pending.el.getAttribute("data-ohw-href-key");
|
|
7656
|
-
if (!key) return;
|
|
7657
|
-
beginNavDragRef.current({
|
|
7658
|
-
hrefKey: key,
|
|
7659
|
-
wasSelected: pending.wasSelected,
|
|
7660
|
-
draggedEl: pending.el,
|
|
7661
|
-
lastClientX: e.clientX,
|
|
7662
|
-
lastClientY: e.clientY,
|
|
7663
|
-
activeSlot: null
|
|
7664
|
-
});
|
|
7665
|
-
};
|
|
7666
|
-
const endPointerDrag = (e) => {
|
|
7667
|
-
const pending = navPointerDragRef.current;
|
|
7668
|
-
navPointerDragRef.current = null;
|
|
7669
|
-
try {
|
|
7670
|
-
if (document.body.hasPointerCapture(e.pointerId)) {
|
|
7671
|
-
document.body.releasePointerCapture(e.pointerId);
|
|
7672
|
-
}
|
|
7673
|
-
} catch {
|
|
7674
|
-
}
|
|
7675
|
-
if (!pending) return;
|
|
7676
|
-
if (!pending.started) {
|
|
7677
|
-
unlockItemDragInteraction();
|
|
7678
|
-
return;
|
|
7679
|
-
}
|
|
7680
|
-
suppressNextClickRef.current = true;
|
|
7681
|
-
suppressClickUntilRef.current = Date.now() + 500;
|
|
7682
|
-
commitNavDragRef.current(e.clientX, e.clientY);
|
|
7683
|
-
};
|
|
7684
|
-
const blockSelectStart = (e) => {
|
|
7685
|
-
if (navDragRef.current || navPointerDragRef.current?.started || document.documentElement.hasAttribute("data-ohw-footer-press-drag")) {
|
|
7686
|
-
e.preventDefault();
|
|
7687
|
-
}
|
|
7688
|
-
};
|
|
7689
|
-
const onDragEnd = () => {
|
|
7690
|
-
if (!navDragRef.current) return;
|
|
7691
|
-
suppressNextClickRef.current = true;
|
|
7692
|
-
suppressClickUntilRef.current = Date.now() + 500;
|
|
7693
|
-
commitNavDragRef.current();
|
|
7694
|
-
};
|
|
7695
|
-
document.addEventListener("pointerdown", onPointerDown, true);
|
|
7696
|
-
document.addEventListener("pointermove", onPointerMove, true);
|
|
7697
|
-
document.addEventListener("pointerup", endPointerDrag, true);
|
|
7698
|
-
document.addEventListener("pointercancel", endPointerDrag, true);
|
|
7699
|
-
document.addEventListener("selectstart", blockSelectStart, true);
|
|
7700
|
-
document.addEventListener("dragend", onDragEnd, true);
|
|
7701
|
-
return () => {
|
|
7702
|
-
document.removeEventListener("pointerdown", onPointerDown, true);
|
|
7703
|
-
document.removeEventListener("pointermove", onPointerMove, true);
|
|
7704
|
-
document.removeEventListener("pointerup", endPointerDrag, true);
|
|
7705
|
-
document.removeEventListener("pointercancel", endPointerDrag, true);
|
|
7706
|
-
document.removeEventListener("selectstart", blockSelectStart, true);
|
|
7707
|
-
document.removeEventListener("dragend", onDragEnd, true);
|
|
7708
|
-
unlockItemDragInteraction();
|
|
7709
|
-
};
|
|
7710
|
-
}, [
|
|
7711
|
-
activeElRef,
|
|
7712
|
-
deactivateRef,
|
|
7713
|
-
footerDragRef,
|
|
7714
|
-
getNavigationItemAnchor2,
|
|
7715
|
-
isDragHandleDisabled2,
|
|
7716
|
-
isEditMode,
|
|
7717
|
-
isNavbarButton3,
|
|
7718
|
-
linkPopoverOpenRef,
|
|
7719
|
-
selectedElRef,
|
|
7720
|
-
setLinkPopover,
|
|
7721
|
-
suppressNextClickRef
|
|
7722
|
-
]);
|
|
7723
|
-
const armNavPressFromChrome = (0, import_react8.useCallback)(
|
|
7724
|
-
(selected, clientX, clientY, pointerId) => {
|
|
7725
|
-
const hrefKey = selected.getAttribute("data-ohw-href-key");
|
|
7726
|
-
if (!hrefKey || !isNavbarHrefKey(hrefKey)) return false;
|
|
7727
|
-
if (isNavbarButton3(selected) || isDragHandleDisabled2(selected)) return false;
|
|
7728
|
-
navPointerDragRef.current = {
|
|
7729
|
-
el: selected,
|
|
7730
|
-
startX: clientX,
|
|
7731
|
-
startY: clientY,
|
|
7732
|
-
pointerId,
|
|
7733
|
-
wasSelected: true,
|
|
7734
|
-
started: false
|
|
7735
|
-
};
|
|
7736
|
-
return true;
|
|
7737
|
-
},
|
|
7738
|
-
[isDragHandleDisabled2, isNavbarButton3]
|
|
7739
|
-
);
|
|
7740
|
-
return {
|
|
7741
|
-
navDragRef,
|
|
7742
|
-
navDropSlots,
|
|
7743
|
-
activeNavDropIndex,
|
|
7744
|
-
startNavLinkDrag,
|
|
7745
|
-
commitNavDrag,
|
|
7746
|
-
onNavDragOver,
|
|
7747
|
-
armNavPressFromChrome,
|
|
7748
|
-
clearNavDragVisuals,
|
|
7749
|
-
refreshNavDragVisualsRef
|
|
7750
|
-
};
|
|
7751
|
-
}
|
|
7752
|
-
|
|
7753
|
-
// src/ui/navbar-container-chrome.tsx
|
|
7754
|
-
var import_lucide_react10 = require("lucide-react");
|
|
7755
|
-
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
7756
|
-
function NavbarContainerChrome({
|
|
7757
|
-
rect,
|
|
7758
|
-
onAdd
|
|
7759
|
-
}) {
|
|
7760
|
-
const chromeGap = 6;
|
|
7761
|
-
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
7762
|
-
"div",
|
|
7763
|
-
{
|
|
7764
|
-
"data-ohw-navbar-container-chrome": "",
|
|
7765
|
-
"data-ohw-bridge": "",
|
|
7766
|
-
className: "pointer-events-none fixed z-[2147483647]",
|
|
7767
|
-
style: {
|
|
7768
|
-
top: rect.top - chromeGap,
|
|
7769
|
-
left: rect.left - chromeGap,
|
|
7770
|
-
width: rect.width + chromeGap * 2,
|
|
7771
|
-
height: rect.height + chromeGap * 2
|
|
7772
|
-
},
|
|
7773
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
7774
|
-
"button",
|
|
7775
|
-
{
|
|
7776
|
-
type: "button",
|
|
7777
|
-
"data-ohw-navbar-add-button": "",
|
|
7778
|
-
className: "pointer-events-auto absolute left-1/2 flex p-0.5 rounded-[10px] size-7 -translate-x-1/2 translate-y-1/2 items-center justify-center border border-border bg-background shadow-sm transition-colors hover:bg-muted/80",
|
|
7779
|
-
style: { top: "70%" },
|
|
7780
|
-
"aria-label": "Add item",
|
|
7781
|
-
onMouseDown: (e) => {
|
|
7782
|
-
e.preventDefault();
|
|
7783
|
-
e.stopPropagation();
|
|
7784
|
-
},
|
|
7785
|
-
onClick: (e) => {
|
|
7786
|
-
e.preventDefault();
|
|
7787
|
-
e.stopPropagation();
|
|
7788
|
-
onAdd();
|
|
7789
|
-
},
|
|
7790
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react10.Plus, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
|
|
7791
|
-
}
|
|
7792
|
-
)
|
|
7793
|
-
}
|
|
7794
|
-
);
|
|
7795
|
-
}
|
|
7796
|
-
|
|
7797
|
-
// src/ui/drop-indicator.tsx
|
|
7798
|
-
var React10 = __toESM(require("react"), 1);
|
|
7799
|
-
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
7800
|
-
var dropIndicatorVariants = cva(
|
|
7801
|
-
"ov-gap-line pointer-events-none shrink-0 transition-opacity duration-150",
|
|
7802
|
-
{
|
|
7803
|
-
variants: {
|
|
7804
|
-
direction: {
|
|
7805
|
-
vertical: "h-6 w-[3px]",
|
|
7806
|
-
horizontal: "h-[3px] w-[200px]"
|
|
7807
|
-
},
|
|
7808
|
-
state: {
|
|
7809
|
-
default: "opacity-0",
|
|
7810
|
-
hover: "opacity-100",
|
|
7811
|
-
dragIdle: "opacity-40",
|
|
7812
|
-
dragActive: "opacity-100"
|
|
7813
|
-
}
|
|
7814
|
-
},
|
|
7815
|
-
defaultVariants: {
|
|
7816
|
-
direction: "vertical",
|
|
7817
|
-
state: "default"
|
|
7818
|
-
}
|
|
7819
|
-
}
|
|
7820
|
-
);
|
|
7821
|
-
var DropIndicator = React10.forwardRef(
|
|
7822
|
-
({ className, direction, state, ...props }, ref) => {
|
|
7823
|
-
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
7824
|
-
"div",
|
|
7825
|
-
{
|
|
7826
|
-
ref,
|
|
7827
|
-
"data-slot": "drop-indicator",
|
|
7828
|
-
"data-direction": direction ?? "vertical",
|
|
7829
|
-
"data-state": state ?? "default",
|
|
7830
|
-
"aria-hidden": "true",
|
|
7831
|
-
className: cn(dropIndicatorVariants({ direction, state }), className),
|
|
7832
|
-
...props
|
|
7833
|
-
}
|
|
7834
|
-
);
|
|
7835
|
-
}
|
|
7836
|
-
);
|
|
7837
|
-
DropIndicator.displayName = "DropIndicator";
|
|
7838
|
-
|
|
7839
|
-
// src/ui/badge.tsx
|
|
7840
|
-
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
7841
|
-
var badgeVariants = cva(
|
|
7842
|
-
"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",
|
|
7843
|
-
{
|
|
7844
|
-
variants: {
|
|
7845
|
-
variant: {
|
|
7846
|
-
default: "border-transparent bg-primary text-primary-foreground",
|
|
7847
|
-
secondary: "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
7848
|
-
destructive: "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",
|
|
7849
|
-
outline: "text-foreground"
|
|
7850
|
-
}
|
|
7851
|
-
},
|
|
7852
|
-
defaultVariants: {
|
|
7853
|
-
variant: "default"
|
|
7854
|
-
}
|
|
7855
|
-
}
|
|
7856
|
-
);
|
|
7857
|
-
function Badge({ className, variant, ...props }) {
|
|
7858
|
-
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: cn(badgeVariants({ variant }), className), ...props });
|
|
6568
|
+
);
|
|
6569
|
+
function Badge({ className, variant, ...props }) {
|
|
6570
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: cn(badgeVariants({ variant }), className), ...props });
|
|
7859
6571
|
}
|
|
7860
6572
|
|
|
7861
6573
|
// src/OhhwellsBridge.tsx
|
|
7862
6574
|
var import_lucide_react11 = require("lucide-react");
|
|
7863
|
-
var
|
|
6575
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
7864
6576
|
var PRIMARY2 = "#0885FE";
|
|
7865
6577
|
var IMAGE_FADE_MS = 300;
|
|
7866
6578
|
function runOpacityFade(el, onDone) {
|
|
@@ -8039,7 +6751,7 @@ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId,
|
|
|
8039
6751
|
const root = (0, import_client.createRoot)(container);
|
|
8040
6752
|
(0, import_react_dom2.flushSync)(() => {
|
|
8041
6753
|
root.render(
|
|
8042
|
-
/* @__PURE__ */ (0,
|
|
6754
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8043
6755
|
SchedulingWidget,
|
|
8044
6756
|
{
|
|
8045
6757
|
notifyOnConnect,
|
|
@@ -8101,20 +6813,7 @@ function isDragHandleDisabled(el) {
|
|
|
8101
6813
|
return raw === "true" || raw === "";
|
|
8102
6814
|
});
|
|
8103
6815
|
}
|
|
8104
|
-
function
|
|
8105
|
-
const { key, disabled } = getNavigationItemReorderState(anchor);
|
|
8106
|
-
return Boolean(key) && !disabled;
|
|
8107
|
-
}
|
|
8108
|
-
function syncNavigationDragCursorAttrs() {
|
|
8109
|
-
document.querySelectorAll("nav [data-ohw-href-key], footer [data-ohw-href-key]").forEach((el) => {
|
|
8110
|
-
if (!isNavigationItem(el) || !canDragNavigationItem(el)) {
|
|
8111
|
-
el.removeAttribute("data-ohw-can-drag");
|
|
8112
|
-
return;
|
|
8113
|
-
}
|
|
8114
|
-
el.setAttribute("data-ohw-can-drag", "");
|
|
8115
|
-
});
|
|
8116
|
-
}
|
|
8117
|
-
function collectEditableNodes(extraContent) {
|
|
6816
|
+
function collectEditableNodes() {
|
|
8118
6817
|
const nodes = Array.from(document.querySelectorAll("[data-ohw-editable]")).map((el) => {
|
|
8119
6818
|
if (el.dataset.ohwEditable === "image") {
|
|
8120
6819
|
const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
|
|
@@ -8142,14 +6841,6 @@ function collectEditableNodes(extraContent) {
|
|
|
8142
6841
|
if (!key) return;
|
|
8143
6842
|
nodes.push({ key, type: "link", text: getLinkHref2(el) });
|
|
8144
6843
|
});
|
|
8145
|
-
if (extraContent) {
|
|
8146
|
-
for (const key of [NAV_ORDER_KEY, FOOTER_ORDER_KEY, NAV_COUNT_KEY]) {
|
|
8147
|
-
const text = extraContent[key];
|
|
8148
|
-
if (typeof text === "string" && text.length > 0) {
|
|
8149
|
-
nodes.push({ key, type: "meta", text });
|
|
8150
|
-
}
|
|
8151
|
-
}
|
|
8152
|
-
}
|
|
8153
6844
|
document.querySelectorAll('[data-ohw-editable="video"]').forEach((el) => {
|
|
8154
6845
|
const key = el.dataset.ohwKey ?? "";
|
|
8155
6846
|
const video = getVideoEl(el);
|
|
@@ -8263,11 +6954,6 @@ function getNavigationItemAnchor(el) {
|
|
|
8263
6954
|
function isNavigationItem(el) {
|
|
8264
6955
|
return getNavigationItemAnchor(el) !== null;
|
|
8265
6956
|
}
|
|
8266
|
-
function listNavigationItems() {
|
|
8267
|
-
return Array.from(
|
|
8268
|
-
document.querySelectorAll("nav [data-ohw-href-key], footer [data-ohw-href-key]")
|
|
8269
|
-
).filter((el) => isNavigationItem(el));
|
|
8270
|
-
}
|
|
8271
6957
|
function getNavigationItemReorderState(anchor) {
|
|
8272
6958
|
if (isNavbarButton2(anchor)) return { key: null, disabled: false };
|
|
8273
6959
|
return getReorderHandleStateFromAnchor(anchor);
|
|
@@ -8296,20 +6982,18 @@ function getNavigationRoot(el) {
|
|
|
8296
6982
|
if (explicit) return explicit;
|
|
8297
6983
|
return el.closest("nav, footer, aside");
|
|
8298
6984
|
}
|
|
8299
|
-
function countFooterNavItems(el) {
|
|
8300
|
-
return Array.from(el.querySelectorAll("[data-ohw-href-key]")).filter(isNavigationItem).length;
|
|
8301
|
-
}
|
|
8302
6985
|
function findFooterItemGroup(item) {
|
|
8303
|
-
const explicit = item.closest("[data-ohw-footer-col], [data-ohw-footer-column]");
|
|
8304
|
-
if (explicit) return explicit;
|
|
8305
6986
|
const footer = item.closest("footer");
|
|
8306
6987
|
if (!footer) return null;
|
|
8307
6988
|
let node = item.parentElement;
|
|
8308
6989
|
while (node && node !== footer) {
|
|
8309
|
-
|
|
6990
|
+
const hasDirectNavItems = Array.from(
|
|
6991
|
+
node.querySelectorAll(":scope > [data-ohw-href-key]")
|
|
6992
|
+
).some(isNavigationItem);
|
|
6993
|
+
if (hasDirectNavItems) return node;
|
|
8310
6994
|
node = node.parentElement;
|
|
8311
6995
|
}
|
|
8312
|
-
return
|
|
6996
|
+
return null;
|
|
8313
6997
|
}
|
|
8314
6998
|
function isNavigationRoot(el) {
|
|
8315
6999
|
return el.hasAttribute("data-ohw-nav-root") || el.matches("nav, footer, aside");
|
|
@@ -8317,49 +7001,16 @@ function isNavigationRoot(el) {
|
|
|
8317
7001
|
function isInferredFooterGroup(el) {
|
|
8318
7002
|
const footer = el.closest("footer");
|
|
8319
7003
|
if (!footer || el === footer) return false;
|
|
8320
|
-
|
|
8321
|
-
return countFooterNavItems(el) >= 2;
|
|
7004
|
+
return Array.from(el.querySelectorAll(":scope > [data-ohw-href-key]")).some(isNavigationItem);
|
|
8322
7005
|
}
|
|
8323
7006
|
function isNavigationContainer(el) {
|
|
8324
|
-
return el.hasAttribute("data-ohw-nav-container") ||
|
|
8325
|
-
}
|
|
8326
|
-
function isNavbarLinksContainer(el) {
|
|
8327
|
-
return el.hasAttribute("data-ohw-nav-container");
|
|
8328
|
-
}
|
|
8329
|
-
function getFooterColumn(el) {
|
|
8330
|
-
return el.closest("[data-ohw-footer-col], [data-ohw-footer-column]");
|
|
8331
|
-
}
|
|
8332
|
-
function resolveFooterColumnSelectionTarget(target, clientX, clientY) {
|
|
8333
|
-
if (getNavigationItemAnchor(target)) return null;
|
|
8334
|
-
const column = getFooterColumn(target);
|
|
8335
|
-
if (!column) return null;
|
|
8336
|
-
if (isPointOverNavItem(column, clientX, clientY)) return null;
|
|
8337
|
-
return column;
|
|
7007
|
+
return el.hasAttribute("data-ohw-nav-container") || isNavigationRoot(el) || isInferredFooterGroup(el);
|
|
8338
7008
|
}
|
|
8339
7009
|
function isPointOverNavigation(x, y) {
|
|
8340
|
-
const roots = /* @__PURE__ */ new Set();
|
|
8341
7010
|
const navRoot = document.querySelector("[data-ohw-nav-root]") ?? document.querySelector("nav");
|
|
8342
|
-
if (navRoot)
|
|
8343
|
-
const
|
|
8344
|
-
|
|
8345
|
-
for (const root of roots) {
|
|
8346
|
-
const r2 = root.getBoundingClientRect();
|
|
8347
|
-
if (x >= r2.left && x <= r2.right && y >= r2.top && y <= r2.bottom) return true;
|
|
8348
|
-
}
|
|
8349
|
-
return false;
|
|
8350
|
-
}
|
|
8351
|
-
function findHoveredNavOrFooterContainer(x, y) {
|
|
8352
|
-
const candidates = [
|
|
8353
|
-
...document.querySelectorAll("[data-ohw-nav-container]"),
|
|
8354
|
-
...listFooterColumns()
|
|
8355
|
-
];
|
|
8356
|
-
for (const container of candidates) {
|
|
8357
|
-
const r2 = container.getBoundingClientRect();
|
|
8358
|
-
if (x < r2.left || x > r2.right || y < r2.top || y > r2.bottom) continue;
|
|
8359
|
-
if (isPointOverNavItem(container, x, y)) continue;
|
|
8360
|
-
return container;
|
|
8361
|
-
}
|
|
8362
|
-
return null;
|
|
7011
|
+
if (!navRoot) return false;
|
|
7012
|
+
const r2 = navRoot.getBoundingClientRect();
|
|
7013
|
+
return x >= r2.left && x <= r2.right && y >= r2.top && y <= r2.bottom;
|
|
8363
7014
|
}
|
|
8364
7015
|
function isPointOverNavItem(container, x, y) {
|
|
8365
7016
|
return Array.from(container.querySelectorAll("[data-ohw-href-key]")).some((el) => {
|
|
@@ -8392,63 +7043,36 @@ function getNavigationSelectionParent(el) {
|
|
|
8392
7043
|
if (isNavigationItem(el)) {
|
|
8393
7044
|
const explicit = el.closest("[data-ohw-nav-container]");
|
|
8394
7045
|
if (explicit) return explicit;
|
|
8395
|
-
const footerColumn = getFooterColumn(el);
|
|
8396
|
-
if (footerColumn) return footerColumn;
|
|
8397
7046
|
const footerGroup = findFooterItemGroup(el);
|
|
8398
7047
|
if (footerGroup) return footerGroup;
|
|
8399
7048
|
return getNavigationRoot(el);
|
|
8400
7049
|
}
|
|
8401
|
-
if (el.hasAttribute("data-ohw-nav-container") ||
|
|
7050
|
+
if (el.hasAttribute("data-ohw-nav-container") || isInferredFooterGroup(el)) {
|
|
8402
7051
|
return getNavigationRoot(el);
|
|
8403
7052
|
}
|
|
8404
7053
|
return null;
|
|
8405
7054
|
}
|
|
8406
|
-
function collectNavigationItemSiblingHintRects(selected) {
|
|
8407
|
-
if (!isNavigationItem(selected)) return [];
|
|
8408
|
-
const footerColumn = getFooterColumn(selected);
|
|
8409
|
-
if (footerColumn) {
|
|
8410
|
-
return listFooterLinksInColumn(footerColumn).filter((link) => link !== selected).map((link) => link.getBoundingClientRect());
|
|
8411
|
-
}
|
|
8412
|
-
const navContainer = selected.closest("[data-ohw-nav-container], [data-ohw-nav-drawer]");
|
|
8413
|
-
if (navContainer) {
|
|
8414
|
-
return Array.from(navContainer.querySelectorAll("[data-ohw-href-key]")).filter((el) => isNavigationItem(el) && el !== selected).map((el) => el.getBoundingClientRect());
|
|
8415
|
-
}
|
|
8416
|
-
return listNavigationItems().filter((el) => el !== selected).map((el) => el.getBoundingClientRect());
|
|
8417
|
-
}
|
|
8418
7055
|
function placeCaretAtPoint(el, x, y) {
|
|
8419
7056
|
const selection = window.getSelection();
|
|
8420
7057
|
if (!selection) return;
|
|
8421
|
-
|
|
8422
|
-
document.
|
|
8423
|
-
|
|
8424
|
-
|
|
8425
|
-
|
|
8426
|
-
|
|
8427
|
-
for (const node of overlays) node.style.pointerEvents = "none";
|
|
8428
|
-
try {
|
|
8429
|
-
if (typeof document.caretRangeFromPoint === "function") {
|
|
8430
|
-
const range = document.caretRangeFromPoint(x, y);
|
|
8431
|
-
if (range && el.contains(range.startContainer)) {
|
|
8432
|
-
selection.removeAllRanges();
|
|
8433
|
-
selection.addRange(range);
|
|
8434
|
-
return;
|
|
8435
|
-
}
|
|
7058
|
+
if (typeof document.caretRangeFromPoint === "function") {
|
|
7059
|
+
const range = document.caretRangeFromPoint(x, y);
|
|
7060
|
+
if (range && el.contains(range.startContainer)) {
|
|
7061
|
+
selection.removeAllRanges();
|
|
7062
|
+
selection.addRange(range);
|
|
7063
|
+
return;
|
|
8436
7064
|
}
|
|
8437
|
-
|
|
8438
|
-
|
|
8439
|
-
|
|
8440
|
-
|
|
8441
|
-
|
|
8442
|
-
|
|
8443
|
-
|
|
8444
|
-
|
|
8445
|
-
|
|
8446
|
-
|
|
7065
|
+
}
|
|
7066
|
+
const caretPositionFromPoint = document.caretPositionFromPoint;
|
|
7067
|
+
if (typeof caretPositionFromPoint === "function") {
|
|
7068
|
+
const position = caretPositionFromPoint(x, y);
|
|
7069
|
+
if (position && el.contains(position.offsetNode)) {
|
|
7070
|
+
const range = document.createRange();
|
|
7071
|
+
range.setStart(position.offsetNode, position.offset);
|
|
7072
|
+
range.collapse(true);
|
|
7073
|
+
selection.removeAllRanges();
|
|
7074
|
+
selection.addRange(range);
|
|
8447
7075
|
}
|
|
8448
|
-
} finally {
|
|
8449
|
-
overlays.forEach((node, i) => {
|
|
8450
|
-
node.style.pointerEvents = prevPointerEvents[i] ?? "";
|
|
8451
|
-
});
|
|
8452
7076
|
}
|
|
8453
7077
|
}
|
|
8454
7078
|
function selectAllTextInEditable(el) {
|
|
@@ -8590,9 +7214,6 @@ var ICONS = {
|
|
|
8590
7214
|
insertUnorderedList: '<line x1="8" y1="6" x2="21" y2="6"/><line x1="8" y1="12" x2="21" y2="12"/><line x1="8" y1="18" x2="21" y2="18"/><line x1="3" y1="6" x2="3.01" y2="6"/><line x1="3" y1="12" x2="3.01" y2="12"/><line x1="3" y1="18" x2="3.01" y2="18"/>',
|
|
8591
7215
|
insertOrderedList: '<line x1="10" y1="6" x2="21" y2="6"/><line x1="10" y1="12" x2="21" y2="12"/><line x1="10" y1="18" x2="21" y2="18"/><path d="M4 6h1v4"/><path d="M4 10h2"/><path d="M6 18H4c0-1 2-2 2-3s-1-1.5-2-1"/>'
|
|
8592
7216
|
};
|
|
8593
|
-
var SELECTION_CHROME_GAP2 = 4;
|
|
8594
|
-
var TOOLBAR_STROKE_GAP2 = 4;
|
|
8595
|
-
var TOOLBAR_OFFSET_FROM_ELEMENT = SELECTION_CHROME_GAP2 + TOOLBAR_STROKE_GAP2;
|
|
8596
7217
|
var TOOLBAR_GROUPS = [
|
|
8597
7218
|
[
|
|
8598
7219
|
{ cmd: "bold", title: "Bold" },
|
|
@@ -8614,11 +7235,10 @@ function EditGlowChrome({
|
|
|
8614
7235
|
rect,
|
|
8615
7236
|
elRef,
|
|
8616
7237
|
reorderHrefKey,
|
|
8617
|
-
dragDisabled = false
|
|
8618
|
-
hideHandle = false
|
|
7238
|
+
dragDisabled = false
|
|
8619
7239
|
}) {
|
|
8620
|
-
const GAP =
|
|
8621
|
-
return /* @__PURE__ */ (0,
|
|
7240
|
+
const GAP = 6;
|
|
7241
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
8622
7242
|
"div",
|
|
8623
7243
|
{
|
|
8624
7244
|
ref: elRef,
|
|
@@ -8633,7 +7253,7 @@ function EditGlowChrome({
|
|
|
8633
7253
|
zIndex: 2147483646
|
|
8634
7254
|
},
|
|
8635
7255
|
children: [
|
|
8636
|
-
/* @__PURE__ */ (0,
|
|
7256
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8637
7257
|
"div",
|
|
8638
7258
|
{
|
|
8639
7259
|
style: {
|
|
@@ -8641,12 +7261,12 @@ function EditGlowChrome({
|
|
|
8641
7261
|
inset: 0,
|
|
8642
7262
|
border: "2px solid var(--ohw-primary, #0885FE)",
|
|
8643
7263
|
borderRadius: 8,
|
|
8644
|
-
boxShadow: "0 0 0 4px
|
|
7264
|
+
boxShadow: "0 0 0 4px rgba(8, 133, 254, 0.12)",
|
|
8645
7265
|
pointerEvents: "none"
|
|
8646
7266
|
}
|
|
8647
7267
|
}
|
|
8648
7268
|
),
|
|
8649
|
-
reorderHrefKey &&
|
|
7269
|
+
reorderHrefKey && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8650
7270
|
"div",
|
|
8651
7271
|
{
|
|
8652
7272
|
"data-ohw-drag-handle-container": "",
|
|
@@ -8658,7 +7278,7 @@ function EditGlowChrome({
|
|
|
8658
7278
|
transform: "translate(calc(-100% - 7px), -50%)",
|
|
8659
7279
|
pointerEvents: dragDisabled ? "none" : "auto"
|
|
8660
7280
|
},
|
|
8661
|
-
children: /* @__PURE__ */ (0,
|
|
7281
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8662
7282
|
DragHandle,
|
|
8663
7283
|
{
|
|
8664
7284
|
"aria-label": `Reorder ${reorderHrefKey}`,
|
|
@@ -8689,7 +7309,6 @@ function applyVisibleViewport(el, parentScroll) {
|
|
|
8689
7309
|
el.style.top = `${top}px`;
|
|
8690
7310
|
el.style.height = `${height}px`;
|
|
8691
7311
|
}
|
|
8692
|
-
var TOOLBAR_EDGE_MARGIN2 = 4;
|
|
8693
7312
|
function clampToolbarToClip(top, transform, rect, clip, approxH, gap) {
|
|
8694
7313
|
const isAbove = transform.includes("translateY(-100%)");
|
|
8695
7314
|
let visualTop = isAbove ? top - approxH : top;
|
|
@@ -8713,16 +7332,10 @@ function clampToolbarToClip(top, transform, rect, clip, approxH, gap) {
|
|
|
8713
7332
|
const pinnedTop = Math.min(maxBottom - approxH, Math.max(minTop, clip.top + gap));
|
|
8714
7333
|
return { top: pinnedTop + approxH, transform: "translateX(-50%) translateY(-100%)" };
|
|
8715
7334
|
}
|
|
8716
|
-
function
|
|
8717
|
-
const
|
|
8718
|
-
return Math.max(
|
|
8719
|
-
TOOLBAR_EDGE_MARGIN2 + half,
|
|
8720
|
-
Math.min(centerX, window.innerWidth - TOOLBAR_EDGE_MARGIN2 - half)
|
|
8721
|
-
);
|
|
8722
|
-
}
|
|
8723
|
-
function calcToolbarPos(rect, parentScroll, toolbarW = 306) {
|
|
8724
|
-
const GAP = TOOLBAR_OFFSET_FROM_ELEMENT;
|
|
7335
|
+
function calcToolbarPos(rect, parentScroll, approxW = 306) {
|
|
7336
|
+
const GAP = 8;
|
|
8725
7337
|
const APPROX_H = 32;
|
|
7338
|
+
const APPROX_W = approxW;
|
|
8726
7339
|
const clip = getIframeVisibleClip(parentScroll);
|
|
8727
7340
|
const clipTop = clip?.top ?? 0;
|
|
8728
7341
|
const canvasTopInIframe = parentScroll != null ? parentScroll.headerH - parentScroll.iframeOffsetTop : 0;
|
|
@@ -8752,7 +7365,7 @@ function calcToolbarPos(rect, parentScroll, toolbarW = 306) {
|
|
|
8752
7365
|
transform = clamped.transform;
|
|
8753
7366
|
}
|
|
8754
7367
|
const rawLeft = rect.left + rect.width / 2;
|
|
8755
|
-
const left =
|
|
7368
|
+
const left = Math.max(GAP + APPROX_W / 2, Math.min(rawLeft, window.innerWidth - GAP - APPROX_W / 2));
|
|
8756
7369
|
return { top, left, transform };
|
|
8757
7370
|
}
|
|
8758
7371
|
function resolveItemInteractionState(rect, parentScroll) {
|
|
@@ -8768,37 +7381,11 @@ function FloatingToolbar({
|
|
|
8768
7381
|
showEditLink,
|
|
8769
7382
|
onEditLink
|
|
8770
7383
|
}) {
|
|
8771
|
-
const
|
|
8772
|
-
|
|
8773
|
-
const setRefs = import_react9.default.useCallback(
|
|
8774
|
-
(node) => {
|
|
8775
|
-
localRef.current = node;
|
|
8776
|
-
if (typeof elRef === "function") elRef(node);
|
|
8777
|
-
else if (elRef) elRef.current = node;
|
|
8778
|
-
if (node) {
|
|
8779
|
-
const w = node.offsetWidth;
|
|
8780
|
-
if (w > 0) setMeasuredW(w);
|
|
8781
|
-
}
|
|
8782
|
-
},
|
|
8783
|
-
[elRef]
|
|
8784
|
-
);
|
|
8785
|
-
import_react9.default.useLayoutEffect(() => {
|
|
8786
|
-
const node = localRef.current;
|
|
8787
|
-
if (!node) return;
|
|
8788
|
-
const update = () => {
|
|
8789
|
-
const w = node.offsetWidth;
|
|
8790
|
-
if (w > 0) setMeasuredW(w);
|
|
8791
|
-
};
|
|
8792
|
-
update();
|
|
8793
|
-
const ro = new ResizeObserver(update);
|
|
8794
|
-
ro.observe(node);
|
|
8795
|
-
return () => ro.disconnect();
|
|
8796
|
-
}, [showEditLink, activeCommands]);
|
|
8797
|
-
const { top, left, transform } = calcToolbarPos(rect, parentScroll, measuredW);
|
|
8798
|
-
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
7384
|
+
const { top, left, transform } = calcToolbarPos(rect, parentScroll, 330);
|
|
7385
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8799
7386
|
"div",
|
|
8800
7387
|
{
|
|
8801
|
-
ref:
|
|
7388
|
+
ref: elRef,
|
|
8802
7389
|
style: {
|
|
8803
7390
|
position: "fixed",
|
|
8804
7391
|
top,
|
|
@@ -8807,12 +7394,12 @@ function FloatingToolbar({
|
|
|
8807
7394
|
zIndex: 2147483647,
|
|
8808
7395
|
pointerEvents: "auto"
|
|
8809
7396
|
},
|
|
8810
|
-
children: /* @__PURE__ */ (0,
|
|
8811
|
-
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ (0,
|
|
8812
|
-
gi > 0 && /* @__PURE__ */ (0,
|
|
7397
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(CustomToolbar, { children: [
|
|
7398
|
+
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_react8.default.Fragment, { children: [
|
|
7399
|
+
gi > 0 && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(CustomToolbarDivider, {}),
|
|
8813
7400
|
btns.map((btn) => {
|
|
8814
7401
|
const isActive = activeCommands.has(btn.cmd);
|
|
8815
|
-
return /* @__PURE__ */ (0,
|
|
7402
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8816
7403
|
CustomToolbarButton,
|
|
8817
7404
|
{
|
|
8818
7405
|
title: btn.title,
|
|
@@ -8821,7 +7408,7 @@ function FloatingToolbar({
|
|
|
8821
7408
|
e.preventDefault();
|
|
8822
7409
|
onCommand(btn.cmd);
|
|
8823
7410
|
},
|
|
8824
|
-
children: /* @__PURE__ */ (0,
|
|
7411
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8825
7412
|
"svg",
|
|
8826
7413
|
{
|
|
8827
7414
|
width: "16",
|
|
@@ -8842,7 +7429,7 @@ function FloatingToolbar({
|
|
|
8842
7429
|
);
|
|
8843
7430
|
})
|
|
8844
7431
|
] }, gi)),
|
|
8845
|
-
showEditLink ? /* @__PURE__ */ (0,
|
|
7432
|
+
showEditLink ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8846
7433
|
CustomToolbarButton,
|
|
8847
7434
|
{
|
|
8848
7435
|
type: "button",
|
|
@@ -8856,7 +7443,7 @@ function FloatingToolbar({
|
|
|
8856
7443
|
e.preventDefault();
|
|
8857
7444
|
e.stopPropagation();
|
|
8858
7445
|
},
|
|
8859
|
-
children: /* @__PURE__ */ (0,
|
|
7446
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react11.Link, { className: "size-4 shrink-0", "aria-hidden": true })
|
|
8860
7447
|
}
|
|
8861
7448
|
) : null
|
|
8862
7449
|
] })
|
|
@@ -8873,7 +7460,7 @@ function StateToggle({
|
|
|
8873
7460
|
states,
|
|
8874
7461
|
onStateChange
|
|
8875
7462
|
}) {
|
|
8876
|
-
return /* @__PURE__ */ (0,
|
|
7463
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8877
7464
|
ToggleGroup,
|
|
8878
7465
|
{
|
|
8879
7466
|
"data-ohw-state-toggle": "",
|
|
@@ -8887,7 +7474,7 @@ function StateToggle({
|
|
|
8887
7474
|
left: rect.right - 8,
|
|
8888
7475
|
transform: "translateX(-100%)"
|
|
8889
7476
|
},
|
|
8890
|
-
children: states.map((state) => /* @__PURE__ */ (0,
|
|
7477
|
+
children: states.map((state) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ToggleGroupItem, { value: state, size: "sm", children: state }, state))
|
|
8891
7478
|
}
|
|
8892
7479
|
);
|
|
8893
7480
|
}
|
|
@@ -8914,8 +7501,8 @@ function OhhwellsBridge() {
|
|
|
8914
7501
|
const router = (0, import_navigation2.useRouter)();
|
|
8915
7502
|
const searchParams = (0, import_navigation2.useSearchParams)();
|
|
8916
7503
|
const isEditMode = isEditSessionActive();
|
|
8917
|
-
const [bridgeRoot, setBridgeRoot] = (0,
|
|
8918
|
-
(0,
|
|
7504
|
+
const [bridgeRoot, setBridgeRoot] = (0, import_react8.useState)(null);
|
|
7505
|
+
(0, import_react8.useEffect)(() => {
|
|
8919
7506
|
const figtreeFontId = "ohw-figtree-font";
|
|
8920
7507
|
if (!document.getElementById(figtreeFontId)) {
|
|
8921
7508
|
const preconnect1 = Object.assign(document.createElement("link"), { rel: "preconnect", href: "https://fonts.googleapis.com" });
|
|
@@ -8943,137 +7530,91 @@ function OhhwellsBridge() {
|
|
|
8943
7530
|
const subdomainFromQuery = searchParams.get("subdomain");
|
|
8944
7531
|
const subdomain = resolveSubdomain(subdomainFromQuery);
|
|
8945
7532
|
useLinkHrefGuardian(pathname, subdomain, isEditMode);
|
|
8946
|
-
const postToParent2 = (0,
|
|
7533
|
+
const postToParent2 = (0, import_react8.useCallback)((data) => {
|
|
8947
7534
|
if (typeof window !== "undefined" && window.parent !== window) {
|
|
8948
7535
|
window.parent.postMessage(data, "*");
|
|
8949
7536
|
}
|
|
8950
7537
|
}, []);
|
|
8951
|
-
const [fetchState, setFetchState] = (0,
|
|
8952
|
-
const autoSaveTimers = (0,
|
|
8953
|
-
const activeElRef = (0,
|
|
8954
|
-
const
|
|
8955
|
-
const
|
|
8956
|
-
const
|
|
8957
|
-
const
|
|
8958
|
-
const
|
|
8959
|
-
const
|
|
8960
|
-
const
|
|
8961
|
-
const visibleViewportRef = (0, import_react9.useRef)(null);
|
|
8962
|
-
const [dialogPortalContainer, setDialogPortalContainer] = (0, import_react9.useState)(null);
|
|
8963
|
-
const attachVisibleViewport = (0, import_react9.useCallback)((node) => {
|
|
7538
|
+
const [fetchState, setFetchState] = (0, import_react8.useState)("idle");
|
|
7539
|
+
const autoSaveTimers = (0, import_react8.useRef)(/* @__PURE__ */ new Map());
|
|
7540
|
+
const activeElRef = (0, import_react8.useRef)(null);
|
|
7541
|
+
const selectedElRef = (0, import_react8.useRef)(null);
|
|
7542
|
+
const originalContentRef = (0, import_react8.useRef)(null);
|
|
7543
|
+
const activeStateElRef = (0, import_react8.useRef)(null);
|
|
7544
|
+
const parentScrollRef = (0, import_react8.useRef)(null);
|
|
7545
|
+
const visibleViewportRef = (0, import_react8.useRef)(null);
|
|
7546
|
+
const [dialogPortalContainer, setDialogPortalContainer] = (0, import_react8.useState)(null);
|
|
7547
|
+
const attachVisibleViewport = (0, import_react8.useCallback)((node) => {
|
|
8964
7548
|
visibleViewportRef.current = node;
|
|
8965
7549
|
setDialogPortalContainer(node);
|
|
8966
7550
|
if (node) applyVisibleViewport(node, parentScrollRef.current);
|
|
8967
7551
|
}, []);
|
|
8968
|
-
const toolbarElRef = (0,
|
|
8969
|
-
const glowElRef = (0,
|
|
8970
|
-
const hoveredImageRef = (0,
|
|
8971
|
-
const hoveredImageHasTextOverlapRef = (0,
|
|
8972
|
-
const dragOverElRef = (0,
|
|
8973
|
-
const [mediaHover, setMediaHover] = (0,
|
|
8974
|
-
const [uploadingRects, setUploadingRects] = (0,
|
|
8975
|
-
const hoveredGapRef = (0,
|
|
8976
|
-
const imageUnhoverTimerRef = (0,
|
|
8977
|
-
const imageShowTimerRef = (0,
|
|
8978
|
-
const editStylesRef = (0,
|
|
8979
|
-
const activateRef = (0,
|
|
7552
|
+
const toolbarElRef = (0, import_react8.useRef)(null);
|
|
7553
|
+
const glowElRef = (0, import_react8.useRef)(null);
|
|
7554
|
+
const hoveredImageRef = (0, import_react8.useRef)(null);
|
|
7555
|
+
const hoveredImageHasTextOverlapRef = (0, import_react8.useRef)(false);
|
|
7556
|
+
const dragOverElRef = (0, import_react8.useRef)(null);
|
|
7557
|
+
const [mediaHover, setMediaHover] = (0, import_react8.useState)(null);
|
|
7558
|
+
const [uploadingRects, setUploadingRects] = (0, import_react8.useState)({});
|
|
7559
|
+
const hoveredGapRef = (0, import_react8.useRef)(null);
|
|
7560
|
+
const imageUnhoverTimerRef = (0, import_react8.useRef)(null);
|
|
7561
|
+
const imageShowTimerRef = (0, import_react8.useRef)(null);
|
|
7562
|
+
const editStylesRef = (0, import_react8.useRef)(null);
|
|
7563
|
+
const activateRef = (0, import_react8.useRef)(() => {
|
|
8980
7564
|
});
|
|
8981
|
-
const deactivateRef = (0,
|
|
7565
|
+
const deactivateRef = (0, import_react8.useRef)(() => {
|
|
8982
7566
|
});
|
|
8983
|
-
const selectRef = (0,
|
|
7567
|
+
const selectRef = (0, import_react8.useRef)(() => {
|
|
8984
7568
|
});
|
|
8985
|
-
const selectFrameRef = (0,
|
|
7569
|
+
const selectFrameRef = (0, import_react8.useRef)(() => {
|
|
8986
7570
|
});
|
|
8987
|
-
const deselectRef = (0,
|
|
7571
|
+
const deselectRef = (0, import_react8.useRef)(() => {
|
|
8988
7572
|
});
|
|
8989
|
-
const reselectNavigationItemRef = (0,
|
|
7573
|
+
const reselectNavigationItemRef = (0, import_react8.useRef)(() => {
|
|
8990
7574
|
});
|
|
8991
|
-
const commitNavigationTextEditRef = (0,
|
|
7575
|
+
const commitNavigationTextEditRef = (0, import_react8.useRef)(() => {
|
|
8992
7576
|
});
|
|
8993
|
-
const refreshActiveCommandsRef = (0,
|
|
7577
|
+
const refreshActiveCommandsRef = (0, import_react8.useRef)(() => {
|
|
8994
7578
|
});
|
|
8995
|
-
const postToParentRef = (0,
|
|
7579
|
+
const postToParentRef = (0, import_react8.useRef)(postToParent2);
|
|
8996
7580
|
postToParentRef.current = postToParent2;
|
|
8997
|
-
const sectionsLoadedRef = (0,
|
|
8998
|
-
const pendingScheduleConfigRequests = (0,
|
|
8999
|
-
const [toolbarRect, setToolbarRect] = (0,
|
|
9000
|
-
const [toolbarVariant, setToolbarVariant] = (0,
|
|
9001
|
-
const toolbarVariantRef = (0,
|
|
7581
|
+
const sectionsLoadedRef = (0, import_react8.useRef)(false);
|
|
7582
|
+
const pendingScheduleConfigRequests = (0, import_react8.useRef)([]);
|
|
7583
|
+
const [toolbarRect, setToolbarRect] = (0, import_react8.useState)(null);
|
|
7584
|
+
const [toolbarVariant, setToolbarVariant] = (0, import_react8.useState)("none");
|
|
7585
|
+
const toolbarVariantRef = (0, import_react8.useRef)("none");
|
|
9002
7586
|
toolbarVariantRef.current = toolbarVariant;
|
|
9003
|
-
const [
|
|
9004
|
-
const [
|
|
9005
|
-
const [
|
|
9006
|
-
const [
|
|
9007
|
-
const [
|
|
9008
|
-
const [
|
|
9009
|
-
const [
|
|
9010
|
-
const
|
|
9011
|
-
const
|
|
9012
|
-
const
|
|
9013
|
-
const
|
|
9014
|
-
const
|
|
9015
|
-
const
|
|
9016
|
-
const [
|
|
9017
|
-
const [
|
|
9018
|
-
const
|
|
9019
|
-
const
|
|
9020
|
-
const
|
|
9021
|
-
const [
|
|
9022
|
-
const [
|
|
9023
|
-
const
|
|
9024
|
-
const
|
|
9025
|
-
const
|
|
9026
|
-
const
|
|
9027
|
-
const
|
|
9028
|
-
const linkPopoverSessionRef = (0, import_react9.useRef)(null);
|
|
9029
|
-
const addNavAfterAnchorRef = (0, import_react9.useRef)(null);
|
|
9030
|
-
const editContentRef = (0, import_react9.useRef)({});
|
|
9031
|
-
const [sitePages, setSitePages] = (0, import_react9.useState)([]);
|
|
9032
|
-
const [sectionsByPath, setSectionsByPath] = (0, import_react9.useState)({});
|
|
9033
|
-
const sectionsPrefetchGenRef = (0, import_react9.useRef)(0);
|
|
9034
|
-
const setLinkPopoverRef = (0, import_react9.useRef)(setLinkPopover);
|
|
9035
|
-
const linkPopoverPanelRef = (0, import_react9.useRef)(null);
|
|
9036
|
-
const linkPopoverOpenRef = (0, import_react9.useRef)(false);
|
|
9037
|
-
const linkPopoverGraceUntilRef = (0, import_react9.useRef)(0);
|
|
7587
|
+
const [reorderHrefKey, setReorderHrefKey] = (0, import_react8.useState)(null);
|
|
7588
|
+
const [reorderDragDisabled, setReorderDragDisabled] = (0, import_react8.useState)(false);
|
|
7589
|
+
const [toggleState, setToggleState] = (0, import_react8.useState)(null);
|
|
7590
|
+
const [maxBadge, setMaxBadge] = (0, import_react8.useState)(null);
|
|
7591
|
+
const [activeCommands, setActiveCommands] = (0, import_react8.useState)(/* @__PURE__ */ new Set());
|
|
7592
|
+
const [sectionGap, setSectionGap] = (0, import_react8.useState)(null);
|
|
7593
|
+
const [toolbarShowEditLink, setToolbarShowEditLink] = (0, import_react8.useState)(false);
|
|
7594
|
+
const hoveredNavContainerRef = (0, import_react8.useRef)(null);
|
|
7595
|
+
const [hoveredNavContainerRect, setHoveredNavContainerRect] = (0, import_react8.useState)(null);
|
|
7596
|
+
const hoveredItemElRef = (0, import_react8.useRef)(null);
|
|
7597
|
+
const [hoveredItemRect, setHoveredItemRect] = (0, import_react8.useState)(null);
|
|
7598
|
+
const siblingHintElRef = (0, import_react8.useRef)(null);
|
|
7599
|
+
const [siblingHintRect, setSiblingHintRect] = (0, import_react8.useState)(null);
|
|
7600
|
+
const [isItemDragging, setIsItemDragging] = (0, import_react8.useState)(false);
|
|
7601
|
+
const [linkPopover, setLinkPopover] = (0, import_react8.useState)(null);
|
|
7602
|
+
const linkPopoverSessionRef = (0, import_react8.useRef)(null);
|
|
7603
|
+
const addNavAfterAnchorRef = (0, import_react8.useRef)(null);
|
|
7604
|
+
const editContentRef = (0, import_react8.useRef)({});
|
|
7605
|
+
const [sitePages, setSitePages] = (0, import_react8.useState)([]);
|
|
7606
|
+
const [sectionsByPath, setSectionsByPath] = (0, import_react8.useState)({});
|
|
7607
|
+
const sectionsPrefetchGenRef = (0, import_react8.useRef)(0);
|
|
7608
|
+
const setLinkPopoverRef = (0, import_react8.useRef)(setLinkPopover);
|
|
7609
|
+
const linkPopoverPanelRef = (0, import_react8.useRef)(null);
|
|
7610
|
+
const linkPopoverOpenRef = (0, import_react8.useRef)(false);
|
|
7611
|
+
const linkPopoverGraceUntilRef = (0, import_react8.useRef)(0);
|
|
9038
7612
|
setLinkPopoverRef.current = setLinkPopover;
|
|
9039
7613
|
linkPopoverSessionRef.current = linkPopover;
|
|
9040
|
-
const {
|
|
9041
|
-
navDragRef,
|
|
9042
|
-
navDropSlots,
|
|
9043
|
-
activeNavDropIndex,
|
|
9044
|
-
startNavLinkDrag,
|
|
9045
|
-
commitNavDrag,
|
|
9046
|
-
onNavDragOver,
|
|
9047
|
-
armNavPressFromChrome,
|
|
9048
|
-
refreshNavDragVisualsRef
|
|
9049
|
-
} = useNavItemDrag({
|
|
9050
|
-
isEditMode,
|
|
9051
|
-
editContentRef,
|
|
9052
|
-
selectedElRef,
|
|
9053
|
-
activeElRef,
|
|
9054
|
-
footerDragRef,
|
|
9055
|
-
suppressNextClickRef,
|
|
9056
|
-
suppressClickUntilRef,
|
|
9057
|
-
siblingHintElRef,
|
|
9058
|
-
postToParentRef,
|
|
9059
|
-
deselectRef,
|
|
9060
|
-
selectRef,
|
|
9061
|
-
deactivateRef,
|
|
9062
|
-
setLinkPopover: () => setLinkPopover(null),
|
|
9063
|
-
linkPopoverOpenRef,
|
|
9064
|
-
setIsItemDragging,
|
|
9065
|
-
setDraggedItemRect,
|
|
9066
|
-
setSiblingHintRect,
|
|
9067
|
-
setSiblingHintRects,
|
|
9068
|
-
setToolbarRect,
|
|
9069
|
-
getNavigationItemAnchor,
|
|
9070
|
-
isDragHandleDisabled,
|
|
9071
|
-
isNavbarButton: isNavbarButton2
|
|
9072
|
-
});
|
|
9073
7614
|
const bumpLinkPopoverGrace = () => {
|
|
9074
7615
|
linkPopoverGraceUntilRef.current = Date.now() + 350;
|
|
9075
7616
|
};
|
|
9076
|
-
const runSectionsPrefetch = (0,
|
|
7617
|
+
const runSectionsPrefetch = (0, import_react8.useCallback)((pages) => {
|
|
9077
7618
|
if (!isEditMode || shouldUseDevFixtures() || pages.length === 0) return;
|
|
9078
7619
|
const gen = ++sectionsPrefetchGenRef.current;
|
|
9079
7620
|
const paths = pages.map((p) => p.path);
|
|
@@ -9092,24 +7633,10 @@ function OhhwellsBridge() {
|
|
|
9092
7633
|
);
|
|
9093
7634
|
});
|
|
9094
7635
|
}, [isEditMode, pathname]);
|
|
9095
|
-
const runSectionsPrefetchRef = (0,
|
|
7636
|
+
const runSectionsPrefetchRef = (0, import_react8.useRef)(runSectionsPrefetch);
|
|
9096
7637
|
runSectionsPrefetchRef.current = runSectionsPrefetch;
|
|
9097
|
-
(0,
|
|
9098
|
-
if (!linkPopover)
|
|
9099
|
-
document.documentElement.removeAttribute("data-ohw-link-popover-open");
|
|
9100
|
-
return;
|
|
9101
|
-
}
|
|
9102
|
-
document.documentElement.setAttribute("data-ohw-link-popover-open", "");
|
|
9103
|
-
hoveredItemElRef.current = null;
|
|
9104
|
-
setHoveredItemRect(null);
|
|
9105
|
-
hoveredNavContainerRef.current = null;
|
|
9106
|
-
setHoveredNavContainerRect(null);
|
|
9107
|
-
siblingHintElRef.current = null;
|
|
9108
|
-
setSiblingHintRect(null);
|
|
9109
|
-
setSiblingHintRects([]);
|
|
9110
|
-
if (selectedElRef.current || toolbarVariantRef.current !== "none") {
|
|
9111
|
-
deselectRef.current();
|
|
9112
|
-
}
|
|
7638
|
+
(0, import_react8.useEffect)(() => {
|
|
7639
|
+
if (!linkPopover) return;
|
|
9113
7640
|
if (hoveredImageRef.current) {
|
|
9114
7641
|
hoveredImageRef.current = null;
|
|
9115
7642
|
hoveredImageHasTextOverlapRef.current = false;
|
|
@@ -9143,7 +7670,7 @@ function OhhwellsBridge() {
|
|
|
9143
7670
|
document.removeEventListener("touchmove", preventBackgroundScroll, scrollOpts);
|
|
9144
7671
|
};
|
|
9145
7672
|
}, [linkPopover, postToParent2]);
|
|
9146
|
-
(0,
|
|
7673
|
+
(0, import_react8.useEffect)(() => {
|
|
9147
7674
|
if (!isEditMode) return;
|
|
9148
7675
|
const useFixtures = shouldUseDevFixtures();
|
|
9149
7676
|
if (useFixtures) {
|
|
@@ -9167,14 +7694,14 @@ function OhhwellsBridge() {
|
|
|
9167
7694
|
if (!useFixtures) postToParent2({ type: "ow:request-site-pages" });
|
|
9168
7695
|
return () => window.removeEventListener("message", onSitePages);
|
|
9169
7696
|
}, [isEditMode, postToParent2]);
|
|
9170
|
-
(0,
|
|
7697
|
+
(0, import_react8.useEffect)(() => {
|
|
9171
7698
|
if (!isEditMode || shouldUseDevFixtures()) return;
|
|
9172
7699
|
void loadAllSectionsManifest().then((manifest) => {
|
|
9173
7700
|
if (Object.keys(manifest).length === 0) return;
|
|
9174
7701
|
setSectionsByPath((prev) => ({ ...manifest, ...prev }));
|
|
9175
7702
|
});
|
|
9176
7703
|
}, [isEditMode]);
|
|
9177
|
-
(0,
|
|
7704
|
+
(0, import_react8.useEffect)(() => {
|
|
9178
7705
|
const update = () => {
|
|
9179
7706
|
const el = activeElRef.current ?? selectedElRef.current;
|
|
9180
7707
|
if (el) setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
|
|
@@ -9198,10 +7725,10 @@ function OhhwellsBridge() {
|
|
|
9198
7725
|
vvp.removeEventListener("resize", update);
|
|
9199
7726
|
};
|
|
9200
7727
|
}, []);
|
|
9201
|
-
const refreshStateRules = (0,
|
|
7728
|
+
const refreshStateRules = (0, import_react8.useCallback)(() => {
|
|
9202
7729
|
editStylesRef.current?.forceHover && (editStylesRef.current.forceHover.textContent = collectStateRules());
|
|
9203
7730
|
}, []);
|
|
9204
|
-
const processConfigRequest = (0,
|
|
7731
|
+
const processConfigRequest = (0, import_react8.useCallback)((insertAfterVal) => {
|
|
9205
7732
|
const tracker = getSectionsTracker();
|
|
9206
7733
|
let entries = [];
|
|
9207
7734
|
try {
|
|
@@ -9224,7 +7751,7 @@ function OhhwellsBridge() {
|
|
|
9224
7751
|
}
|
|
9225
7752
|
window.postMessage({ type: "ow:schedule-config", insertAfter: insertAfterVal, scheduleId: null }, "*");
|
|
9226
7753
|
}, [isEditMode]);
|
|
9227
|
-
const deactivate = (0,
|
|
7754
|
+
const deactivate = (0, import_react8.useCallback)(() => {
|
|
9228
7755
|
const el = activeElRef.current;
|
|
9229
7756
|
if (!el) return;
|
|
9230
7757
|
const key = el.dataset.ohwKey;
|
|
@@ -9243,7 +7770,6 @@ function OhhwellsBridge() {
|
|
|
9243
7770
|
}
|
|
9244
7771
|
}
|
|
9245
7772
|
el.removeAttribute("contenteditable");
|
|
9246
|
-
el.removeAttribute("data-ohw-editing");
|
|
9247
7773
|
activeElRef.current = null;
|
|
9248
7774
|
setReorderHrefKey(null);
|
|
9249
7775
|
setReorderDragDisabled(false);
|
|
@@ -9256,23 +7782,12 @@ function OhhwellsBridge() {
|
|
|
9256
7782
|
setToolbarShowEditLink(false);
|
|
9257
7783
|
postToParent2({ type: "ow:exit-edit" });
|
|
9258
7784
|
}, [postToParent2]);
|
|
9259
|
-
const
|
|
9260
|
-
document.querySelectorAll("[data-ohw-selected]").forEach((el) => {
|
|
9261
|
-
el.removeAttribute("data-ohw-selected");
|
|
9262
|
-
});
|
|
9263
|
-
}, []);
|
|
9264
|
-
const deselect = (0, import_react9.useCallback)(() => {
|
|
9265
|
-
clearSelectedAttr();
|
|
7785
|
+
const deselect = (0, import_react8.useCallback)(() => {
|
|
9266
7786
|
selectedElRef.current = null;
|
|
9267
|
-
selectedHrefKeyRef.current = null;
|
|
9268
|
-
selectedFooterColAttrRef.current = null;
|
|
9269
|
-
setSelectedIsCta(false);
|
|
9270
7787
|
setReorderHrefKey(null);
|
|
9271
7788
|
setReorderDragDisabled(false);
|
|
9272
|
-
setIsFooterFrameSelection(false);
|
|
9273
7789
|
siblingHintElRef.current = null;
|
|
9274
7790
|
setSiblingHintRect(null);
|
|
9275
|
-
setSiblingHintRects([]);
|
|
9276
7791
|
setIsItemDragging(false);
|
|
9277
7792
|
hoveredNavContainerRef.current = null;
|
|
9278
7793
|
setHoveredNavContainerRect(null);
|
|
@@ -9280,70 +7795,18 @@ function OhhwellsBridge() {
|
|
|
9280
7795
|
setToolbarRect(null);
|
|
9281
7796
|
setToolbarVariant("none");
|
|
9282
7797
|
}
|
|
9283
|
-
}, [clearSelectedAttr]);
|
|
9284
|
-
const markSelected = (0, import_react9.useCallback)((el) => {
|
|
9285
|
-
clearSelectedAttr();
|
|
9286
|
-
el.setAttribute("data-ohw-selected", "");
|
|
9287
|
-
}, [clearSelectedAttr]);
|
|
9288
|
-
const resolveHrefKeyElement = (0, import_react9.useCallback)((hrefKey) => {
|
|
9289
|
-
if (isFooterHrefKey(hrefKey)) {
|
|
9290
|
-
return document.querySelector(
|
|
9291
|
-
`footer [data-ohw-href-key="${CSS.escape(hrefKey)}"]`
|
|
9292
|
-
);
|
|
9293
|
-
}
|
|
9294
|
-
if (isNavbarHrefKey(hrefKey)) {
|
|
9295
|
-
const desktop = document.querySelector("[data-ohw-nav-container]");
|
|
9296
|
-
const drawer = document.querySelector("[data-ohw-nav-drawer]");
|
|
9297
|
-
return desktop?.querySelector(`[data-ohw-href-key="${CSS.escape(hrefKey)}"]`) ?? drawer?.querySelector(`[data-ohw-href-key="${CSS.escape(hrefKey)}"]`) ?? document.querySelector(`[data-ohw-href-key="${CSS.escape(hrefKey)}"]`);
|
|
9298
|
-
}
|
|
9299
|
-
return document.querySelector(
|
|
9300
|
-
`[data-ohw-href-key="${CSS.escape(hrefKey)}"]`
|
|
9301
|
-
);
|
|
9302
7798
|
}, []);
|
|
9303
|
-
const
|
|
9304
|
-
const hrefKey = selectedHrefKeyRef.current;
|
|
9305
|
-
if (hrefKey) {
|
|
9306
|
-
const link = resolveHrefKeyElement(hrefKey);
|
|
9307
|
-
if (!link || !isNavigationItem(link)) return;
|
|
9308
|
-
selectedElRef.current = link;
|
|
9309
|
-
const { key, disabled } = getNavigationItemReorderState(link);
|
|
9310
|
-
setReorderHrefKey(key);
|
|
9311
|
-
setReorderDragDisabled(disabled);
|
|
9312
|
-
setIsFooterFrameSelection(false);
|
|
9313
|
-
setToolbarVariant("link-action");
|
|
9314
|
-
setToolbarRect(link.getBoundingClientRect());
|
|
9315
|
-
setSiblingHintRects(collectNavigationItemSiblingHintRects(link));
|
|
9316
|
-
return;
|
|
9317
|
-
}
|
|
9318
|
-
const colAttr = selectedFooterColAttrRef.current;
|
|
9319
|
-
if (colAttr != null) {
|
|
9320
|
-
const column = document.querySelector(`[data-ohw-footer-col="${CSS.escape(colAttr)}"]`) ?? listFooterColumns()[Number(colAttr)] ?? null;
|
|
9321
|
-
if (!column || !isNavigationContainer(column)) return;
|
|
9322
|
-
selectedElRef.current = column;
|
|
9323
|
-
setIsFooterFrameSelection(true);
|
|
9324
|
-
setToolbarVariant("select-frame");
|
|
9325
|
-
setToolbarRect(column.getBoundingClientRect());
|
|
9326
|
-
setSiblingHintRects(
|
|
9327
|
-
listFooterColumns().filter((c) => c !== column).map((c) => c.getBoundingClientRect())
|
|
9328
|
-
);
|
|
9329
|
-
}
|
|
9330
|
-
}, [resolveHrefKeyElement]);
|
|
9331
|
-
const reselectNavigationItem = (0, import_react9.useCallback)((navAnchor) => {
|
|
7799
|
+
const reselectNavigationItem = (0, import_react8.useCallback)((navAnchor) => {
|
|
9332
7800
|
selectedElRef.current = navAnchor;
|
|
9333
|
-
selectedHrefKeyRef.current = navAnchor.getAttribute("data-ohw-href-key");
|
|
9334
|
-
selectedFooterColAttrRef.current = null;
|
|
9335
|
-
markSelected(navAnchor);
|
|
9336
|
-
setSelectedIsCta(isNavbarButton2(navAnchor));
|
|
9337
7801
|
const { key, disabled } = getNavigationItemReorderState(navAnchor);
|
|
9338
7802
|
setReorderHrefKey(key);
|
|
9339
7803
|
setReorderDragDisabled(disabled);
|
|
9340
7804
|
setToolbarVariant("link-action");
|
|
9341
7805
|
setToolbarRect(navAnchor.getBoundingClientRect());
|
|
9342
|
-
setSiblingHintRects(collectNavigationItemSiblingHintRects(navAnchor));
|
|
9343
7806
|
setToolbarShowEditLink(false);
|
|
9344
7807
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
9345
|
-
}, [
|
|
9346
|
-
const commitNavigationTextEdit = (0,
|
|
7808
|
+
}, []);
|
|
7809
|
+
const commitNavigationTextEdit = (0, import_react8.useCallback)((navAnchor) => {
|
|
9347
7810
|
const el = activeElRef.current;
|
|
9348
7811
|
if (!el) return;
|
|
9349
7812
|
const key = el.dataset.ohwKey;
|
|
@@ -9362,7 +7825,6 @@ function OhhwellsBridge() {
|
|
|
9362
7825
|
}
|
|
9363
7826
|
}
|
|
9364
7827
|
el.removeAttribute("contenteditable");
|
|
9365
|
-
el.removeAttribute("data-ohw-editing");
|
|
9366
7828
|
activeElRef.current = null;
|
|
9367
7829
|
setMaxBadge(null);
|
|
9368
7830
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
@@ -9370,7 +7832,7 @@ function OhhwellsBridge() {
|
|
|
9370
7832
|
postToParent2({ type: "ow:exit-edit" });
|
|
9371
7833
|
reselectNavigationItem(navAnchor);
|
|
9372
7834
|
}, [postToParent2, reselectNavigationItem]);
|
|
9373
|
-
const handleAddTopLevelNavItem = (0,
|
|
7835
|
+
const handleAddTopLevelNavItem = (0, import_react8.useCallback)(() => {
|
|
9374
7836
|
const items = listNavbarItems();
|
|
9375
7837
|
addNavAfterAnchorRef.current = items[items.length - 1] ?? null;
|
|
9376
7838
|
deselectRef.current();
|
|
@@ -9382,321 +7844,20 @@ function OhhwellsBridge() {
|
|
|
9382
7844
|
intent: "add-nav"
|
|
9383
7845
|
});
|
|
9384
7846
|
}, []);
|
|
9385
|
-
const
|
|
9386
|
-
|
|
9387
|
-
|
|
9388
|
-
|
|
9389
|
-
setActiveFooterDropIndex(null);
|
|
9390
|
-
setDraggedItemRect(null);
|
|
9391
|
-
setIsItemDragging(false);
|
|
9392
|
-
unlockFooterDragInteraction();
|
|
9393
|
-
}, []);
|
|
9394
|
-
const refreshFooterDragVisuals = (0, import_react9.useCallback)((session, activeSlot, clientX, clientY) => {
|
|
9395
|
-
const dragged = session.draggedEl;
|
|
9396
|
-
setDraggedItemRect(dragged.getBoundingClientRect());
|
|
9397
|
-
if (typeof clientX === "number" && typeof clientY === "number") {
|
|
9398
|
-
session.lastClientX = clientX;
|
|
9399
|
-
session.lastClientY = clientY;
|
|
9400
|
-
}
|
|
9401
|
-
session.activeSlot = activeSlot;
|
|
9402
|
-
if (session.kind === "link") {
|
|
9403
|
-
const columns2 = listFooterColumns();
|
|
9404
|
-
const focusCols = /* @__PURE__ */ new Set([session.sourceColumnIndex]);
|
|
9405
|
-
if (activeSlot) focusCols.add(activeSlot.columnIndex);
|
|
9406
|
-
const siblingRects = [];
|
|
9407
|
-
columns2.forEach((col, i) => {
|
|
9408
|
-
if (!focusCols.has(i)) return;
|
|
9409
|
-
for (const link of listFooterLinksInColumn(col)) {
|
|
9410
|
-
if (link === dragged) continue;
|
|
9411
|
-
siblingRects.push(link.getBoundingClientRect());
|
|
9412
|
-
}
|
|
9413
|
-
});
|
|
9414
|
-
setSiblingHintRects(siblingRects);
|
|
9415
|
-
const slots2 = [];
|
|
9416
|
-
columns2.forEach((col, i) => {
|
|
9417
|
-
slots2.push(...buildLinkDropSlots(col, i));
|
|
9418
|
-
});
|
|
9419
|
-
setFooterDropSlots(slots2);
|
|
9420
|
-
const activeIdx2 = activeSlot ? slots2.findIndex((s) => s.columnIndex === activeSlot.columnIndex && s.insertIndex === activeSlot.insertIndex) : -1;
|
|
9421
|
-
setActiveFooterDropIndex(activeIdx2 >= 0 ? activeIdx2 : null);
|
|
9422
|
-
return;
|
|
9423
|
-
}
|
|
9424
|
-
const columns = listFooterColumns();
|
|
9425
|
-
setSiblingHintRects(columns.filter((col) => col !== dragged).map((col) => col.getBoundingClientRect()));
|
|
9426
|
-
const slots = buildColumnDropSlots();
|
|
9427
|
-
setFooterDropSlots(slots);
|
|
9428
|
-
const activeIdx = activeSlot ? slots.findIndex((s) => s.insertIndex === activeSlot.insertIndex) : -1;
|
|
9429
|
-
setActiveFooterDropIndex(activeIdx >= 0 ? activeIdx : null);
|
|
7847
|
+
const handleItemDragStart = (0, import_react8.useCallback)(() => {
|
|
7848
|
+
siblingHintElRef.current = null;
|
|
7849
|
+
setSiblingHintRect(null);
|
|
7850
|
+
setIsItemDragging(true);
|
|
9430
7851
|
}, []);
|
|
9431
|
-
const
|
|
9432
|
-
|
|
9433
|
-
const commitFooterDragRef = (0, import_react9.useRef)(() => {
|
|
9434
|
-
});
|
|
9435
|
-
const beginFooterDragRef = (0, import_react9.useRef)(() => {
|
|
9436
|
-
});
|
|
9437
|
-
const beginFooterDrag = (0, import_react9.useCallback)(
|
|
9438
|
-
(session) => {
|
|
9439
|
-
const rect = session.draggedEl.getBoundingClientRect();
|
|
9440
|
-
session.lastClientX = session.lastClientX || rect.left + rect.width / 2;
|
|
9441
|
-
session.lastClientY = session.lastClientY || rect.top + rect.height / 2;
|
|
9442
|
-
session.activeSlot = session.activeSlot ?? null;
|
|
9443
|
-
footerDragRef.current = session;
|
|
9444
|
-
setIsItemDragging(true);
|
|
9445
|
-
lockFooterDuringDrag();
|
|
9446
|
-
siblingHintElRef.current = null;
|
|
9447
|
-
setSiblingHintRect(null);
|
|
9448
|
-
if (session.wasSelected && selectedElRef.current === session.draggedEl) {
|
|
9449
|
-
setToolbarRect(rect);
|
|
9450
|
-
}
|
|
9451
|
-
const initialSlot = session.kind === "link" && session.hrefKey ? hitTestLinkDropSlot(session.lastClientX, session.lastClientY, session.hrefKey) : hitTestColumnDropSlot(session.lastClientX, session.lastClientY);
|
|
9452
|
-
refreshFooterDragVisuals(session, initialSlot, session.lastClientX, session.lastClientY);
|
|
9453
|
-
},
|
|
9454
|
-
[refreshFooterDragVisuals]
|
|
9455
|
-
);
|
|
9456
|
-
beginFooterDragRef.current = beginFooterDrag;
|
|
9457
|
-
const commitFooterDrag = (0, import_react9.useCallback)(
|
|
9458
|
-
(clientX, clientY) => {
|
|
9459
|
-
const session = footerDragRef.current;
|
|
9460
|
-
if (!session) {
|
|
9461
|
-
clearFooterDragVisuals();
|
|
9462
|
-
return;
|
|
9463
|
-
}
|
|
9464
|
-
const x = typeof clientX === "number" && (clientX !== 0 || clientY !== 0) ? clientX : session.lastClientX;
|
|
9465
|
-
const y = typeof clientY === "number" && (clientX !== 0 || clientY !== 0) ? clientY : session.lastClientY;
|
|
9466
|
-
let nextOrder = null;
|
|
9467
|
-
const slot = session.activeSlot ?? (session.kind === "link" && session.hrefKey ? hitTestLinkDropSlot(x, y, session.hrefKey) : session.kind === "column" ? hitTestColumnDropSlot(x, y) : null);
|
|
9468
|
-
if (session.kind === "link" && session.hrefKey && slot) {
|
|
9469
|
-
nextOrder = planFooterLinkMove(session.hrefKey, slot.columnIndex, slot.insertIndex);
|
|
9470
|
-
} else if (session.kind === "column" && slot) {
|
|
9471
|
-
nextOrder = planFooterColumnMove(session.sourceColumnIndex, slot.insertIndex);
|
|
9472
|
-
}
|
|
9473
|
-
const wasSelected = session.wasSelected;
|
|
9474
|
-
const draggedEl = session.draggedEl;
|
|
9475
|
-
const hrefKey = session.hrefKey;
|
|
9476
|
-
let movedColumnIndex = null;
|
|
9477
|
-
if (session.kind === "column" && slot && nextOrder) {
|
|
9478
|
-
let adjusted = slot.insertIndex;
|
|
9479
|
-
if (session.sourceColumnIndex < slot.insertIndex) adjusted -= 1;
|
|
9480
|
-
movedColumnIndex = Math.max(0, Math.min(adjusted, nextOrder.length - 1));
|
|
9481
|
-
}
|
|
9482
|
-
const applySelectionAfterDrop = () => {
|
|
9483
|
-
if (!wasSelected) {
|
|
9484
|
-
deselectRef.current();
|
|
9485
|
-
return;
|
|
9486
|
-
}
|
|
9487
|
-
if (hrefKey) {
|
|
9488
|
-
selectedHrefKeyRef.current = hrefKey;
|
|
9489
|
-
selectedFooterColAttrRef.current = null;
|
|
9490
|
-
const link = resolveHrefKeyElement(hrefKey);
|
|
9491
|
-
if (link && isNavigationItem(link)) {
|
|
9492
|
-
selectRef.current(link);
|
|
9493
|
-
return;
|
|
9494
|
-
}
|
|
9495
|
-
}
|
|
9496
|
-
if (movedColumnIndex !== null && nextOrder) {
|
|
9497
|
-
const colKeys = nextOrder[movedColumnIndex] ?? [];
|
|
9498
|
-
let column = null;
|
|
9499
|
-
for (const key of colKeys) {
|
|
9500
|
-
const link = document.querySelector(
|
|
9501
|
-
`footer [data-ohw-href-key="${CSS.escape(key)}"]`
|
|
9502
|
-
);
|
|
9503
|
-
if (link) {
|
|
9504
|
-
column = findFooterColumnForLink(link);
|
|
9505
|
-
if (column) break;
|
|
9506
|
-
}
|
|
9507
|
-
}
|
|
9508
|
-
if (!column) column = listFooterColumns()[movedColumnIndex] ?? null;
|
|
9509
|
-
if (column && isNavigationContainer(column)) {
|
|
9510
|
-
selectFrameRef.current(column);
|
|
9511
|
-
return;
|
|
9512
|
-
}
|
|
9513
|
-
}
|
|
9514
|
-
if (document.body.contains(draggedEl)) {
|
|
9515
|
-
if (isNavigationItem(draggedEl)) {
|
|
9516
|
-
selectRef.current(draggedEl);
|
|
9517
|
-
return;
|
|
9518
|
-
}
|
|
9519
|
-
if (isNavigationContainer(draggedEl)) {
|
|
9520
|
-
selectFrameRef.current(draggedEl);
|
|
9521
|
-
return;
|
|
9522
|
-
}
|
|
9523
|
-
}
|
|
9524
|
-
deselectRef.current();
|
|
9525
|
-
};
|
|
9526
|
-
if (nextOrder) {
|
|
9527
|
-
const orderJson = JSON.stringify(nextOrder);
|
|
9528
|
-
editContentRef.current = {
|
|
9529
|
-
...editContentRef.current,
|
|
9530
|
-
[FOOTER_ORDER_KEY]: orderJson
|
|
9531
|
-
};
|
|
9532
|
-
applyFooterOrder(nextOrder);
|
|
9533
|
-
document.querySelectorAll("footer [data-ohw-href-key]").forEach(disableNativeHrefDrag);
|
|
9534
|
-
postToParentRef.current({
|
|
9535
|
-
type: "ow:change",
|
|
9536
|
-
nodes: [{ key: FOOTER_ORDER_KEY, text: orderJson }]
|
|
9537
|
-
});
|
|
9538
|
-
applySelectionAfterDrop();
|
|
9539
|
-
clearFooterDragVisuals();
|
|
9540
|
-
requestAnimationFrame(() => {
|
|
9541
|
-
if (editContentRef.current[FOOTER_ORDER_KEY] === orderJson) {
|
|
9542
|
-
applyFooterOrder(nextOrder);
|
|
9543
|
-
document.querySelectorAll("footer [data-ohw-href-key]").forEach(disableNativeHrefDrag);
|
|
9544
|
-
}
|
|
9545
|
-
applySelectionAfterDrop();
|
|
9546
|
-
requestAnimationFrame(() => {
|
|
9547
|
-
if (editContentRef.current[FOOTER_ORDER_KEY] === orderJson) {
|
|
9548
|
-
applyFooterOrder(nextOrder);
|
|
9549
|
-
}
|
|
9550
|
-
resyncSelectedNavigationItem();
|
|
9551
|
-
});
|
|
9552
|
-
});
|
|
9553
|
-
return;
|
|
9554
|
-
}
|
|
9555
|
-
applySelectionAfterDrop();
|
|
9556
|
-
clearFooterDragVisuals();
|
|
9557
|
-
},
|
|
9558
|
-
[clearFooterDragVisuals, resolveHrefKeyElement, resyncSelectedNavigationItem]
|
|
9559
|
-
);
|
|
9560
|
-
commitFooterDragRef.current = commitFooterDrag;
|
|
9561
|
-
const startFooterLinkDrag = (0, import_react9.useCallback)(
|
|
9562
|
-
(anchor, clientX, clientY, wasSelected) => {
|
|
9563
|
-
const hrefKey = anchor.getAttribute("data-ohw-href-key");
|
|
9564
|
-
if (!hrefKey || !isFooterHrefKey(hrefKey)) return false;
|
|
9565
|
-
const column = findFooterColumnForLink(anchor);
|
|
9566
|
-
const columns = listFooterColumns();
|
|
9567
|
-
beginFooterDrag({
|
|
9568
|
-
kind: "link",
|
|
9569
|
-
hrefKey,
|
|
9570
|
-
columnEl: column,
|
|
9571
|
-
sourceColumnIndex: column ? columns.indexOf(column) : 0,
|
|
9572
|
-
wasSelected,
|
|
9573
|
-
draggedEl: anchor,
|
|
9574
|
-
lastClientX: clientX,
|
|
9575
|
-
lastClientY: clientY,
|
|
9576
|
-
activeSlot: null
|
|
9577
|
-
});
|
|
9578
|
-
return true;
|
|
9579
|
-
},
|
|
9580
|
-
[beginFooterDrag]
|
|
9581
|
-
);
|
|
9582
|
-
const startFooterColumnDrag = (0, import_react9.useCallback)(
|
|
9583
|
-
(columnEl, clientX, clientY, wasSelected) => {
|
|
9584
|
-
const columns = listFooterColumns();
|
|
9585
|
-
const idx = columns.indexOf(columnEl);
|
|
9586
|
-
if (idx < 0) return false;
|
|
9587
|
-
beginFooterDrag({
|
|
9588
|
-
kind: "column",
|
|
9589
|
-
hrefKey: null,
|
|
9590
|
-
columnEl,
|
|
9591
|
-
sourceColumnIndex: idx,
|
|
9592
|
-
wasSelected,
|
|
9593
|
-
draggedEl: columnEl,
|
|
9594
|
-
lastClientX: clientX,
|
|
9595
|
-
lastClientY: clientY,
|
|
9596
|
-
activeSlot: null
|
|
9597
|
-
});
|
|
9598
|
-
return true;
|
|
9599
|
-
},
|
|
9600
|
-
[beginFooterDrag]
|
|
9601
|
-
);
|
|
9602
|
-
const handleItemDragStart = (0, import_react9.useCallback)(
|
|
9603
|
-
(e) => {
|
|
9604
|
-
const selected = selectedElRef.current;
|
|
9605
|
-
if (!selected) {
|
|
9606
|
-
setIsItemDragging(true);
|
|
9607
|
-
return;
|
|
9608
|
-
}
|
|
9609
|
-
const clientX = e?.clientX ?? selected.getBoundingClientRect().left + 8;
|
|
9610
|
-
const clientY = e?.clientY ?? selected.getBoundingClientRect().top + 8;
|
|
9611
|
-
if (startFooterLinkDrag(selected, clientX, clientY, true)) return;
|
|
9612
|
-
if (selected.hasAttribute("data-ohw-footer-col") || isInferredFooterGroup(selected) && selected.closest("footer")) {
|
|
9613
|
-
if (startFooterColumnDrag(selected, clientX, clientY, true)) return;
|
|
9614
|
-
}
|
|
9615
|
-
if (startNavLinkDrag(selected, clientX, clientY, true)) return;
|
|
9616
|
-
siblingHintElRef.current = null;
|
|
9617
|
-
setSiblingHintRect(null);
|
|
9618
|
-
setIsItemDragging(true);
|
|
9619
|
-
},
|
|
9620
|
-
[startFooterColumnDrag, startFooterLinkDrag, startNavLinkDrag]
|
|
9621
|
-
);
|
|
9622
|
-
const handleItemDragEnd = (0, import_react9.useCallback)(
|
|
9623
|
-
(e) => {
|
|
9624
|
-
if (footerDragRef.current) {
|
|
9625
|
-
const x = e?.clientX;
|
|
9626
|
-
const y = e?.clientY;
|
|
9627
|
-
if (typeof x === "number" && typeof y === "number" && (x !== 0 || y !== 0)) {
|
|
9628
|
-
commitFooterDrag(x, y);
|
|
9629
|
-
} else {
|
|
9630
|
-
commitFooterDrag();
|
|
9631
|
-
}
|
|
9632
|
-
return;
|
|
9633
|
-
}
|
|
9634
|
-
if (navDragRef.current) {
|
|
9635
|
-
const x = e?.clientX;
|
|
9636
|
-
const y = e?.clientY;
|
|
9637
|
-
if (typeof x === "number" && typeof y === "number" && (x !== 0 || y !== 0)) {
|
|
9638
|
-
commitNavDrag(x, y);
|
|
9639
|
-
} else {
|
|
9640
|
-
commitNavDrag();
|
|
9641
|
-
}
|
|
9642
|
-
return;
|
|
9643
|
-
}
|
|
9644
|
-
setIsItemDragging(false);
|
|
9645
|
-
},
|
|
9646
|
-
[commitFooterDrag, commitNavDrag, navDragRef]
|
|
9647
|
-
);
|
|
9648
|
-
const handleItemChromePointerDown = (0, import_react9.useCallback)((e) => {
|
|
9649
|
-
if (e.button !== 0) return;
|
|
9650
|
-
const selected = selectedElRef.current;
|
|
9651
|
-
if (!selected) return;
|
|
9652
|
-
const hrefKey = selected.getAttribute("data-ohw-href-key");
|
|
9653
|
-
if (hrefKey && isFooterHrefKey(hrefKey)) {
|
|
9654
|
-
footerPointerDragRef.current = {
|
|
9655
|
-
el: selected,
|
|
9656
|
-
kind: "link",
|
|
9657
|
-
startX: e.clientX,
|
|
9658
|
-
startY: e.clientY,
|
|
9659
|
-
pointerId: e.pointerId,
|
|
9660
|
-
wasSelected: true,
|
|
9661
|
-
started: false
|
|
9662
|
-
};
|
|
9663
|
-
return;
|
|
9664
|
-
}
|
|
9665
|
-
if (selected.hasAttribute("data-ohw-footer-col") || isInferredFooterGroup(selected) && selected.closest("footer")) {
|
|
9666
|
-
footerPointerDragRef.current = {
|
|
9667
|
-
el: selected,
|
|
9668
|
-
kind: "column",
|
|
9669
|
-
startX: e.clientX,
|
|
9670
|
-
startY: e.clientY,
|
|
9671
|
-
pointerId: e.pointerId,
|
|
9672
|
-
wasSelected: true,
|
|
9673
|
-
started: false
|
|
9674
|
-
};
|
|
9675
|
-
return;
|
|
9676
|
-
}
|
|
9677
|
-
if (armNavPressFromChrome(selected, e.clientX, e.clientY, e.pointerId)) return;
|
|
9678
|
-
}, [armNavPressFromChrome]);
|
|
9679
|
-
const handleItemChromeClick = (0, import_react9.useCallback)((clientX, clientY) => {
|
|
9680
|
-
if (suppressNextClickRef.current || Date.now() < suppressClickUntilRef.current) {
|
|
9681
|
-
suppressNextClickRef.current = false;
|
|
9682
|
-
return;
|
|
9683
|
-
}
|
|
9684
|
-
const selected = selectedElRef.current;
|
|
9685
|
-
if (!selected || !isNavigationItem(selected)) return;
|
|
9686
|
-
const editable = selected.querySelector('[data-ohw-editable="text"]') ?? selected.querySelector("[data-ohw-editable]");
|
|
9687
|
-
if (!editable) return;
|
|
9688
|
-
activateRef.current(editable, { caretX: clientX, caretY: clientY });
|
|
7852
|
+
const handleItemDragEnd = (0, import_react8.useCallback)(() => {
|
|
7853
|
+
setIsItemDragging(false);
|
|
9689
7854
|
}, []);
|
|
9690
7855
|
reselectNavigationItemRef.current = reselectNavigationItem;
|
|
9691
7856
|
commitNavigationTextEditRef.current = commitNavigationTextEdit;
|
|
9692
|
-
const select = (0,
|
|
7857
|
+
const select = (0, import_react8.useCallback)((anchor) => {
|
|
9693
7858
|
if (!isNavigationItem(anchor)) return;
|
|
9694
7859
|
if (activeElRef.current) deactivate();
|
|
9695
7860
|
selectedElRef.current = anchor;
|
|
9696
|
-
selectedHrefKeyRef.current = anchor.getAttribute("data-ohw-href-key");
|
|
9697
|
-
selectedFooterColAttrRef.current = null;
|
|
9698
|
-
markSelected(anchor);
|
|
9699
|
-
setSelectedIsCta(isNavbarButton2(anchor));
|
|
9700
7861
|
clearHrefKeyHover(anchor);
|
|
9701
7862
|
hoveredNavContainerRef.current = null;
|
|
9702
7863
|
setHoveredNavContainerRect(null);
|
|
@@ -9704,26 +7865,19 @@ function OhhwellsBridge() {
|
|
|
9704
7865
|
hoveredItemElRef.current = null;
|
|
9705
7866
|
siblingHintElRef.current = null;
|
|
9706
7867
|
setSiblingHintRect(null);
|
|
9707
|
-
setSiblingHintRects(collectNavigationItemSiblingHintRects(anchor));
|
|
9708
7868
|
setIsItemDragging(false);
|
|
9709
7869
|
const { key, disabled } = getNavigationItemReorderState(anchor);
|
|
9710
7870
|
setReorderHrefKey(key);
|
|
9711
7871
|
setReorderDragDisabled(disabled);
|
|
9712
|
-
setIsFooterFrameSelection(false);
|
|
9713
7872
|
setToolbarVariant("link-action");
|
|
9714
7873
|
setToolbarRect(anchor.getBoundingClientRect());
|
|
9715
7874
|
setToolbarShowEditLink(false);
|
|
9716
7875
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
9717
|
-
}, [deactivate
|
|
9718
|
-
const selectFrame = (0,
|
|
7876
|
+
}, [deactivate]);
|
|
7877
|
+
const selectFrame = (0, import_react8.useCallback)((el) => {
|
|
9719
7878
|
if (!isNavigationContainer(el)) return;
|
|
9720
7879
|
if (activeElRef.current) deactivate();
|
|
9721
|
-
const isFooterColumn = el.hasAttribute("data-ohw-footer-col") || Boolean(el.closest("footer") && isInferredFooterGroup(el));
|
|
9722
7880
|
selectedElRef.current = el;
|
|
9723
|
-
selectedHrefKeyRef.current = null;
|
|
9724
|
-
selectedFooterColAttrRef.current = isFooterColumn ? el.getAttribute("data-ohw-footer-col") ?? String(listFooterColumns().indexOf(el)) : null;
|
|
9725
|
-
markSelected(el);
|
|
9726
|
-
setSelectedIsCta(false);
|
|
9727
7881
|
clearHrefKeyHover(el);
|
|
9728
7882
|
hoveredNavContainerRef.current = null;
|
|
9729
7883
|
setHoveredNavContainerRect(null);
|
|
@@ -9731,25 +7885,17 @@ function OhhwellsBridge() {
|
|
|
9731
7885
|
hoveredItemElRef.current = null;
|
|
9732
7886
|
siblingHintElRef.current = null;
|
|
9733
7887
|
setSiblingHintRect(null);
|
|
9734
|
-
setSiblingHintRects(
|
|
9735
|
-
isFooterColumn ? listFooterColumns().filter((column) => column !== el).map((column) => column.getBoundingClientRect()) : []
|
|
9736
|
-
);
|
|
9737
7888
|
setIsItemDragging(false);
|
|
9738
7889
|
setReorderHrefKey(null);
|
|
9739
7890
|
setReorderDragDisabled(false);
|
|
9740
|
-
setIsFooterFrameSelection(isFooterColumn);
|
|
9741
7891
|
setToolbarVariant("select-frame");
|
|
9742
7892
|
setToolbarRect(el.getBoundingClientRect());
|
|
9743
7893
|
setToolbarShowEditLink(false);
|
|
9744
7894
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
9745
|
-
}, [deactivate
|
|
9746
|
-
const activate = (0,
|
|
7895
|
+
}, [deactivate]);
|
|
7896
|
+
const activate = (0, import_react8.useCallback)((el, options) => {
|
|
9747
7897
|
if (activeElRef.current === el) return;
|
|
9748
|
-
clearSelectedAttr();
|
|
9749
7898
|
selectedElRef.current = null;
|
|
9750
|
-
selectedHrefKeyRef.current = null;
|
|
9751
|
-
selectedFooterColAttrRef.current = null;
|
|
9752
|
-
setSelectedIsCta(false);
|
|
9753
7899
|
deactivate();
|
|
9754
7900
|
if (hoveredImageRef.current) {
|
|
9755
7901
|
hoveredImageRef.current = null;
|
|
@@ -9759,34 +7905,14 @@ function OhhwellsBridge() {
|
|
|
9759
7905
|
siblingHintElRef.current = null;
|
|
9760
7906
|
setSiblingHintRect(null);
|
|
9761
7907
|
setIsItemDragging(false);
|
|
9762
|
-
const preActivationSelection = window.getSelection();
|
|
9763
|
-
const preservedRange = preActivationSelection && preActivationSelection.rangeCount > 0 && !preActivationSelection.isCollapsed && el.contains(preActivationSelection.getRangeAt(0).commonAncestorContainer) ? preActivationSelection.getRangeAt(0).cloneRange() : null;
|
|
9764
7908
|
el.setAttribute("contenteditable", "true");
|
|
9765
|
-
el.setAttribute("data-ohw-editing", "");
|
|
9766
7909
|
el.removeAttribute("data-ohw-hovered");
|
|
9767
7910
|
el.closest("[data-ohw-href-key]")?.removeAttribute("data-ohw-hovered");
|
|
9768
7911
|
activeElRef.current = el;
|
|
9769
7912
|
originalContentRef.current = el.innerHTML;
|
|
9770
|
-
el.focus(
|
|
9771
|
-
if (
|
|
9772
|
-
|
|
9773
|
-
selection?.removeAllRanges();
|
|
9774
|
-
selection?.addRange(preservedRange);
|
|
9775
|
-
} else if (options?.caretX !== void 0 && options?.caretY !== void 0) {
|
|
9776
|
-
const { caretX, caretY } = options;
|
|
9777
|
-
placeCaretAtPoint(el, caretX, caretY);
|
|
9778
|
-
requestAnimationFrame(() => {
|
|
9779
|
-
if (activeElRef.current === el) placeCaretAtPoint(el, caretX, caretY);
|
|
9780
|
-
});
|
|
9781
|
-
} else {
|
|
9782
|
-
const selection = window.getSelection();
|
|
9783
|
-
if (selection && selection.rangeCount === 0) {
|
|
9784
|
-
const range = document.createRange();
|
|
9785
|
-
range.selectNodeContents(el);
|
|
9786
|
-
range.collapse(false);
|
|
9787
|
-
selection.removeAllRanges();
|
|
9788
|
-
selection.addRange(range);
|
|
9789
|
-
}
|
|
7913
|
+
el.focus();
|
|
7914
|
+
if (options?.caretX !== void 0 && options?.caretY !== void 0) {
|
|
7915
|
+
placeCaretAtPoint(el, options.caretX, options.caretY);
|
|
9790
7916
|
}
|
|
9791
7917
|
setToolbarShowEditLink(Boolean(getHrefKeyFromElement(el)));
|
|
9792
7918
|
const navAnchor = getNavigationItemAnchor(el);
|
|
@@ -9801,13 +7927,13 @@ function OhhwellsBridge() {
|
|
|
9801
7927
|
setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
|
|
9802
7928
|
postToParent2({ type: "ow:enter-edit", key: el.dataset.ohwKey });
|
|
9803
7929
|
requestAnimationFrame(() => refreshActiveCommandsRef.current());
|
|
9804
|
-
}, [
|
|
7930
|
+
}, [deactivate, postToParent2]);
|
|
9805
7931
|
activateRef.current = activate;
|
|
9806
7932
|
deactivateRef.current = deactivate;
|
|
9807
7933
|
selectRef.current = select;
|
|
9808
7934
|
selectFrameRef.current = selectFrame;
|
|
9809
7935
|
deselectRef.current = deselect;
|
|
9810
|
-
(0,
|
|
7936
|
+
(0, import_react8.useLayoutEffect)(() => {
|
|
9811
7937
|
if (!subdomain || isEditMode) {
|
|
9812
7938
|
setFetchState("done");
|
|
9813
7939
|
return;
|
|
@@ -9848,7 +7974,6 @@ function OhhwellsBridge() {
|
|
|
9848
7974
|
applyLinkByKey(key, val);
|
|
9849
7975
|
}
|
|
9850
7976
|
reconcileNavbarItemsFromContent(content);
|
|
9851
|
-
reconcileFooterOrderFromContent(content);
|
|
9852
7977
|
enforceLinkHrefs();
|
|
9853
7978
|
initSectionsFromContent(content, true);
|
|
9854
7979
|
sectionsLoadedRef.current = true;
|
|
@@ -9877,7 +8002,7 @@ function OhhwellsBridge() {
|
|
|
9877
8002
|
cancelled = true;
|
|
9878
8003
|
};
|
|
9879
8004
|
}, [subdomain, isEditMode]);
|
|
9880
|
-
(0,
|
|
8005
|
+
(0, import_react8.useEffect)(() => {
|
|
9881
8006
|
if (!subdomain || isEditMode) return;
|
|
9882
8007
|
let debounceTimer = null;
|
|
9883
8008
|
let observer = null;
|
|
@@ -9909,7 +8034,6 @@ function OhhwellsBridge() {
|
|
|
9909
8034
|
applyLinkByKey(key, val);
|
|
9910
8035
|
}
|
|
9911
8036
|
reconcileNavbarItemsFromContent(content);
|
|
9912
|
-
reconcileFooterOrderFromContent(content);
|
|
9913
8037
|
} finally {
|
|
9914
8038
|
observer?.observe(document.body, { childList: true, subtree: true });
|
|
9915
8039
|
}
|
|
@@ -9927,16 +8051,16 @@ function OhhwellsBridge() {
|
|
|
9927
8051
|
if (debounceTimer) clearTimeout(debounceTimer);
|
|
9928
8052
|
};
|
|
9929
8053
|
}, [subdomain, isEditMode, pathname]);
|
|
9930
|
-
(0,
|
|
8054
|
+
(0, import_react8.useLayoutEffect)(() => {
|
|
9931
8055
|
const el = document.getElementById("ohw-loader");
|
|
9932
8056
|
if (!el) return;
|
|
9933
8057
|
const visible = Boolean(subdomain) && fetchState !== "done";
|
|
9934
8058
|
el.style.display = visible ? "flex" : "none";
|
|
9935
8059
|
}, [subdomain, fetchState]);
|
|
9936
|
-
(0,
|
|
8060
|
+
(0, import_react8.useEffect)(() => {
|
|
9937
8061
|
postToParent2({ type: "ow:navigation", path: pathname });
|
|
9938
8062
|
}, [pathname, postToParent2]);
|
|
9939
|
-
(0,
|
|
8063
|
+
(0, import_react8.useEffect)(() => {
|
|
9940
8064
|
if (!isEditMode) return;
|
|
9941
8065
|
if (linkPopoverSessionRef.current?.intent === "add-nav") return;
|
|
9942
8066
|
if (document.querySelector("[data-ohw-section-picker]")) return;
|
|
@@ -9944,72 +8068,23 @@ function OhhwellsBridge() {
|
|
|
9944
8068
|
deselectRef.current();
|
|
9945
8069
|
deactivateRef.current();
|
|
9946
8070
|
}, [pathname, isEditMode]);
|
|
9947
|
-
(0,
|
|
8071
|
+
(0, import_react8.useEffect)(() => {
|
|
9948
8072
|
const contentForNav = () => {
|
|
9949
8073
|
if (isEditMode) return editContentRef.current;
|
|
9950
8074
|
if (!subdomain) return {};
|
|
9951
8075
|
return contentCache.get(subdomain) ?? {};
|
|
9952
8076
|
};
|
|
9953
|
-
const
|
|
9954
|
-
(el) => Boolean(el)
|
|
9955
|
-
);
|
|
9956
|
-
const roots = observeRoots();
|
|
9957
|
-
if (roots.length === 0) {
|
|
9958
|
-
reconcileNavbarItemsFromContent(contentForNav());
|
|
9959
|
-
reconcileFooterOrderFromContent(contentForNav());
|
|
9960
|
-
if (isEditMode) syncNavigationDragCursorAttrs();
|
|
9961
|
-
return;
|
|
9962
|
-
}
|
|
9963
|
-
let rafId = null;
|
|
9964
|
-
let applying = false;
|
|
9965
|
-
let observer = null;
|
|
9966
|
-
const attach = () => {
|
|
9967
|
-
for (const root of observeRoots()) {
|
|
9968
|
-
observer?.observe(root, { childList: true, subtree: true });
|
|
9969
|
-
}
|
|
9970
|
-
};
|
|
9971
|
-
const run = () => {
|
|
9972
|
-
if (footerDragRef.current || navDragRef.current || applying) return;
|
|
9973
|
-
applying = true;
|
|
9974
|
-
observer?.disconnect();
|
|
9975
|
-
try {
|
|
9976
|
-
const content = contentForNav();
|
|
9977
|
-
reconcileNavbarItemsFromContent(content);
|
|
9978
|
-
reconcileFooterOrderFromContent(content);
|
|
9979
|
-
document.querySelectorAll("footer [data-ohw-href-key]").forEach((el) => {
|
|
9980
|
-
if (isFooterHrefKey(el.getAttribute("data-ohw-href-key"))) {
|
|
9981
|
-
disableNativeHrefDrag(el);
|
|
9982
|
-
}
|
|
9983
|
-
});
|
|
9984
|
-
document.querySelectorAll(
|
|
9985
|
-
"nav [data-ohw-href-key], [data-ohw-nav-container] [data-ohw-href-key], [data-ohw-nav-drawer] [data-ohw-href-key]"
|
|
9986
|
-
).forEach((el) => {
|
|
9987
|
-
if (isNavbarHrefKey(el.getAttribute("data-ohw-href-key"))) {
|
|
9988
|
-
disableNativeHrefDrag(el);
|
|
9989
|
-
}
|
|
9990
|
-
});
|
|
9991
|
-
resyncSelectedNavigationItem();
|
|
9992
|
-
if (isEditMode) syncNavigationDragCursorAttrs();
|
|
9993
|
-
} finally {
|
|
9994
|
-
applying = false;
|
|
9995
|
-
attach();
|
|
9996
|
-
}
|
|
9997
|
-
};
|
|
9998
|
-
const schedule = () => {
|
|
9999
|
-
if (applying || rafId != null) return;
|
|
10000
|
-
rafId = requestAnimationFrame(() => {
|
|
10001
|
-
rafId = null;
|
|
10002
|
-
run();
|
|
10003
|
-
});
|
|
10004
|
-
};
|
|
10005
|
-
observer = new MutationObserver(schedule);
|
|
8077
|
+
const run = () => reconcileNavbarItemsFromContent(contentForNav());
|
|
10006
8078
|
run();
|
|
10007
|
-
|
|
10008
|
-
|
|
10009
|
-
|
|
10010
|
-
|
|
10011
|
-
|
|
10012
|
-
|
|
8079
|
+
const nav = document.querySelector("nav");
|
|
8080
|
+
if (!nav) return;
|
|
8081
|
+
const observer = new MutationObserver(() => {
|
|
8082
|
+
requestAnimationFrame(run);
|
|
8083
|
+
});
|
|
8084
|
+
observer.observe(nav, { childList: true, subtree: true });
|
|
8085
|
+
return () => observer.disconnect();
|
|
8086
|
+
}, [isEditMode, pathname, subdomain, fetchState]);
|
|
8087
|
+
(0, import_react8.useEffect)(() => {
|
|
10013
8088
|
if (!isEditMode) return;
|
|
10014
8089
|
const measure = () => {
|
|
10015
8090
|
const h = document.body.scrollHeight;
|
|
@@ -10033,7 +8108,7 @@ function OhhwellsBridge() {
|
|
|
10033
8108
|
window.removeEventListener("resize", handleResize);
|
|
10034
8109
|
};
|
|
10035
8110
|
}, [pathname, isEditMode, postToParent2]);
|
|
10036
|
-
(0,
|
|
8111
|
+
(0, import_react8.useEffect)(() => {
|
|
10037
8112
|
if (!subdomainFromQuery || isEditMode) return;
|
|
10038
8113
|
const handleClick = (e) => {
|
|
10039
8114
|
const anchor = e.target.closest("a");
|
|
@@ -10049,53 +8124,30 @@ function OhhwellsBridge() {
|
|
|
10049
8124
|
document.addEventListener("click", handleClick, true);
|
|
10050
8125
|
return () => document.removeEventListener("click", handleClick, true);
|
|
10051
8126
|
}, [subdomainFromQuery, isEditMode, router]);
|
|
10052
|
-
(0,
|
|
8127
|
+
(0, import_react8.useEffect)(() => {
|
|
10053
8128
|
if (!isEditMode) {
|
|
10054
8129
|
editStylesRef.current?.base.remove();
|
|
10055
8130
|
editStylesRef.current?.forceHover.remove();
|
|
10056
8131
|
editStylesRef.current?.stateViews.remove();
|
|
10057
8132
|
editStylesRef.current = null;
|
|
10058
|
-
document.querySelectorAll("[data-ohw-can-drag]").forEach((el) => {
|
|
10059
|
-
el.removeAttribute("data-ohw-can-drag");
|
|
10060
|
-
});
|
|
10061
8133
|
return;
|
|
10062
8134
|
}
|
|
10063
|
-
|
|
10064
|
-
|
|
10065
|
-
|
|
10066
|
-
|
|
10067
|
-
|
|
10068
|
-
}
|
|
10069
|
-
const baseCss = `
|
|
8135
|
+
if (!editStylesRef.current) {
|
|
8136
|
+
const initialVh = window.innerHeight;
|
|
8137
|
+
const base = document.createElement("style");
|
|
8138
|
+
base.setAttribute("data-ohw-edit-style", "");
|
|
8139
|
+
base.textContent = `
|
|
10070
8140
|
html { height: auto !important; }
|
|
10071
8141
|
body { height: auto !important; min-height: 0 !important; overflow: hidden !important; }
|
|
10072
8142
|
.min-h-screen, .min-h-svh, .min-h-dvh { min-height: ${initialVh}px !important; }
|
|
10073
8143
|
.h-screen, .h-svh, .h-dvh { height: ${initialVh}px !important; }
|
|
10074
|
-
[style*="100vh"] { min-height: ${initialVh}px !important; height: ${initialVh}px !important; }
|
|
10075
|
-
[style*="100svh"] { min-height: ${initialVh}px !important; height: ${initialVh}px !important; }
|
|
10076
|
-
[style*="100dvh"] { min-height: ${initialVh}px !important; height: ${initialVh}px !important; }
|
|
10077
|
-
[data-ohw-editable] {
|
|
10078
|
-
display: block;
|
|
10079
|
-
}
|
|
10080
|
-
/* Body text (no item-action toolbar) \u2014 first click enters text edit \u2192 I-beam.
|
|
10081
|
-
Exclude select-first nav/footer labels so grab/default on [data-ohw-href-key] can win. */
|
|
10082
|
-
[data-ohw-editable]:not([contenteditable]):not([data-ohw-editable="image"]):not([data-ohw-editable="bg-image"]):not([data-ohw-editable="video"]):not([data-ohw-editable="link"]):not(:is([data-ohw-href-key] *)) {
|
|
10083
|
-
cursor: text !important;
|
|
10084
|
-
}
|
|
10085
|
-
/* Select-first items: default arrow; grab only when drag-start is allowed (data-ohw-can-drag). */
|
|
10086
|
-
[data-ohw-href-key]:not([data-ohw-selected]),
|
|
10087
|
-
[data-ohw-href-key]:not([data-ohw-selected]) * {
|
|
10088
|
-
cursor: default !important;
|
|
10089
|
-
}
|
|
10090
|
-
[data-ohw-href-key][data-ohw-can-drag]:not([data-ohw-selected]),
|
|
10091
|
-
[data-ohw-href-key][data-ohw-can-drag]:not([data-ohw-selected]) * {
|
|
10092
|
-
cursor: grab !important;
|
|
10093
|
-
}
|
|
10094
|
-
/* Selected (action-toolbar) \u2014 next click enters text edit at caret. */
|
|
10095
|
-
[data-ohw-href-key][data-ohw-selected],
|
|
10096
|
-
[data-ohw-href-key][data-ohw-selected] * {
|
|
10097
|
-
cursor: text !important;
|
|
8144
|
+
[style*="100vh"] { min-height: ${initialVh}px !important; height: ${initialVh}px !important; }
|
|
8145
|
+
[style*="100svh"] { min-height: ${initialVh}px !important; height: ${initialVh}px !important; }
|
|
8146
|
+
[style*="100dvh"] { min-height: ${initialVh}px !important; height: ${initialVh}px !important; }
|
|
8147
|
+
[data-ohw-editable] {
|
|
8148
|
+
display: block;
|
|
10098
8149
|
}
|
|
8150
|
+
[data-ohw-editable]:not([contenteditable]):not([data-ohw-editable="image"]):not([data-ohw-editable="bg-image"]):not([data-ohw-editable="video"]) { cursor: text !important; }
|
|
10099
8151
|
[data-ohw-editable="image"], [data-ohw-editable="image"] *,
|
|
10100
8152
|
[data-ohw-editable="video"], [data-ohw-editable="video"] *,
|
|
10101
8153
|
[data-ohw-editable="bg-image"], [data-ohw-editable="bg-image"] * { cursor: pointer !important; }
|
|
@@ -10111,32 +8163,9 @@ function OhhwellsBridge() {
|
|
|
10111
8163
|
outline: none !important;
|
|
10112
8164
|
outline-offset: 0 !important;
|
|
10113
8165
|
}
|
|
10114
|
-
|
|
10115
|
-
nav [data-ohw-href-key]:focus,
|
|
10116
|
-
nav [data-ohw-href-key]:focus-visible,
|
|
10117
|
-
nav [data-ohw-href-key]:focus-within,
|
|
10118
|
-
footer [data-ohw-href-key]:focus,
|
|
10119
|
-
footer [data-ohw-href-key]:focus-visible,
|
|
10120
|
-
footer [data-ohw-href-key]:focus-within,
|
|
10121
|
-
nav [data-ohw-href-key] [data-ohw-editable]:focus,
|
|
10122
|
-
nav [data-ohw-href-key] [data-ohw-editable]:focus-visible,
|
|
10123
|
-
footer [data-ohw-href-key] [data-ohw-editable]:focus,
|
|
10124
|
-
footer [data-ohw-href-key] [data-ohw-editable]:focus-visible {
|
|
10125
|
-
outline: none !important;
|
|
10126
|
-
outline-offset: 0 !important;
|
|
10127
|
-
box-shadow: none !important;
|
|
10128
|
-
}
|
|
10129
|
-
/* Text edit wins over grab/default (must beat [data-ohw-can-drag] *). */
|
|
10130
|
-
[data-ohw-editing],
|
|
10131
|
-
[data-ohw-editing] *,
|
|
10132
|
-
[data-ohw-editable][contenteditable],
|
|
10133
|
-
[data-ohw-editable][contenteditable] *,
|
|
10134
|
-
nav [data-ohw-href-key] [data-ohw-editable][contenteditable],
|
|
10135
|
-
nav [data-ohw-href-key] [data-ohw-editable][contenteditable] *,
|
|
10136
|
-
footer [data-ohw-href-key] [data-ohw-editable][contenteditable],
|
|
10137
|
-
footer [data-ohw-href-key] [data-ohw-editable][contenteditable] * {
|
|
8166
|
+
[data-ohw-editable][contenteditable] {
|
|
10138
8167
|
outline: none !important;
|
|
10139
|
-
caret-color: ${PRIMARY2}
|
|
8168
|
+
caret-color: ${PRIMARY2};
|
|
10140
8169
|
cursor: text !important;
|
|
10141
8170
|
}
|
|
10142
8171
|
[data-ohw-editable][contenteditable]::selection,
|
|
@@ -10145,9 +8174,6 @@ function OhhwellsBridge() {
|
|
|
10145
8174
|
[data-ohw-editable-state][data-ohw-active-state] [data-ohw-editable] { pointer-events: auto !important; }
|
|
10146
8175
|
[data-ohw-editable-state][data-ohw-active-state][data-ohw-editable] { pointer-events: auto !important; }
|
|
10147
8176
|
`;
|
|
10148
|
-
if (!existing) {
|
|
10149
|
-
const base = document.createElement("style");
|
|
10150
|
-
base.setAttribute("data-ohw-edit-style", "");
|
|
10151
8177
|
const forceHover = document.createElement("style");
|
|
10152
8178
|
forceHover.setAttribute("data-ohw-active-state-style", "");
|
|
10153
8179
|
const stateViews = document.createElement("style");
|
|
@@ -10163,43 +8189,14 @@ function OhhwellsBridge() {
|
|
|
10163
8189
|
document.head.appendChild(stateViews);
|
|
10164
8190
|
editStylesRef.current = { base, forceHover, stateViews };
|
|
10165
8191
|
}
|
|
10166
|
-
editStylesRef.current.base.textContent = baseCss;
|
|
10167
|
-
syncNavigationDragCursorAttrs();
|
|
10168
8192
|
refreshStateRules();
|
|
10169
8193
|
const handleClick = (e) => {
|
|
10170
|
-
if (suppressNextClickRef.current || Date.now() < suppressClickUntilRef.current) {
|
|
10171
|
-
suppressNextClickRef.current = false;
|
|
10172
|
-
e.preventDefault();
|
|
10173
|
-
e.stopPropagation();
|
|
10174
|
-
return;
|
|
10175
|
-
}
|
|
10176
8194
|
const target = e.target;
|
|
10177
8195
|
if (target.closest("[data-ohw-toolbar]")) return;
|
|
10178
8196
|
if (target.closest("[data-ohw-state-toggle]")) return;
|
|
10179
8197
|
if (target.closest("[data-ohw-max-badge]")) return;
|
|
10180
8198
|
if (isInsideLinkEditor(target)) return;
|
|
10181
8199
|
if (target.closest('[data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
|
|
10182
|
-
if (target.closest("[data-ohw-item-drag-surface]")) {
|
|
10183
|
-
e.preventDefault();
|
|
10184
|
-
e.stopPropagation();
|
|
10185
|
-
const selected = selectedElRef.current;
|
|
10186
|
-
if (selected && isNavigationItem(selected)) {
|
|
10187
|
-
const editable2 = selected.querySelector('[data-ohw-editable="text"]') ?? selected.querySelector("[data-ohw-editable]");
|
|
10188
|
-
if (editable2) {
|
|
10189
|
-
activateRef.current(editable2, {
|
|
10190
|
-
caretX: e.clientX,
|
|
10191
|
-
caretY: e.clientY
|
|
10192
|
-
});
|
|
10193
|
-
}
|
|
10194
|
-
} else if (selected?.hasAttribute("data-ohw-footer-col")) {
|
|
10195
|
-
const link = listFooterLinksInColumn(selected).find((el) => {
|
|
10196
|
-
const r2 = el.getBoundingClientRect();
|
|
10197
|
-
return e.clientX >= r2.left && e.clientX <= r2.right && e.clientY >= r2.top && e.clientY <= r2.bottom;
|
|
10198
|
-
});
|
|
10199
|
-
if (link) selectRef.current(link);
|
|
10200
|
-
}
|
|
10201
|
-
return;
|
|
10202
|
-
}
|
|
10203
8200
|
const navFromChrome = resolveNavContainerSelectionTarget(target, e.clientX, e.clientY);
|
|
10204
8201
|
if (navFromChrome) {
|
|
10205
8202
|
e.preventDefault();
|
|
@@ -10207,45 +8204,10 @@ function OhhwellsBridge() {
|
|
|
10207
8204
|
selectFrameRef.current(navFromChrome);
|
|
10208
8205
|
return;
|
|
10209
8206
|
}
|
|
10210
|
-
const footerFromChrome = resolveFooterColumnSelectionTarget(target, e.clientX, e.clientY);
|
|
10211
|
-
if (footerFromChrome) {
|
|
10212
|
-
e.preventDefault();
|
|
10213
|
-
e.stopPropagation();
|
|
10214
|
-
selectFrameRef.current(footerFromChrome);
|
|
10215
|
-
return;
|
|
10216
|
-
}
|
|
10217
8207
|
e.preventDefault();
|
|
10218
8208
|
e.stopPropagation();
|
|
10219
8209
|
return;
|
|
10220
8210
|
}
|
|
10221
|
-
if (activeElRef.current) {
|
|
10222
|
-
const active = activeElRef.current;
|
|
10223
|
-
const inActive = active === target || active.contains(target);
|
|
10224
|
-
const navAnchor = getNavigationItemAnchor(active);
|
|
10225
|
-
const inActiveNav = Boolean(
|
|
10226
|
-
navAnchor && (navAnchor === target || navAnchor.contains(target))
|
|
10227
|
-
);
|
|
10228
|
-
if (inActive || inActiveNav) {
|
|
10229
|
-
e.preventDefault();
|
|
10230
|
-
e.stopPropagation();
|
|
10231
|
-
const selection = window.getSelection();
|
|
10232
|
-
const hasRangeSelection = Boolean(selection && !selection.isCollapsed);
|
|
10233
|
-
console.log(
|
|
10234
|
-
"[OHW DEBUG handleClick] already-active branch",
|
|
10235
|
-
"detail=",
|
|
10236
|
-
e.detail,
|
|
10237
|
-
"hasRangeSelection=",
|
|
10238
|
-
hasRangeSelection,
|
|
10239
|
-
"willPlaceCaret=",
|
|
10240
|
-
e.detail < 2 && !hasRangeSelection
|
|
10241
|
-
);
|
|
10242
|
-
if (e.detail < 2 && !hasRangeSelection) {
|
|
10243
|
-
placeCaretAtPoint(active, e.clientX, e.clientY);
|
|
10244
|
-
refreshActiveCommandsRef.current();
|
|
10245
|
-
}
|
|
10246
|
-
return;
|
|
10247
|
-
}
|
|
10248
|
-
}
|
|
10249
8211
|
const editable = target.closest("[data-ohw-editable]");
|
|
10250
8212
|
if (editable) {
|
|
10251
8213
|
if (editable.dataset.ohwEditable === "link") {
|
|
@@ -10282,15 +8244,6 @@ function OhhwellsBridge() {
|
|
|
10282
8244
|
}
|
|
10283
8245
|
e.preventDefault();
|
|
10284
8246
|
e.stopPropagation();
|
|
10285
|
-
console.log(
|
|
10286
|
-
"[OHW DEBUG handleClick] first-activation branch",
|
|
10287
|
-
"detail=",
|
|
10288
|
-
e.detail,
|
|
10289
|
-
"selectionAtClick=",
|
|
10290
|
-
JSON.stringify(window.getSelection()?.toString() ?? ""),
|
|
10291
|
-
"collapsedAtClick=",
|
|
10292
|
-
window.getSelection()?.isCollapsed
|
|
10293
|
-
);
|
|
10294
8247
|
activateRef.current(editable);
|
|
10295
8248
|
return;
|
|
10296
8249
|
}
|
|
@@ -10298,26 +8251,10 @@ function OhhwellsBridge() {
|
|
|
10298
8251
|
if (hrefAnchor) {
|
|
10299
8252
|
e.preventDefault();
|
|
10300
8253
|
e.stopPropagation();
|
|
10301
|
-
if (selectedElRef.current === hrefAnchor)
|
|
10302
|
-
const textEditable = hrefAnchor.querySelector('[data-ohw-editable="text"]') ?? hrefAnchor.querySelector("[data-ohw-editable]");
|
|
10303
|
-
if (textEditable) {
|
|
10304
|
-
activateRef.current(textEditable, {
|
|
10305
|
-
caretX: e.clientX,
|
|
10306
|
-
caretY: e.clientY
|
|
10307
|
-
});
|
|
10308
|
-
}
|
|
10309
|
-
return;
|
|
10310
|
-
}
|
|
8254
|
+
if (selectedElRef.current === hrefAnchor) return;
|
|
10311
8255
|
selectRef.current(hrefAnchor);
|
|
10312
8256
|
return;
|
|
10313
8257
|
}
|
|
10314
|
-
const footerColClick = target.closest("[data-ohw-footer-col]");
|
|
10315
|
-
if (footerColClick) {
|
|
10316
|
-
e.preventDefault();
|
|
10317
|
-
e.stopPropagation();
|
|
10318
|
-
selectFrameRef.current(footerColClick);
|
|
10319
|
-
return;
|
|
10320
|
-
}
|
|
10321
8258
|
const navContainerToSelect = resolveNavContainerSelectionTarget(target, e.clientX, e.clientY);
|
|
10322
8259
|
if (navContainerToSelect) {
|
|
10323
8260
|
e.preventDefault();
|
|
@@ -10325,13 +8262,6 @@ function OhhwellsBridge() {
|
|
|
10325
8262
|
selectFrameRef.current(navContainerToSelect);
|
|
10326
8263
|
return;
|
|
10327
8264
|
}
|
|
10328
|
-
const footerColumnToSelect = resolveFooterColumnSelectionTarget(target, e.clientX, e.clientY);
|
|
10329
|
-
if (footerColumnToSelect) {
|
|
10330
|
-
e.preventDefault();
|
|
10331
|
-
e.stopPropagation();
|
|
10332
|
-
selectFrameRef.current(footerColumnToSelect);
|
|
10333
|
-
return;
|
|
10334
|
-
}
|
|
10335
8265
|
const selectedContainer = selectedElRef.current;
|
|
10336
8266
|
if (selectedContainer && isNavigationContainer(selectedContainer)) {
|
|
10337
8267
|
const navItem = getNavigationItemAnchor(target);
|
|
@@ -10391,13 +8321,6 @@ function OhhwellsBridge() {
|
|
|
10391
8321
|
const handleMouseOver = (e) => {
|
|
10392
8322
|
if (document.documentElement.hasAttribute("data-ohw-section-picking")) return;
|
|
10393
8323
|
const target = e.target;
|
|
10394
|
-
if (linkPopoverOpenRef.current) {
|
|
10395
|
-
hoveredItemElRef.current = null;
|
|
10396
|
-
setHoveredItemRect(null);
|
|
10397
|
-
hoveredNavContainerRef.current = null;
|
|
10398
|
-
setHoveredNavContainerRect(null);
|
|
10399
|
-
return;
|
|
10400
|
-
}
|
|
10401
8324
|
if (toolbarVariantRef.current !== "select-frame") {
|
|
10402
8325
|
const navContainer = target.closest("[data-ohw-nav-container]");
|
|
10403
8326
|
if (navContainer && !getNavigationItemAnchor(target)) {
|
|
@@ -10417,21 +8340,12 @@ function OhhwellsBridge() {
|
|
|
10417
8340
|
hoveredNavContainerRef.current = null;
|
|
10418
8341
|
setHoveredNavContainerRect(null);
|
|
10419
8342
|
const selected2 = selectedElRef.current;
|
|
10420
|
-
if (selected2 === navAnchor) return;
|
|
8343
|
+
if (selected2 === navAnchor || selected2?.contains(navAnchor)) return;
|
|
10421
8344
|
clearHrefKeyHover(navAnchor);
|
|
10422
8345
|
hoveredItemElRef.current = navAnchor;
|
|
10423
8346
|
setHoveredItemRect(navAnchor.getBoundingClientRect());
|
|
10424
8347
|
return;
|
|
10425
8348
|
}
|
|
10426
|
-
const footerCol = target.closest("[data-ohw-footer-col]") ?? target.closest("[data-ohw-footer-column]");
|
|
10427
|
-
if (footerCol) {
|
|
10428
|
-
hoveredNavContainerRef.current = null;
|
|
10429
|
-
setHoveredNavContainerRect(null);
|
|
10430
|
-
if (selectedElRef.current === footerCol) return;
|
|
10431
|
-
hoveredItemElRef.current = footerCol;
|
|
10432
|
-
setHoveredItemRect(footerCol.getBoundingClientRect());
|
|
10433
|
-
return;
|
|
10434
|
-
}
|
|
10435
8349
|
const editable = target.closest("[data-ohw-editable]");
|
|
10436
8350
|
if (!editable) return;
|
|
10437
8351
|
const selected = selectedElRef.current;
|
|
@@ -10449,25 +8363,14 @@ function OhhwellsBridge() {
|
|
|
10449
8363
|
};
|
|
10450
8364
|
const handleMouseOut = (e) => {
|
|
10451
8365
|
const target = e.target;
|
|
10452
|
-
if (target.closest("[data-ohw-nav-container]
|
|
8366
|
+
if (target.closest("[data-ohw-nav-container]")) {
|
|
10453
8367
|
const related2 = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
10454
|
-
if (related2?.closest("[data-ohw-nav-container], [data-ohw-
|
|
8368
|
+
if (related2?.closest("[data-ohw-nav-container], [data-ohw-navbar-container-chrome], [data-ohw-navbar-add-button]")) {
|
|
10455
8369
|
return;
|
|
10456
8370
|
}
|
|
10457
8371
|
hoveredNavContainerRef.current = null;
|
|
10458
8372
|
setHoveredNavContainerRect(null);
|
|
10459
8373
|
}
|
|
10460
|
-
const footerCol = target.closest("[data-ohw-footer-col]") ?? target.closest("[data-ohw-footer-column]");
|
|
10461
|
-
if (footerCol && hoveredItemElRef.current === footerCol) {
|
|
10462
|
-
const related2 = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
10463
|
-
if (related2?.closest("[data-ohw-drag-handle-container], [data-ohw-item-interaction]")) return;
|
|
10464
|
-
if (related2?.closest("[data-ohw-footer-col], [data-ohw-footer-column]") === footerCol) {
|
|
10465
|
-
return;
|
|
10466
|
-
}
|
|
10467
|
-
hoveredItemElRef.current = null;
|
|
10468
|
-
setHoveredItemRect(null);
|
|
10469
|
-
return;
|
|
10470
|
-
}
|
|
10471
8374
|
const navAnchor = getNavigationItemAnchor(target);
|
|
10472
8375
|
if (navAnchor) {
|
|
10473
8376
|
const related2 = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
@@ -10601,75 +8504,43 @@ function OhhwellsBridge() {
|
|
|
10601
8504
|
if (toolbarVariantRef.current === "select-frame") {
|
|
10602
8505
|
hoveredNavContainerRef.current = null;
|
|
10603
8506
|
setHoveredNavContainerRect(null);
|
|
8507
|
+
return;
|
|
10604
8508
|
}
|
|
10605
|
-
const
|
|
10606
|
-
|
|
10607
|
-
);
|
|
10608
|
-
const footerColumns = listFooterColumns();
|
|
10609
|
-
for (const container of [...navContainers, ...footerColumns]) {
|
|
10610
|
-
const containerRect = container.getBoundingClientRect();
|
|
10611
|
-
const overContainer = x >= containerRect.left && x <= containerRect.right && y >= containerRect.top && y <= containerRect.bottom;
|
|
10612
|
-
if (!overContainer) continue;
|
|
10613
|
-
const navItemHit = Array.from(
|
|
10614
|
-
container.querySelectorAll("[data-ohw-href-key]")
|
|
10615
|
-
).find((el) => {
|
|
10616
|
-
if (!isNavigationItem(el) || isNavbarButton2(el)) return false;
|
|
10617
|
-
const itemRect = el.getBoundingClientRect();
|
|
10618
|
-
return x >= itemRect.left && x <= itemRect.right && y >= itemRect.top && y <= itemRect.bottom;
|
|
10619
|
-
});
|
|
10620
|
-
if (navItemHit) {
|
|
10621
|
-
hoveredNavContainerRef.current = null;
|
|
10622
|
-
setHoveredNavContainerRect(null);
|
|
10623
|
-
const selected = selectedElRef.current;
|
|
10624
|
-
if (selected !== navItemHit) {
|
|
10625
|
-
clearHrefKeyHover(navItemHit);
|
|
10626
|
-
hoveredItemElRef.current = navItemHit;
|
|
10627
|
-
setHoveredItemRect(navItemHit.getBoundingClientRect());
|
|
10628
|
-
} else if (hoveredItemElRef.current === navItemHit) {
|
|
10629
|
-
hoveredItemElRef.current = null;
|
|
10630
|
-
setHoveredItemRect(null);
|
|
10631
|
-
}
|
|
10632
|
-
return;
|
|
10633
|
-
}
|
|
10634
|
-
}
|
|
10635
|
-
if (toolbarVariantRef.current !== "select-frame") {
|
|
10636
|
-
for (const container of navContainers) {
|
|
10637
|
-
const containerRect = container.getBoundingClientRect();
|
|
10638
|
-
const overContainer = x >= containerRect.left && x <= containerRect.right && y >= containerRect.top && y <= containerRect.bottom;
|
|
10639
|
-
if (!overContainer) continue;
|
|
10640
|
-
if (isPointOverNavItem(container, x, y)) continue;
|
|
10641
|
-
hoveredNavContainerRef.current = container;
|
|
10642
|
-
setHoveredNavContainerRect(container.getBoundingClientRect());
|
|
10643
|
-
hoveredItemElRef.current = null;
|
|
10644
|
-
setHoveredItemRect(null);
|
|
10645
|
-
return;
|
|
10646
|
-
}
|
|
8509
|
+
const navContainer = document.querySelector("[data-ohw-nav-container]");
|
|
8510
|
+
if (!navContainer) {
|
|
10647
8511
|
hoveredNavContainerRef.current = null;
|
|
10648
8512
|
setHoveredNavContainerRect(null);
|
|
10649
|
-
|
|
8513
|
+
return;
|
|
8514
|
+
}
|
|
8515
|
+
const containerRect = navContainer.getBoundingClientRect();
|
|
8516
|
+
const overContainer = x >= containerRect.left && x <= containerRect.right && y >= containerRect.top && y <= containerRect.bottom;
|
|
8517
|
+
if (!overContainer) {
|
|
10650
8518
|
hoveredNavContainerRef.current = null;
|
|
10651
8519
|
setHoveredNavContainerRect(null);
|
|
8520
|
+
return;
|
|
10652
8521
|
}
|
|
10653
|
-
|
|
10654
|
-
|
|
10655
|
-
|
|
10656
|
-
if (!
|
|
10657
|
-
|
|
10658
|
-
|
|
10659
|
-
|
|
10660
|
-
|
|
10661
|
-
|
|
10662
|
-
|
|
10663
|
-
|
|
8522
|
+
const navItemHit = Array.from(
|
|
8523
|
+
navContainer.querySelectorAll("[data-ohw-href-key]")
|
|
8524
|
+
).find((el) => {
|
|
8525
|
+
if (!isNavigationItem(el) || isNavbarButton2(el)) return false;
|
|
8526
|
+
const itemRect = el.getBoundingClientRect();
|
|
8527
|
+
return x >= itemRect.left && x <= itemRect.right && y >= itemRect.top && y <= itemRect.bottom;
|
|
8528
|
+
});
|
|
8529
|
+
if (navItemHit) {
|
|
8530
|
+
hoveredNavContainerRef.current = null;
|
|
8531
|
+
setHoveredNavContainerRect(null);
|
|
8532
|
+
const selected = selectedElRef.current;
|
|
8533
|
+
if (selected !== navItemHit && !selected?.contains(navItemHit)) {
|
|
8534
|
+
clearHrefKeyHover(navItemHit);
|
|
8535
|
+
hoveredItemElRef.current = navItemHit;
|
|
8536
|
+
setHoveredItemRect(navItemHit.getBoundingClientRect());
|
|
10664
8537
|
}
|
|
10665
|
-
hoveredItemElRef.current = column;
|
|
10666
|
-
setHoveredItemRect(column.getBoundingClientRect());
|
|
10667
8538
|
return;
|
|
10668
8539
|
}
|
|
10669
|
-
|
|
10670
|
-
|
|
10671
|
-
|
|
10672
|
-
|
|
8540
|
+
hoveredNavContainerRef.current = navContainer;
|
|
8541
|
+
setHoveredNavContainerRect(containerRect);
|
|
8542
|
+
hoveredItemElRef.current = null;
|
|
8543
|
+
setHoveredItemRect(null);
|
|
10673
8544
|
};
|
|
10674
8545
|
const probeImageAt = (clientX, clientY, isDragOver = false, fromParentViewport = false) => {
|
|
10675
8546
|
if (linkPopoverOpenRef.current) {
|
|
@@ -10690,10 +8561,6 @@ function OhhwellsBridge() {
|
|
|
10690
8561
|
}
|
|
10691
8562
|
hoveredNavContainerRef.current = null;
|
|
10692
8563
|
setHoveredNavContainerRect(null);
|
|
10693
|
-
if (hoveredItemElRef.current?.hasAttribute("data-ohw-footer-col") || hoveredItemElRef.current?.hasAttribute("data-ohw-footer-column")) {
|
|
10694
|
-
hoveredItemElRef.current = null;
|
|
10695
|
-
setHoveredItemRect(null);
|
|
10696
|
-
}
|
|
10697
8564
|
const toggleEl = document.querySelector("[data-ohw-state-toggle]");
|
|
10698
8565
|
if (toggleEl) {
|
|
10699
8566
|
const tr = toggleEl.getBoundingClientRect();
|
|
@@ -10941,15 +8808,6 @@ function OhhwellsBridge() {
|
|
|
10941
8808
|
probeHoverCardsAt(clientX, clientY);
|
|
10942
8809
|
};
|
|
10943
8810
|
const handleDragOver = (e) => {
|
|
10944
|
-
const footerSession = footerDragRef.current;
|
|
10945
|
-
if (footerSession) {
|
|
10946
|
-
e.preventDefault();
|
|
10947
|
-
if (e.dataTransfer) e.dataTransfer.dropEffect = "move";
|
|
10948
|
-
const slot = footerSession.kind === "link" && footerSession.hrefKey ? hitTestLinkDropSlot(e.clientX, e.clientY, footerSession.hrefKey) : hitTestColumnDropSlot(e.clientX, e.clientY);
|
|
10949
|
-
refreshFooterDragVisualsRef.current(footerSession, slot, e.clientX, e.clientY);
|
|
10950
|
-
return;
|
|
10951
|
-
}
|
|
10952
|
-
if (onNavDragOver(e)) return;
|
|
10953
8811
|
e.preventDefault();
|
|
10954
8812
|
const el = findImageAtPoint(e.clientX, e.clientY, false);
|
|
10955
8813
|
if (!el) {
|
|
@@ -11112,8 +8970,8 @@ function OhhwellsBridge() {
|
|
|
11112
8970
|
if (sibling !== el) sibling.innerHTML = html;
|
|
11113
8971
|
});
|
|
11114
8972
|
const timers = autoSaveTimers.current;
|
|
11115
|
-
const
|
|
11116
|
-
if (
|
|
8973
|
+
const existing = timers.get(key);
|
|
8974
|
+
if (existing) clearTimeout(existing);
|
|
11117
8975
|
timers.set(key, setTimeout(() => {
|
|
11118
8976
|
timers.delete(key);
|
|
11119
8977
|
postToParentRef.current({ type: "ow:change", nodes: [{ key, text: html }] });
|
|
@@ -11156,7 +9014,6 @@ function OhhwellsBridge() {
|
|
|
11156
9014
|
}
|
|
11157
9015
|
editContentRef.current = { ...editContentRef.current, ...content };
|
|
11158
9016
|
reconcileNavbarItemsFromContent(editContentRef.current);
|
|
11159
|
-
syncNavigationDragCursorAttrs();
|
|
11160
9017
|
enforceLinkHrefs();
|
|
11161
9018
|
postToParentRef.current({ type: "ow:hydrate-done" });
|
|
11162
9019
|
};
|
|
@@ -11177,48 +9034,6 @@ function OhhwellsBridge() {
|
|
|
11177
9034
|
if (e.data?.type !== "ui:escape") return;
|
|
11178
9035
|
if (linkPopoverOpenRef.current) {
|
|
11179
9036
|
setLinkPopoverRef.current(null);
|
|
11180
|
-
return;
|
|
11181
|
-
}
|
|
11182
|
-
if (activeElRef.current) {
|
|
11183
|
-
const hrefCtx = getHrefKeyFromElement(activeElRef.current);
|
|
11184
|
-
const navAnchor = hrefCtx ? getNavigationItemAnchor(hrefCtx.anchor) : null;
|
|
11185
|
-
if (navAnchor) {
|
|
11186
|
-
const el = activeElRef.current;
|
|
11187
|
-
if (originalContentRef.current !== null) {
|
|
11188
|
-
el.innerHTML = originalContentRef.current;
|
|
11189
|
-
}
|
|
11190
|
-
el.removeAttribute("contenteditable");
|
|
11191
|
-
el.removeAttribute("data-ohw-editing");
|
|
11192
|
-
activeElRef.current = null;
|
|
11193
|
-
setMaxBadge(null);
|
|
11194
|
-
setActiveCommands(/* @__PURE__ */ new Set());
|
|
11195
|
-
setToolbarShowEditLink(false);
|
|
11196
|
-
postToParentRef.current({ type: "ow:exit-edit" });
|
|
11197
|
-
reselectNavigationItemRef.current(navAnchor);
|
|
11198
|
-
return;
|
|
11199
|
-
}
|
|
11200
|
-
if (originalContentRef.current !== null) {
|
|
11201
|
-
activeElRef.current.innerHTML = originalContentRef.current;
|
|
11202
|
-
const key = activeElRef.current.dataset.ohwKey;
|
|
11203
|
-
if (key) {
|
|
11204
|
-
postToParentRef.current({ type: "ow:change", nodes: [{ key, text: originalContentRef.current }] });
|
|
11205
|
-
}
|
|
11206
|
-
}
|
|
11207
|
-
deselectRef.current();
|
|
11208
|
-
deactivateRef.current();
|
|
11209
|
-
return;
|
|
11210
|
-
}
|
|
11211
|
-
if (selectedElRef.current) {
|
|
11212
|
-
if (toolbarVariantRef.current === "select-frame") {
|
|
11213
|
-
deselectRef.current();
|
|
11214
|
-
return;
|
|
11215
|
-
}
|
|
11216
|
-
const parent = getNavigationSelectionParent(selectedElRef.current);
|
|
11217
|
-
if (parent && isNavigationContainer(parent)) {
|
|
11218
|
-
selectFrameRef.current(parent);
|
|
11219
|
-
} else {
|
|
11220
|
-
deselectRef.current();
|
|
11221
|
-
}
|
|
11222
9037
|
}
|
|
11223
9038
|
};
|
|
11224
9039
|
window.addEventListener("message", handleUiEscape);
|
|
@@ -11243,7 +9058,7 @@ function OhhwellsBridge() {
|
|
|
11243
9058
|
return;
|
|
11244
9059
|
}
|
|
11245
9060
|
const parent = getNavigationSelectionParent(selectedElRef.current);
|
|
11246
|
-
if (parent
|
|
9061
|
+
if (parent) {
|
|
11247
9062
|
e.preventDefault();
|
|
11248
9063
|
selectFrameRef.current(parent);
|
|
11249
9064
|
} else {
|
|
@@ -11261,7 +9076,6 @@ function OhhwellsBridge() {
|
|
|
11261
9076
|
el2.innerHTML = originalContentRef.current;
|
|
11262
9077
|
}
|
|
11263
9078
|
el2.removeAttribute("contenteditable");
|
|
11264
|
-
el2.removeAttribute("data-ohw-editing");
|
|
11265
9079
|
activeElRef.current = null;
|
|
11266
9080
|
setMaxBadge(null);
|
|
11267
9081
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
@@ -11313,26 +9127,6 @@ function OhhwellsBridge() {
|
|
|
11313
9127
|
if (siblingHintElRef.current) {
|
|
11314
9128
|
setSiblingHintRect(siblingHintElRef.current.getBoundingClientRect());
|
|
11315
9129
|
}
|
|
11316
|
-
const selected = selectedElRef.current;
|
|
11317
|
-
if (selected && !footerDragRef.current && !navDragRef.current) {
|
|
11318
|
-
if (selected.hasAttribute("data-ohw-footer-col") || Boolean(selected.closest("footer") && isInferredFooterGroup(selected))) {
|
|
11319
|
-
setSiblingHintRects(
|
|
11320
|
-
listFooterColumns().filter((column) => column !== selected).map((column) => column.getBoundingClientRect())
|
|
11321
|
-
);
|
|
11322
|
-
} else if (isNavigationItem(selected)) {
|
|
11323
|
-
setSiblingHintRects(collectNavigationItemSiblingHintRects(selected));
|
|
11324
|
-
}
|
|
11325
|
-
}
|
|
11326
|
-
if (footerDragRef.current) {
|
|
11327
|
-
const session = footerDragRef.current;
|
|
11328
|
-
const slot = session.kind === "link" && session.hrefKey ? hitTestLinkDropSlot(session.lastClientX, session.lastClientY, session.hrefKey) : hitTestColumnDropSlot(session.lastClientX, session.lastClientY);
|
|
11329
|
-
refreshFooterDragVisualsRef.current(session, slot, session.lastClientX, session.lastClientY);
|
|
11330
|
-
}
|
|
11331
|
-
if (navDragRef.current) {
|
|
11332
|
-
const session = navDragRef.current;
|
|
11333
|
-
const slot = hitTestNavDropSlot(session.lastClientX, session.lastClientY, session.hrefKey);
|
|
11334
|
-
refreshNavDragVisualsRef.current(session, slot, session.lastClientX, session.lastClientY);
|
|
11335
|
-
}
|
|
11336
9130
|
if (hoveredImageRef.current) {
|
|
11337
9131
|
const el = hoveredImageRef.current;
|
|
11338
9132
|
const r2 = el.getBoundingClientRect();
|
|
@@ -11343,7 +9137,7 @@ function OhhwellsBridge() {
|
|
|
11343
9137
|
};
|
|
11344
9138
|
const handleSave = (e) => {
|
|
11345
9139
|
if (e.data?.type !== "ow:save") return;
|
|
11346
|
-
const nodes = collectEditableNodes(
|
|
9140
|
+
const nodes = collectEditableNodes();
|
|
11347
9141
|
const tracker = document.querySelector("[data-ohw-sections-tracker]");
|
|
11348
9142
|
if (tracker?.textContent) nodes.push({ key: "__ohw_sections", type: "sections", text: tracker.textContent });
|
|
11349
9143
|
postToParentRef.current({ type: "ow:save-result", nodes });
|
|
@@ -11401,83 +9195,30 @@ function OhhwellsBridge() {
|
|
|
11401
9195
|
const h = document.documentElement.scrollHeight;
|
|
11402
9196
|
if (h > 50) postToParentRef.current({ type: "ow:height", height: h });
|
|
11403
9197
|
};
|
|
11404
|
-
|
|
11405
|
-
|
|
11406
|
-
selectionChangeRaf = null;
|
|
11407
|
-
const activeRoot = activeElRef.current;
|
|
11408
|
-
if (!activeRoot) return;
|
|
9198
|
+
const handleSelectionChange = () => {
|
|
9199
|
+
if (!activeElRef.current) return;
|
|
11409
9200
|
const next = /* @__PURE__ */ new Set();
|
|
11410
|
-
const
|
|
11411
|
-
|
|
11412
|
-
|
|
11413
|
-
|
|
11414
|
-
startNode = range.startContainer;
|
|
11415
|
-
if (startNode.nodeType === Node.ELEMENT_NODE) {
|
|
11416
|
-
const el = startNode;
|
|
11417
|
-
startNode = el.childNodes[range.startOffset] ?? el.childNodes[range.startOffset - 1] ?? el;
|
|
9201
|
+
for (const cmd of ["bold", "italic", "underline", "strikeThrough", "insertUnorderedList", "insertOrderedList"]) {
|
|
9202
|
+
try {
|
|
9203
|
+
if (document.queryCommandState(cmd)) next.add(cmd);
|
|
9204
|
+
} catch {
|
|
11418
9205
|
}
|
|
11419
9206
|
}
|
|
11420
|
-
const
|
|
11421
|
-
|
|
11422
|
-
|
|
11423
|
-
const
|
|
11424
|
-
|
|
11425
|
-
|
|
11426
|
-
|
|
11427
|
-
|
|
11428
|
-
|
|
11429
|
-
|
|
11430
|
-
for (let el = startEl; el; el = el.parentElement) {
|
|
11431
|
-
if (el.tagName === "B" || el.tagName === "STRONG") hasBold = true;
|
|
11432
|
-
if (el.tagName === "I" || el.tagName === "EM") hasItalic = true;
|
|
11433
|
-
const decoration = getComputedStyle(el).textDecorationLine;
|
|
11434
|
-
if (decoration.includes("underline") || el.tagName === "U" || el.tagName === "INS") hasUnderline = true;
|
|
11435
|
-
if (decoration.includes("line-through") || el.tagName === "S" || el.tagName === "STRIKE" || el.tagName === "DEL") hasStrike = true;
|
|
11436
|
-
if (el.tagName === "UL") hasUl = true;
|
|
11437
|
-
if (el.tagName === "OL") hasOl = true;
|
|
11438
|
-
if (el === activeRoot) break;
|
|
11439
|
-
}
|
|
11440
|
-
if (hasBold) next.add("bold");
|
|
11441
|
-
if (hasItalic) next.add("italic");
|
|
11442
|
-
if (hasUnderline) next.add("underline");
|
|
11443
|
-
if (hasStrike) next.add("strikeThrough");
|
|
11444
|
-
if (hasUl) next.add("insertUnorderedList");
|
|
11445
|
-
if (hasOl) next.add("insertOrderedList");
|
|
11446
|
-
const block = startEl.closest("div, p, h1, h2, h3, h4, h5, h6, li, td, th") ?? startEl;
|
|
11447
|
-
const align = getComputedStyle(block).textAlign;
|
|
11448
|
-
if (align === "center") next.add("justifyCenter");
|
|
11449
|
-
else if (align === "right" || align === "end") next.add("justifyRight");
|
|
11450
|
-
else next.add("justifyLeft");
|
|
11451
|
-
}
|
|
11452
|
-
setActiveCommands((prev) => {
|
|
11453
|
-
if (prev.size === next.size) {
|
|
11454
|
-
let same = true;
|
|
11455
|
-
for (const cmd of prev) {
|
|
11456
|
-
if (!next.has(cmd)) {
|
|
11457
|
-
same = false;
|
|
11458
|
-
break;
|
|
11459
|
-
}
|
|
11460
|
-
}
|
|
11461
|
-
if (same) return prev;
|
|
9207
|
+
const sel = window.getSelection();
|
|
9208
|
+
const anchor = sel?.anchorNode;
|
|
9209
|
+
if (anchor) {
|
|
9210
|
+
const el = anchor.nodeType === Node.TEXT_NODE ? anchor.parentElement : anchor;
|
|
9211
|
+
const block = el?.closest("div, p, h1, h2, h3, h4, h5, h6, li, td, th") ?? el;
|
|
9212
|
+
if (block) {
|
|
9213
|
+
const align = getComputedStyle(block).textAlign;
|
|
9214
|
+
if (align === "center") next.add("justifyCenter");
|
|
9215
|
+
else if (align === "right" || align === "end") next.add("justifyRight");
|
|
9216
|
+
else next.add("justifyLeft");
|
|
11462
9217
|
}
|
|
11463
|
-
|
|
11464
|
-
|
|
11465
|
-
};
|
|
11466
|
-
const handleSelectionChange = () => {
|
|
11467
|
-
if (pointerHeldRef.current) return;
|
|
11468
|
-
if (selectionChangeRaf !== null) return;
|
|
11469
|
-
selectionChangeRaf = requestAnimationFrame(runSelectionChange);
|
|
11470
|
-
};
|
|
11471
|
-
const markPointerHeld = (e) => {
|
|
11472
|
-
if (e.button !== 0) return;
|
|
11473
|
-
pointerHeldRef.current = true;
|
|
11474
|
-
};
|
|
11475
|
-
const markPointerReleased = () => {
|
|
11476
|
-
if (!pointerHeldRef.current) return;
|
|
11477
|
-
pointerHeldRef.current = false;
|
|
11478
|
-
handleSelectionChange();
|
|
9218
|
+
}
|
|
9219
|
+
setActiveCommands(next);
|
|
11479
9220
|
};
|
|
11480
|
-
refreshActiveCommandsRef.current =
|
|
9221
|
+
refreshActiveCommandsRef.current = handleSelectionChange;
|
|
11481
9222
|
const handleDocMouseLeave = () => {
|
|
11482
9223
|
hoveredImageRef.current = null;
|
|
11483
9224
|
setMediaHover(null);
|
|
@@ -11522,15 +9263,15 @@ function OhhwellsBridge() {
|
|
|
11522
9263
|
};
|
|
11523
9264
|
const applyToolbarPos = (rect) => {
|
|
11524
9265
|
const ps = parentScrollRef.current;
|
|
11525
|
-
const
|
|
9266
|
+
const approxW = 330;
|
|
11526
9267
|
if (toolbarElRef.current) {
|
|
11527
|
-
const { top, left, transform } = calcToolbarPos(rect, ps,
|
|
9268
|
+
const { top, left, transform } = calcToolbarPos(rect, ps, approxW);
|
|
11528
9269
|
toolbarElRef.current.style.top = `${top}px`;
|
|
11529
9270
|
toolbarElRef.current.style.left = `${left}px`;
|
|
11530
9271
|
toolbarElRef.current.style.transform = transform;
|
|
11531
9272
|
}
|
|
11532
9273
|
if (glowElRef.current) {
|
|
11533
|
-
const GAP =
|
|
9274
|
+
const GAP = 6;
|
|
11534
9275
|
glowElRef.current.style.top = `${rect.top - GAP}px`;
|
|
11535
9276
|
glowElRef.current.style.left = `${rect.left - GAP}px`;
|
|
11536
9277
|
glowElRef.current.style.width = `${rect.width + GAP * 2}px`;
|
|
@@ -11618,11 +9359,6 @@ function OhhwellsBridge() {
|
|
|
11618
9359
|
return;
|
|
11619
9360
|
}
|
|
11620
9361
|
}
|
|
11621
|
-
const footerColumn = findHoveredNavOrFooterContainer(clientX, clientY);
|
|
11622
|
-
if (footerColumn?.hasAttribute("data-ohw-footer-col") || footerColumn?.hasAttribute("data-ohw-footer-column")) {
|
|
11623
|
-
selectFrameRef.current(footerColumn);
|
|
11624
|
-
return;
|
|
11625
|
-
}
|
|
11626
9362
|
deactivateRef.current();
|
|
11627
9363
|
};
|
|
11628
9364
|
window.addEventListener("message", handleSave);
|
|
@@ -11694,177 +9430,7 @@ function OhhwellsBridge() {
|
|
|
11694
9430
|
if (imageShowTimerRef.current) clearTimeout(imageShowTimerRef.current);
|
|
11695
9431
|
};
|
|
11696
9432
|
}, [isEditMode, refreshStateRules]);
|
|
11697
|
-
(0,
|
|
11698
|
-
if (!isEditMode) return;
|
|
11699
|
-
const THRESHOLD = 10;
|
|
11700
|
-
const resolveWasSelected = (el) => {
|
|
11701
|
-
if (selectedElRef.current === el) return true;
|
|
11702
|
-
const activeAnchor = activeElRef.current ? getNavigationItemAnchor(activeElRef.current) : null;
|
|
11703
|
-
return activeAnchor === el;
|
|
11704
|
-
};
|
|
11705
|
-
const onPointerDown = (e) => {
|
|
11706
|
-
if (e.button !== 0) return;
|
|
11707
|
-
if (suppressNextClickRef.current && Date.now() >= suppressClickUntilRef.current && !footerDragRef.current && !footerPointerDragRef.current?.started) {
|
|
11708
|
-
suppressNextClickRef.current = false;
|
|
11709
|
-
}
|
|
11710
|
-
if (footerDragRef.current) return;
|
|
11711
|
-
const target = e.target;
|
|
11712
|
-
if (!target) return;
|
|
11713
|
-
if (target.closest('[data-ohw-drag-handle-container], [data-slot="drag-handle"], [data-ohw-toolbar], [data-ohw-item-toolbar-anchor], [data-ohw-link-popover-root]')) {
|
|
11714
|
-
return;
|
|
11715
|
-
}
|
|
11716
|
-
if (target.closest("[data-ohw-item-drag-surface]")) return;
|
|
11717
|
-
const anchor = getNavigationItemAnchor(target);
|
|
11718
|
-
const hrefKey = anchor?.getAttribute("data-ohw-href-key") ?? null;
|
|
11719
|
-
if (anchor && isFooterHrefKey(hrefKey)) {
|
|
11720
|
-
footerPointerDragRef.current = {
|
|
11721
|
-
el: anchor,
|
|
11722
|
-
kind: "link",
|
|
11723
|
-
startX: e.clientX,
|
|
11724
|
-
startY: e.clientY,
|
|
11725
|
-
pointerId: e.pointerId,
|
|
11726
|
-
wasSelected: resolveWasSelected(anchor),
|
|
11727
|
-
started: false
|
|
11728
|
-
};
|
|
11729
|
-
return;
|
|
11730
|
-
}
|
|
11731
|
-
const col = target.closest("[data-ohw-footer-col]");
|
|
11732
|
-
if (col && !getNavigationItemAnchor(target)) {
|
|
11733
|
-
footerPointerDragRef.current = {
|
|
11734
|
-
el: col,
|
|
11735
|
-
kind: "column",
|
|
11736
|
-
startX: e.clientX,
|
|
11737
|
-
startY: e.clientY,
|
|
11738
|
-
pointerId: e.pointerId,
|
|
11739
|
-
wasSelected: resolveWasSelected(col),
|
|
11740
|
-
started: false
|
|
11741
|
-
};
|
|
11742
|
-
}
|
|
11743
|
-
};
|
|
11744
|
-
const onPointerMove = (e) => {
|
|
11745
|
-
const pending = footerPointerDragRef.current;
|
|
11746
|
-
if (!pending) return;
|
|
11747
|
-
if (pending.started) {
|
|
11748
|
-
e.preventDefault();
|
|
11749
|
-
clearTextSelection();
|
|
11750
|
-
const session = footerDragRef.current;
|
|
11751
|
-
if (!session) return;
|
|
11752
|
-
const slot = session.kind === "link" && session.hrefKey ? hitTestLinkDropSlot(e.clientX, e.clientY, session.hrefKey) : hitTestColumnDropSlot(e.clientX, e.clientY);
|
|
11753
|
-
refreshFooterDragVisualsRef.current(session, slot, e.clientX, e.clientY);
|
|
11754
|
-
return;
|
|
11755
|
-
}
|
|
11756
|
-
const dx = e.clientX - pending.startX;
|
|
11757
|
-
const dy = e.clientY - pending.startY;
|
|
11758
|
-
if (dx * dx + dy * dy < THRESHOLD * THRESHOLD) return;
|
|
11759
|
-
e.preventDefault();
|
|
11760
|
-
pending.started = true;
|
|
11761
|
-
armFooterPressDrag();
|
|
11762
|
-
clearTextSelection();
|
|
11763
|
-
try {
|
|
11764
|
-
document.body.setPointerCapture(pending.pointerId);
|
|
11765
|
-
} catch {
|
|
11766
|
-
}
|
|
11767
|
-
if (linkPopoverOpenRef.current) {
|
|
11768
|
-
setLinkPopoverRef.current(null);
|
|
11769
|
-
}
|
|
11770
|
-
if (activeElRef.current) {
|
|
11771
|
-
deactivateRef.current();
|
|
11772
|
-
}
|
|
11773
|
-
if (pending.kind === "link") {
|
|
11774
|
-
const key = pending.el.getAttribute("data-ohw-href-key");
|
|
11775
|
-
if (!key) return;
|
|
11776
|
-
const column = findFooterColumnForLink(pending.el);
|
|
11777
|
-
const columns2 = listFooterColumns();
|
|
11778
|
-
beginFooterDragRef.current({
|
|
11779
|
-
kind: "link",
|
|
11780
|
-
hrefKey: key,
|
|
11781
|
-
columnEl: column,
|
|
11782
|
-
sourceColumnIndex: column ? columns2.indexOf(column) : 0,
|
|
11783
|
-
wasSelected: pending.wasSelected,
|
|
11784
|
-
draggedEl: pending.el,
|
|
11785
|
-
lastClientX: e.clientX,
|
|
11786
|
-
lastClientY: e.clientY,
|
|
11787
|
-
activeSlot: null
|
|
11788
|
-
});
|
|
11789
|
-
return;
|
|
11790
|
-
}
|
|
11791
|
-
const columns = listFooterColumns();
|
|
11792
|
-
const idx = columns.indexOf(pending.el);
|
|
11793
|
-
if (idx < 0) return;
|
|
11794
|
-
beginFooterDragRef.current({
|
|
11795
|
-
kind: "column",
|
|
11796
|
-
hrefKey: null,
|
|
11797
|
-
columnEl: pending.el,
|
|
11798
|
-
sourceColumnIndex: idx,
|
|
11799
|
-
wasSelected: pending.wasSelected,
|
|
11800
|
-
draggedEl: pending.el,
|
|
11801
|
-
lastClientX: e.clientX,
|
|
11802
|
-
lastClientY: e.clientY,
|
|
11803
|
-
activeSlot: null
|
|
11804
|
-
});
|
|
11805
|
-
};
|
|
11806
|
-
const endPointerDrag = (e) => {
|
|
11807
|
-
const pending = footerPointerDragRef.current;
|
|
11808
|
-
footerPointerDragRef.current = null;
|
|
11809
|
-
try {
|
|
11810
|
-
if (document.body.hasPointerCapture(e.pointerId)) {
|
|
11811
|
-
document.body.releasePointerCapture(e.pointerId);
|
|
11812
|
-
}
|
|
11813
|
-
} catch {
|
|
11814
|
-
}
|
|
11815
|
-
if (!pending) return;
|
|
11816
|
-
if (!pending.started) {
|
|
11817
|
-
unlockFooterDragInteraction();
|
|
11818
|
-
return;
|
|
11819
|
-
}
|
|
11820
|
-
suppressNextClickRef.current = true;
|
|
11821
|
-
suppressClickUntilRef.current = Date.now() + 500;
|
|
11822
|
-
commitFooterDragRef.current(e.clientX, e.clientY);
|
|
11823
|
-
};
|
|
11824
|
-
const blockSelectStart = (e) => {
|
|
11825
|
-
if (footerDragRef.current || footerPointerDragRef.current?.started || document.documentElement.hasAttribute("data-ohw-footer-press-drag")) {
|
|
11826
|
-
e.preventDefault();
|
|
11827
|
-
}
|
|
11828
|
-
};
|
|
11829
|
-
const onDragEnd = (_e) => {
|
|
11830
|
-
if (!footerDragRef.current) return;
|
|
11831
|
-
suppressNextClickRef.current = true;
|
|
11832
|
-
suppressClickUntilRef.current = Date.now() + 500;
|
|
11833
|
-
commitFooterDragRef.current();
|
|
11834
|
-
};
|
|
11835
|
-
document.addEventListener("pointerdown", onPointerDown, true);
|
|
11836
|
-
document.addEventListener("pointermove", onPointerMove, true);
|
|
11837
|
-
document.addEventListener("pointerup", endPointerDrag, true);
|
|
11838
|
-
document.addEventListener("pointercancel", endPointerDrag, true);
|
|
11839
|
-
document.addEventListener("selectstart", blockSelectStart, true);
|
|
11840
|
-
document.addEventListener("dragend", onDragEnd, true);
|
|
11841
|
-
return () => {
|
|
11842
|
-
document.removeEventListener("pointerdown", onPointerDown, true);
|
|
11843
|
-
document.removeEventListener("pointermove", onPointerMove, true);
|
|
11844
|
-
document.removeEventListener("pointerup", endPointerDrag, true);
|
|
11845
|
-
document.removeEventListener("pointercancel", endPointerDrag, true);
|
|
11846
|
-
document.removeEventListener("selectstart", blockSelectStart, true);
|
|
11847
|
-
document.removeEventListener("dragend", onDragEnd, true);
|
|
11848
|
-
unlockFooterDragInteraction();
|
|
11849
|
-
};
|
|
11850
|
-
}, [isEditMode]);
|
|
11851
|
-
(0, import_react9.useEffect)(() => {
|
|
11852
|
-
if (!isEditMode) return;
|
|
11853
|
-
const debugSelectionChange = () => {
|
|
11854
|
-
const sel = window.getSelection();
|
|
11855
|
-
console.log(
|
|
11856
|
-
"[OHW DEBUG selectionchange]",
|
|
11857
|
-
JSON.stringify(sel?.toString() ?? ""),
|
|
11858
|
-
"collapsed=",
|
|
11859
|
-
sel?.isCollapsed,
|
|
11860
|
-
"anchorNode=",
|
|
11861
|
-
sel?.anchorNode,
|
|
11862
|
-
"activeEl=",
|
|
11863
|
-
activeElRef.current
|
|
11864
|
-
);
|
|
11865
|
-
};
|
|
11866
|
-
}, [isEditMode]);
|
|
11867
|
-
(0, import_react9.useEffect)(() => {
|
|
9433
|
+
(0, import_react8.useEffect)(() => {
|
|
11868
9434
|
const handler = (e) => {
|
|
11869
9435
|
if (e.data?.type !== "ow:request-schedule-config") return;
|
|
11870
9436
|
const insertAfterVal = e.data.insertAfter;
|
|
@@ -11880,7 +9446,7 @@ function OhhwellsBridge() {
|
|
|
11880
9446
|
window.addEventListener("message", handler);
|
|
11881
9447
|
return () => window.removeEventListener("message", handler);
|
|
11882
9448
|
}, [processConfigRequest]);
|
|
11883
|
-
(0,
|
|
9449
|
+
(0, import_react8.useEffect)(() => {
|
|
11884
9450
|
if (!isEditMode) return;
|
|
11885
9451
|
document.querySelectorAll("[data-ohw-active-state]").forEach((el) => {
|
|
11886
9452
|
el.removeAttribute("data-ohw-active-state");
|
|
@@ -11901,13 +9467,7 @@ function OhhwellsBridge() {
|
|
|
11901
9467
|
const next = { ...prev, [pathKey]: sections };
|
|
11902
9468
|
return shouldUseDevFixtures() ? { ...DEV_SECTIONS_BY_PATH, ...next } : next;
|
|
11903
9469
|
});
|
|
11904
|
-
postToParent2({
|
|
11905
|
-
type: "ow:ready",
|
|
11906
|
-
version: "1",
|
|
11907
|
-
path: pathname,
|
|
11908
|
-
nodes: collectEditableNodes(editContentRef.current),
|
|
11909
|
-
sections
|
|
11910
|
-
});
|
|
9470
|
+
postToParent2({ type: "ow:ready", version: "1", path: pathname, nodes: collectEditableNodes(), sections });
|
|
11911
9471
|
postToParent2({ type: "ow:request-site-pages" });
|
|
11912
9472
|
}, 150);
|
|
11913
9473
|
return () => {
|
|
@@ -11915,20 +9475,19 @@ function OhhwellsBridge() {
|
|
|
11915
9475
|
clearTimeout(timer);
|
|
11916
9476
|
};
|
|
11917
9477
|
}, [pathname, isEditMode, refreshStateRules, postToParent2]);
|
|
11918
|
-
(0,
|
|
9478
|
+
(0, import_react8.useEffect)(() => {
|
|
11919
9479
|
scrollToHashSectionWhenReady();
|
|
11920
9480
|
const onHashChange = () => scrollToHashSectionWhenReady();
|
|
11921
9481
|
window.addEventListener("hashchange", onHashChange);
|
|
11922
9482
|
return () => window.removeEventListener("hashchange", onHashChange);
|
|
11923
9483
|
}, [pathname]);
|
|
11924
|
-
const handleCommand = (0,
|
|
11925
|
-
document.execCommand("styleWithCSS", false, true);
|
|
9484
|
+
const handleCommand = (0, import_react8.useCallback)((cmd) => {
|
|
11926
9485
|
document.execCommand(cmd, false);
|
|
11927
9486
|
activeElRef.current?.focus();
|
|
11928
9487
|
if (activeElRef.current) setToolbarRect(getEditMeasureEl(activeElRef.current).getBoundingClientRect());
|
|
11929
9488
|
refreshActiveCommandsRef.current();
|
|
11930
9489
|
}, []);
|
|
11931
|
-
const handleStateChange = (0,
|
|
9490
|
+
const handleStateChange = (0, import_react8.useCallback)((state) => {
|
|
11932
9491
|
if (!activeStateElRef.current) return;
|
|
11933
9492
|
const el = activeStateElRef.current;
|
|
11934
9493
|
if (state === "Default") {
|
|
@@ -11941,11 +9500,11 @@ function OhhwellsBridge() {
|
|
|
11941
9500
|
}
|
|
11942
9501
|
setToggleState((prev) => prev ? { ...prev, activeState: state } : null);
|
|
11943
9502
|
}, [deactivate]);
|
|
11944
|
-
const closeLinkPopover = (0,
|
|
9503
|
+
const closeLinkPopover = (0, import_react8.useCallback)(() => {
|
|
11945
9504
|
addNavAfterAnchorRef.current = null;
|
|
11946
9505
|
setLinkPopover(null);
|
|
11947
9506
|
}, []);
|
|
11948
|
-
const openLinkPopoverForActive = (0,
|
|
9507
|
+
const openLinkPopoverForActive = (0, import_react8.useCallback)(() => {
|
|
11949
9508
|
const hrefCtx = getHrefKeyFromElement(activeElRef.current);
|
|
11950
9509
|
if (!hrefCtx) return;
|
|
11951
9510
|
bumpLinkPopoverGrace();
|
|
@@ -11956,7 +9515,7 @@ function OhhwellsBridge() {
|
|
|
11956
9515
|
});
|
|
11957
9516
|
deactivate();
|
|
11958
9517
|
}, [deactivate]);
|
|
11959
|
-
const openLinkPopoverForSelected = (0,
|
|
9518
|
+
const openLinkPopoverForSelected = (0, import_react8.useCallback)(() => {
|
|
11960
9519
|
const anchor = selectedElRef.current;
|
|
11961
9520
|
if (!anchor) return;
|
|
11962
9521
|
const key = anchor.getAttribute("data-ohw-href-key");
|
|
@@ -11969,7 +9528,7 @@ function OhhwellsBridge() {
|
|
|
11969
9528
|
});
|
|
11970
9529
|
deselect();
|
|
11971
9530
|
}, [deselect]);
|
|
11972
|
-
const handleLinkPopoverSubmit = (0,
|
|
9531
|
+
const handleLinkPopoverSubmit = (0, import_react8.useCallback)(
|
|
11973
9532
|
(target) => {
|
|
11974
9533
|
const session = linkPopoverSessionRef.current;
|
|
11975
9534
|
if (!session) return;
|
|
@@ -12028,13 +9587,13 @@ function OhhwellsBridge() {
|
|
|
12028
9587
|
const showEditLink = toolbarShowEditLink;
|
|
12029
9588
|
const currentSections = sectionsByPath[pathname] ?? [];
|
|
12030
9589
|
linkPopoverOpenRef.current = linkPopover !== null;
|
|
12031
|
-
const handleMediaReplace = (0,
|
|
9590
|
+
const handleMediaReplace = (0, import_react8.useCallback)(
|
|
12032
9591
|
(key) => {
|
|
12033
9592
|
postToParent2({ type: "ow:image-pick", key, elementType: mediaHover?.elementType ?? "image" });
|
|
12034
9593
|
},
|
|
12035
9594
|
[postToParent2, mediaHover?.elementType]
|
|
12036
9595
|
);
|
|
12037
|
-
const handleMediaFadeOutComplete = (0,
|
|
9596
|
+
const handleMediaFadeOutComplete = (0, import_react8.useCallback)((key) => {
|
|
12038
9597
|
setUploadingRects((prev) => {
|
|
12039
9598
|
if (!(key in prev)) return prev;
|
|
12040
9599
|
const next = { ...prev };
|
|
@@ -12042,7 +9601,7 @@ function OhhwellsBridge() {
|
|
|
12042
9601
|
return next;
|
|
12043
9602
|
});
|
|
12044
9603
|
}, []);
|
|
12045
|
-
const handleVideoSettingsChange = (0,
|
|
9604
|
+
const handleVideoSettingsChange = (0, import_react8.useCallback)(
|
|
12046
9605
|
(key, settings) => {
|
|
12047
9606
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
12048
9607
|
const video = getVideoEl(el);
|
|
@@ -12065,9 +9624,9 @@ function OhhwellsBridge() {
|
|
|
12065
9624
|
[postToParent2]
|
|
12066
9625
|
);
|
|
12067
9626
|
return bridgeRoot ? (0, import_react_dom3.createPortal)(
|
|
12068
|
-
/* @__PURE__ */ (0,
|
|
12069
|
-
/* @__PURE__ */ (0,
|
|
12070
|
-
Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ (0,
|
|
9627
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
|
|
9628
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
|
|
9629
|
+
Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
12071
9630
|
MediaOverlay,
|
|
12072
9631
|
{
|
|
12073
9632
|
hover: { key, rect, elementType: "image", isDragOver: false, hasTextOverlap: false },
|
|
@@ -12078,7 +9637,7 @@ function OhhwellsBridge() {
|
|
|
12078
9637
|
},
|
|
12079
9638
|
`uploading-${key}`
|
|
12080
9639
|
)),
|
|
12081
|
-
mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */ (0,
|
|
9640
|
+
mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
12082
9641
|
MediaOverlay,
|
|
12083
9642
|
{
|
|
12084
9643
|
hover: mediaHover,
|
|
@@ -12087,93 +9646,49 @@ function OhhwellsBridge() {
|
|
|
12087
9646
|
onVideoSettingsChange: handleVideoSettingsChange
|
|
12088
9647
|
}
|
|
12089
9648
|
),
|
|
12090
|
-
siblingHintRect && !
|
|
12091
|
-
|
|
12092
|
-
|
|
12093
|
-
|
|
12094
|
-
"div",
|
|
12095
|
-
{
|
|
12096
|
-
className: "pointer-events-none fixed z-2147483646",
|
|
12097
|
-
style: {
|
|
12098
|
-
left: slot.left,
|
|
12099
|
-
top: slot.top,
|
|
12100
|
-
width: slot.width,
|
|
12101
|
-
height: slot.height
|
|
12102
|
-
},
|
|
12103
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
12104
|
-
DropIndicator,
|
|
12105
|
-
{
|
|
12106
|
-
direction: slot.direction,
|
|
12107
|
-
state: activeFooterDropIndex === i ? "dragActive" : "dragIdle",
|
|
12108
|
-
className: "!h-full !w-full"
|
|
12109
|
-
}
|
|
12110
|
-
)
|
|
12111
|
-
},
|
|
12112
|
-
`footer-drop-${slot.direction}-${slot.columnIndex}-${slot.insertIndex}-${i}`
|
|
12113
|
-
)),
|
|
12114
|
-
isItemDragging && navDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
12115
|
-
"div",
|
|
9649
|
+
siblingHintRect && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
|
|
9650
|
+
hoveredNavContainerRect && toolbarVariant !== "select-frame" && !linkPopover && !isItemDragging && !siblingHintRect && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ItemInteractionLayer, { rect: hoveredNavContainerRect, state: "hover" }),
|
|
9651
|
+
toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
9652
|
+
NavbarContainerChrome,
|
|
12116
9653
|
{
|
|
12117
|
-
|
|
12118
|
-
|
|
12119
|
-
|
|
12120
|
-
|
|
12121
|
-
|
|
12122
|
-
|
|
12123
|
-
},
|
|
12124
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
12125
|
-
DropIndicator,
|
|
12126
|
-
{
|
|
12127
|
-
direction: slot.direction,
|
|
12128
|
-
state: activeNavDropIndex === i ? "dragActive" : "dragIdle",
|
|
12129
|
-
className: "!h-full !w-full"
|
|
12130
|
-
}
|
|
12131
|
-
)
|
|
12132
|
-
},
|
|
12133
|
-
`nav-drop-${slot.direction}-${slot.parentId ?? "root"}-${slot.insertIndex}-${i}`
|
|
12134
|
-
)),
|
|
12135
|
-
hoveredNavContainerRect && toolbarVariant !== "select-frame" && !linkPopover && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ItemInteractionLayer, { rect: hoveredNavContainerRect, state: "hover" }),
|
|
12136
|
-
hoveredItemRect && !linkPopover && !hoveredNavContainerRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
|
|
12137
|
-
toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isNavbarLinksContainer(selectedElRef.current) && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(NavbarContainerChrome, { rect: toolbarRect, onAdd: handleAddTopLevelNavItem }),
|
|
12138
|
-
toolbarRect && !linkPopover && (toolbarVariant === "link-action" || toolbarVariant === "select-frame") && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
9654
|
+
rect: toolbarRect,
|
|
9655
|
+
onAdd: handleAddTopLevelNavItem
|
|
9656
|
+
}
|
|
9657
|
+
),
|
|
9658
|
+
hoveredItemRect && !hoveredNavContainerRect && !siblingHintRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
|
|
9659
|
+
toolbarRect && (toolbarVariant === "link-action" || toolbarVariant === "select-frame") && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
12139
9660
|
ItemInteractionLayer,
|
|
12140
9661
|
{
|
|
12141
|
-
rect:
|
|
9662
|
+
rect: toolbarRect,
|
|
12142
9663
|
elRef: glowElRef,
|
|
12143
9664
|
state: isItemDragging ? "dragging" : resolveItemInteractionState(toolbarRect, parentScrollRef.current),
|
|
12144
|
-
showHandle: toolbarVariant === "link-action" && Boolean(reorderHrefKey)
|
|
9665
|
+
showHandle: toolbarVariant === "link-action" && Boolean(reorderHrefKey),
|
|
12145
9666
|
dragDisabled: reorderDragDisabled,
|
|
12146
9667
|
dragHandleLabel: reorderHrefKey ? `Reorder ${reorderHrefKey}` : "Reorder item",
|
|
12147
9668
|
onDragHandleDragStart: handleItemDragStart,
|
|
12148
9669
|
onDragHandleDragEnd: handleItemDragEnd,
|
|
12149
|
-
|
|
12150
|
-
onItemClick: handleItemChromeClick,
|
|
12151
|
-
itemDragSurface: !isFooterFrameSelection,
|
|
12152
|
-
toolbar: toolbarVariant === "link-action" && !isItemDragging ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
9670
|
+
toolbar: toolbarVariant === "link-action" && !isItemDragging ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
12153
9671
|
ItemActionToolbar,
|
|
12154
9672
|
{
|
|
12155
9673
|
onEditLink: openLinkPopoverForSelected,
|
|
12156
9674
|
addItemDisabled: true,
|
|
12157
9675
|
editLinkDisabled: false,
|
|
12158
|
-
moreDisabled: true
|
|
12159
|
-
showAddItem: !selectedIsCta,
|
|
12160
|
-
showMore: !selectedIsCta
|
|
9676
|
+
moreDisabled: true
|
|
12161
9677
|
}
|
|
12162
9678
|
) : void 0
|
|
12163
9679
|
}
|
|
12164
9680
|
),
|
|
12165
|
-
toolbarRect && toolbarVariant === "rich-text" &&
|
|
12166
|
-
/* @__PURE__ */ (0,
|
|
9681
|
+
toolbarRect && toolbarVariant === "rich-text" && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
|
|
9682
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
12167
9683
|
EditGlowChrome,
|
|
12168
9684
|
{
|
|
12169
9685
|
rect: toolbarRect,
|
|
12170
9686
|
elRef: glowElRef,
|
|
12171
9687
|
reorderHrefKey,
|
|
12172
|
-
dragDisabled: reorderDragDisabled
|
|
12173
|
-
hideHandle: isItemDragging
|
|
9688
|
+
dragDisabled: reorderDragDisabled
|
|
12174
9689
|
}
|
|
12175
9690
|
),
|
|
12176
|
-
/* @__PURE__ */ (0,
|
|
9691
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
12177
9692
|
FloatingToolbar,
|
|
12178
9693
|
{
|
|
12179
9694
|
rect: toolbarRect,
|
|
@@ -12186,7 +9701,7 @@ function OhhwellsBridge() {
|
|
|
12186
9701
|
}
|
|
12187
9702
|
)
|
|
12188
9703
|
] }),
|
|
12189
|
-
maxBadge && /* @__PURE__ */ (0,
|
|
9704
|
+
maxBadge && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
12190
9705
|
"div",
|
|
12191
9706
|
{
|
|
12192
9707
|
"data-ohw-max-badge": "",
|
|
@@ -12212,7 +9727,7 @@ function OhhwellsBridge() {
|
|
|
12212
9727
|
]
|
|
12213
9728
|
}
|
|
12214
9729
|
),
|
|
12215
|
-
toggleState && !linkPopover && /* @__PURE__ */ (0,
|
|
9730
|
+
toggleState && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
12216
9731
|
StateToggle,
|
|
12217
9732
|
{
|
|
12218
9733
|
rect: toggleState.rect,
|
|
@@ -12221,36 +9736,32 @@ function OhhwellsBridge() {
|
|
|
12221
9736
|
onStateChange: handleStateChange
|
|
12222
9737
|
}
|
|
12223
9738
|
),
|
|
12224
|
-
sectionGap && !linkPopover && /* @__PURE__ */ (0,
|
|
9739
|
+
sectionGap && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
12225
9740
|
"div",
|
|
12226
9741
|
{
|
|
12227
9742
|
"data-ohw-section-insert-line": "",
|
|
12228
9743
|
className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
|
|
12229
9744
|
style: { top: sectionGap.y, transform: "translateY(-50%)" },
|
|
12230
9745
|
children: [
|
|
12231
|
-
/* @__PURE__ */ (0,
|
|
12232
|
-
/* @__PURE__ */ (0,
|
|
9746
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
|
|
9747
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
12233
9748
|
Badge,
|
|
12234
9749
|
{
|
|
12235
9750
|
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",
|
|
12236
9751
|
onClick: () => {
|
|
12237
9752
|
window.parent.postMessage(
|
|
12238
|
-
{
|
|
12239
|
-
type: "ow:add-section",
|
|
12240
|
-
insertAfter: sectionGap.insertAfter,
|
|
12241
|
-
insertBefore: sectionGap.insertBefore
|
|
12242
|
-
},
|
|
9753
|
+
{ type: "ow:add-section", insertAfter: sectionGap.insertAfter, insertBefore: sectionGap.insertBefore },
|
|
12243
9754
|
"*"
|
|
12244
9755
|
);
|
|
12245
9756
|
},
|
|
12246
9757
|
children: "Add Section"
|
|
12247
9758
|
}
|
|
12248
9759
|
),
|
|
12249
|
-
/* @__PURE__ */ (0,
|
|
9760
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } })
|
|
12250
9761
|
]
|
|
12251
9762
|
}
|
|
12252
9763
|
),
|
|
12253
|
-
linkPopover && dialogPortalContainer ? /* @__PURE__ */ (0,
|
|
9764
|
+
linkPopover && dialogPortalContainer ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
12254
9765
|
LinkPopover,
|
|
12255
9766
|
{
|
|
12256
9767
|
panelRef: linkPopoverPanelRef,
|
|
@@ -12271,6 +9782,48 @@ function OhhwellsBridge() {
|
|
|
12271
9782
|
bridgeRoot
|
|
12272
9783
|
) : null;
|
|
12273
9784
|
}
|
|
9785
|
+
|
|
9786
|
+
// src/ui/drop-indicator.tsx
|
|
9787
|
+
var React10 = __toESM(require("react"), 1);
|
|
9788
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
9789
|
+
var dropIndicatorVariants = cva(
|
|
9790
|
+
"ov-gap-line pointer-events-none shrink-0 transition-opacity duration-150",
|
|
9791
|
+
{
|
|
9792
|
+
variants: {
|
|
9793
|
+
direction: {
|
|
9794
|
+
vertical: "h-6 w-[3px]",
|
|
9795
|
+
horizontal: "h-[3px] w-[200px]"
|
|
9796
|
+
},
|
|
9797
|
+
state: {
|
|
9798
|
+
default: "opacity-0",
|
|
9799
|
+
hover: "opacity-100",
|
|
9800
|
+
dragIdle: "opacity-40",
|
|
9801
|
+
dragActive: "opacity-100"
|
|
9802
|
+
}
|
|
9803
|
+
},
|
|
9804
|
+
defaultVariants: {
|
|
9805
|
+
direction: "vertical",
|
|
9806
|
+
state: "default"
|
|
9807
|
+
}
|
|
9808
|
+
}
|
|
9809
|
+
);
|
|
9810
|
+
var DropIndicator = React10.forwardRef(
|
|
9811
|
+
({ className, direction, state, ...props }, ref) => {
|
|
9812
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
9813
|
+
"div",
|
|
9814
|
+
{
|
|
9815
|
+
ref,
|
|
9816
|
+
"data-slot": "drop-indicator",
|
|
9817
|
+
"data-direction": direction ?? "vertical",
|
|
9818
|
+
"data-state": state ?? "default",
|
|
9819
|
+
"aria-hidden": "true",
|
|
9820
|
+
className: cn(dropIndicatorVariants({ direction, state }), className),
|
|
9821
|
+
...props
|
|
9822
|
+
}
|
|
9823
|
+
);
|
|
9824
|
+
}
|
|
9825
|
+
);
|
|
9826
|
+
DropIndicator.displayName = "DropIndicator";
|
|
12274
9827
|
// Annotate the CommonJS export names for ESM import in node:
|
|
12275
9828
|
0 && (module.exports = {
|
|
12276
9829
|
CustomToolbar,
|