@ohhwells/bridge 0.1.50 → 0.1.51-next.119
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/dist/index.cjs +1907 -585
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +30 -4
- package/dist/index.d.ts +30 -4
- package/dist/index.js +1724 -408
- package/dist/index.js.map +1 -1
- package/dist/styles.css +348 -375
- package/package.json +2 -1
package/dist/index.cjs
CHANGED
|
@@ -36,6 +36,12 @@ __export(index_exports, {
|
|
|
36
36
|
CustomToolbarDivider: () => CustomToolbarDivider,
|
|
37
37
|
DragHandle: () => DragHandle,
|
|
38
38
|
DropIndicator: () => DropIndicator,
|
|
39
|
+
DropdownMenu: () => DropdownMenu,
|
|
40
|
+
DropdownMenuContent: () => DropdownMenuContent,
|
|
41
|
+
DropdownMenuGroup: () => DropdownMenuGroup,
|
|
42
|
+
DropdownMenuItem: () => DropdownMenuItem,
|
|
43
|
+
DropdownMenuSeparator: () => DropdownMenuSeparator,
|
|
44
|
+
DropdownMenuTrigger: () => DropdownMenuTrigger,
|
|
39
45
|
ItemActionToolbar: () => ItemActionToolbar,
|
|
40
46
|
ItemInteractionLayer: () => ItemInteractionLayer,
|
|
41
47
|
LinkEditorPanel: () => LinkEditorPanel,
|
|
@@ -63,7 +69,7 @@ __export(index_exports, {
|
|
|
63
69
|
module.exports = __toCommonJS(index_exports);
|
|
64
70
|
|
|
65
71
|
// src/OhhwellsBridge.tsx
|
|
66
|
-
var
|
|
72
|
+
var import_react11 = __toESM(require("react"), 1);
|
|
67
73
|
var import_client = require("react-dom/client");
|
|
68
74
|
var import_react_dom2 = require("react-dom");
|
|
69
75
|
|
|
@@ -75,6 +81,9 @@ function setStoredLinkHref(key, href) {
|
|
|
75
81
|
function getStoredLinkHref(key) {
|
|
76
82
|
return linkHrefStore.get(key);
|
|
77
83
|
}
|
|
84
|
+
function clearStoredLinkHref(key) {
|
|
85
|
+
linkHrefStore.delete(key);
|
|
86
|
+
}
|
|
78
87
|
function enforceLinkHrefs() {
|
|
79
88
|
document.querySelectorAll("[data-ohw-href-key]").forEach((el) => {
|
|
80
89
|
const key = el.getAttribute("data-ohw-href-key") ?? "";
|
|
@@ -4400,22 +4409,116 @@ var CustomToolbarButton = React4.forwardRef(
|
|
|
4400
4409
|
CustomToolbarButton.displayName = "CustomToolbarButton";
|
|
4401
4410
|
|
|
4402
4411
|
// src/ui/item-action-toolbar.tsx
|
|
4412
|
+
var import_react4 = require("react");
|
|
4403
4413
|
var import_lucide_react2 = require("lucide-react");
|
|
4404
4414
|
|
|
4405
|
-
// src/ui/
|
|
4415
|
+
// src/ui/dropdown-menu.tsx
|
|
4406
4416
|
var import_radix_ui3 = require("radix-ui");
|
|
4407
4417
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
4418
|
+
function DropdownMenu({ ...props }) {
|
|
4419
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_radix_ui3.DropdownMenu.Root, { "data-slot": "dropdown-menu", ...props });
|
|
4420
|
+
}
|
|
4421
|
+
function DropdownMenuTrigger({
|
|
4422
|
+
...props
|
|
4423
|
+
}) {
|
|
4424
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_radix_ui3.DropdownMenu.Trigger, { "data-slot": "dropdown-menu-trigger", ...props });
|
|
4425
|
+
}
|
|
4426
|
+
function DropdownMenuGroup({
|
|
4427
|
+
className,
|
|
4428
|
+
...props
|
|
4429
|
+
}) {
|
|
4430
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
4431
|
+
import_radix_ui3.DropdownMenu.Group,
|
|
4432
|
+
{
|
|
4433
|
+
"data-slot": "dropdown-menu-group",
|
|
4434
|
+
className: cn("flex w-full flex-col items-start p-1", className),
|
|
4435
|
+
...props
|
|
4436
|
+
}
|
|
4437
|
+
);
|
|
4438
|
+
}
|
|
4439
|
+
function DropdownMenuContent({
|
|
4440
|
+
className,
|
|
4441
|
+
sideOffset = 6,
|
|
4442
|
+
...props
|
|
4443
|
+
}) {
|
|
4444
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_radix_ui3.DropdownMenu.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
4445
|
+
import_radix_ui3.DropdownMenu.Content,
|
|
4446
|
+
{
|
|
4447
|
+
"data-slot": "dropdown-menu-content",
|
|
4448
|
+
"data-ohw-more-menu": "",
|
|
4449
|
+
sideOffset,
|
|
4450
|
+
className: cn(
|
|
4451
|
+
"z-[2147483647] flex w-56 min-w-32 flex-col items-center overflow-hidden rounded-[6px] border border-border bg-popover p-0 text-popover-foreground outline-none",
|
|
4452
|
+
"shadow-[0px_4px_6px_0px_rgba(0,0,0,0.1),0px_2px_4px_0px_rgba(0,0,0,0.1)]",
|
|
4453
|
+
"origin-[var(--radix-dropdown-menu-content-transform-origin)]",
|
|
4454
|
+
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
|
|
4455
|
+
"data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
|
4456
|
+
className
|
|
4457
|
+
),
|
|
4458
|
+
...props
|
|
4459
|
+
}
|
|
4460
|
+
) });
|
|
4461
|
+
}
|
|
4462
|
+
function DropdownMenuItem({
|
|
4463
|
+
className,
|
|
4464
|
+
inset,
|
|
4465
|
+
variant = "default",
|
|
4466
|
+
...props
|
|
4467
|
+
}) {
|
|
4468
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
4469
|
+
import_radix_ui3.DropdownMenu.Item,
|
|
4470
|
+
{
|
|
4471
|
+
"data-slot": "dropdown-menu-item",
|
|
4472
|
+
"data-inset": inset ? "" : void 0,
|
|
4473
|
+
"data-variant": variant,
|
|
4474
|
+
className: cn(
|
|
4475
|
+
"relative flex w-full min-w-32 cursor-pointer select-none items-center gap-2 rounded-[calc(var(--radius,0.5rem)-4px)] py-1.5 pl-8 pr-2 text-sm leading-5 outline-none",
|
|
4476
|
+
"text-popover-foreground",
|
|
4477
|
+
"focus:bg-muted data-[highlighted]:bg-muted",
|
|
4478
|
+
"data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
4479
|
+
"[&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
|
4480
|
+
"[&_svg:not([class*=absolute])]:relative",
|
|
4481
|
+
// Leading icon — Figma absolute left-2 / top-1/2
|
|
4482
|
+
"[&>svg:first-child]:absolute [&>svg:first-child]:left-2 [&>svg:first-child]:top-1/2 [&>svg:first-child]:-translate-y-1/2",
|
|
4483
|
+
"data-[variant=destructive]:text-destructive",
|
|
4484
|
+
"data-[variant=destructive]:focus:bg-bg-destructive-10 data-[variant=destructive]:focus:text-destructive",
|
|
4485
|
+
"data-[variant=destructive]:data-[highlighted]:bg-bg-destructive-10 data-[variant=destructive]:data-[highlighted]:text-destructive",
|
|
4486
|
+
"data-[variant=destructive]:[&_svg]:text-destructive",
|
|
4487
|
+
inset && "pl-8",
|
|
4488
|
+
className
|
|
4489
|
+
),
|
|
4490
|
+
...props
|
|
4491
|
+
}
|
|
4492
|
+
);
|
|
4493
|
+
}
|
|
4494
|
+
function DropdownMenuSeparator({
|
|
4495
|
+
className,
|
|
4496
|
+
...props
|
|
4497
|
+
}) {
|
|
4498
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
4499
|
+
import_radix_ui3.DropdownMenu.Separator,
|
|
4500
|
+
{
|
|
4501
|
+
"data-slot": "dropdown-menu-separator",
|
|
4502
|
+
className: cn("h-px w-full bg-border", className),
|
|
4503
|
+
...props
|
|
4504
|
+
}
|
|
4505
|
+
);
|
|
4506
|
+
}
|
|
4507
|
+
|
|
4508
|
+
// src/ui/tooltip.tsx
|
|
4509
|
+
var import_radix_ui4 = require("radix-ui");
|
|
4510
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
4408
4511
|
function TooltipProvider({
|
|
4409
4512
|
delayDuration = 0,
|
|
4410
4513
|
...props
|
|
4411
4514
|
}) {
|
|
4412
|
-
return /* @__PURE__ */ (0,
|
|
4515
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_radix_ui4.Tooltip.Provider, { "data-slot": "tooltip-provider", delayDuration, ...props });
|
|
4413
4516
|
}
|
|
4414
4517
|
function Tooltip({ ...props }) {
|
|
4415
|
-
return /* @__PURE__ */ (0,
|
|
4518
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_radix_ui4.Tooltip.Root, { "data-slot": "tooltip", ...props });
|
|
4416
4519
|
}
|
|
4417
4520
|
function TooltipTrigger({ ...props }) {
|
|
4418
|
-
return /* @__PURE__ */ (0,
|
|
4521
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_radix_ui4.Tooltip.Trigger, { "data-slot": "tooltip-trigger", ...props });
|
|
4419
4522
|
}
|
|
4420
4523
|
var arrowClassBySide = {
|
|
4421
4524
|
top: "before:bottom-0 before:left-1/2 before:-translate-x-1/2 before:translate-y-1/2",
|
|
@@ -4432,8 +4535,8 @@ function TooltipContent({
|
|
|
4432
4535
|
...props
|
|
4433
4536
|
}) {
|
|
4434
4537
|
const resolvedSide = side ?? "bottom";
|
|
4435
|
-
return /* @__PURE__ */ (0,
|
|
4436
|
-
|
|
4538
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_radix_ui4.Tooltip.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
4539
|
+
import_radix_ui4.Tooltip.Content,
|
|
4437
4540
|
{
|
|
4438
4541
|
"data-slot": "tooltip-content",
|
|
4439
4542
|
side,
|
|
@@ -4455,7 +4558,7 @@ function TooltipContent({
|
|
|
4455
4558
|
}
|
|
4456
4559
|
|
|
4457
4560
|
// src/ui/item-action-toolbar.tsx
|
|
4458
|
-
var
|
|
4561
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
4459
4562
|
function ToolbarActionTooltip({
|
|
4460
4563
|
label,
|
|
4461
4564
|
side = "bottom",
|
|
@@ -4463,25 +4566,32 @@ function ToolbarActionTooltip({
|
|
|
4463
4566
|
buttonProps,
|
|
4464
4567
|
children
|
|
4465
4568
|
}) {
|
|
4466
|
-
const button = /* @__PURE__ */ (0,
|
|
4467
|
-
return /* @__PURE__ */ (0,
|
|
4468
|
-
/* @__PURE__ */ (0,
|
|
4469
|
-
/* @__PURE__ */ (0,
|
|
4569
|
+
const button = /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(CustomToolbarButton, { type: "button", "aria-label": label, disabled, ...buttonProps, children });
|
|
4570
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Tooltip, { children: [
|
|
4571
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(TooltipTrigger, { asChild: true, children: disabled ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "inline-flex", children: button }) : button }),
|
|
4572
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(TooltipContent, { side, sideOffset: 9, children: label })
|
|
4470
4573
|
] });
|
|
4471
4574
|
}
|
|
4472
4575
|
function ItemActionToolbar({
|
|
4473
4576
|
onEditLink,
|
|
4474
4577
|
onAddItem,
|
|
4475
|
-
|
|
4578
|
+
onSelectParent,
|
|
4579
|
+
onDuplicate,
|
|
4580
|
+
onDelete,
|
|
4476
4581
|
editLinkDisabled = false,
|
|
4477
4582
|
addItemDisabled = true,
|
|
4478
|
-
moreDisabled =
|
|
4583
|
+
moreDisabled = false,
|
|
4584
|
+
selectParentDisabled = false,
|
|
4585
|
+
duplicateDisabled = false,
|
|
4586
|
+
deleteDisabled = false,
|
|
4587
|
+
showEditLink = true,
|
|
4479
4588
|
showAddItem = true,
|
|
4480
4589
|
showMore = true,
|
|
4481
4590
|
tooltipSide = "bottom"
|
|
4482
4591
|
}) {
|
|
4483
|
-
|
|
4484
|
-
|
|
4592
|
+
const [moreOpen, setMoreOpen] = (0, import_react4.useState)(false);
|
|
4593
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(CustomToolbar, { children: [
|
|
4594
|
+
showEditLink ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
4485
4595
|
ToolbarActionTooltip,
|
|
4486
4596
|
{
|
|
4487
4597
|
label: "Edit link",
|
|
@@ -4499,10 +4609,10 @@ function ItemActionToolbar({
|
|
|
4499
4609
|
e.stopPropagation();
|
|
4500
4610
|
}
|
|
4501
4611
|
},
|
|
4502
|
-
children: /* @__PURE__ */ (0,
|
|
4612
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react2.Link, { className: "size-4 shrink-0", "aria-hidden": true })
|
|
4503
4613
|
}
|
|
4504
|
-
),
|
|
4505
|
-
showAddItem ? /* @__PURE__ */ (0,
|
|
4614
|
+
) : null,
|
|
4615
|
+
showAddItem ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
4506
4616
|
ToolbarActionTooltip,
|
|
4507
4617
|
{
|
|
4508
4618
|
label: "Add item",
|
|
@@ -4516,32 +4626,84 @@ function ItemActionToolbar({
|
|
|
4516
4626
|
onAddItem?.();
|
|
4517
4627
|
}
|
|
4518
4628
|
},
|
|
4519
|
-
children: /* @__PURE__ */ (0,
|
|
4629
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react2.Plus, { className: "size-4 shrink-0", "aria-hidden": true })
|
|
4520
4630
|
}
|
|
4521
4631
|
) : null,
|
|
4522
|
-
showMore ? /* @__PURE__ */ (0,
|
|
4523
|
-
|
|
4524
|
-
|
|
4525
|
-
|
|
4526
|
-
|
|
4527
|
-
|
|
4528
|
-
|
|
4632
|
+
showMore ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(DropdownMenu, { open: moreOpen, onOpenChange: setMoreOpen, children: [
|
|
4633
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Tooltip, { open: moreOpen ? false : void 0, children: [
|
|
4634
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(DropdownMenuTrigger, { asChild: true, disabled: moreDisabled, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
4635
|
+
CustomToolbarButton,
|
|
4636
|
+
{
|
|
4637
|
+
type: "button",
|
|
4638
|
+
"aria-label": "More",
|
|
4639
|
+
disabled: moreDisabled,
|
|
4640
|
+
onMouseDown: (e) => {
|
|
4641
|
+
e.preventDefault();
|
|
4642
|
+
e.stopPropagation();
|
|
4643
|
+
},
|
|
4644
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react2.MoreHorizontal, { className: "size-4 shrink-0", "aria-hidden": true })
|
|
4645
|
+
}
|
|
4646
|
+
) }) }),
|
|
4647
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(TooltipContent, { side: tooltipSide, sideOffset: 9, children: "More" })
|
|
4648
|
+
] }),
|
|
4649
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
4650
|
+
DropdownMenuContent,
|
|
4651
|
+
{
|
|
4652
|
+
align: "end",
|
|
4653
|
+
side: "bottom",
|
|
4654
|
+
onCloseAutoFocus: (e) => e.preventDefault(),
|
|
4529
4655
|
onMouseDown: (e) => {
|
|
4530
|
-
if (moreDisabled) return;
|
|
4531
4656
|
e.preventDefault();
|
|
4532
4657
|
e.stopPropagation();
|
|
4533
|
-
|
|
4534
|
-
|
|
4535
|
-
|
|
4536
|
-
|
|
4537
|
-
|
|
4538
|
-
|
|
4658
|
+
},
|
|
4659
|
+
children: [
|
|
4660
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(DropdownMenuGroup, { children: [
|
|
4661
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
4662
|
+
DropdownMenuItem,
|
|
4663
|
+
{
|
|
4664
|
+
disabled: selectParentDisabled,
|
|
4665
|
+
onSelect: () => onSelectParent?.(),
|
|
4666
|
+
children: [
|
|
4667
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react2.CornerLeftUp, { size: 12, "aria-hidden": true }),
|
|
4668
|
+
"Select parent"
|
|
4669
|
+
]
|
|
4670
|
+
}
|
|
4671
|
+
),
|
|
4672
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
4673
|
+
DropdownMenuItem,
|
|
4674
|
+
{
|
|
4675
|
+
disabled: duplicateDisabled,
|
|
4676
|
+
onSelect: () => onDuplicate?.(),
|
|
4677
|
+
children: [
|
|
4678
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react2.Copy, { size: 12, "aria-hidden": true }),
|
|
4679
|
+
"Duplicate"
|
|
4680
|
+
]
|
|
4681
|
+
}
|
|
4682
|
+
)
|
|
4683
|
+
] }),
|
|
4684
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(DropdownMenuSeparator, {}),
|
|
4685
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(DropdownMenuGroup, { children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
4686
|
+
DropdownMenuItem,
|
|
4687
|
+
{
|
|
4688
|
+
variant: "destructive",
|
|
4689
|
+
disabled: deleteDisabled,
|
|
4690
|
+
onSelect: () => onDelete?.(),
|
|
4691
|
+
children: [
|
|
4692
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react2.Trash2, { size: 15, "aria-hidden": true }),
|
|
4693
|
+
"Delete"
|
|
4694
|
+
]
|
|
4695
|
+
}
|
|
4696
|
+
) })
|
|
4697
|
+
]
|
|
4698
|
+
}
|
|
4699
|
+
)
|
|
4700
|
+
] }) : null
|
|
4539
4701
|
] }) });
|
|
4540
4702
|
}
|
|
4541
4703
|
|
|
4542
4704
|
// src/ui/item-interaction-layer.tsx
|
|
4543
4705
|
var React5 = __toESM(require("react"), 1);
|
|
4544
|
-
var
|
|
4706
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
4545
4707
|
var PRIMARY = "var(--ohw-primary, #0885FE)";
|
|
4546
4708
|
var FOCUS_RING = `0 0 0 4px color-mix(in srgb, ${PRIMARY} 12%, transparent)`;
|
|
4547
4709
|
var DRAG_SHADOW = "0px 4px 6px -1px rgba(0, 0, 0, 0.1), 0px 2px 4px -2px rgba(0, 0, 0, 0.1)";
|
|
@@ -4623,7 +4785,7 @@ function ClampedToolbarSlot({
|
|
|
4623
4785
|
window.removeEventListener("resize", clamp);
|
|
4624
4786
|
};
|
|
4625
4787
|
}, [placement, children]);
|
|
4626
|
-
return /* @__PURE__ */ (0,
|
|
4788
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
4627
4789
|
"div",
|
|
4628
4790
|
{
|
|
4629
4791
|
ref: slotRef,
|
|
@@ -4663,7 +4825,7 @@ function ItemInteractionLayer({
|
|
|
4663
4825
|
const showToolbar = isActive && toolbar;
|
|
4664
4826
|
const showDragHandle = (isActive || isDragging) && showHandle;
|
|
4665
4827
|
const itemDragEnabled = itemDragSurface && isActive && showHandle && !isDragging && !dragDisabled;
|
|
4666
|
-
return /* @__PURE__ */ (0,
|
|
4828
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
4667
4829
|
"div",
|
|
4668
4830
|
{
|
|
4669
4831
|
ref: elRef,
|
|
@@ -4679,7 +4841,7 @@ function ItemInteractionLayer({
|
|
|
4679
4841
|
zIndex: getChromeZIndex(state)
|
|
4680
4842
|
},
|
|
4681
4843
|
children: [
|
|
4682
|
-
/* @__PURE__ */ (0,
|
|
4844
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
4683
4845
|
"div",
|
|
4684
4846
|
{
|
|
4685
4847
|
"aria-hidden": true,
|
|
@@ -4687,7 +4849,7 @@ function ItemInteractionLayer({
|
|
|
4687
4849
|
style: getChromeStyle(state)
|
|
4688
4850
|
}
|
|
4689
4851
|
),
|
|
4690
|
-
itemDragEnabled && /* @__PURE__ */ (0,
|
|
4852
|
+
itemDragEnabled && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
4691
4853
|
"div",
|
|
4692
4854
|
{
|
|
4693
4855
|
"data-ohw-item-drag-surface": "",
|
|
@@ -4703,14 +4865,14 @@ function ItemInteractionLayer({
|
|
|
4703
4865
|
}
|
|
4704
4866
|
}
|
|
4705
4867
|
),
|
|
4706
|
-
showDragHandle && /* @__PURE__ */ (0,
|
|
4868
|
+
showDragHandle && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
4707
4869
|
"div",
|
|
4708
4870
|
{
|
|
4709
4871
|
"data-ohw-drag-handle-container": "",
|
|
4710
4872
|
className: "pointer-events-auto absolute left-0 top-1/2 z-10 -translate-x-[calc(100%+7px)] -translate-y-1/2",
|
|
4711
4873
|
style: isDragging ? { opacity: 0 } : void 0,
|
|
4712
4874
|
"aria-hidden": isDragging || void 0,
|
|
4713
|
-
children: /* @__PURE__ */ (0,
|
|
4875
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
4714
4876
|
DragHandle,
|
|
4715
4877
|
{
|
|
4716
4878
|
draggable: !dragDisabled,
|
|
@@ -4740,8 +4902,8 @@ function ItemInteractionLayer({
|
|
|
4740
4902
|
)
|
|
4741
4903
|
}
|
|
4742
4904
|
),
|
|
4743
|
-
showToolbar && state === "active-top" && /* @__PURE__ */ (0,
|
|
4744
|
-
showToolbar && state === "active-bottom" && /* @__PURE__ */ (0,
|
|
4905
|
+
showToolbar && state === "active-top" && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ClampedToolbarSlot, { placement: "top", children: toolbar }),
|
|
4906
|
+
showToolbar && state === "active-bottom" && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ClampedToolbarSlot, { placement: "bottom", children: toolbar })
|
|
4745
4907
|
]
|
|
4746
4908
|
}
|
|
4747
4909
|
);
|
|
@@ -4753,8 +4915,8 @@ var import_lucide_react3 = require("lucide-react");
|
|
|
4753
4915
|
|
|
4754
4916
|
// src/ui/button.tsx
|
|
4755
4917
|
var React6 = __toESM(require("react"), 1);
|
|
4756
|
-
var
|
|
4757
|
-
var
|
|
4918
|
+
var import_radix_ui5 = require("radix-ui");
|
|
4919
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
4758
4920
|
var buttonVariants = cva(
|
|
4759
4921
|
"inline-flex items-center justify-center gap-1 whitespace-nowrap rounded-md text-sm font-medium transition-colors outline-none disabled:pointer-events-none disabled:opacity-50 min-w-[80px] px-3 py-2",
|
|
4760
4922
|
{
|
|
@@ -4777,8 +4939,8 @@ var buttonVariants = cva(
|
|
|
4777
4939
|
);
|
|
4778
4940
|
var Button = React6.forwardRef(
|
|
4779
4941
|
({ className, variant, size, asChild = false, ...props }, ref) => {
|
|
4780
|
-
const Comp = asChild ?
|
|
4781
|
-
return /* @__PURE__ */ (0,
|
|
4942
|
+
const Comp = asChild ? import_radix_ui5.Slot.Root : "button";
|
|
4943
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
4782
4944
|
Comp,
|
|
4783
4945
|
{
|
|
4784
4946
|
ref,
|
|
@@ -4792,7 +4954,7 @@ var Button = React6.forwardRef(
|
|
|
4792
4954
|
Button.displayName = "Button";
|
|
4793
4955
|
|
|
4794
4956
|
// src/ui/MediaOverlay.tsx
|
|
4795
|
-
var
|
|
4957
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
4796
4958
|
var MEDIA_UPLOAD_FADE_MS = 300;
|
|
4797
4959
|
var VIDEO_SETTINGS_BAR_INSET = 8;
|
|
4798
4960
|
var OVERLAY_BUTTON_STYLE = {
|
|
@@ -4850,7 +5012,7 @@ function MediaOverlay({
|
|
|
4850
5012
|
return () => anim.cancel();
|
|
4851
5013
|
}, [isUploading, fadingOut, onFadeOutComplete, hover.key]);
|
|
4852
5014
|
if (isUploading) {
|
|
4853
|
-
return /* @__PURE__ */ (0,
|
|
5015
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
4854
5016
|
"div",
|
|
4855
5017
|
{
|
|
4856
5018
|
ref: skeletonRef,
|
|
@@ -4859,11 +5021,11 @@ function MediaOverlay({
|
|
|
4859
5021
|
"data-ohw-media-skeleton": "",
|
|
4860
5022
|
"aria-hidden": true,
|
|
4861
5023
|
style: { ...box, pointerEvents: "none" },
|
|
4862
|
-
children: /* @__PURE__ */ (0,
|
|
5024
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("style", { children: SKELETON_CSS })
|
|
4863
5025
|
}
|
|
4864
5026
|
);
|
|
4865
5027
|
}
|
|
4866
|
-
const settingsBar = isVideo && !hover.isDragOver ? /* @__PURE__ */ (0,
|
|
5028
|
+
const settingsBar = isVideo && !hover.isDragOver ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
4867
5029
|
"div",
|
|
4868
5030
|
{
|
|
4869
5031
|
"data-ohw-bridge": "",
|
|
@@ -4879,7 +5041,7 @@ function MediaOverlay({
|
|
|
4879
5041
|
},
|
|
4880
5042
|
onClick: (e) => e.stopPropagation(),
|
|
4881
5043
|
children: [
|
|
4882
|
-
/* @__PURE__ */ (0,
|
|
5044
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
4883
5045
|
Button,
|
|
4884
5046
|
{
|
|
4885
5047
|
"data-ohw-media-overlay": "",
|
|
@@ -4894,10 +5056,10 @@ function MediaOverlay({
|
|
|
4894
5056
|
e.stopPropagation();
|
|
4895
5057
|
onVideoSettingsChange?.(hover.key, { autoplay: !autoplay });
|
|
4896
5058
|
},
|
|
4897
|
-
children: autoplay ? /* @__PURE__ */ (0,
|
|
5059
|
+
children: autoplay ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react3.Pause, { size: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react3.Play, { size: 14 })
|
|
4898
5060
|
}
|
|
4899
5061
|
),
|
|
4900
|
-
/* @__PURE__ */ (0,
|
|
5062
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
4901
5063
|
Button,
|
|
4902
5064
|
{
|
|
4903
5065
|
"data-ohw-media-overlay": "",
|
|
@@ -4912,15 +5074,15 @@ function MediaOverlay({
|
|
|
4912
5074
|
e.stopPropagation();
|
|
4913
5075
|
onVideoSettingsChange?.(hover.key, { muted: !muted });
|
|
4914
5076
|
},
|
|
4915
|
-
children: muted ? /* @__PURE__ */ (0,
|
|
5077
|
+
children: muted ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react3.VolumeX, { size: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react3.Volume2, { size: 14 })
|
|
4916
5078
|
}
|
|
4917
5079
|
)
|
|
4918
5080
|
]
|
|
4919
5081
|
}
|
|
4920
5082
|
) : null;
|
|
4921
|
-
return /* @__PURE__ */ (0,
|
|
5083
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
|
|
4922
5084
|
settingsBar,
|
|
4923
|
-
/* @__PURE__ */ (0,
|
|
5085
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
4924
5086
|
"div",
|
|
4925
5087
|
{
|
|
4926
5088
|
"data-ohw-bridge": "",
|
|
@@ -4937,21 +5099,25 @@ function MediaOverlay({
|
|
|
4937
5099
|
background: "color-mix(in srgb, var(--color-primary) 20%, transparent)"
|
|
4938
5100
|
},
|
|
4939
5101
|
onClick: () => onReplace(hover.key),
|
|
4940
|
-
children: /* @__PURE__ */ (0,
|
|
5102
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
4941
5103
|
Button,
|
|
4942
5104
|
{
|
|
4943
5105
|
"data-ohw-media-overlay": "",
|
|
4944
5106
|
variant: "outline",
|
|
4945
5107
|
size: "sm",
|
|
4946
5108
|
className: "gap-1.5 cursor-pointer hover:bg-background",
|
|
4947
|
-
style:
|
|
5109
|
+
style: {
|
|
5110
|
+
...OVERLAY_BUTTON_STYLE,
|
|
5111
|
+
// Don't let Replace steal clicks when text (e.g. nav) sits on top of this media.
|
|
5112
|
+
pointerEvents: hover.hasTextOverlap ? "none" : "auto"
|
|
5113
|
+
},
|
|
4948
5114
|
onMouseDown: (e) => e.preventDefault(),
|
|
4949
5115
|
onClick: (e) => {
|
|
4950
5116
|
e.stopPropagation();
|
|
4951
5117
|
onReplace(hover.key);
|
|
4952
5118
|
},
|
|
4953
5119
|
children: [
|
|
4954
|
-
isVideo ? /* @__PURE__ */ (0,
|
|
5120
|
+
isVideo ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react3.Film, { size: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react3.ImageIcon, { size: 14 }),
|
|
4955
5121
|
isVideo ? "Replace video" : "Replace image"
|
|
4956
5122
|
]
|
|
4957
5123
|
}
|
|
@@ -4963,7 +5129,7 @@ function MediaOverlay({
|
|
|
4963
5129
|
|
|
4964
5130
|
// src/ui/CarouselOverlay.tsx
|
|
4965
5131
|
var import_lucide_react4 = require("lucide-react");
|
|
4966
|
-
var
|
|
5132
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
4967
5133
|
var OVERLAY_BUTTON_STYLE2 = {
|
|
4968
5134
|
pointerEvents: "auto",
|
|
4969
5135
|
fontFamily: "Inter, sans-serif",
|
|
@@ -4975,7 +5141,7 @@ function CarouselOverlay({
|
|
|
4975
5141
|
onEdit
|
|
4976
5142
|
}) {
|
|
4977
5143
|
const { rect } = hover;
|
|
4978
|
-
return /* @__PURE__ */ (0,
|
|
5144
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
4979
5145
|
"div",
|
|
4980
5146
|
{
|
|
4981
5147
|
"data-ohw-bridge": "",
|
|
@@ -4993,7 +5159,7 @@ function CarouselOverlay({
|
|
|
4993
5159
|
background: "color-mix(in srgb, var(--color-primary) 20%, transparent)"
|
|
4994
5160
|
},
|
|
4995
5161
|
onClick: () => onEdit(hover.key),
|
|
4996
|
-
children: /* @__PURE__ */ (0,
|
|
5162
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
4997
5163
|
Button,
|
|
4998
5164
|
{
|
|
4999
5165
|
"data-ohw-carousel-overlay": "",
|
|
@@ -5007,7 +5173,7 @@ function CarouselOverlay({
|
|
|
5007
5173
|
onEdit(hover.key);
|
|
5008
5174
|
},
|
|
5009
5175
|
children: [
|
|
5010
|
-
/* @__PURE__ */ (0,
|
|
5176
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react4.GalleryHorizontal, { size: 14 }),
|
|
5011
5177
|
"Edit gallery"
|
|
5012
5178
|
]
|
|
5013
5179
|
}
|
|
@@ -5296,29 +5462,29 @@ function scrollToHashSectionWhenReady(behavior = "smooth") {
|
|
|
5296
5462
|
}
|
|
5297
5463
|
|
|
5298
5464
|
// src/ui/link-modal/LinkPopover.tsx
|
|
5299
|
-
var
|
|
5465
|
+
var import_react8 = require("react");
|
|
5300
5466
|
|
|
5301
5467
|
// src/ui/dialog.tsx
|
|
5302
5468
|
var React8 = __toESM(require("react"), 1);
|
|
5303
|
-
var
|
|
5469
|
+
var import_radix_ui6 = require("radix-ui");
|
|
5304
5470
|
var import_lucide_react5 = require("lucide-react");
|
|
5305
|
-
var
|
|
5471
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
5306
5472
|
function Dialog2({
|
|
5307
5473
|
...props
|
|
5308
5474
|
}) {
|
|
5309
|
-
return /* @__PURE__ */ (0,
|
|
5475
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_radix_ui6.Dialog.Root, { "data-slot": "dialog", ...props });
|
|
5310
5476
|
}
|
|
5311
5477
|
function DialogPortal({
|
|
5312
5478
|
...props
|
|
5313
5479
|
}) {
|
|
5314
|
-
return /* @__PURE__ */ (0,
|
|
5480
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_radix_ui6.Dialog.Portal, { ...props });
|
|
5315
5481
|
}
|
|
5316
5482
|
function DialogOverlay({
|
|
5317
5483
|
className,
|
|
5318
5484
|
...props
|
|
5319
5485
|
}) {
|
|
5320
|
-
return /* @__PURE__ */ (0,
|
|
5321
|
-
|
|
5486
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
5487
|
+
import_radix_ui6.Dialog.Overlay,
|
|
5322
5488
|
{
|
|
5323
5489
|
"data-slot": "dialog-overlay",
|
|
5324
5490
|
"data-ohw-link-modal-root": "",
|
|
@@ -5330,10 +5496,10 @@ function DialogOverlay({
|
|
|
5330
5496
|
var DialogContent = React8.forwardRef(
|
|
5331
5497
|
({ className, children, showCloseButton = true, container, ...props }, ref) => {
|
|
5332
5498
|
const positionMode = container ? "absolute" : "fixed";
|
|
5333
|
-
return /* @__PURE__ */ (0,
|
|
5334
|
-
/* @__PURE__ */ (0,
|
|
5335
|
-
/* @__PURE__ */ (0,
|
|
5336
|
-
|
|
5499
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(DialogPortal, { container: container ?? void 0, children: [
|
|
5500
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(DialogOverlay, { className: cn(positionMode, "inset-0") }),
|
|
5501
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
5502
|
+
import_radix_ui6.Dialog.Content,
|
|
5337
5503
|
{
|
|
5338
5504
|
ref,
|
|
5339
5505
|
"data-slot": "dialog-content",
|
|
@@ -5348,13 +5514,13 @@ var DialogContent = React8.forwardRef(
|
|
|
5348
5514
|
...props,
|
|
5349
5515
|
children: [
|
|
5350
5516
|
children,
|
|
5351
|
-
showCloseButton ? /* @__PURE__ */ (0,
|
|
5352
|
-
|
|
5517
|
+
showCloseButton ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
5518
|
+
import_radix_ui6.Dialog.Close,
|
|
5353
5519
|
{
|
|
5354
5520
|
type: "button",
|
|
5355
5521
|
className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50",
|
|
5356
5522
|
"aria-label": "Close",
|
|
5357
|
-
children: /* @__PURE__ */ (0,
|
|
5523
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react5.X, { size: 16, "aria-hidden": true })
|
|
5358
5524
|
}
|
|
5359
5525
|
) : null
|
|
5360
5526
|
]
|
|
@@ -5363,18 +5529,18 @@ var DialogContent = React8.forwardRef(
|
|
|
5363
5529
|
] });
|
|
5364
5530
|
}
|
|
5365
5531
|
);
|
|
5366
|
-
DialogContent.displayName =
|
|
5532
|
+
DialogContent.displayName = import_radix_ui6.Dialog.Content.displayName;
|
|
5367
5533
|
function DialogHeader({
|
|
5368
5534
|
className,
|
|
5369
5535
|
...props
|
|
5370
5536
|
}) {
|
|
5371
|
-
return /* @__PURE__ */ (0,
|
|
5537
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: cn("flex flex-col gap-1.5", className), ...props });
|
|
5372
5538
|
}
|
|
5373
5539
|
function DialogFooter({
|
|
5374
5540
|
className,
|
|
5375
5541
|
...props
|
|
5376
5542
|
}) {
|
|
5377
|
-
return /* @__PURE__ */ (0,
|
|
5543
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
5378
5544
|
"div",
|
|
5379
5545
|
{
|
|
5380
5546
|
className: cn("flex items-center justify-end gap-2", className),
|
|
@@ -5382,8 +5548,8 @@ function DialogFooter({
|
|
|
5382
5548
|
}
|
|
5383
5549
|
);
|
|
5384
5550
|
}
|
|
5385
|
-
var DialogTitle = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0,
|
|
5386
|
-
|
|
5551
|
+
var DialogTitle = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
5552
|
+
import_radix_ui6.Dialog.Title,
|
|
5387
5553
|
{
|
|
5388
5554
|
ref,
|
|
5389
5555
|
className: cn(
|
|
@@ -5393,36 +5559,36 @@ var DialogTitle = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE
|
|
|
5393
5559
|
...props
|
|
5394
5560
|
}
|
|
5395
5561
|
));
|
|
5396
|
-
DialogTitle.displayName =
|
|
5397
|
-
var DialogDescription = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0,
|
|
5398
|
-
|
|
5562
|
+
DialogTitle.displayName = import_radix_ui6.Dialog.Title.displayName;
|
|
5563
|
+
var DialogDescription = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
5564
|
+
import_radix_ui6.Dialog.Description,
|
|
5399
5565
|
{
|
|
5400
5566
|
ref,
|
|
5401
5567
|
className: cn("text-sm text-muted-foreground", className),
|
|
5402
5568
|
...props
|
|
5403
5569
|
}
|
|
5404
5570
|
));
|
|
5405
|
-
DialogDescription.displayName =
|
|
5406
|
-
var DialogClose =
|
|
5571
|
+
DialogDescription.displayName = import_radix_ui6.Dialog.Description.displayName;
|
|
5572
|
+
var DialogClose = import_radix_ui6.Dialog.Close;
|
|
5407
5573
|
|
|
5408
5574
|
// src/ui/link-modal/LinkEditorPanel.tsx
|
|
5409
5575
|
var import_lucide_react9 = require("lucide-react");
|
|
5410
5576
|
|
|
5411
5577
|
// src/ui/link-modal/DestinationBreadcrumb.tsx
|
|
5412
5578
|
var import_lucide_react6 = require("lucide-react");
|
|
5413
|
-
var
|
|
5579
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
5414
5580
|
function DestinationBreadcrumb({
|
|
5415
5581
|
pageTitle,
|
|
5416
5582
|
sectionLabel
|
|
5417
5583
|
}) {
|
|
5418
|
-
return /* @__PURE__ */ (0,
|
|
5419
|
-
/* @__PURE__ */ (0,
|
|
5420
|
-
/* @__PURE__ */ (0,
|
|
5421
|
-
/* @__PURE__ */ (0,
|
|
5422
|
-
/* @__PURE__ */ (0,
|
|
5423
|
-
/* @__PURE__ */ (0,
|
|
5584
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex w-full flex-col gap-2", children: [
|
|
5585
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "text-sm font-medium! text-foreground m-0", children: "Destination" }),
|
|
5586
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex items-center gap-3", children: [
|
|
5587
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
5588
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_lucide_react6.File, { size: 16, className: "shrink-0 text-foreground", "aria-hidden": true }),
|
|
5589
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "text-sm font-medium leading-none text-foreground!", children: pageTitle })
|
|
5424
5590
|
] }),
|
|
5425
|
-
/* @__PURE__ */ (0,
|
|
5591
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
5426
5592
|
import_lucide_react6.ArrowRight,
|
|
5427
5593
|
{
|
|
5428
5594
|
size: 16,
|
|
@@ -5430,8 +5596,8 @@ function DestinationBreadcrumb({
|
|
|
5430
5596
|
"aria-hidden": true
|
|
5431
5597
|
}
|
|
5432
5598
|
),
|
|
5433
|
-
/* @__PURE__ */ (0,
|
|
5434
|
-
/* @__PURE__ */ (0,
|
|
5599
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
|
|
5600
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
5435
5601
|
import_lucide_react6.GalleryVertical,
|
|
5436
5602
|
{
|
|
5437
5603
|
size: 16,
|
|
@@ -5439,7 +5605,7 @@ function DestinationBreadcrumb({
|
|
|
5439
5605
|
"aria-hidden": true
|
|
5440
5606
|
}
|
|
5441
5607
|
),
|
|
5442
|
-
/* @__PURE__ */ (0,
|
|
5608
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "truncate text-sm font-medium leading-none text-foreground", children: sectionLabel })
|
|
5443
5609
|
] })
|
|
5444
5610
|
] })
|
|
5445
5611
|
] });
|
|
@@ -5447,22 +5613,22 @@ function DestinationBreadcrumb({
|
|
|
5447
5613
|
|
|
5448
5614
|
// src/ui/link-modal/SectionTreeItem.tsx
|
|
5449
5615
|
var import_lucide_react7 = require("lucide-react");
|
|
5450
|
-
var
|
|
5616
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
5451
5617
|
function SectionTreeItem({
|
|
5452
5618
|
section,
|
|
5453
5619
|
onSelect,
|
|
5454
5620
|
selected
|
|
5455
5621
|
}) {
|
|
5456
5622
|
const interactive = Boolean(onSelect);
|
|
5457
|
-
return /* @__PURE__ */ (0,
|
|
5458
|
-
/* @__PURE__ */ (0,
|
|
5623
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex h-9 w-full items-end pl-3", children: [
|
|
5624
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
5459
5625
|
"div",
|
|
5460
5626
|
{
|
|
5461
5627
|
className: "mr-[-1px] h-9 w-2 shrink-0 rounded-bl-sm border-b border-l border-border mb-4",
|
|
5462
5628
|
"aria-hidden": true
|
|
5463
5629
|
}
|
|
5464
5630
|
),
|
|
5465
|
-
/* @__PURE__ */ (0,
|
|
5631
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
5466
5632
|
"div",
|
|
5467
5633
|
{
|
|
5468
5634
|
role: interactive ? "button" : void 0,
|
|
@@ -5480,7 +5646,7 @@ function SectionTreeItem({
|
|
|
5480
5646
|
interactive && selected && "border-primary"
|
|
5481
5647
|
),
|
|
5482
5648
|
children: [
|
|
5483
|
-
/* @__PURE__ */ (0,
|
|
5649
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
5484
5650
|
import_lucide_react7.GalleryVertical,
|
|
5485
5651
|
{
|
|
5486
5652
|
size: 16,
|
|
@@ -5488,7 +5654,7 @@ function SectionTreeItem({
|
|
|
5488
5654
|
"aria-hidden": true
|
|
5489
5655
|
}
|
|
5490
5656
|
),
|
|
5491
|
-
/* @__PURE__ */ (0,
|
|
5657
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "truncate text-sm font-normal leading-5 text-foreground", children: section.label })
|
|
5492
5658
|
]
|
|
5493
5659
|
}
|
|
5494
5660
|
)
|
|
@@ -5496,14 +5662,14 @@ function SectionTreeItem({
|
|
|
5496
5662
|
}
|
|
5497
5663
|
|
|
5498
5664
|
// src/ui/link-modal/UrlOrPageInput.tsx
|
|
5499
|
-
var
|
|
5665
|
+
var import_react5 = require("react");
|
|
5500
5666
|
|
|
5501
5667
|
// src/ui/input.tsx
|
|
5502
5668
|
var React9 = __toESM(require("react"), 1);
|
|
5503
|
-
var
|
|
5669
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
5504
5670
|
var Input = React9.forwardRef(
|
|
5505
5671
|
({ className, type, ...props }, ref) => {
|
|
5506
|
-
return /* @__PURE__ */ (0,
|
|
5672
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
5507
5673
|
"input",
|
|
5508
5674
|
{
|
|
5509
5675
|
type,
|
|
@@ -5521,11 +5687,11 @@ var Input = React9.forwardRef(
|
|
|
5521
5687
|
Input.displayName = "Input";
|
|
5522
5688
|
|
|
5523
5689
|
// src/ui/label.tsx
|
|
5524
|
-
var
|
|
5525
|
-
var
|
|
5690
|
+
var import_radix_ui7 = require("radix-ui");
|
|
5691
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
5526
5692
|
function Label({ className, ...props }) {
|
|
5527
|
-
return /* @__PURE__ */ (0,
|
|
5528
|
-
|
|
5693
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5694
|
+
import_radix_ui7.Label.Root,
|
|
5529
5695
|
{
|
|
5530
5696
|
"data-slot": "label",
|
|
5531
5697
|
className: cn("text-sm font-medium leading-5 text-foreground", className),
|
|
@@ -5536,11 +5702,11 @@ function Label({ className, ...props }) {
|
|
|
5536
5702
|
|
|
5537
5703
|
// src/ui/link-modal/UrlOrPageInput.tsx
|
|
5538
5704
|
var import_lucide_react8 = require("lucide-react");
|
|
5539
|
-
var
|
|
5705
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
5540
5706
|
function FieldChevron({
|
|
5541
5707
|
onClick
|
|
5542
5708
|
}) {
|
|
5543
|
-
return /* @__PURE__ */ (0,
|
|
5709
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5544
5710
|
"button",
|
|
5545
5711
|
{
|
|
5546
5712
|
type: "button",
|
|
@@ -5548,7 +5714,7 @@ function FieldChevron({
|
|
|
5548
5714
|
onClick,
|
|
5549
5715
|
"aria-label": "Open page list",
|
|
5550
5716
|
tabIndex: -1,
|
|
5551
|
-
children: /* @__PURE__ */ (0,
|
|
5717
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react8.ChevronDown, { size: 16 })
|
|
5552
5718
|
}
|
|
5553
5719
|
);
|
|
5554
5720
|
}
|
|
@@ -5564,11 +5730,11 @@ function UrlOrPageInput({
|
|
|
5564
5730
|
readOnly = false,
|
|
5565
5731
|
urlError
|
|
5566
5732
|
}) {
|
|
5567
|
-
const inputId = (0,
|
|
5568
|
-
const inputRef = (0,
|
|
5569
|
-
const rootRef = (0,
|
|
5570
|
-
const [isFocused, setIsFocused] = (0,
|
|
5571
|
-
(0,
|
|
5733
|
+
const inputId = (0, import_react5.useId)();
|
|
5734
|
+
const inputRef = (0, import_react5.useRef)(null);
|
|
5735
|
+
const rootRef = (0, import_react5.useRef)(null);
|
|
5736
|
+
const [isFocused, setIsFocused] = (0, import_react5.useState)(false);
|
|
5737
|
+
(0, import_react5.useEffect)(() => {
|
|
5572
5738
|
if (!dropdownOpen) return;
|
|
5573
5739
|
const isOutside = (e) => {
|
|
5574
5740
|
const root = rootRef.current;
|
|
@@ -5609,11 +5775,11 @@ function UrlOrPageInput({
|
|
|
5609
5775
|
"data-ohw-link-field flex h-[36px] w-full items-center overflow-hidden rounded-md border bg-background pl-3 pr-3 py-2 outline-none transition-[border-color,box-shadow]",
|
|
5610
5776
|
urlError ? "border-destructive shadow-[0_0_0_1px_var(--ohw-destructive)]" : isFocused ? "border-primary shadow-[0_0_0_1px_var(--ohw-primary)]" : "border-input"
|
|
5611
5777
|
);
|
|
5612
|
-
return /* @__PURE__ */ (0,
|
|
5613
|
-
/* @__PURE__ */ (0,
|
|
5614
|
-
/* @__PURE__ */ (0,
|
|
5615
|
-
/* @__PURE__ */ (0,
|
|
5616
|
-
selectedPage ? /* @__PURE__ */ (0,
|
|
5778
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex w-full flex-col gap-2 p-0", children: [
|
|
5779
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Label, { htmlFor: inputId, className: cn(urlError && "text-destructive"), children: "Destination" }),
|
|
5780
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { ref: rootRef, className: "relative w-full", children: [
|
|
5781
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { "data-ohw-link-field": true, className: fieldClassName, children: [
|
|
5782
|
+
selectedPage ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "flex shrink-0 items-center pr-2", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5617
5783
|
import_lucide_react8.File,
|
|
5618
5784
|
{
|
|
5619
5785
|
size: 16,
|
|
@@ -5621,7 +5787,7 @@ function UrlOrPageInput({
|
|
|
5621
5787
|
"aria-hidden": true
|
|
5622
5788
|
}
|
|
5623
5789
|
) }) : null,
|
|
5624
|
-
readOnly ? /* @__PURE__ */ (0,
|
|
5790
|
+
readOnly ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "min-w-0 flex-1 truncate text-sm leading-5 text-foreground", children: selectedPage?.title ?? value }) : /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5625
5791
|
Input,
|
|
5626
5792
|
{
|
|
5627
5793
|
ref: inputRef,
|
|
@@ -5647,7 +5813,7 @@ function UrlOrPageInput({
|
|
|
5647
5813
|
)
|
|
5648
5814
|
}
|
|
5649
5815
|
),
|
|
5650
|
-
selectedPage && !readOnly ? /* @__PURE__ */ (0,
|
|
5816
|
+
selectedPage && !readOnly ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5651
5817
|
"button",
|
|
5652
5818
|
{
|
|
5653
5819
|
type: "button",
|
|
@@ -5655,26 +5821,26 @@ function UrlOrPageInput({
|
|
|
5655
5821
|
onMouseDown: clearSelection,
|
|
5656
5822
|
"aria-label": "Clear selected page",
|
|
5657
5823
|
tabIndex: -1,
|
|
5658
|
-
children: /* @__PURE__ */ (0,
|
|
5824
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react8.X, { size: 16, "aria-hidden": true })
|
|
5659
5825
|
}
|
|
5660
5826
|
) : null,
|
|
5661
|
-
!readOnly ? /* @__PURE__ */ (0,
|
|
5827
|
+
!readOnly ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(FieldChevron, { onClick: toggleDropdown }) : null
|
|
5662
5828
|
] }),
|
|
5663
|
-
dropdownOpen && !readOnly && filteredPages.length > 0 ? /* @__PURE__ */ (0,
|
|
5829
|
+
dropdownOpen && !readOnly && filteredPages.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5664
5830
|
"div",
|
|
5665
5831
|
{
|
|
5666
5832
|
"data-ohw-link-page-dropdown": "",
|
|
5667
5833
|
className: "absolute left-0 right-0 top-[calc(100%+4px)] z-50 max-h-48 overflow-auto rounded-lg border border-border bg-popover py-1 shadow-lg",
|
|
5668
5834
|
onMouseDown: (e) => e.preventDefault(),
|
|
5669
|
-
children: filteredPages.map((page) => /* @__PURE__ */ (0,
|
|
5835
|
+
children: filteredPages.map((page) => /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
5670
5836
|
"button",
|
|
5671
5837
|
{
|
|
5672
5838
|
type: "button",
|
|
5673
5839
|
className: "flex h-9 w-full items-center gap-2 border-0 bg-transparent px-3 text-left text-sm leading-5 text-foreground outline-none hover:bg-muted",
|
|
5674
5840
|
onClick: () => onPageSelect(page),
|
|
5675
5841
|
children: [
|
|
5676
|
-
/* @__PURE__ */ (0,
|
|
5677
|
-
/* @__PURE__ */ (0,
|
|
5842
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react8.File, { size: 16, className: "shrink-0", "aria-hidden": true }),
|
|
5843
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "truncate", children: page.title })
|
|
5678
5844
|
]
|
|
5679
5845
|
},
|
|
5680
5846
|
page.path
|
|
@@ -5682,34 +5848,34 @@ function UrlOrPageInput({
|
|
|
5682
5848
|
}
|
|
5683
5849
|
) : null
|
|
5684
5850
|
] }),
|
|
5685
|
-
urlError ? /* @__PURE__ */ (0,
|
|
5851
|
+
urlError ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "text-sm font-medium text-destructive", children: urlError }) : null
|
|
5686
5852
|
] });
|
|
5687
5853
|
}
|
|
5688
5854
|
|
|
5689
5855
|
// src/ui/link-modal/LinkEditorPanel.tsx
|
|
5690
|
-
var
|
|
5856
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
5691
5857
|
function LinkEditorPanel({ state, onClose }) {
|
|
5692
5858
|
const isCancel = state.secondaryLabel === "Cancel" || state.secondaryLabel === "Back to sections";
|
|
5693
|
-
return /* @__PURE__ */ (0,
|
|
5694
|
-
/* @__PURE__ */ (0,
|
|
5859
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
|
|
5860
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(DialogClose, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5695
5861
|
"button",
|
|
5696
5862
|
{
|
|
5697
5863
|
type: "button",
|
|
5698
5864
|
className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50 h-7",
|
|
5699
5865
|
"aria-label": "Close",
|
|
5700
5866
|
onClick: onClose,
|
|
5701
|
-
children: /* @__PURE__ */ (0,
|
|
5867
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react9.X, { size: 16, "aria-hidden": true })
|
|
5702
5868
|
}
|
|
5703
5869
|
) }),
|
|
5704
|
-
/* @__PURE__ */ (0,
|
|
5705
|
-
/* @__PURE__ */ (0,
|
|
5706
|
-
state.showBreadcrumb && state.selectedPage && state.selectedSection ? /* @__PURE__ */ (0,
|
|
5870
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(DialogHeader, { className: "w-full gap-1.5 p-6 pr-12", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(DialogTitle, { className: "m-0 w-full break-words", children: state.title }) }),
|
|
5871
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex w-full flex-col gap-3 px-6 pb-8 pt-1", children: [
|
|
5872
|
+
state.showBreadcrumb && state.selectedPage && state.selectedSection ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5707
5873
|
DestinationBreadcrumb,
|
|
5708
5874
|
{
|
|
5709
5875
|
pageTitle: state.selectedPage.title,
|
|
5710
5876
|
sectionLabel: state.selectedSection.label
|
|
5711
5877
|
}
|
|
5712
|
-
) : /* @__PURE__ */ (0,
|
|
5878
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5713
5879
|
UrlOrPageInput,
|
|
5714
5880
|
{
|
|
5715
5881
|
value: state.searchValue,
|
|
@@ -5722,8 +5888,8 @@ function LinkEditorPanel({ state, onClose }) {
|
|
|
5722
5888
|
urlError: state.urlError
|
|
5723
5889
|
}
|
|
5724
5890
|
),
|
|
5725
|
-
state.showChooseSection ? /* @__PURE__ */ (0,
|
|
5726
|
-
/* @__PURE__ */ (0,
|
|
5891
|
+
state.showChooseSection ? /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex flex-col justify-center gap-2", children: [
|
|
5892
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5727
5893
|
Button,
|
|
5728
5894
|
{
|
|
5729
5895
|
type: "button",
|
|
@@ -5734,15 +5900,15 @@ function LinkEditorPanel({ state, onClose }) {
|
|
|
5734
5900
|
children: "Choose a section"
|
|
5735
5901
|
}
|
|
5736
5902
|
),
|
|
5737
|
-
/* @__PURE__ */ (0,
|
|
5738
|
-
/* @__PURE__ */ (0,
|
|
5739
|
-
/* @__PURE__ */ (0,
|
|
5903
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex items-center gap-1 text-sm text-muted-foreground", children: [
|
|
5904
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react9.Info, { size: 16, className: "shrink-0", "aria-hidden": true }),
|
|
5905
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { children: "Pick a section this link should scroll to." })
|
|
5740
5906
|
] })
|
|
5741
5907
|
] }) : null,
|
|
5742
|
-
state.showSectionRow && state.selectedSection ? /* @__PURE__ */ (0,
|
|
5908
|
+
state.showSectionRow && state.selectedSection ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(SectionTreeItem, { section: state.selectedSection, selected: true }) : null
|
|
5743
5909
|
] }),
|
|
5744
|
-
/* @__PURE__ */ (0,
|
|
5745
|
-
/* @__PURE__ */ (0,
|
|
5910
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(DialogFooter, { className: "w-full px-6 pb-6", children: [
|
|
5911
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5746
5912
|
Button,
|
|
5747
5913
|
{
|
|
5748
5914
|
type: "button",
|
|
@@ -5757,7 +5923,7 @@ function LinkEditorPanel({ state, onClose }) {
|
|
|
5757
5923
|
children: state.secondaryLabel
|
|
5758
5924
|
}
|
|
5759
5925
|
),
|
|
5760
|
-
/* @__PURE__ */ (0,
|
|
5926
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5761
5927
|
Button,
|
|
5762
5928
|
{
|
|
5763
5929
|
type: "button",
|
|
@@ -5776,11 +5942,11 @@ function LinkEditorPanel({ state, onClose }) {
|
|
|
5776
5942
|
}
|
|
5777
5943
|
|
|
5778
5944
|
// src/ui/link-modal/SectionPickerOverlay.tsx
|
|
5779
|
-
var
|
|
5945
|
+
var import_react6 = require("react");
|
|
5780
5946
|
var import_react_dom = require("react-dom");
|
|
5781
5947
|
var import_lucide_react10 = require("lucide-react");
|
|
5782
5948
|
var import_navigation = require("next/navigation");
|
|
5783
|
-
var
|
|
5949
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
5784
5950
|
var DIM_OVERLAY = "rgba(0, 0, 0, 0.45)";
|
|
5785
5951
|
function rectsEqual(a, b) {
|
|
5786
5952
|
if (a.size !== b.size) return false;
|
|
@@ -5813,12 +5979,12 @@ function hitTestSectionId(x, y, sectionIds, rects) {
|
|
|
5813
5979
|
return null;
|
|
5814
5980
|
}
|
|
5815
5981
|
function useSectionRects(sectionIdsKey, enabled) {
|
|
5816
|
-
const [rects, setRects] = (0,
|
|
5817
|
-
const sectionIds = (0,
|
|
5982
|
+
const [rects, setRects] = (0, import_react6.useState)(/* @__PURE__ */ new Map());
|
|
5983
|
+
const sectionIds = (0, import_react6.useMemo)(
|
|
5818
5984
|
() => sectionIdsKey ? sectionIdsKey.split("\0") : [],
|
|
5819
5985
|
[sectionIdsKey]
|
|
5820
5986
|
);
|
|
5821
|
-
(0,
|
|
5987
|
+
(0, import_react6.useEffect)(() => {
|
|
5822
5988
|
if (!enabled || sectionIds.length === 0) {
|
|
5823
5989
|
setRects((prev) => prev.size === 0 ? prev : /* @__PURE__ */ new Map());
|
|
5824
5990
|
return;
|
|
@@ -5859,13 +6025,13 @@ function SectionPickerOverlay({
|
|
|
5859
6025
|
}) {
|
|
5860
6026
|
const router = (0, import_navigation.useRouter)();
|
|
5861
6027
|
const pathname = (0, import_navigation.usePathname)();
|
|
5862
|
-
const [selectedId, setSelectedId] = (0,
|
|
5863
|
-
const [hoveredId, setHoveredId] = (0,
|
|
5864
|
-
const pointerRef = (0,
|
|
5865
|
-
const pointerScreenRef = (0,
|
|
5866
|
-
const iframeOffsetTopRef = (0,
|
|
5867
|
-
const sectionIdsRef = (0,
|
|
5868
|
-
const [chromeClip, setChromeClip] = (0,
|
|
6028
|
+
const [selectedId, setSelectedId] = (0, import_react6.useState)(null);
|
|
6029
|
+
const [hoveredId, setHoveredId] = (0, import_react6.useState)(null);
|
|
6030
|
+
const pointerRef = (0, import_react6.useRef)(null);
|
|
6031
|
+
const pointerScreenRef = (0, import_react6.useRef)(null);
|
|
6032
|
+
const iframeOffsetTopRef = (0, import_react6.useRef)(null);
|
|
6033
|
+
const sectionIdsRef = (0, import_react6.useRef)([]);
|
|
6034
|
+
const [chromeClip, setChromeClip] = (0, import_react6.useState)(
|
|
5869
6035
|
() => ({
|
|
5870
6036
|
top: 0,
|
|
5871
6037
|
bottom: typeof window !== "undefined" ? window.innerHeight : 0
|
|
@@ -5873,12 +6039,12 @@ function SectionPickerOverlay({
|
|
|
5873
6039
|
);
|
|
5874
6040
|
const normalizedTarget = normalizePath(pagePath);
|
|
5875
6041
|
const isOnTargetPage = normalizePath(pathname) === normalizedTarget;
|
|
5876
|
-
(0,
|
|
6042
|
+
(0, import_react6.useEffect)(() => {
|
|
5877
6043
|
if (isOnTargetPage) return;
|
|
5878
6044
|
const search = readPreservedSearch();
|
|
5879
6045
|
router.push(`${normalizedTarget}${search}`);
|
|
5880
6046
|
}, [isOnTargetPage, normalizedTarget, router]);
|
|
5881
|
-
(0,
|
|
6047
|
+
(0, import_react6.useEffect)(() => {
|
|
5882
6048
|
document.documentElement.setAttribute("data-ohw-section-picking", "");
|
|
5883
6049
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => {
|
|
5884
6050
|
el.removeAttribute("data-ohw-hovered");
|
|
@@ -5890,24 +6056,24 @@ function SectionPickerOverlay({
|
|
|
5890
6056
|
document.documentElement.removeAttribute("data-ohw-section-picking");
|
|
5891
6057
|
};
|
|
5892
6058
|
}, []);
|
|
5893
|
-
const liveSections = (0,
|
|
6059
|
+
const liveSections = (0, import_react6.useMemo)(() => {
|
|
5894
6060
|
if (!isOnTargetPage) return sections;
|
|
5895
6061
|
const live = collectSectionsFromDom();
|
|
5896
6062
|
if (live.length === 0) return sections;
|
|
5897
6063
|
const labels = new Map(sections.map((s) => [s.id, s.label]));
|
|
5898
6064
|
return live.map((s) => ({ id: s.id, label: labels.get(s.id) ?? s.label }));
|
|
5899
6065
|
}, [isOnTargetPage, sections, pathname]);
|
|
5900
|
-
const sectionIdsKey = (0,
|
|
6066
|
+
const sectionIdsKey = (0, import_react6.useMemo)(
|
|
5901
6067
|
() => liveSections.map((s) => s.id).join("\0"),
|
|
5902
6068
|
[liveSections]
|
|
5903
6069
|
);
|
|
5904
|
-
const sectionIds = (0,
|
|
6070
|
+
const sectionIds = (0, import_react6.useMemo)(
|
|
5905
6071
|
() => liveSections.map((s) => s.id),
|
|
5906
6072
|
[liveSections]
|
|
5907
6073
|
);
|
|
5908
6074
|
sectionIdsRef.current = sectionIds;
|
|
5909
6075
|
const rects = useSectionRects(sectionIdsKey, isOnTargetPage);
|
|
5910
|
-
const applyHoverAt = (0,
|
|
6076
|
+
const applyHoverAt = (0, import_react6.useCallback)(
|
|
5911
6077
|
(x, y, liveRects) => {
|
|
5912
6078
|
const ids = sectionIdsRef.current;
|
|
5913
6079
|
const map = liveRects ?? readSectionRects(ids);
|
|
@@ -5916,7 +6082,7 @@ function SectionPickerOverlay({
|
|
|
5916
6082
|
},
|
|
5917
6083
|
[]
|
|
5918
6084
|
);
|
|
5919
|
-
(0,
|
|
6085
|
+
(0, import_react6.useEffect)(() => {
|
|
5920
6086
|
const applyClip = (iframeOffsetTop, visibleCanvasTop, canvasH) => {
|
|
5921
6087
|
const top = Math.max(0, visibleCanvasTop - iframeOffsetTop);
|
|
5922
6088
|
const bottom = Math.min(
|
|
@@ -5958,12 +6124,12 @@ function SectionPickerOverlay({
|
|
|
5958
6124
|
window.removeEventListener("resize", onResize);
|
|
5959
6125
|
};
|
|
5960
6126
|
}, [applyHoverAt]);
|
|
5961
|
-
(0,
|
|
6127
|
+
(0, import_react6.useEffect)(() => {
|
|
5962
6128
|
const ptr = pointerRef.current;
|
|
5963
6129
|
if (!ptr) return;
|
|
5964
6130
|
applyHoverAt(ptr.x, ptr.y, rects);
|
|
5965
6131
|
}, [rects, applyHoverAt]);
|
|
5966
|
-
(0,
|
|
6132
|
+
(0, import_react6.useEffect)(() => {
|
|
5967
6133
|
const rememberPointer = (clientX, clientY) => {
|
|
5968
6134
|
pointerRef.current = { x: clientX, y: clientY };
|
|
5969
6135
|
const top = iframeOffsetTopRef.current;
|
|
@@ -5987,7 +6153,7 @@ function SectionPickerOverlay({
|
|
|
5987
6153
|
window.removeEventListener("message", onPointerSync);
|
|
5988
6154
|
};
|
|
5989
6155
|
}, [rects, applyHoverAt]);
|
|
5990
|
-
const handleSelect = (0,
|
|
6156
|
+
const handleSelect = (0, import_react6.useCallback)(
|
|
5991
6157
|
(section) => {
|
|
5992
6158
|
if (selectedId) return;
|
|
5993
6159
|
setSelectedId(section.id);
|
|
@@ -5995,7 +6161,7 @@ function SectionPickerOverlay({
|
|
|
5995
6161
|
},
|
|
5996
6162
|
[selectedId, onSelect]
|
|
5997
6163
|
);
|
|
5998
|
-
(0,
|
|
6164
|
+
(0, import_react6.useEffect)(() => {
|
|
5999
6165
|
const onKeyDown = (e) => {
|
|
6000
6166
|
if (e.key === "Escape") {
|
|
6001
6167
|
e.preventDefault();
|
|
@@ -6009,7 +6175,7 @@ function SectionPickerOverlay({
|
|
|
6009
6175
|
const portalRoot = typeof document !== "undefined" ? document.querySelector("[data-ohw-bridge-root]") ?? document.body : null;
|
|
6010
6176
|
if (!portalRoot) return null;
|
|
6011
6177
|
return (0, import_react_dom.createPortal)(
|
|
6012
|
-
/* @__PURE__ */ (0,
|
|
6178
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
6013
6179
|
"div",
|
|
6014
6180
|
{
|
|
6015
6181
|
"data-ohw-section-picker": "",
|
|
@@ -6019,12 +6185,12 @@ function SectionPickerOverlay({
|
|
|
6019
6185
|
role: "dialog",
|
|
6020
6186
|
"aria-label": "Choose a section",
|
|
6021
6187
|
children: [
|
|
6022
|
-
/* @__PURE__ */ (0,
|
|
6188
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
6023
6189
|
"div",
|
|
6024
6190
|
{
|
|
6025
6191
|
className: "pointer-events-auto fixed left-5 z-[2]",
|
|
6026
6192
|
style: { top: chromeClip.top + 20 },
|
|
6027
|
-
children: /* @__PURE__ */ (0,
|
|
6193
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
6028
6194
|
Button,
|
|
6029
6195
|
{
|
|
6030
6196
|
type: "button",
|
|
@@ -6033,14 +6199,14 @@ function SectionPickerOverlay({
|
|
|
6033
6199
|
className: "h-8 min-w-0 gap-1 border-border bg-background px-2 py-1.5 shadow-sm hover:bg-muted cursor-pointer",
|
|
6034
6200
|
onClick: onBack,
|
|
6035
6201
|
children: [
|
|
6036
|
-
/* @__PURE__ */ (0,
|
|
6202
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react10.ArrowLeft, { className: "size-4 shrink-0", "aria-hidden": true }),
|
|
6037
6203
|
"Back"
|
|
6038
6204
|
]
|
|
6039
6205
|
}
|
|
6040
6206
|
)
|
|
6041
6207
|
}
|
|
6042
6208
|
),
|
|
6043
|
-
/* @__PURE__ */ (0,
|
|
6209
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
6044
6210
|
"div",
|
|
6045
6211
|
{
|
|
6046
6212
|
className: "pointer-events-none fixed left-1/2 z-[2] rounded-lg px-4 py-3 text-xs leading-4 tracking-[0.18px] text-white shadow-md",
|
|
@@ -6053,7 +6219,7 @@ function SectionPickerOverlay({
|
|
|
6053
6219
|
children: "Click on section to select"
|
|
6054
6220
|
}
|
|
6055
6221
|
),
|
|
6056
|
-
!isOnTargetPage ? /* @__PURE__ */ (0,
|
|
6222
|
+
!isOnTargetPage ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
6057
6223
|
"div",
|
|
6058
6224
|
{
|
|
6059
6225
|
className: "pointer-events-none fixed left-1/2 z-[1] -translate-x-1/2 rounded-md px-3 py-2 text-sm text-muted-foreground shadow-sm",
|
|
@@ -6061,14 +6227,14 @@ function SectionPickerOverlay({
|
|
|
6061
6227
|
children: "Loading page preview\u2026"
|
|
6062
6228
|
}
|
|
6063
6229
|
) : null,
|
|
6064
|
-
isOnTargetPage && liveSections.length === 0 ? /* @__PURE__ */ (0,
|
|
6230
|
+
isOnTargetPage && liveSections.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "pointer-events-auto fixed inset-0 z-[1] flex items-center justify-center bg-muted/40", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "text-sm text-muted-foreground", children: "No sections found on this page." }) }) : null,
|
|
6065
6231
|
isOnTargetPage ? liveSections.map((section) => {
|
|
6066
6232
|
const rect = rects.get(section.id);
|
|
6067
6233
|
if (!rect || rect.width <= 0 || rect.height <= 0) return null;
|
|
6068
6234
|
const isSelected = selectedId === section.id;
|
|
6069
6235
|
const isHovered = hoveredId === section.id;
|
|
6070
6236
|
const isLit = isSelected || isHovered;
|
|
6071
|
-
return /* @__PURE__ */ (0,
|
|
6237
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
6072
6238
|
"button",
|
|
6073
6239
|
{
|
|
6074
6240
|
type: "button",
|
|
@@ -6083,7 +6249,7 @@ function SectionPickerOverlay({
|
|
|
6083
6249
|
"aria-label": `Select section ${section.label}`,
|
|
6084
6250
|
onClick: () => handleSelect(section),
|
|
6085
6251
|
children: [
|
|
6086
|
-
isLit ? /* @__PURE__ */ (0,
|
|
6252
|
+
isLit ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
6087
6253
|
"span",
|
|
6088
6254
|
{
|
|
6089
6255
|
className: "pointer-events-none absolute",
|
|
@@ -6096,13 +6262,13 @@ function SectionPickerOverlay({
|
|
|
6096
6262
|
"aria-hidden": true
|
|
6097
6263
|
}
|
|
6098
6264
|
) : null,
|
|
6099
|
-
isSelected ? /* @__PURE__ */ (0,
|
|
6265
|
+
isSelected ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
6100
6266
|
"span",
|
|
6101
6267
|
{
|
|
6102
6268
|
className: "absolute right-3 top-3 flex size-8 items-center justify-center rounded-full text-white",
|
|
6103
6269
|
style: { backgroundColor: "var(--ohw-primary, #0885fe)" },
|
|
6104
6270
|
"aria-hidden": true,
|
|
6105
|
-
children: /* @__PURE__ */ (0,
|
|
6271
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react10.Check, { className: "size-5" })
|
|
6106
6272
|
}
|
|
6107
6273
|
) : null
|
|
6108
6274
|
]
|
|
@@ -6118,7 +6284,7 @@ function SectionPickerOverlay({
|
|
|
6118
6284
|
}
|
|
6119
6285
|
|
|
6120
6286
|
// src/ui/link-modal/useLinkModalState.ts
|
|
6121
|
-
var
|
|
6287
|
+
var import_react7 = require("react");
|
|
6122
6288
|
function useLinkModalState({
|
|
6123
6289
|
open,
|
|
6124
6290
|
mode,
|
|
@@ -6130,14 +6296,14 @@ function useLinkModalState({
|
|
|
6130
6296
|
onClose,
|
|
6131
6297
|
onSubmit
|
|
6132
6298
|
}) {
|
|
6133
|
-
const availablePages = (0,
|
|
6134
|
-
const [searchValue, setSearchValue] = (0,
|
|
6135
|
-
const [selectedPage, setSelectedPage] = (0,
|
|
6136
|
-
const [selectedSection, setSelectedSection] = (0,
|
|
6137
|
-
const [step, setStep] = (0,
|
|
6138
|
-
const [dropdownOpen, setDropdownOpen] = (0,
|
|
6139
|
-
const [urlError, setUrlError] = (0,
|
|
6140
|
-
const reset = (0,
|
|
6299
|
+
const availablePages = (0, import_react7.useMemo)(() => pages, [pages]);
|
|
6300
|
+
const [searchValue, setSearchValue] = (0, import_react7.useState)("");
|
|
6301
|
+
const [selectedPage, setSelectedPage] = (0, import_react7.useState)(null);
|
|
6302
|
+
const [selectedSection, setSelectedSection] = (0, import_react7.useState)(null);
|
|
6303
|
+
const [step, setStep] = (0, import_react7.useState)("input");
|
|
6304
|
+
const [dropdownOpen, setDropdownOpen] = (0, import_react7.useState)(false);
|
|
6305
|
+
const [urlError, setUrlError] = (0, import_react7.useState)("");
|
|
6306
|
+
const reset = (0, import_react7.useCallback)(() => {
|
|
6141
6307
|
setSearchValue("");
|
|
6142
6308
|
setSelectedPage(null);
|
|
6143
6309
|
setSelectedSection(null);
|
|
@@ -6145,7 +6311,7 @@ function useLinkModalState({
|
|
|
6145
6311
|
setDropdownOpen(false);
|
|
6146
6312
|
setUrlError("");
|
|
6147
6313
|
}, []);
|
|
6148
|
-
(0,
|
|
6314
|
+
(0, import_react7.useEffect)(() => {
|
|
6149
6315
|
if (!open) return;
|
|
6150
6316
|
if (mode === "edit" && initialTarget) {
|
|
6151
6317
|
const { pageRoute } = parseTarget(initialTarget);
|
|
@@ -6161,11 +6327,11 @@ function useLinkModalState({
|
|
|
6161
6327
|
setDropdownOpen(false);
|
|
6162
6328
|
setUrlError("");
|
|
6163
6329
|
}, [open, mode, initialTarget, reset]);
|
|
6164
|
-
const filteredPages = (0,
|
|
6330
|
+
const filteredPages = (0, import_react7.useMemo)(() => {
|
|
6165
6331
|
if (!searchValue.trim()) return availablePages;
|
|
6166
6332
|
return availablePages.filter((p) => p.title.toLowerCase().startsWith(searchValue.toLowerCase()));
|
|
6167
6333
|
}, [availablePages, searchValue]);
|
|
6168
|
-
const activeSections = (0,
|
|
6334
|
+
const activeSections = (0, import_react7.useMemo)(() => {
|
|
6169
6335
|
if (!selectedPage) return [];
|
|
6170
6336
|
return getSectionsForPath(sectionsByPath, selectedPage.path);
|
|
6171
6337
|
}, [selectedPage, sectionsByPath]);
|
|
@@ -6214,7 +6380,7 @@ function useLinkModalState({
|
|
|
6214
6380
|
reset();
|
|
6215
6381
|
onClose();
|
|
6216
6382
|
};
|
|
6217
|
-
const isValid = (0,
|
|
6383
|
+
const isValid = (0, import_react7.useMemo)(() => {
|
|
6218
6384
|
if (urlError) return false;
|
|
6219
6385
|
if (showBreadcrumb) return true;
|
|
6220
6386
|
if (selectedPage) return true;
|
|
@@ -6282,7 +6448,7 @@ function useLinkModalState({
|
|
|
6282
6448
|
}
|
|
6283
6449
|
|
|
6284
6450
|
// src/ui/link-modal/LinkPopover.tsx
|
|
6285
|
-
var
|
|
6451
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
6286
6452
|
function postToParent(data) {
|
|
6287
6453
|
window.parent?.postMessage(data, "*");
|
|
6288
6454
|
}
|
|
@@ -6311,7 +6477,7 @@ function LinkPopover({
|
|
|
6311
6477
|
onSubmit
|
|
6312
6478
|
});
|
|
6313
6479
|
const sectionPickerActive = state.showSectionPicker && Boolean(state.selectedPage);
|
|
6314
|
-
(0,
|
|
6480
|
+
(0, import_react8.useEffect)(() => {
|
|
6315
6481
|
if (!open) return;
|
|
6316
6482
|
if (sectionPickerActive) {
|
|
6317
6483
|
postToParent({ type: "ui:unlock" });
|
|
@@ -6378,15 +6544,15 @@ function LinkPopover({
|
|
|
6378
6544
|
);
|
|
6379
6545
|
};
|
|
6380
6546
|
}, [open, sectionPickerActive]);
|
|
6381
|
-
return /* @__PURE__ */ (0,
|
|
6382
|
-
/* @__PURE__ */ (0,
|
|
6547
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
|
|
6548
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
6383
6549
|
Dialog2,
|
|
6384
6550
|
{
|
|
6385
6551
|
open: open && !sectionPickerActive,
|
|
6386
6552
|
onOpenChange: (next) => {
|
|
6387
6553
|
if (!next) onClose?.();
|
|
6388
6554
|
},
|
|
6389
|
-
children: /* @__PURE__ */ (0,
|
|
6555
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
6390
6556
|
DialogContent,
|
|
6391
6557
|
{
|
|
6392
6558
|
ref: panelRef,
|
|
@@ -6396,12 +6562,12 @@ function LinkPopover({
|
|
|
6396
6562
|
"data-ohw-bridge": "",
|
|
6397
6563
|
showCloseButton: false,
|
|
6398
6564
|
className: "gap-0 p-0 w-full max-w-[448px] pointer-events-auto z-[2147483646] overflow-visible",
|
|
6399
|
-
children: /* @__PURE__ */ (0,
|
|
6565
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(LinkEditorPanel, { state, onClose })
|
|
6400
6566
|
}
|
|
6401
6567
|
)
|
|
6402
6568
|
}
|
|
6403
6569
|
),
|
|
6404
|
-
sectionPickerActive && state.selectedPage ? /* @__PURE__ */ (0,
|
|
6570
|
+
sectionPickerActive && state.selectedPage ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
6405
6571
|
SectionPickerOverlay,
|
|
6406
6572
|
{
|
|
6407
6573
|
pagePath: state.selectedPage.path,
|
|
@@ -6890,6 +7056,22 @@ function navbarIndexExistsInDom(index) {
|
|
|
6890
7056
|
return document.querySelector(`[data-ohw-href-key="nav-${index}-href"]`) !== null;
|
|
6891
7057
|
}
|
|
6892
7058
|
function reconcileNavbarItemsFromContent(content) {
|
|
7059
|
+
const orderForest = parseNavOrderJson(content[NAV_ORDER_KEY]);
|
|
7060
|
+
if (orderForest?.length) {
|
|
7061
|
+
const allowed = new Set(flattenNavOrder(orderForest));
|
|
7062
|
+
for (const hrefKey of allowed) {
|
|
7063
|
+
const index = parseNavIndexFromKey(hrefKey);
|
|
7064
|
+
if (index === null) continue;
|
|
7065
|
+
if (navbarIndexExistsInDom(index)) continue;
|
|
7066
|
+
const href = content[`nav-${index}-href`];
|
|
7067
|
+
const label = content[`nav-${index}-label`];
|
|
7068
|
+
if (!href && !label) continue;
|
|
7069
|
+
insertNavbarItemDom(index, href ?? "/", label ?? "Untitled", null);
|
|
7070
|
+
}
|
|
7071
|
+
pruneNavbarItemsNotInOrder(allowed);
|
|
7072
|
+
applyNavForest(orderForest);
|
|
7073
|
+
return;
|
|
7074
|
+
}
|
|
6893
7075
|
const indices = collectNavbarIndicesFromContent(content);
|
|
6894
7076
|
for (const index of indices) {
|
|
6895
7077
|
if (navbarIndexExistsInDom(index)) continue;
|
|
@@ -6898,9 +7080,22 @@ function reconcileNavbarItemsFromContent(content) {
|
|
|
6898
7080
|
if (!href && !label) continue;
|
|
6899
7081
|
insertNavbarItemDom(index, href ?? "/", label ?? "Untitled", null);
|
|
6900
7082
|
}
|
|
6901
|
-
|
|
6902
|
-
|
|
6903
|
-
|
|
7083
|
+
}
|
|
7084
|
+
function pruneNavbarItemsNotInOrder(allowed) {
|
|
7085
|
+
const roots = [getNavbarDesktopContainer(), getNavbarDrawerContainer()].filter(
|
|
7086
|
+
(el) => Boolean(el)
|
|
7087
|
+
);
|
|
7088
|
+
const searchRoots = roots.length > 0 ? roots : [document.body];
|
|
7089
|
+
for (const root of searchRoots) {
|
|
7090
|
+
const items = Array.from(root.querySelectorAll("[data-ohw-href-key]")).filter(
|
|
7091
|
+
isNavbarLinkItem
|
|
7092
|
+
);
|
|
7093
|
+
for (const item of items) {
|
|
7094
|
+
if (!item.isConnected) continue;
|
|
7095
|
+
const key = item.getAttribute("data-ohw-href-key");
|
|
7096
|
+
if (!key || !isNavbarHrefKey(key) || allowed.has(key)) continue;
|
|
7097
|
+
resolveRemovableNavUnit(item).remove();
|
|
7098
|
+
}
|
|
6904
7099
|
}
|
|
6905
7100
|
}
|
|
6906
7101
|
function buildNavOrderAfterInsert(afterAnchor, newHrefKey) {
|
|
@@ -6940,9 +7135,126 @@ function insertNavbarItem(href, label, afterAnchor = null) {
|
|
|
6940
7135
|
order
|
|
6941
7136
|
};
|
|
6942
7137
|
}
|
|
7138
|
+
function duplicateNavbarItem(sourceAnchor) {
|
|
7139
|
+
if (!isNavbarLinkItem(sourceAnchor)) return null;
|
|
7140
|
+
const sourceHrefKey = sourceAnchor.getAttribute("data-ohw-href-key");
|
|
7141
|
+
if (!sourceHrefKey || !isNavbarHrefKey(sourceHrefKey)) return null;
|
|
7142
|
+
const href = getLinkHref(sourceAnchor);
|
|
7143
|
+
const labelEl = sourceAnchor.querySelector('[data-ohw-editable="text"]');
|
|
7144
|
+
const label = (labelEl?.textContent ?? "").trim() || "Untitled";
|
|
7145
|
+
const forest = getNavForestFromDom();
|
|
7146
|
+
const sourceNode = forest.find((n) => n.id === sourceHrefKey);
|
|
7147
|
+
const childIds = sourceNode?.children.map((c) => c.id) ?? [];
|
|
7148
|
+
const primary = insertNavbarItem(href, label, sourceAnchor);
|
|
7149
|
+
const childResults = [];
|
|
7150
|
+
let after = primary.anchor;
|
|
7151
|
+
for (const childId of childIds) {
|
|
7152
|
+
const childEl = findCounterpartByHrefKey(childId, document) ?? document.querySelector(`[data-ohw-href-key="${CSS.escape(childId)}"]`);
|
|
7153
|
+
if (!childEl || !isNavbarLinkItem(childEl)) continue;
|
|
7154
|
+
const childHref = getLinkHref(childEl);
|
|
7155
|
+
const childLabelEl = childEl.querySelector('[data-ohw-editable="text"]');
|
|
7156
|
+
const childLabel = (childLabelEl?.textContent ?? "").trim() || "Untitled";
|
|
7157
|
+
const inserted = insertNavbarItem(childHref, childLabel, after);
|
|
7158
|
+
childResults.push(inserted);
|
|
7159
|
+
after = inserted.anchor;
|
|
7160
|
+
}
|
|
7161
|
+
let orderJson;
|
|
7162
|
+
if (childResults.length > 0) {
|
|
7163
|
+
const nextForest = getNavForestFromDom();
|
|
7164
|
+
const withoutNew = nextForest.filter(
|
|
7165
|
+
(n) => n.id !== primary.hrefKey && !childResults.some((c) => c.hrefKey === n.id)
|
|
7166
|
+
);
|
|
7167
|
+
const sourceIdx = withoutNew.findIndex((n) => n.id === sourceHrefKey);
|
|
7168
|
+
const insertAt = sourceIdx >= 0 ? sourceIdx + 1 : withoutNew.length;
|
|
7169
|
+
withoutNew.splice(insertAt, 0, {
|
|
7170
|
+
id: primary.hrefKey,
|
|
7171
|
+
children: childResults.map((c) => ({ id: c.hrefKey, children: [] }))
|
|
7172
|
+
});
|
|
7173
|
+
applyNavForest(withoutNew);
|
|
7174
|
+
orderJson = serializeNavOrder(withoutNew);
|
|
7175
|
+
} else {
|
|
7176
|
+
orderJson = serializeNavOrder(getNavForestFromDom());
|
|
7177
|
+
}
|
|
7178
|
+
return {
|
|
7179
|
+
...primary,
|
|
7180
|
+
order: flattenNavOrder(parseNavOrderJson(orderJson) ?? getNavForestFromDom()),
|
|
7181
|
+
childResults,
|
|
7182
|
+
orderJson
|
|
7183
|
+
};
|
|
7184
|
+
}
|
|
7185
|
+
function collectSubtreeHrefKeys(node) {
|
|
7186
|
+
const keys = [node.id];
|
|
7187
|
+
for (const child of node.children) {
|
|
7188
|
+
keys.push(...collectSubtreeHrefKeys(child));
|
|
7189
|
+
}
|
|
7190
|
+
return keys;
|
|
7191
|
+
}
|
|
7192
|
+
function labelKeyFromHrefKey(hrefKey) {
|
|
7193
|
+
return hrefKey.replace(/-href$/, "-label");
|
|
7194
|
+
}
|
|
7195
|
+
function resolveRemovableNavUnit(anchor) {
|
|
7196
|
+
if (anchor.closest("[data-ohw-nav-children]")) return anchor;
|
|
7197
|
+
const group = anchor.closest("[data-ohw-nav-group]");
|
|
7198
|
+
if (group?.querySelector(":scope > [data-ohw-nav-children]")) return group;
|
|
7199
|
+
return anchor;
|
|
7200
|
+
}
|
|
7201
|
+
function deleteNavbarItem(sourceAnchor) {
|
|
7202
|
+
if (!isNavbarLinkItem(sourceAnchor)) return null;
|
|
7203
|
+
const sourceHrefKey = sourceAnchor.getAttribute("data-ohw-href-key");
|
|
7204
|
+
if (!sourceHrefKey || !isNavbarHrefKey(sourceHrefKey)) return null;
|
|
7205
|
+
const labelEl = sourceAnchor.querySelector('[data-ohw-editable="text"]');
|
|
7206
|
+
const label = (labelEl?.textContent ?? "").trim() || "Untitled";
|
|
7207
|
+
const previousForest = getNavForestFromDom();
|
|
7208
|
+
const previousOrderJson = serializeNavOrder(previousForest);
|
|
7209
|
+
const taken = takeNode(previousForest, sourceHrefKey);
|
|
7210
|
+
if (!taken) return null;
|
|
7211
|
+
const removedHrefKeys = collectSubtreeHrefKeys(taken.taken);
|
|
7212
|
+
const removedKeys = removedHrefKeys.flatMap((hrefKey) => [hrefKey, labelKeyFromHrefKey(hrefKey)]);
|
|
7213
|
+
const previousContent = {};
|
|
7214
|
+
for (const hrefKey of removedHrefKeys) {
|
|
7215
|
+
const el = findCounterpartByHrefKey(hrefKey, document) ?? document.querySelector(`[data-ohw-href-key="${CSS.escape(hrefKey)}"]`);
|
|
7216
|
+
previousContent[hrefKey] = el ? getLinkHref(el) : "";
|
|
7217
|
+
const labEl = el?.querySelector('[data-ohw-editable="text"]');
|
|
7218
|
+
previousContent[labelKeyFromHrefKey(hrefKey)] = (labEl?.textContent ?? "").trim();
|
|
7219
|
+
}
|
|
7220
|
+
const roots = [getNavbarDesktopContainer(), getNavbarDrawerContainer()].filter(
|
|
7221
|
+
(el) => Boolean(el)
|
|
7222
|
+
);
|
|
7223
|
+
const searchRoots = roots.length > 0 ? roots : [document.body];
|
|
7224
|
+
const placements = [];
|
|
7225
|
+
for (const root of searchRoots) {
|
|
7226
|
+
const primary = findCounterpartByHrefKey(sourceHrefKey, root);
|
|
7227
|
+
if (!primary?.isConnected || !primary.parentElement) continue;
|
|
7228
|
+
const unit = resolveRemovableNavUnit(primary);
|
|
7229
|
+
if (!unit.parentElement) continue;
|
|
7230
|
+
placements.push({
|
|
7231
|
+
node: unit,
|
|
7232
|
+
parent: unit.parentElement,
|
|
7233
|
+
nextSibling: unit.nextSibling
|
|
7234
|
+
});
|
|
7235
|
+
unit.remove();
|
|
7236
|
+
}
|
|
7237
|
+
applyNavForest(taken.forest);
|
|
7238
|
+
const orderJson = serializeNavOrder(taken.forest);
|
|
7239
|
+
return {
|
|
7240
|
+
label,
|
|
7241
|
+
hrefKey: sourceHrefKey,
|
|
7242
|
+
removedKeys,
|
|
7243
|
+
previousContent,
|
|
7244
|
+
orderJson,
|
|
7245
|
+
previousOrderJson,
|
|
7246
|
+
undo: () => {
|
|
7247
|
+
for (const placement of placements) {
|
|
7248
|
+
placement.parent.insertBefore(placement.node, placement.nextSibling);
|
|
7249
|
+
}
|
|
7250
|
+
applyNavForest(previousForest);
|
|
7251
|
+
}
|
|
7252
|
+
};
|
|
7253
|
+
}
|
|
6943
7254
|
|
|
6944
7255
|
// src/lib/footer-items.ts
|
|
6945
7256
|
var FOOTER_ORDER_KEY = "__ohw_footer_order";
|
|
7257
|
+
var MAX_FOOTER_COLUMNS = 18;
|
|
6946
7258
|
var FOOTER_HREF_RE = /^footer-(\d+)-(\d+)-href$/;
|
|
6947
7259
|
function parseFooterHrefKey(key) {
|
|
6948
7260
|
if (!key) return null;
|
|
@@ -7123,22 +7435,266 @@ function parseFooterOrder(content) {
|
|
|
7123
7435
|
return null;
|
|
7124
7436
|
}
|
|
7125
7437
|
}
|
|
7438
|
+
var FOOTER_HEADING_RE = /^footer-(\d+)-heading$/;
|
|
7439
|
+
var FOOTER_LABEL_RE = /^footer-(\d+)-(\d+)-label$/;
|
|
7440
|
+
var DEFAULT_FOOTER_COLUMN_HEADING = "New";
|
|
7441
|
+
var DEFAULT_FOOTER_COLUMN_LINK_LABEL = "New link";
|
|
7442
|
+
var DEFAULT_FOOTER_COLUMN_LINK_HREF = "";
|
|
7443
|
+
function isFooterLinksContainer(el) {
|
|
7444
|
+
return el.hasAttribute("data-ohw-footer-links") || el.classList.contains("rb-footer-links");
|
|
7445
|
+
}
|
|
7446
|
+
function getFooterColumnIndicesInDom() {
|
|
7447
|
+
const indices = /* @__PURE__ */ new Set();
|
|
7448
|
+
for (const col of listFooterColumns()) {
|
|
7449
|
+
const attr = col.getAttribute("data-ohw-footer-col");
|
|
7450
|
+
if (attr != null) {
|
|
7451
|
+
const n = parseInt(attr, 10);
|
|
7452
|
+
if (Number.isFinite(n)) indices.add(n);
|
|
7453
|
+
}
|
|
7454
|
+
for (const link of listFooterLinksInColumn(col)) {
|
|
7455
|
+
const parsed = parseFooterHrefKey(link.getAttribute("data-ohw-href-key"));
|
|
7456
|
+
if (parsed) indices.add(parsed.col);
|
|
7457
|
+
}
|
|
7458
|
+
const heading = col.querySelector('[data-ohw-key^="footer-"][data-ohw-key$="-heading"]');
|
|
7459
|
+
const headingKey = heading?.getAttribute("data-ohw-key");
|
|
7460
|
+
if (headingKey) {
|
|
7461
|
+
const match = headingKey.match(FOOTER_HEADING_RE);
|
|
7462
|
+
if (match) indices.add(parseInt(match[1], 10));
|
|
7463
|
+
}
|
|
7464
|
+
}
|
|
7465
|
+
return [...indices].sort((a, b) => a - b);
|
|
7466
|
+
}
|
|
7467
|
+
function getNextFooterColumnIndex() {
|
|
7468
|
+
const indices = getFooterColumnIndicesInDom();
|
|
7469
|
+
if (indices.length === 0) return 0;
|
|
7470
|
+
return Math.max(...indices) + 1;
|
|
7471
|
+
}
|
|
7472
|
+
function canAddFooterColumn() {
|
|
7473
|
+
return listFooterColumns().length < MAX_FOOTER_COLUMNS;
|
|
7474
|
+
}
|
|
7475
|
+
function buildFooterHeading(colIndex, text) {
|
|
7476
|
+
const heading = document.createElement("p");
|
|
7477
|
+
heading.setAttribute("data-ohw-editable", "text");
|
|
7478
|
+
heading.setAttribute("data-ohw-key", `footer-${colIndex}-heading`);
|
|
7479
|
+
heading.textContent = text;
|
|
7480
|
+
heading.style.cssText = [
|
|
7481
|
+
"color: var(--espresso, #3d312b)",
|
|
7482
|
+
"font-size: 14px",
|
|
7483
|
+
"font-weight: 800",
|
|
7484
|
+
"opacity: 0.82",
|
|
7485
|
+
"margin: 0 0 6px",
|
|
7486
|
+
"padding: 0",
|
|
7487
|
+
"line-height: 1.2"
|
|
7488
|
+
].join(";");
|
|
7489
|
+
return heading;
|
|
7490
|
+
}
|
|
7491
|
+
function buildFooterLink(colIndex, itemIndex, href, label, template) {
|
|
7492
|
+
const anchor = cloneFooterLinkShell(template);
|
|
7493
|
+
anchor.setAttribute("href", href);
|
|
7494
|
+
anchor.setAttribute("data-ohw-href-key", `footer-${colIndex}-${itemIndex}-href`);
|
|
7495
|
+
const span = document.createElement("span");
|
|
7496
|
+
span.setAttribute("data-ohw-editable", "text");
|
|
7497
|
+
span.setAttribute("data-ohw-key", `footer-${colIndex}-${itemIndex}-label`);
|
|
7498
|
+
span.textContent = label;
|
|
7499
|
+
anchor.appendChild(span);
|
|
7500
|
+
return anchor;
|
|
7501
|
+
}
|
|
7502
|
+
function footerColumnExistsInDom(colIndex) {
|
|
7503
|
+
return document.querySelector(`[data-ohw-footer-col="${colIndex}"]`) !== null || document.querySelector(`[data-ohw-href-key^="footer-${colIndex}-"]`) !== null || document.querySelector(`[data-ohw-key="footer-${colIndex}-heading"]`) !== null;
|
|
7504
|
+
}
|
|
7505
|
+
function getFooterLinkTemplate() {
|
|
7506
|
+
for (const col of listFooterColumns()) {
|
|
7507
|
+
const link = listFooterLinksInColumn(col)[0];
|
|
7508
|
+
if (link) return link;
|
|
7509
|
+
}
|
|
7510
|
+
return null;
|
|
7511
|
+
}
|
|
7512
|
+
function getFooterColumnTemplate() {
|
|
7513
|
+
return listFooterColumns()[0] ?? null;
|
|
7514
|
+
}
|
|
7515
|
+
function insertFooterColumnDom(colIndex, heading, items) {
|
|
7516
|
+
const container = getFooterLinksContainer();
|
|
7517
|
+
if (!container) return null;
|
|
7518
|
+
const colTemplate = getFooterColumnTemplate();
|
|
7519
|
+
const linkTemplate = getFooterLinkTemplate();
|
|
7520
|
+
const column = document.createElement("div");
|
|
7521
|
+
if (colTemplate?.className) column.className = colTemplate.className;
|
|
7522
|
+
else column.className = "rb-footer-link-col";
|
|
7523
|
+
column.setAttribute("data-ohw-footer-col", String(colIndex));
|
|
7524
|
+
if (colTemplate) {
|
|
7525
|
+
const gap = getComputedStyle(colTemplate).gap;
|
|
7526
|
+
if (gap && gap !== "normal") column.style.gap = gap;
|
|
7527
|
+
column.style.display = getComputedStyle(colTemplate).display || "flex";
|
|
7528
|
+
column.style.flexDirection = "column";
|
|
7529
|
+
}
|
|
7530
|
+
column.appendChild(buildFooterHeading(colIndex, heading));
|
|
7531
|
+
let firstLink = null;
|
|
7532
|
+
items.forEach((item, itemIndex) => {
|
|
7533
|
+
const link = buildFooterLink(colIndex, itemIndex, item.href, item.label, linkTemplate);
|
|
7534
|
+
column.appendChild(link);
|
|
7535
|
+
if (!firstLink) firstLink = link;
|
|
7536
|
+
});
|
|
7537
|
+
container.appendChild(column);
|
|
7538
|
+
return { column, firstLink };
|
|
7539
|
+
}
|
|
7540
|
+
function insertFooterColumn(heading = DEFAULT_FOOTER_COLUMN_HEADING, linkLabel = DEFAULT_FOOTER_COLUMN_LINK_LABEL, linkHref = DEFAULT_FOOTER_COLUMN_LINK_HREF) {
|
|
7541
|
+
if (!canAddFooterColumn()) {
|
|
7542
|
+
throw new Error(`Footer column limit reached (${MAX_FOOTER_COLUMNS})`);
|
|
7543
|
+
}
|
|
7544
|
+
const colIndex = getNextFooterColumnIndex();
|
|
7545
|
+
const inserted = insertFooterColumnDom(colIndex, heading, [{ href: linkHref, label: linkLabel }]);
|
|
7546
|
+
if (!inserted?.firstLink) throw new Error("Failed to insert footer column");
|
|
7547
|
+
syncFooterColumnIndices(listFooterColumns());
|
|
7548
|
+
return {
|
|
7549
|
+
column: inserted.column,
|
|
7550
|
+
firstLink: inserted.firstLink,
|
|
7551
|
+
colIndex,
|
|
7552
|
+
headingKey: `footer-${colIndex}-heading`,
|
|
7553
|
+
hrefKey: `footer-${colIndex}-0-href`,
|
|
7554
|
+
labelKey: `footer-${colIndex}-0-label`,
|
|
7555
|
+
heading,
|
|
7556
|
+
label: linkLabel,
|
|
7557
|
+
href: linkHref,
|
|
7558
|
+
order: getFooterOrderFromDom()
|
|
7559
|
+
};
|
|
7560
|
+
}
|
|
7561
|
+
function collectFooterColumnIndicesFromContent(content) {
|
|
7562
|
+
const indices = /* @__PURE__ */ new Set();
|
|
7563
|
+
for (const key of Object.keys(content)) {
|
|
7564
|
+
const href = parseFooterHrefKey(key);
|
|
7565
|
+
if (href) indices.add(href.col);
|
|
7566
|
+
const heading = key.match(FOOTER_HEADING_RE);
|
|
7567
|
+
if (heading) indices.add(parseInt(heading[1], 10));
|
|
7568
|
+
const label = key.match(FOOTER_LABEL_RE);
|
|
7569
|
+
if (label) indices.add(parseInt(label[1], 10));
|
|
7570
|
+
}
|
|
7571
|
+
const order = parseFooterOrder(content);
|
|
7572
|
+
if (order) {
|
|
7573
|
+
for (const col of order) {
|
|
7574
|
+
for (const hrefKey of col) {
|
|
7575
|
+
const parsed = parseFooterHrefKey(hrefKey);
|
|
7576
|
+
if (parsed) indices.add(parsed.col);
|
|
7577
|
+
}
|
|
7578
|
+
}
|
|
7579
|
+
}
|
|
7580
|
+
return [...indices].sort((a, b) => a - b);
|
|
7581
|
+
}
|
|
7582
|
+
function collectFooterItemsForColumn(content, colIndex) {
|
|
7583
|
+
const itemIndices = /* @__PURE__ */ new Set();
|
|
7584
|
+
for (const key of Object.keys(content)) {
|
|
7585
|
+
const href = parseFooterHrefKey(key);
|
|
7586
|
+
if (href?.col === colIndex) itemIndices.add(href.item);
|
|
7587
|
+
const label = key.match(FOOTER_LABEL_RE);
|
|
7588
|
+
if (label && parseInt(label[1], 10) === colIndex) {
|
|
7589
|
+
itemIndices.add(parseInt(label[2], 10));
|
|
7590
|
+
}
|
|
7591
|
+
}
|
|
7592
|
+
const sorted = [...itemIndices].sort((a, b) => a - b);
|
|
7593
|
+
if (sorted.length === 0) {
|
|
7594
|
+
return [
|
|
7595
|
+
{
|
|
7596
|
+
href: content[`footer-${colIndex}-0-href`] ?? DEFAULT_FOOTER_COLUMN_LINK_HREF,
|
|
7597
|
+
label: content[`footer-${colIndex}-0-label`] ?? DEFAULT_FOOTER_COLUMN_LINK_LABEL
|
|
7598
|
+
}
|
|
7599
|
+
];
|
|
7600
|
+
}
|
|
7601
|
+
return sorted.map((itemIndex) => ({
|
|
7602
|
+
href: content[`footer-${colIndex}-${itemIndex}-href`] ?? DEFAULT_FOOTER_COLUMN_LINK_HREF,
|
|
7603
|
+
label: content[`footer-${colIndex}-${itemIndex}-label`] ?? DEFAULT_FOOTER_COLUMN_LINK_LABEL
|
|
7604
|
+
}));
|
|
7605
|
+
}
|
|
7606
|
+
function reconcileFooterColumnsFromContent(content) {
|
|
7607
|
+
const order = parseFooterOrder(content);
|
|
7608
|
+
const allowedCols = order ? new Set(
|
|
7609
|
+
order.flatMap(
|
|
7610
|
+
(col) => col.map((k) => parseFooterHrefKey(k)?.col).filter((n) => n !== void 0 && n !== null)
|
|
7611
|
+
)
|
|
7612
|
+
) : null;
|
|
7613
|
+
const indices = collectFooterColumnIndicesFromContent(content);
|
|
7614
|
+
for (const colIndex of indices) {
|
|
7615
|
+
if (allowedCols && !allowedCols.has(colIndex)) continue;
|
|
7616
|
+
if (footerColumnExistsInDom(colIndex)) continue;
|
|
7617
|
+
const heading = content[`footer-${colIndex}-heading`] ?? DEFAULT_FOOTER_COLUMN_HEADING;
|
|
7618
|
+
const items = collectFooterItemsForColumn(content, colIndex);
|
|
7619
|
+
const hasPayload = Boolean(content[`footer-${colIndex}-heading`]) || items.some(
|
|
7620
|
+
(_, i) => content[`footer-${colIndex}-${i}-href`] !== void 0 || content[`footer-${colIndex}-${i}-label`] !== void 0
|
|
7621
|
+
) || (order?.some((col) => col.some((k) => parseFooterHrefKey(k)?.col === colIndex)) ?? false);
|
|
7622
|
+
if (!hasPayload) continue;
|
|
7623
|
+
insertFooterColumnDom(colIndex, heading, items);
|
|
7624
|
+
}
|
|
7625
|
+
}
|
|
7126
7626
|
function reconcileFooterOrderFromContent(content) {
|
|
7627
|
+
reconcileFooterColumnsFromContent(content);
|
|
7127
7628
|
const order = parseFooterOrder(content);
|
|
7128
7629
|
if (!order?.length) return;
|
|
7129
|
-
const
|
|
7130
|
-
|
|
7131
|
-
|
|
7132
|
-
|
|
7630
|
+
const linkTemplate = getFooterLinkTemplate();
|
|
7631
|
+
for (let c = 0; c < order.length; c++) {
|
|
7632
|
+
const colOrder = order[c];
|
|
7633
|
+
for (const hrefKey of colOrder) {
|
|
7634
|
+
if (findFooterLinkByKey(hrefKey)) continue;
|
|
7635
|
+
const parsed = parseFooterHrefKey(hrefKey);
|
|
7636
|
+
if (!parsed) continue;
|
|
7637
|
+
const columns = listFooterColumns();
|
|
7638
|
+
const column = columns.find((col) => col.getAttribute("data-ohw-footer-col") === String(parsed.col)) ?? columns[c] ?? null;
|
|
7639
|
+
if (!column) continue;
|
|
7640
|
+
const href = content[hrefKey] ?? DEFAULT_FOOTER_COLUMN_LINK_HREF;
|
|
7641
|
+
const labelKey = `footer-${parsed.col}-${parsed.item}-label`;
|
|
7642
|
+
const label = content[labelKey] ?? DEFAULT_FOOTER_COLUMN_LINK_LABEL;
|
|
7643
|
+
if (!href && !label) continue;
|
|
7644
|
+
column.appendChild(buildFooterLink(parsed.col, parsed.item, href || "/", label, linkTemplate));
|
|
7645
|
+
}
|
|
7133
7646
|
}
|
|
7647
|
+
pruneFooterToOrder(order);
|
|
7134
7648
|
applyFooterOrder(order);
|
|
7135
7649
|
}
|
|
7136
|
-
function
|
|
7137
|
-
|
|
7138
|
-
const
|
|
7139
|
-
|
|
7140
|
-
|
|
7141
|
-
|
|
7650
|
+
function pruneFooterToOrder(order) {
|
|
7651
|
+
const allowedKeys = new Set(order.flat());
|
|
7652
|
+
const allowedColIndices = new Set(
|
|
7653
|
+
[...allowedKeys].map((k) => parseFooterHrefKey(k)?.col).filter((n) => n !== void 0 && n !== null)
|
|
7654
|
+
);
|
|
7655
|
+
for (const column of [...listFooterColumns()]) {
|
|
7656
|
+
if (!column.isConnected) continue;
|
|
7657
|
+
for (const link of [...listFooterLinksInColumn(column)]) {
|
|
7658
|
+
const key = link.getAttribute("data-ohw-href-key");
|
|
7659
|
+
if (!key || allowedKeys.has(key)) continue;
|
|
7660
|
+
link.remove();
|
|
7661
|
+
}
|
|
7662
|
+
const remaining = listFooterLinksInColumn(column);
|
|
7663
|
+
const colAttr = column.getAttribute("data-ohw-footer-col");
|
|
7664
|
+
const colIndex = colAttr != null ? parseInt(colAttr, 10) : NaN;
|
|
7665
|
+
const referenced = remaining.some((link) => allowedKeys.has(link.getAttribute("data-ohw-href-key") ?? ""));
|
|
7666
|
+
if (!referenced && (!Number.isFinite(colIndex) || !allowedColIndices.has(colIndex))) {
|
|
7667
|
+
column.remove();
|
|
7668
|
+
}
|
|
7669
|
+
}
|
|
7670
|
+
syncFooterColumnIndices(listFooterColumns());
|
|
7671
|
+
}
|
|
7672
|
+
function resolveFooterLinksContainerSelectionTarget(target, clientX, clientY, isPointOverItem) {
|
|
7673
|
+
const container = getFooterLinksContainer();
|
|
7674
|
+
if (!container) return null;
|
|
7675
|
+
const inContainer = target === container || container.contains(target) && Boolean(target.closest("[data-ohw-footer-links], .rb-footer-links"));
|
|
7676
|
+
if (!inContainer && target !== container) {
|
|
7677
|
+
const r2 = container.getBoundingClientRect();
|
|
7678
|
+
const over = clientX >= r2.left && clientX <= r2.right && clientY >= r2.top && clientY <= r2.bottom;
|
|
7679
|
+
if (!over) return null;
|
|
7680
|
+
}
|
|
7681
|
+
if (isPointOverItem(container, clientX, clientY)) return null;
|
|
7682
|
+
const column = target.closest("[data-ohw-footer-col], [data-ohw-footer-column]") ?? null;
|
|
7683
|
+
if (column && container.contains(column)) {
|
|
7684
|
+
if (target === column || column.contains(target)) return null;
|
|
7685
|
+
}
|
|
7686
|
+
if (target === container || container.contains(target) || inContainer) {
|
|
7687
|
+
if (target === container || isFooterLinksContainer(target)) return container;
|
|
7688
|
+
if (!column) return container;
|
|
7689
|
+
}
|
|
7690
|
+
return null;
|
|
7691
|
+
}
|
|
7692
|
+
function isRowLayoutColumn(links) {
|
|
7693
|
+
if (links.length < 2) return false;
|
|
7694
|
+
const firstTop = links[0].getBoundingClientRect().top;
|
|
7695
|
+
return links.every((link) => Math.abs(link.getBoundingClientRect().top - firstTop) < 4);
|
|
7696
|
+
}
|
|
7697
|
+
function buildLinkDropSlots(column, columnIndex) {
|
|
7142
7698
|
const links = listFooterLinksInColumn(column);
|
|
7143
7699
|
const colRect = column.getBoundingClientRect();
|
|
7144
7700
|
const slots = [];
|
|
@@ -7287,6 +7843,197 @@ function hitTestColumnDropSlot(clientX, _clientY) {
|
|
|
7287
7843
|
}
|
|
7288
7844
|
return best?.slot ?? null;
|
|
7289
7845
|
}
|
|
7846
|
+
function getLinkHref2(el) {
|
|
7847
|
+
const key = el.getAttribute("data-ohw-href-key");
|
|
7848
|
+
if (key) {
|
|
7849
|
+
const stored = getStoredLinkHref(key);
|
|
7850
|
+
if (stored !== void 0) return stored;
|
|
7851
|
+
}
|
|
7852
|
+
return el.getAttribute("href") ?? "";
|
|
7853
|
+
}
|
|
7854
|
+
function getNextFooterItemIndex(col) {
|
|
7855
|
+
let max = -1;
|
|
7856
|
+
for (const el of document.querySelectorAll("footer [data-ohw-href-key]")) {
|
|
7857
|
+
const parsed = parseFooterHrefKey(el.getAttribute("data-ohw-href-key"));
|
|
7858
|
+
if (!parsed || parsed.col !== col) continue;
|
|
7859
|
+
if (parsed.item > max) max = parsed.item;
|
|
7860
|
+
}
|
|
7861
|
+
return max + 1;
|
|
7862
|
+
}
|
|
7863
|
+
function cloneFooterLinkShell(template) {
|
|
7864
|
+
const anchor = document.createElement("a");
|
|
7865
|
+
if (template) {
|
|
7866
|
+
anchor.style.cssText = template.style.cssText;
|
|
7867
|
+
if (template.className) anchor.className = template.className;
|
|
7868
|
+
}
|
|
7869
|
+
anchor.style.cursor = "pointer";
|
|
7870
|
+
anchor.style.textDecoration = "none";
|
|
7871
|
+
return anchor;
|
|
7872
|
+
}
|
|
7873
|
+
function insertFooterItem(column, href, label, afterAnchor = null) {
|
|
7874
|
+
const columns = listFooterColumns();
|
|
7875
|
+
const colIndex = columns.indexOf(column);
|
|
7876
|
+
if (colIndex < 0) throw new Error("Footer column not found");
|
|
7877
|
+
const item = getNextFooterItemIndex(colIndex);
|
|
7878
|
+
const hrefKey = `footer-${colIndex}-${item}-href`;
|
|
7879
|
+
const labelKey = `footer-${colIndex}-${item}-label`;
|
|
7880
|
+
const template = listFooterLinksInColumn(column)[0] ?? null;
|
|
7881
|
+
const anchor = cloneFooterLinkShell(template);
|
|
7882
|
+
anchor.href = href;
|
|
7883
|
+
anchor.setAttribute("data-ohw-href-key", hrefKey);
|
|
7884
|
+
const span = document.createElement("span");
|
|
7885
|
+
span.setAttribute("data-ohw-editable", "text");
|
|
7886
|
+
span.setAttribute("data-ohw-key", labelKey);
|
|
7887
|
+
span.textContent = label;
|
|
7888
|
+
anchor.appendChild(span);
|
|
7889
|
+
if (afterAnchor && afterAnchor.parentElement === column) {
|
|
7890
|
+
afterAnchor.insertAdjacentElement("afterend", anchor);
|
|
7891
|
+
} else {
|
|
7892
|
+
column.appendChild(anchor);
|
|
7893
|
+
}
|
|
7894
|
+
const order = getFooterOrderFromDom();
|
|
7895
|
+
applyFooterOrder(order);
|
|
7896
|
+
return {
|
|
7897
|
+
anchor,
|
|
7898
|
+
col: colIndex,
|
|
7899
|
+
item,
|
|
7900
|
+
hrefKey,
|
|
7901
|
+
labelKey,
|
|
7902
|
+
href,
|
|
7903
|
+
label,
|
|
7904
|
+
order
|
|
7905
|
+
};
|
|
7906
|
+
}
|
|
7907
|
+
function duplicateFooterItem(sourceAnchor) {
|
|
7908
|
+
if (!isFooterLinkAnchor(sourceAnchor)) return null;
|
|
7909
|
+
const column = findFooterColumnForLink(sourceAnchor);
|
|
7910
|
+
if (!column) return null;
|
|
7911
|
+
const href = getLinkHref2(sourceAnchor);
|
|
7912
|
+
const labelEl = sourceAnchor.querySelector('[data-ohw-editable="text"]');
|
|
7913
|
+
const label = (labelEl?.textContent ?? "").trim() || "Untitled";
|
|
7914
|
+
return insertFooterItem(column, href || "/", label, sourceAnchor);
|
|
7915
|
+
}
|
|
7916
|
+
function footerLabelKeyFromHrefKey(hrefKey) {
|
|
7917
|
+
return hrefKey.replace(/-href$/, "-label");
|
|
7918
|
+
}
|
|
7919
|
+
function deleteFooterItem(sourceAnchor) {
|
|
7920
|
+
if (!isFooterLinkAnchor(sourceAnchor)) return null;
|
|
7921
|
+
const hrefKey = sourceAnchor.getAttribute("data-ohw-href-key");
|
|
7922
|
+
if (!hrefKey || !isFooterHrefKey(hrefKey)) return null;
|
|
7923
|
+
const labelEl = sourceAnchor.querySelector('[data-ohw-editable="text"]');
|
|
7924
|
+
const label = (labelEl?.textContent ?? "").trim() || "Untitled";
|
|
7925
|
+
const labelKey = footerLabelKeyFromHrefKey(hrefKey);
|
|
7926
|
+
const previousOrder = getFooterOrderFromDom();
|
|
7927
|
+
const previousOrderJson = JSON.stringify(previousOrder);
|
|
7928
|
+
const previousContent = {
|
|
7929
|
+
[hrefKey]: getLinkHref2(sourceAnchor),
|
|
7930
|
+
[labelKey]: label
|
|
7931
|
+
};
|
|
7932
|
+
if (!sourceAnchor.parentElement) return null;
|
|
7933
|
+
const placement = {
|
|
7934
|
+
node: sourceAnchor,
|
|
7935
|
+
parent: sourceAnchor.parentElement,
|
|
7936
|
+
nextSibling: sourceAnchor.nextSibling
|
|
7937
|
+
};
|
|
7938
|
+
sourceAnchor.remove();
|
|
7939
|
+
const order = getFooterOrderFromDom();
|
|
7940
|
+
applyFooterOrder(order);
|
|
7941
|
+
const orderJson = JSON.stringify(order);
|
|
7942
|
+
return {
|
|
7943
|
+
label,
|
|
7944
|
+
removedKeys: [hrefKey, labelKey],
|
|
7945
|
+
previousContent,
|
|
7946
|
+
orderJson,
|
|
7947
|
+
previousOrderJson,
|
|
7948
|
+
undo: () => {
|
|
7949
|
+
placement.parent.insertBefore(placement.node, placement.nextSibling);
|
|
7950
|
+
applyFooterOrder(previousOrder);
|
|
7951
|
+
}
|
|
7952
|
+
};
|
|
7953
|
+
}
|
|
7954
|
+
function deleteFooterColumn(column) {
|
|
7955
|
+
const columns = listFooterColumns();
|
|
7956
|
+
if (!columns.includes(column)) return null;
|
|
7957
|
+
if (!column.parentElement) return null;
|
|
7958
|
+
const links = listFooterLinksInColumn(column);
|
|
7959
|
+
const heading = column.querySelector(
|
|
7960
|
+
'[data-ohw-key^="footer-"][data-ohw-key$="-heading"]'
|
|
7961
|
+
);
|
|
7962
|
+
const headingKey = heading?.getAttribute("data-ohw-key") ?? null;
|
|
7963
|
+
const headingText = (heading?.textContent ?? "").trim();
|
|
7964
|
+
const label = headingText || (links[0]?.querySelector('[data-ohw-editable="text"]')?.textContent ?? "").trim() || "Untitled";
|
|
7965
|
+
const previousOrder = getFooterOrderFromDom();
|
|
7966
|
+
const previousOrderJson = JSON.stringify(previousOrder);
|
|
7967
|
+
const previousContent = {};
|
|
7968
|
+
const removedKeys = [];
|
|
7969
|
+
if (headingKey) {
|
|
7970
|
+
removedKeys.push(headingKey);
|
|
7971
|
+
previousContent[headingKey] = headingText;
|
|
7972
|
+
}
|
|
7973
|
+
for (const link of links) {
|
|
7974
|
+
const hrefKey = link.getAttribute("data-ohw-href-key");
|
|
7975
|
+
if (!hrefKey) continue;
|
|
7976
|
+
const labelKey = footerLabelKeyFromHrefKey(hrefKey);
|
|
7977
|
+
removedKeys.push(hrefKey, labelKey);
|
|
7978
|
+
previousContent[hrefKey] = getLinkHref2(link);
|
|
7979
|
+
previousContent[labelKey] = (link.querySelector('[data-ohw-editable="text"]')?.textContent ?? "").trim();
|
|
7980
|
+
}
|
|
7981
|
+
const placement = {
|
|
7982
|
+
node: column,
|
|
7983
|
+
parent: column.parentElement,
|
|
7984
|
+
nextSibling: column.nextSibling
|
|
7985
|
+
};
|
|
7986
|
+
column.remove();
|
|
7987
|
+
const remaining = listFooterColumns();
|
|
7988
|
+
syncFooterColumnIndices(remaining);
|
|
7989
|
+
const order = getFooterOrderFromDom();
|
|
7990
|
+
applyFooterOrder(order);
|
|
7991
|
+
const orderJson = JSON.stringify(order);
|
|
7992
|
+
return {
|
|
7993
|
+
label,
|
|
7994
|
+
removedKeys,
|
|
7995
|
+
previousContent,
|
|
7996
|
+
orderJson,
|
|
7997
|
+
previousOrderJson,
|
|
7998
|
+
undo: () => {
|
|
7999
|
+
placement.parent.insertBefore(placement.node, placement.nextSibling);
|
|
8000
|
+
syncFooterColumnIndices(listFooterColumns());
|
|
8001
|
+
applyFooterOrder(previousOrder);
|
|
8002
|
+
}
|
|
8003
|
+
};
|
|
8004
|
+
}
|
|
8005
|
+
|
|
8006
|
+
// src/lib/add-footer-column.ts
|
|
8007
|
+
function buildFooterColumnEditContentPatch(result) {
|
|
8008
|
+
return {
|
|
8009
|
+
[result.headingKey]: result.heading,
|
|
8010
|
+
[result.hrefKey]: result.href,
|
|
8011
|
+
[result.labelKey]: result.label,
|
|
8012
|
+
[FOOTER_ORDER_KEY]: JSON.stringify(result.order)
|
|
8013
|
+
};
|
|
8014
|
+
}
|
|
8015
|
+
function addFooterColumnWithPersist({
|
|
8016
|
+
postToParent: postToParent2
|
|
8017
|
+
}) {
|
|
8018
|
+
if (!canAddFooterColumn()) {
|
|
8019
|
+
postToParent2({
|
|
8020
|
+
type: "ow:toast",
|
|
8021
|
+
title: `Maximum ${MAX_FOOTER_COLUMNS} columns`,
|
|
8022
|
+
toastType: "error"
|
|
8023
|
+
});
|
|
8024
|
+
return null;
|
|
8025
|
+
}
|
|
8026
|
+
const result = insertFooterColumn();
|
|
8027
|
+
const patch = buildFooterColumnEditContentPatch(result);
|
|
8028
|
+
setStoredLinkHref(result.hrefKey, result.href);
|
|
8029
|
+
postToParent2({
|
|
8030
|
+
type: "ow:change",
|
|
8031
|
+
nodes: Object.entries(patch).map(([key, text]) => ({ key, text }))
|
|
8032
|
+
});
|
|
8033
|
+
postToParent2({ type: "ow:toast", title: "Item added", toastType: "success" });
|
|
8034
|
+
enforceLinkHrefs();
|
|
8035
|
+
return result;
|
|
8036
|
+
}
|
|
7290
8037
|
|
|
7291
8038
|
// src/lib/item-drag-interaction.ts
|
|
7292
8039
|
function disableNativeHrefDrag(el) {
|
|
@@ -7485,7 +8232,7 @@ function hitTestNavDropSlot(clientX, clientY, draggedHrefKey) {
|
|
|
7485
8232
|
}
|
|
7486
8233
|
|
|
7487
8234
|
// src/useNavItemDrag.ts
|
|
7488
|
-
var
|
|
8235
|
+
var import_react9 = require("react");
|
|
7489
8236
|
function useNavItemDrag({
|
|
7490
8237
|
isEditMode,
|
|
7491
8238
|
editContentRef,
|
|
@@ -7510,11 +8257,11 @@ function useNavItemDrag({
|
|
|
7510
8257
|
isDragHandleDisabled: isDragHandleDisabled2,
|
|
7511
8258
|
isNavbarButton: isNavbarButton3
|
|
7512
8259
|
}) {
|
|
7513
|
-
const navDragRef = (0,
|
|
7514
|
-
const [navDropSlots, setNavDropSlots] = (0,
|
|
7515
|
-
const [activeNavDropIndex, setActiveNavDropIndex] = (0,
|
|
7516
|
-
const navPointerDragRef = (0,
|
|
7517
|
-
const clearNavDragVisuals = (0,
|
|
8260
|
+
const navDragRef = (0, import_react9.useRef)(null);
|
|
8261
|
+
const [navDropSlots, setNavDropSlots] = (0, import_react9.useState)([]);
|
|
8262
|
+
const [activeNavDropIndex, setActiveNavDropIndex] = (0, import_react9.useState)(null);
|
|
8263
|
+
const navPointerDragRef = (0, import_react9.useRef)(null);
|
|
8264
|
+
const clearNavDragVisuals = (0, import_react9.useCallback)(() => {
|
|
7518
8265
|
navDragRef.current = null;
|
|
7519
8266
|
setNavDropSlots([]);
|
|
7520
8267
|
setActiveNavDropIndex(null);
|
|
@@ -7523,7 +8270,7 @@ function useNavItemDrag({
|
|
|
7523
8270
|
setIsItemDragging(false);
|
|
7524
8271
|
unlockItemDragInteraction();
|
|
7525
8272
|
}, [setDraggedItemRect, setIsItemDragging, setSiblingHintRects]);
|
|
7526
|
-
const refreshNavDragVisuals = (0,
|
|
8273
|
+
const refreshNavDragVisuals = (0, import_react9.useCallback)(
|
|
7527
8274
|
(session, activeSlot, clientX, clientY) => {
|
|
7528
8275
|
setDraggedItemRect(session.draggedEl.getBoundingClientRect());
|
|
7529
8276
|
if (typeof clientX === "number" && typeof clientY === "number") {
|
|
@@ -7541,13 +8288,13 @@ function useNavItemDrag({
|
|
|
7541
8288
|
},
|
|
7542
8289
|
[setDraggedItemRect, setSiblingHintRects]
|
|
7543
8290
|
);
|
|
7544
|
-
const refreshNavDragVisualsRef = (0,
|
|
8291
|
+
const refreshNavDragVisualsRef = (0, import_react9.useRef)(refreshNavDragVisuals);
|
|
7545
8292
|
refreshNavDragVisualsRef.current = refreshNavDragVisuals;
|
|
7546
|
-
const commitNavDragRef = (0,
|
|
8293
|
+
const commitNavDragRef = (0, import_react9.useRef)(() => {
|
|
7547
8294
|
});
|
|
7548
|
-
const beginNavDragRef = (0,
|
|
8295
|
+
const beginNavDragRef = (0, import_react9.useRef)(() => {
|
|
7549
8296
|
});
|
|
7550
|
-
const beginNavDrag = (0,
|
|
8297
|
+
const beginNavDrag = (0, import_react9.useCallback)(
|
|
7551
8298
|
(session) => {
|
|
7552
8299
|
const rect = session.draggedEl.getBoundingClientRect();
|
|
7553
8300
|
session.lastClientX = session.lastClientX || rect.left + rect.width / 2;
|
|
@@ -7574,7 +8321,7 @@ function useNavItemDrag({
|
|
|
7574
8321
|
]
|
|
7575
8322
|
);
|
|
7576
8323
|
beginNavDragRef.current = beginNavDrag;
|
|
7577
|
-
const commitNavDrag = (0,
|
|
8324
|
+
const commitNavDrag = (0, import_react9.useCallback)(
|
|
7578
8325
|
(clientX, clientY) => {
|
|
7579
8326
|
const session = navDragRef.current;
|
|
7580
8327
|
if (!session) {
|
|
@@ -7635,7 +8382,7 @@ function useNavItemDrag({
|
|
|
7635
8382
|
[clearNavDragVisuals, deselectRef, editContentRef, postToParentRef, selectRef]
|
|
7636
8383
|
);
|
|
7637
8384
|
commitNavDragRef.current = commitNavDrag;
|
|
7638
|
-
const startNavLinkDrag = (0,
|
|
8385
|
+
const startNavLinkDrag = (0, import_react9.useCallback)(
|
|
7639
8386
|
(anchor, clientX, clientY, wasSelected) => {
|
|
7640
8387
|
if (footerDragRef.current) return false;
|
|
7641
8388
|
const hrefKey = anchor.getAttribute("data-ohw-href-key");
|
|
@@ -7653,7 +8400,7 @@ function useNavItemDrag({
|
|
|
7653
8400
|
},
|
|
7654
8401
|
[beginNavDrag, footerDragRef, isDragHandleDisabled2, isNavbarButton3]
|
|
7655
8402
|
);
|
|
7656
|
-
const onNavDragOver = (0,
|
|
8403
|
+
const onNavDragOver = (0, import_react9.useCallback)(
|
|
7657
8404
|
(e) => {
|
|
7658
8405
|
const session = navDragRef.current;
|
|
7659
8406
|
if (!session) return false;
|
|
@@ -7665,7 +8412,7 @@ function useNavItemDrag({
|
|
|
7665
8412
|
},
|
|
7666
8413
|
[]
|
|
7667
8414
|
);
|
|
7668
|
-
(0,
|
|
8415
|
+
(0, import_react9.useEffect)(() => {
|
|
7669
8416
|
if (!isEditMode) return;
|
|
7670
8417
|
const THRESHOLD = 10;
|
|
7671
8418
|
const resolveWasSelected = (el) => {
|
|
@@ -7790,7 +8537,7 @@ function useNavItemDrag({
|
|
|
7790
8537
|
setLinkPopover,
|
|
7791
8538
|
suppressNextClickRef
|
|
7792
8539
|
]);
|
|
7793
|
-
const armNavPressFromChrome = (0,
|
|
8540
|
+
const armNavPressFromChrome = (0, import_react9.useCallback)(
|
|
7794
8541
|
(selected, clientX, clientY, pointerId) => {
|
|
7795
8542
|
const hrefKey = selected.getAttribute("data-ohw-href-key");
|
|
7796
8543
|
if (!hrefKey || !isNavbarHrefKey(hrefKey)) return false;
|
|
@@ -7820,8 +8567,59 @@ function useNavItemDrag({
|
|
|
7820
8567
|
};
|
|
7821
8568
|
}
|
|
7822
8569
|
|
|
8570
|
+
// src/ui/footer-container-chrome.tsx
|
|
8571
|
+
var import_lucide_react11 = require("lucide-react");
|
|
8572
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
8573
|
+
function FooterContainerChrome({
|
|
8574
|
+
rect,
|
|
8575
|
+
onAdd,
|
|
8576
|
+
addDisabled = false
|
|
8577
|
+
}) {
|
|
8578
|
+
const chromeGap = 6;
|
|
8579
|
+
const buttonMargin = 7;
|
|
8580
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8581
|
+
"div",
|
|
8582
|
+
{
|
|
8583
|
+
"data-ohw-footer-container-chrome": "",
|
|
8584
|
+
"data-ohw-bridge": "",
|
|
8585
|
+
className: "pointer-events-none fixed z-[2147483647]",
|
|
8586
|
+
style: {
|
|
8587
|
+
top: rect.top - chromeGap,
|
|
8588
|
+
left: rect.left - chromeGap,
|
|
8589
|
+
width: rect.width + chromeGap * 2,
|
|
8590
|
+
height: rect.height + chromeGap * 2
|
|
8591
|
+
},
|
|
8592
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(Tooltip, { children: [
|
|
8593
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8594
|
+
"button",
|
|
8595
|
+
{
|
|
8596
|
+
type: "button",
|
|
8597
|
+
"data-ohw-footer-add-button": "",
|
|
8598
|
+
disabled: addDisabled,
|
|
8599
|
+
className: "pointer-events-auto absolute left-1/2 flex size-7 -translate-x-1/2 -translate-y-full items-center justify-center rounded-[10px] border border-border bg-background p-0.5 shadow-sm transition-colors hover:bg-muted/80 disabled:pointer-events-none disabled:opacity-40",
|
|
8600
|
+
style: { top: chromeGap - buttonMargin },
|
|
8601
|
+
"aria-label": "Add item",
|
|
8602
|
+
onMouseDown: (e) => {
|
|
8603
|
+
e.preventDefault();
|
|
8604
|
+
e.stopPropagation();
|
|
8605
|
+
},
|
|
8606
|
+
onClick: (e) => {
|
|
8607
|
+
e.preventDefault();
|
|
8608
|
+
e.stopPropagation();
|
|
8609
|
+
if (addDisabled) return;
|
|
8610
|
+
onAdd();
|
|
8611
|
+
},
|
|
8612
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react11.Plus, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
|
|
8613
|
+
}
|
|
8614
|
+
) }),
|
|
8615
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TooltipContent, { side: "bottom", sideOffset: 9, children: addDisabled ? "Maximum columns reached" : "Add item" })
|
|
8616
|
+
] })
|
|
8617
|
+
}
|
|
8618
|
+
) });
|
|
8619
|
+
}
|
|
8620
|
+
|
|
7823
8621
|
// src/lib/carousel.ts
|
|
7824
|
-
var
|
|
8622
|
+
var import_react10 = require("react");
|
|
7825
8623
|
var CAROUSEL_ATTR = "data-ohw-carousel";
|
|
7826
8624
|
var CAROUSEL_VALUE_ATTR = "data-ohw-carousel-value";
|
|
7827
8625
|
var CAROUSEL_SLIDE_ATTR = "data-ohw-carousel-slide";
|
|
@@ -7883,8 +8681,8 @@ function applyCarouselNode(key, val) {
|
|
|
7883
8681
|
return true;
|
|
7884
8682
|
}
|
|
7885
8683
|
function useOhwCarousel(key, initial) {
|
|
7886
|
-
const [images, setImages] = (0,
|
|
7887
|
-
(0,
|
|
8684
|
+
const [images, setImages] = (0, import_react10.useState)(initial);
|
|
8685
|
+
(0, import_react10.useEffect)(() => {
|
|
7888
8686
|
const el = document.querySelector(
|
|
7889
8687
|
`[${CAROUSEL_ATTR}][data-ohw-key="${CSS.escape(key)}"]`
|
|
7890
8688
|
);
|
|
@@ -7904,15 +8702,340 @@ function useOhwCarousel(key, initial) {
|
|
|
7904
8702
|
return { images, setImages, bind };
|
|
7905
8703
|
}
|
|
7906
8704
|
|
|
8705
|
+
// src/lib/collect-editable-nodes.ts
|
|
8706
|
+
var VIDEO_AUTOPLAY_SUFFIX = "__ohw_autoplay";
|
|
8707
|
+
var VIDEO_MUTED_SUFFIX = "__ohw_muted";
|
|
8708
|
+
function getVideoEl(el) {
|
|
8709
|
+
return el instanceof HTMLVideoElement ? el : el.querySelector("video");
|
|
8710
|
+
}
|
|
8711
|
+
function getLinkHref3(el) {
|
|
8712
|
+
const key = el.getAttribute("data-ohw-href-key");
|
|
8713
|
+
if (key) {
|
|
8714
|
+
const stored = getStoredLinkHref(key);
|
|
8715
|
+
if (stored !== void 0) return stored;
|
|
8716
|
+
}
|
|
8717
|
+
const anchor = el instanceof HTMLAnchorElement ? el : el.querySelector("a");
|
|
8718
|
+
return anchor?.getAttribute("href") ?? "";
|
|
8719
|
+
}
|
|
8720
|
+
function collectEditableNodes(extraContent) {
|
|
8721
|
+
const nodes = Array.from(
|
|
8722
|
+
document.querySelectorAll("[data-ohw-editable]")
|
|
8723
|
+
).map((el) => {
|
|
8724
|
+
if (el.dataset.ohwEditable === "image") {
|
|
8725
|
+
const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
|
|
8726
|
+
return { key: el.dataset.ohwKey ?? "", type: "image", text: img?.src ?? "" };
|
|
8727
|
+
}
|
|
8728
|
+
if (el.dataset.ohwEditable === "bg-image") {
|
|
8729
|
+
const raw = el.style.backgroundImage;
|
|
8730
|
+
const url = raw.replace(/^url\(['"]?/, "").replace(/['"]?\)$/, "");
|
|
8731
|
+
return { key: el.dataset.ohwKey ?? "", type: "bg-image", text: url };
|
|
8732
|
+
}
|
|
8733
|
+
if (el.dataset.ohwEditable === "video") {
|
|
8734
|
+
return { key: el.dataset.ohwKey ?? "", type: "video", text: getVideoEl(el)?.src ?? "" };
|
|
8735
|
+
}
|
|
8736
|
+
if (el.dataset.ohwEditable === "link") {
|
|
8737
|
+
return { key: el.dataset.ohwKey ?? "", type: "link", text: getLinkHref3(el) };
|
|
8738
|
+
}
|
|
8739
|
+
return {
|
|
8740
|
+
key: el.dataset.ohwKey ?? "",
|
|
8741
|
+
type: el.dataset.ohwEditable ?? "text",
|
|
8742
|
+
text: el.dataset.ohwEditable === "plain" ? el.innerText ?? "" : el.innerHTML
|
|
8743
|
+
};
|
|
8744
|
+
});
|
|
8745
|
+
document.querySelectorAll("[data-ohw-href-key]").forEach((el) => {
|
|
8746
|
+
const key = el.getAttribute("data-ohw-href-key") ?? "";
|
|
8747
|
+
if (!key) return;
|
|
8748
|
+
nodes.push({ key, type: "link", text: getLinkHref3(el) });
|
|
8749
|
+
});
|
|
8750
|
+
if (extraContent) {
|
|
8751
|
+
for (const key of [NAV_ORDER_KEY, FOOTER_ORDER_KEY, NAV_COUNT_KEY]) {
|
|
8752
|
+
const text = extraContent[key];
|
|
8753
|
+
if (typeof text === "string" && text.length > 0) {
|
|
8754
|
+
nodes.push({ key, type: "meta", text });
|
|
8755
|
+
}
|
|
8756
|
+
}
|
|
8757
|
+
}
|
|
8758
|
+
document.querySelectorAll('[data-ohw-editable="video"]').forEach((el) => {
|
|
8759
|
+
const key = el.dataset.ohwKey ?? "";
|
|
8760
|
+
const video = getVideoEl(el);
|
|
8761
|
+
if (!key || !video) return;
|
|
8762
|
+
nodes.push({
|
|
8763
|
+
key: `${key}${VIDEO_AUTOPLAY_SUFFIX}`,
|
|
8764
|
+
type: "video-setting",
|
|
8765
|
+
text: String(video.autoplay)
|
|
8766
|
+
});
|
|
8767
|
+
nodes.push({
|
|
8768
|
+
key: `${key}${VIDEO_MUTED_SUFFIX}`,
|
|
8769
|
+
type: "video-setting",
|
|
8770
|
+
text: String(video.muted)
|
|
8771
|
+
});
|
|
8772
|
+
});
|
|
8773
|
+
for (const key of listCarouselKeys()) {
|
|
8774
|
+
nodes.push({ key, type: "carousel", text: JSON.stringify(readCarouselValue(key)) });
|
|
8775
|
+
}
|
|
8776
|
+
const byKey = /* @__PURE__ */ new Map();
|
|
8777
|
+
for (const node of nodes) {
|
|
8778
|
+
if (!node.key) continue;
|
|
8779
|
+
if (!byKey.has(node.key)) byKey.set(node.key, node);
|
|
8780
|
+
}
|
|
8781
|
+
if (extraContent) {
|
|
8782
|
+
applyNavFooterDeleteOverrides(byKey, extraContent);
|
|
8783
|
+
}
|
|
8784
|
+
return Array.from(byKey.values());
|
|
8785
|
+
}
|
|
8786
|
+
function applyNavFooterDeleteOverrides(byKey, content) {
|
|
8787
|
+
for (const [key, text] of Object.entries(content)) {
|
|
8788
|
+
if (text !== "") continue;
|
|
8789
|
+
if (!key.startsWith("nav-") && !key.startsWith("footer-")) continue;
|
|
8790
|
+
if (key === "nav-book-href" || key === "nav-book-label") continue;
|
|
8791
|
+
byKey.set(key, { key, type: "meta", text: "" });
|
|
8792
|
+
}
|
|
8793
|
+
const navOrder = content[NAV_ORDER_KEY];
|
|
8794
|
+
if (navOrder) {
|
|
8795
|
+
try {
|
|
8796
|
+
const allowed = parseAllowedNavHrefKeys(navOrder);
|
|
8797
|
+
const clearKey = (key) => {
|
|
8798
|
+
byKey.set(key, { key, type: "meta", text: "" });
|
|
8799
|
+
};
|
|
8800
|
+
for (const key of /* @__PURE__ */ new Set([...byKey.keys(), ...Object.keys(content)])) {
|
|
8801
|
+
if (key === "nav-book-href" || key === "nav-book-label") continue;
|
|
8802
|
+
if (isNavbarHrefKey(key) && !allowed.has(key)) {
|
|
8803
|
+
clearKey(key);
|
|
8804
|
+
clearKey(key.replace(/-href$/, "-label"));
|
|
8805
|
+
} else if (/^nav-\d+-label$/.test(key)) {
|
|
8806
|
+
const hrefKey = key.replace(/-label$/, "-href");
|
|
8807
|
+
if (!allowed.has(hrefKey)) clearKey(key);
|
|
8808
|
+
}
|
|
8809
|
+
}
|
|
8810
|
+
} catch {
|
|
8811
|
+
}
|
|
8812
|
+
}
|
|
8813
|
+
const footerOrder = content[FOOTER_ORDER_KEY];
|
|
8814
|
+
if (footerOrder) {
|
|
8815
|
+
try {
|
|
8816
|
+
const { allowedKeys, allowedCols } = parseAllowedFooterKeys(footerOrder);
|
|
8817
|
+
const clearKey = (key) => {
|
|
8818
|
+
byKey.set(key, { key, type: "meta", text: "" });
|
|
8819
|
+
};
|
|
8820
|
+
for (const key of /* @__PURE__ */ new Set([...byKey.keys(), ...Object.keys(content)])) {
|
|
8821
|
+
if (isFooterHrefKey(key) && !allowedKeys.has(key)) {
|
|
8822
|
+
clearKey(key);
|
|
8823
|
+
clearKey(key.replace(/-href$/, "-label"));
|
|
8824
|
+
continue;
|
|
8825
|
+
}
|
|
8826
|
+
const labelMatch = key.match(/^footer-(\d+)-(\d+)-label$/);
|
|
8827
|
+
if (labelMatch) {
|
|
8828
|
+
const hrefKey = `footer-${labelMatch[1]}-${labelMatch[2]}-href`;
|
|
8829
|
+
if (!allowedKeys.has(hrefKey)) clearKey(key);
|
|
8830
|
+
continue;
|
|
8831
|
+
}
|
|
8832
|
+
const headingMatch = key.match(/^footer-(\d+)-heading$/);
|
|
8833
|
+
if (headingMatch && !allowedCols.has(parseInt(headingMatch[1], 10))) {
|
|
8834
|
+
clearKey(key);
|
|
8835
|
+
}
|
|
8836
|
+
}
|
|
8837
|
+
} catch {
|
|
8838
|
+
}
|
|
8839
|
+
}
|
|
8840
|
+
}
|
|
8841
|
+
function parseAllowedNavHrefKeys(raw) {
|
|
8842
|
+
const parsed = JSON.parse(raw);
|
|
8843
|
+
const allowed = /* @__PURE__ */ new Set();
|
|
8844
|
+
const walk = (nodes) => {
|
|
8845
|
+
if (!Array.isArray(nodes)) return;
|
|
8846
|
+
for (const node of nodes) {
|
|
8847
|
+
if (typeof node === "string" && node.length > 0) {
|
|
8848
|
+
allowed.add(node);
|
|
8849
|
+
continue;
|
|
8850
|
+
}
|
|
8851
|
+
if (node && typeof node === "object" && typeof node.id === "string") {
|
|
8852
|
+
allowed.add(node.id);
|
|
8853
|
+
walk(node.children);
|
|
8854
|
+
}
|
|
8855
|
+
}
|
|
8856
|
+
};
|
|
8857
|
+
walk(parsed);
|
|
8858
|
+
return allowed;
|
|
8859
|
+
}
|
|
8860
|
+
function parseAllowedFooterKeys(raw) {
|
|
8861
|
+
const parsed = JSON.parse(raw);
|
|
8862
|
+
const allowedKeys = /* @__PURE__ */ new Set();
|
|
8863
|
+
const allowedCols = /* @__PURE__ */ new Set();
|
|
8864
|
+
if (Array.isArray(parsed)) {
|
|
8865
|
+
for (const col of parsed) {
|
|
8866
|
+
if (!Array.isArray(col)) continue;
|
|
8867
|
+
for (const key of col) {
|
|
8868
|
+
if (typeof key !== "string" || !key) continue;
|
|
8869
|
+
allowedKeys.add(key);
|
|
8870
|
+
const m = key.match(/^footer-(\d+)-\d+-href$/);
|
|
8871
|
+
if (m) allowedCols.add(parseInt(m[1], 10));
|
|
8872
|
+
}
|
|
8873
|
+
}
|
|
8874
|
+
}
|
|
8875
|
+
return { allowedKeys, allowedCols };
|
|
8876
|
+
}
|
|
8877
|
+
|
|
8878
|
+
// src/lib/delete-nav-footer-selection.ts
|
|
8879
|
+
function isNavbarLinksContainer(el) {
|
|
8880
|
+
return el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-nav-drawer");
|
|
8881
|
+
}
|
|
8882
|
+
function isNavigationItem(el) {
|
|
8883
|
+
const anchor = el.matches("[data-ohw-href-key]") ? el : el.closest("[data-ohw-href-key]");
|
|
8884
|
+
if (!anchor) return false;
|
|
8885
|
+
return Boolean(anchor.querySelector('[data-ohw-editable="text"]'));
|
|
8886
|
+
}
|
|
8887
|
+
function findFooterItemGroup(item) {
|
|
8888
|
+
const explicit = item.closest("[data-ohw-footer-col], [data-ohw-footer-column]");
|
|
8889
|
+
if (explicit) return explicit;
|
|
8890
|
+
const footer = item.closest("footer");
|
|
8891
|
+
if (!footer) return null;
|
|
8892
|
+
let node = item.parentElement;
|
|
8893
|
+
while (node && node !== footer) {
|
|
8894
|
+
const count = Array.from(node.querySelectorAll("[data-ohw-href-key]")).filter(
|
|
8895
|
+
isNavigationItem
|
|
8896
|
+
).length;
|
|
8897
|
+
if (count >= 2) return node;
|
|
8898
|
+
node = node.parentElement;
|
|
8899
|
+
}
|
|
8900
|
+
return footer;
|
|
8901
|
+
}
|
|
8902
|
+
function isInferredFooterGroup(el) {
|
|
8903
|
+
const footer = el.closest("footer");
|
|
8904
|
+
if (!footer || el === footer) return false;
|
|
8905
|
+
if (el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column")) return true;
|
|
8906
|
+
const count = Array.from(el.querySelectorAll("[data-ohw-href-key]")).filter(
|
|
8907
|
+
isNavigationItem
|
|
8908
|
+
).length;
|
|
8909
|
+
return count >= 2;
|
|
8910
|
+
}
|
|
8911
|
+
function newActionId() {
|
|
8912
|
+
return typeof crypto !== "undefined" && "randomUUID" in crypto ? crypto.randomUUID() : `delete-${Date.now()}`;
|
|
8913
|
+
}
|
|
8914
|
+
function deleteSelectedNavFooterItem(deps) {
|
|
8915
|
+
const {
|
|
8916
|
+
selected,
|
|
8917
|
+
isTextEditing,
|
|
8918
|
+
isSelectFrame,
|
|
8919
|
+
getEditContent,
|
|
8920
|
+
applyLinkByKey: applyLinkByKey2,
|
|
8921
|
+
postToParent: postToParent2,
|
|
8922
|
+
deselect,
|
|
8923
|
+
setEditContent,
|
|
8924
|
+
setPendingUndo
|
|
8925
|
+
} = deps;
|
|
8926
|
+
if (isTextEditing) return false;
|
|
8927
|
+
if (isNavbarLinksContainer(selected) || isFooterLinksContainer(selected)) return false;
|
|
8928
|
+
const finishDelete = (opts) => {
|
|
8929
|
+
const actionId = newActionId();
|
|
8930
|
+
const clearedNodes = opts.removedKeys.map((key) => ({
|
|
8931
|
+
key,
|
|
8932
|
+
text: ""
|
|
8933
|
+
}));
|
|
8934
|
+
clearedNodes.push({ key: opts.orderKey, text: opts.orderJson });
|
|
8935
|
+
const nextContent = { ...getEditContent() };
|
|
8936
|
+
for (const key of opts.removedKeys) {
|
|
8937
|
+
nextContent[key] = "";
|
|
8938
|
+
clearStoredLinkHref(key);
|
|
8939
|
+
}
|
|
8940
|
+
nextContent[opts.orderKey] = opts.orderJson;
|
|
8941
|
+
setEditContent(nextContent);
|
|
8942
|
+
postToParent2({ type: "ow:change", nodes: clearedNodes });
|
|
8943
|
+
setPendingUndo({
|
|
8944
|
+
actionId,
|
|
8945
|
+
restore: () => {
|
|
8946
|
+
opts.undoDom();
|
|
8947
|
+
for (const [key, text] of Object.entries(opts.previousContent)) {
|
|
8948
|
+
if (key.endsWith("-href")) applyLinkByKey2(key, text);
|
|
8949
|
+
else {
|
|
8950
|
+
document.querySelectorAll(`[data-ohw-key="${CSS.escape(key)}"]`).forEach((el) => {
|
|
8951
|
+
el.textContent = text;
|
|
8952
|
+
});
|
|
8953
|
+
}
|
|
8954
|
+
}
|
|
8955
|
+
setEditContent({
|
|
8956
|
+
...getEditContent(),
|
|
8957
|
+
...opts.previousContent,
|
|
8958
|
+
[opts.orderKey]: opts.previousOrderJson
|
|
8959
|
+
});
|
|
8960
|
+
postToParent2({
|
|
8961
|
+
type: "ow:change",
|
|
8962
|
+
nodes: [
|
|
8963
|
+
...Object.entries(opts.previousContent).map(([key, text]) => ({ key, text })),
|
|
8964
|
+
{ key: opts.orderKey, text: opts.previousOrderJson }
|
|
8965
|
+
]
|
|
8966
|
+
});
|
|
8967
|
+
}
|
|
8968
|
+
});
|
|
8969
|
+
deselect();
|
|
8970
|
+
postToParent2({
|
|
8971
|
+
type: "ow:toast",
|
|
8972
|
+
title: opts.toastTitle,
|
|
8973
|
+
toastType: "success",
|
|
8974
|
+
actionLabel: "Undo",
|
|
8975
|
+
actionId,
|
|
8976
|
+
duration: 6e3
|
|
8977
|
+
});
|
|
8978
|
+
};
|
|
8979
|
+
const isFooterColumnSelection = selected.hasAttribute("data-ohw-footer-col") || selected.hasAttribute("data-ohw-footer-column") || isSelectFrame && isInferredFooterGroup(selected) && Boolean(selected.closest("footer"));
|
|
8980
|
+
if (isFooterColumnSelection) {
|
|
8981
|
+
const column = selected.hasAttribute("data-ohw-footer-col") || selected.hasAttribute("data-ohw-footer-column") ? selected : findFooterItemGroup(selected);
|
|
8982
|
+
if (!column) return false;
|
|
8983
|
+
const result = deleteFooterColumn(column);
|
|
8984
|
+
if (!result) return false;
|
|
8985
|
+
finishDelete({
|
|
8986
|
+
toastTitle: "Item deleted",
|
|
8987
|
+
removedKeys: result.removedKeys,
|
|
8988
|
+
previousContent: result.previousContent,
|
|
8989
|
+
orderKey: FOOTER_ORDER_KEY,
|
|
8990
|
+
orderJson: result.orderJson,
|
|
8991
|
+
previousOrderJson: result.previousOrderJson,
|
|
8992
|
+
undoDom: result.undo
|
|
8993
|
+
});
|
|
8994
|
+
return true;
|
|
8995
|
+
}
|
|
8996
|
+
if (!isNavigationItem(selected)) return false;
|
|
8997
|
+
const hrefKey = selected.getAttribute("data-ohw-href-key");
|
|
8998
|
+
if (!hrefKey) return false;
|
|
8999
|
+
if (isNavbarHrefKey(hrefKey)) {
|
|
9000
|
+
const result = deleteNavbarItem(selected);
|
|
9001
|
+
if (!result) return false;
|
|
9002
|
+
finishDelete({
|
|
9003
|
+
toastTitle: "Nav item deleted",
|
|
9004
|
+
removedKeys: result.removedKeys,
|
|
9005
|
+
previousContent: result.previousContent,
|
|
9006
|
+
orderKey: NAV_ORDER_KEY,
|
|
9007
|
+
orderJson: result.orderJson,
|
|
9008
|
+
previousOrderJson: result.previousOrderJson,
|
|
9009
|
+
undoDom: result.undo
|
|
9010
|
+
});
|
|
9011
|
+
return true;
|
|
9012
|
+
}
|
|
9013
|
+
if (isFooterHrefKey(hrefKey)) {
|
|
9014
|
+
const result = deleteFooterItem(selected);
|
|
9015
|
+
if (!result) return false;
|
|
9016
|
+
finishDelete({
|
|
9017
|
+
toastTitle: "Item deleted",
|
|
9018
|
+
removedKeys: result.removedKeys,
|
|
9019
|
+
previousContent: result.previousContent,
|
|
9020
|
+
orderKey: FOOTER_ORDER_KEY,
|
|
9021
|
+
orderJson: result.orderJson,
|
|
9022
|
+
previousOrderJson: result.previousOrderJson,
|
|
9023
|
+
undoDom: result.undo
|
|
9024
|
+
});
|
|
9025
|
+
return true;
|
|
9026
|
+
}
|
|
9027
|
+
return false;
|
|
9028
|
+
}
|
|
9029
|
+
|
|
7907
9030
|
// src/ui/navbar-container-chrome.tsx
|
|
7908
|
-
var
|
|
7909
|
-
var
|
|
9031
|
+
var import_lucide_react12 = require("lucide-react");
|
|
9032
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
7910
9033
|
function NavbarContainerChrome({
|
|
7911
9034
|
rect,
|
|
7912
9035
|
onAdd
|
|
7913
9036
|
}) {
|
|
7914
9037
|
const chromeGap = 6;
|
|
7915
|
-
return /* @__PURE__ */ (0,
|
|
9038
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
7916
9039
|
"div",
|
|
7917
9040
|
{
|
|
7918
9041
|
"data-ohw-navbar-container-chrome": "",
|
|
@@ -7924,7 +9047,7 @@ function NavbarContainerChrome({
|
|
|
7924
9047
|
width: rect.width + chromeGap * 2,
|
|
7925
9048
|
height: rect.height + chromeGap * 2
|
|
7926
9049
|
},
|
|
7927
|
-
children: /* @__PURE__ */ (0,
|
|
9050
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
7928
9051
|
"button",
|
|
7929
9052
|
{
|
|
7930
9053
|
type: "button",
|
|
@@ -7941,7 +9064,7 @@ function NavbarContainerChrome({
|
|
|
7941
9064
|
e.stopPropagation();
|
|
7942
9065
|
onAdd();
|
|
7943
9066
|
},
|
|
7944
|
-
children: /* @__PURE__ */ (0,
|
|
9067
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react12.Plus, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
|
|
7945
9068
|
}
|
|
7946
9069
|
)
|
|
7947
9070
|
}
|
|
@@ -7950,7 +9073,7 @@ function NavbarContainerChrome({
|
|
|
7950
9073
|
|
|
7951
9074
|
// src/ui/drop-indicator.tsx
|
|
7952
9075
|
var React10 = __toESM(require("react"), 1);
|
|
7953
|
-
var
|
|
9076
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
7954
9077
|
var dropIndicatorVariants = cva(
|
|
7955
9078
|
"ov-gap-line pointer-events-none shrink-0 transition-opacity duration-150",
|
|
7956
9079
|
{
|
|
@@ -7974,7 +9097,7 @@ var dropIndicatorVariants = cva(
|
|
|
7974
9097
|
);
|
|
7975
9098
|
var DropIndicator = React10.forwardRef(
|
|
7976
9099
|
({ className, direction, state, ...props }, ref) => {
|
|
7977
|
-
return /* @__PURE__ */ (0,
|
|
9100
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
7978
9101
|
"div",
|
|
7979
9102
|
{
|
|
7980
9103
|
ref,
|
|
@@ -7991,7 +9114,7 @@ var DropIndicator = React10.forwardRef(
|
|
|
7991
9114
|
DropIndicator.displayName = "DropIndicator";
|
|
7992
9115
|
|
|
7993
9116
|
// src/ui/badge.tsx
|
|
7994
|
-
var
|
|
9117
|
+
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
7995
9118
|
var badgeVariants = cva(
|
|
7996
9119
|
"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",
|
|
7997
9120
|
{
|
|
@@ -8009,12 +9132,12 @@ var badgeVariants = cva(
|
|
|
8009
9132
|
}
|
|
8010
9133
|
);
|
|
8011
9134
|
function Badge({ className, variant, ...props }) {
|
|
8012
|
-
return /* @__PURE__ */ (0,
|
|
9135
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: cn(badgeVariants({ variant }), className), ...props });
|
|
8013
9136
|
}
|
|
8014
9137
|
|
|
8015
9138
|
// src/OhhwellsBridge.tsx
|
|
8016
|
-
var
|
|
8017
|
-
var
|
|
9139
|
+
var import_lucide_react13 = require("lucide-react");
|
|
9140
|
+
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
8018
9141
|
var PRIMARY2 = "#0885FE";
|
|
8019
9142
|
var IMAGE_FADE_MS = 300;
|
|
8020
9143
|
function runOpacityFade(el, onDone) {
|
|
@@ -8193,7 +9316,7 @@ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId,
|
|
|
8193
9316
|
const root = (0, import_client.createRoot)(container);
|
|
8194
9317
|
(0, import_react_dom2.flushSync)(() => {
|
|
8195
9318
|
root.render(
|
|
8196
|
-
/* @__PURE__ */ (0,
|
|
9319
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
8197
9320
|
SchedulingWidget,
|
|
8198
9321
|
{
|
|
8199
9322
|
notifyOnConnect,
|
|
@@ -8233,7 +9356,7 @@ function mountSchedulingEntries(entries, notifyOnConnect = false) {
|
|
|
8233
9356
|
}
|
|
8234
9357
|
}
|
|
8235
9358
|
}
|
|
8236
|
-
function
|
|
9359
|
+
function getLinkHref4(el) {
|
|
8237
9360
|
const anchor = el instanceof HTMLAnchorElement ? el : el.querySelector("a");
|
|
8238
9361
|
return anchor?.getAttribute("href") ?? "";
|
|
8239
9362
|
}
|
|
@@ -8261,78 +9384,22 @@ function canDragNavigationItem(anchor) {
|
|
|
8261
9384
|
}
|
|
8262
9385
|
function syncNavigationDragCursorAttrs() {
|
|
8263
9386
|
document.querySelectorAll("nav [data-ohw-href-key], footer [data-ohw-href-key]").forEach((el) => {
|
|
8264
|
-
if (!
|
|
9387
|
+
if (!isNavigationItem2(el) || !canDragNavigationItem(el)) {
|
|
8265
9388
|
el.removeAttribute("data-ohw-can-drag");
|
|
8266
9389
|
return;
|
|
8267
9390
|
}
|
|
8268
9391
|
el.setAttribute("data-ohw-can-drag", "");
|
|
8269
9392
|
});
|
|
8270
9393
|
}
|
|
8271
|
-
function collectEditableNodes(extraContent) {
|
|
8272
|
-
const nodes = Array.from(document.querySelectorAll("[data-ohw-editable]")).map((el) => {
|
|
8273
|
-
if (el.dataset.ohwEditable === "image") {
|
|
8274
|
-
const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
|
|
8275
|
-
return { key: el.dataset.ohwKey ?? "", type: "image", text: img?.src ?? "" };
|
|
8276
|
-
}
|
|
8277
|
-
if (el.dataset.ohwEditable === "bg-image") {
|
|
8278
|
-
const raw = el.style.backgroundImage;
|
|
8279
|
-
const url = raw.replace(/^url\(['"]?/, "").replace(/['"]?\)$/, "");
|
|
8280
|
-
return { key: el.dataset.ohwKey ?? "", type: "bg-image", text: url };
|
|
8281
|
-
}
|
|
8282
|
-
if (el.dataset.ohwEditable === "video") {
|
|
8283
|
-
return { key: el.dataset.ohwKey ?? "", type: "video", text: getVideoEl(el)?.src ?? "" };
|
|
8284
|
-
}
|
|
8285
|
-
if (el.dataset.ohwEditable === "link") {
|
|
8286
|
-
return { key: el.dataset.ohwKey ?? "", type: "link", text: getLinkHref2(el) };
|
|
8287
|
-
}
|
|
8288
|
-
return {
|
|
8289
|
-
key: el.dataset.ohwKey ?? "",
|
|
8290
|
-
type: el.dataset.ohwEditable ?? "text",
|
|
8291
|
-
text: el.dataset.ohwEditable === "plain" ? el.innerText ?? "" : el.innerHTML
|
|
8292
|
-
};
|
|
8293
|
-
});
|
|
8294
|
-
document.querySelectorAll("[data-ohw-href-key]").forEach((el) => {
|
|
8295
|
-
const key = el.getAttribute("data-ohw-href-key") ?? "";
|
|
8296
|
-
if (!key) return;
|
|
8297
|
-
nodes.push({ key, type: "link", text: getLinkHref2(el) });
|
|
8298
|
-
});
|
|
8299
|
-
if (extraContent) {
|
|
8300
|
-
for (const key of [NAV_ORDER_KEY, FOOTER_ORDER_KEY, NAV_COUNT_KEY]) {
|
|
8301
|
-
const text = extraContent[key];
|
|
8302
|
-
if (typeof text === "string" && text.length > 0) {
|
|
8303
|
-
nodes.push({ key, type: "meta", text });
|
|
8304
|
-
}
|
|
8305
|
-
}
|
|
8306
|
-
}
|
|
8307
|
-
document.querySelectorAll('[data-ohw-editable="video"]').forEach((el) => {
|
|
8308
|
-
const key = el.dataset.ohwKey ?? "";
|
|
8309
|
-
const video = getVideoEl(el);
|
|
8310
|
-
if (!key || !video) return;
|
|
8311
|
-
nodes.push({ key: `${key}${VIDEO_AUTOPLAY_SUFFIX}`, type: "video-setting", text: String(video.autoplay) });
|
|
8312
|
-
nodes.push({ key: `${key}${VIDEO_MUTED_SUFFIX}`, type: "video-setting", text: String(video.muted) });
|
|
8313
|
-
});
|
|
8314
|
-
for (const key of listCarouselKeys()) {
|
|
8315
|
-
nodes.push({ key, type: "carousel", text: JSON.stringify(readCarouselValue(key)) });
|
|
8316
|
-
}
|
|
8317
|
-
const seen = /* @__PURE__ */ new Set();
|
|
8318
|
-
return nodes.filter((node) => {
|
|
8319
|
-
if (!node.key) return true;
|
|
8320
|
-
if (seen.has(node.key)) return false;
|
|
8321
|
-
seen.add(node.key);
|
|
8322
|
-
return true;
|
|
8323
|
-
});
|
|
8324
|
-
}
|
|
8325
9394
|
function isMediaEditable(el) {
|
|
8326
9395
|
const t = el.dataset.ohwEditable;
|
|
8327
9396
|
return t === "image" || t === "bg-image" || t === "video";
|
|
8328
9397
|
}
|
|
8329
9398
|
var MEDIA_SELECTOR = '[data-ohw-editable="image"], [data-ohw-editable="bg-image"], [data-ohw-editable="video"]';
|
|
8330
9399
|
var NON_MEDIA_SELECTOR = '[data-ohw-editable]:not([data-ohw-editable="image"]):not([data-ohw-editable="bg-image"]):not([data-ohw-editable="video"])';
|
|
8331
|
-
function
|
|
9400
|
+
function getVideoEl2(el) {
|
|
8332
9401
|
return el instanceof HTMLVideoElement ? el : el.querySelector("video");
|
|
8333
9402
|
}
|
|
8334
|
-
var VIDEO_AUTOPLAY_SUFFIX = "__ohw_autoplay";
|
|
8335
|
-
var VIDEO_MUTED_SUFFIX = "__ohw_muted";
|
|
8336
9403
|
function isBackgroundVideo(video) {
|
|
8337
9404
|
return video.autoplay && video.muted;
|
|
8338
9405
|
}
|
|
@@ -8377,7 +9444,7 @@ function applyVideoSettingNode(key, val) {
|
|
|
8377
9444
|
const baseKey = key.slice(0, key.length - suffixLen);
|
|
8378
9445
|
const on = val === "true";
|
|
8379
9446
|
document.querySelectorAll(`[data-ohw-key="${baseKey}"]`).forEach((el) => {
|
|
8380
|
-
const video =
|
|
9447
|
+
const video = getVideoEl2(el);
|
|
8381
9448
|
if (!video) return;
|
|
8382
9449
|
if (isAutoplay) video.autoplay = on;
|
|
8383
9450
|
else video.muted = on;
|
|
@@ -8397,7 +9464,7 @@ function applyLinkByKey(key, val) {
|
|
|
8397
9464
|
}
|
|
8398
9465
|
function isInsideLinkEditor(target) {
|
|
8399
9466
|
return Boolean(
|
|
8400
|
-
target.closest("[data-ohw-link-popover-root]") || target.closest("[data-ohw-link-modal-root]") || target.closest("[data-ohw-link-page-dropdown]") || target.closest("[data-ohw-section-picker]") || target.closest("[data-ohw-navbar-container-chrome]") || target.closest("[data-ohw-navbar-add-button]") || target.closest('[data-slot="popover-content"]') || target.closest('[data-slot="dialog-content"]') || target.closest('[data-slot="dialog-overlay"]')
|
|
9467
|
+
target.closest("[data-ohw-link-popover-root]") || target.closest("[data-ohw-link-modal-root]") || target.closest("[data-ohw-link-page-dropdown]") || target.closest("[data-ohw-section-picker]") || target.closest("[data-ohw-navbar-container-chrome]") || target.closest("[data-ohw-navbar-add-button]") || target.closest("[data-ohw-footer-container-chrome]") || target.closest("[data-ohw-footer-add-button]") || target.closest("[data-ohw-more-menu]") || target.closest('[data-slot="dropdown-menu-content"]') || target.closest('[data-slot="popover-content"]') || target.closest('[data-slot="dialog-content"]') || target.closest('[data-slot="dialog-overlay"]')
|
|
8401
9468
|
);
|
|
8402
9469
|
}
|
|
8403
9470
|
function getHrefKeyFromElement(el) {
|
|
@@ -8417,13 +9484,13 @@ function getNavigationItemAnchor(el) {
|
|
|
8417
9484
|
if (!anchor.querySelector('[data-ohw-editable="text"]')) return null;
|
|
8418
9485
|
return anchor;
|
|
8419
9486
|
}
|
|
8420
|
-
function
|
|
9487
|
+
function isNavigationItem2(el) {
|
|
8421
9488
|
return getNavigationItemAnchor(el) !== null;
|
|
8422
9489
|
}
|
|
8423
9490
|
function listNavigationItems() {
|
|
8424
9491
|
return Array.from(
|
|
8425
9492
|
document.querySelectorAll("nav [data-ohw-href-key], footer [data-ohw-href-key]")
|
|
8426
|
-
).filter((el) =>
|
|
9493
|
+
).filter((el) => isNavigationItem2(el));
|
|
8427
9494
|
}
|
|
8428
9495
|
function getNavigationItemReorderState(anchor) {
|
|
8429
9496
|
if (isNavbarButton2(anchor)) return { key: null, disabled: false };
|
|
@@ -8454,9 +9521,9 @@ function getNavigationRoot(el) {
|
|
|
8454
9521
|
return el.closest("nav, footer, aside");
|
|
8455
9522
|
}
|
|
8456
9523
|
function countFooterNavItems(el) {
|
|
8457
|
-
return Array.from(el.querySelectorAll("[data-ohw-href-key]")).filter(
|
|
9524
|
+
return Array.from(el.querySelectorAll("[data-ohw-href-key]")).filter(isNavigationItem2).length;
|
|
8458
9525
|
}
|
|
8459
|
-
function
|
|
9526
|
+
function findFooterItemGroup2(item) {
|
|
8460
9527
|
const explicit = item.closest("[data-ohw-footer-col], [data-ohw-footer-column]");
|
|
8461
9528
|
if (explicit) return explicit;
|
|
8462
9529
|
const footer = item.closest("footer");
|
|
@@ -8471,16 +9538,16 @@ function findFooterItemGroup(item) {
|
|
|
8471
9538
|
function isNavigationRoot(el) {
|
|
8472
9539
|
return el.hasAttribute("data-ohw-nav-root") || el.matches("nav, footer, aside");
|
|
8473
9540
|
}
|
|
8474
|
-
function
|
|
9541
|
+
function isInferredFooterGroup2(el) {
|
|
8475
9542
|
const footer = el.closest("footer");
|
|
8476
9543
|
if (!footer || el === footer) return false;
|
|
8477
9544
|
if (el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column")) return true;
|
|
8478
9545
|
return countFooterNavItems(el) >= 2;
|
|
8479
9546
|
}
|
|
8480
9547
|
function isNavigationContainer(el) {
|
|
8481
|
-
return el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isNavigationRoot(el) ||
|
|
9548
|
+
return el.hasAttribute("data-ohw-nav-container") || isFooterLinksContainer(el) || el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isNavigationRoot(el) || isInferredFooterGroup2(el);
|
|
8482
9549
|
}
|
|
8483
|
-
function
|
|
9550
|
+
function isNavbarLinksContainer2(el) {
|
|
8484
9551
|
return el.hasAttribute("data-ohw-nav-container");
|
|
8485
9552
|
}
|
|
8486
9553
|
function getFooterColumn(el) {
|
|
@@ -8497,6 +9564,9 @@ function isPointOverNavigation(x, y) {
|
|
|
8497
9564
|
const roots = /* @__PURE__ */ new Set();
|
|
8498
9565
|
const navRoot = document.querySelector("[data-ohw-nav-root]") ?? document.querySelector("nav");
|
|
8499
9566
|
if (navRoot) roots.add(navRoot);
|
|
9567
|
+
document.querySelectorAll("[data-ohw-nav-drawer], [data-ohw-nav-container]").forEach((el) => {
|
|
9568
|
+
roots.add(el);
|
|
9569
|
+
});
|
|
8500
9570
|
const footer = document.querySelector("footer");
|
|
8501
9571
|
if (footer) roots.add(footer);
|
|
8502
9572
|
for (const root of roots) {
|
|
@@ -8520,11 +9590,17 @@ function findHoveredNavOrFooterContainer(x, y) {
|
|
|
8520
9590
|
}
|
|
8521
9591
|
function isPointOverNavItem(container, x, y) {
|
|
8522
9592
|
return Array.from(container.querySelectorAll("[data-ohw-href-key]")).some((el) => {
|
|
8523
|
-
if (!
|
|
9593
|
+
if (!isNavigationItem2(el) || isNavbarButton2(el)) return false;
|
|
8524
9594
|
const itemRect = el.getBoundingClientRect();
|
|
8525
9595
|
return x >= itemRect.left && x <= itemRect.right && y >= itemRect.top && y <= itemRect.bottom;
|
|
8526
9596
|
});
|
|
8527
9597
|
}
|
|
9598
|
+
function isPointOverFooterColumn(x, y) {
|
|
9599
|
+
return listFooterColumns().some((col) => {
|
|
9600
|
+
const r2 = col.getBoundingClientRect();
|
|
9601
|
+
return x >= r2.left && x <= r2.right && y >= r2.top && y <= r2.bottom;
|
|
9602
|
+
});
|
|
9603
|
+
}
|
|
8528
9604
|
function resolveNavContainerSelectionTarget(target, clientX, clientY) {
|
|
8529
9605
|
if (getNavigationItemAnchor(target)) return null;
|
|
8530
9606
|
if (target.closest('[data-ohw-role="navbar-button"]')) return null;
|
|
@@ -8546,29 +9622,32 @@ function resolveNavContainerSelectionTarget(target, clientX, clientY) {
|
|
|
8546
9622
|
return null;
|
|
8547
9623
|
}
|
|
8548
9624
|
function getNavigationSelectionParent(el) {
|
|
8549
|
-
if (
|
|
9625
|
+
if (isNavigationItem2(el)) {
|
|
8550
9626
|
const explicit = el.closest("[data-ohw-nav-container]");
|
|
8551
9627
|
if (explicit) return explicit;
|
|
8552
9628
|
const footerColumn = getFooterColumn(el);
|
|
8553
9629
|
if (footerColumn) return footerColumn;
|
|
8554
|
-
const footerGroup =
|
|
9630
|
+
const footerGroup = findFooterItemGroup2(el);
|
|
8555
9631
|
if (footerGroup) return footerGroup;
|
|
8556
9632
|
return getNavigationRoot(el);
|
|
8557
9633
|
}
|
|
8558
|
-
if (el
|
|
9634
|
+
if (!isFooterLinksContainer(el) && (el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isInferredFooterGroup2(el))) {
|
|
9635
|
+
return getFooterLinksContainer();
|
|
9636
|
+
}
|
|
9637
|
+
if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isFooterLinksContainer(el) || isInferredFooterGroup2(el)) {
|
|
8559
9638
|
return getNavigationRoot(el);
|
|
8560
9639
|
}
|
|
8561
9640
|
return null;
|
|
8562
9641
|
}
|
|
8563
9642
|
function collectNavigationItemSiblingHintRects(selected) {
|
|
8564
|
-
if (!
|
|
9643
|
+
if (!isNavigationItem2(selected)) return [];
|
|
8565
9644
|
const footerColumn = getFooterColumn(selected);
|
|
8566
9645
|
if (footerColumn) {
|
|
8567
9646
|
return listFooterLinksInColumn(footerColumn).filter((link) => link !== selected).map((link) => link.getBoundingClientRect());
|
|
8568
9647
|
}
|
|
8569
9648
|
const navContainer = selected.closest("[data-ohw-nav-container], [data-ohw-nav-drawer]");
|
|
8570
9649
|
if (navContainer) {
|
|
8571
|
-
return Array.from(navContainer.querySelectorAll("[data-ohw-href-key]")).filter((el) =>
|
|
9650
|
+
return Array.from(navContainer.querySelectorAll("[data-ohw-href-key]")).filter((el) => isNavigationItem2(el) && el !== selected).map((el) => el.getBoundingClientRect());
|
|
8572
9651
|
}
|
|
8573
9652
|
return listNavigationItems().filter((el) => el !== selected).map((el) => el.getBoundingClientRect());
|
|
8574
9653
|
}
|
|
@@ -8782,7 +9861,7 @@ function EditGlowChrome({
|
|
|
8782
9861
|
hideHandle = false
|
|
8783
9862
|
}) {
|
|
8784
9863
|
const GAP = SELECTION_CHROME_GAP2;
|
|
8785
|
-
return /* @__PURE__ */ (0,
|
|
9864
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
|
|
8786
9865
|
"div",
|
|
8787
9866
|
{
|
|
8788
9867
|
ref: elRef,
|
|
@@ -8797,7 +9876,7 @@ function EditGlowChrome({
|
|
|
8797
9876
|
zIndex: 2147483646
|
|
8798
9877
|
},
|
|
8799
9878
|
children: [
|
|
8800
|
-
/* @__PURE__ */ (0,
|
|
9879
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
8801
9880
|
"div",
|
|
8802
9881
|
{
|
|
8803
9882
|
style: {
|
|
@@ -8810,7 +9889,7 @@ function EditGlowChrome({
|
|
|
8810
9889
|
}
|
|
8811
9890
|
}
|
|
8812
9891
|
),
|
|
8813
|
-
reorderHrefKey && !hideHandle && /* @__PURE__ */ (0,
|
|
9892
|
+
reorderHrefKey && !hideHandle && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
8814
9893
|
"div",
|
|
8815
9894
|
{
|
|
8816
9895
|
"data-ohw-drag-handle-container": "",
|
|
@@ -8822,7 +9901,7 @@ function EditGlowChrome({
|
|
|
8822
9901
|
transform: "translate(calc(-100% - 7px), -50%)",
|
|
8823
9902
|
pointerEvents: dragDisabled ? "none" : "auto"
|
|
8824
9903
|
},
|
|
8825
|
-
children: /* @__PURE__ */ (0,
|
|
9904
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
8826
9905
|
DragHandle,
|
|
8827
9906
|
{
|
|
8828
9907
|
"aria-label": `Reorder ${reorderHrefKey}`,
|
|
@@ -9005,9 +10084,9 @@ function FloatingToolbar({
|
|
|
9005
10084
|
showEditLink,
|
|
9006
10085
|
onEditLink
|
|
9007
10086
|
}) {
|
|
9008
|
-
const localRef =
|
|
9009
|
-
const [measuredW, setMeasuredW] =
|
|
9010
|
-
const setRefs =
|
|
10087
|
+
const localRef = import_react11.default.useRef(null);
|
|
10088
|
+
const [measuredW, setMeasuredW] = import_react11.default.useState(330);
|
|
10089
|
+
const setRefs = import_react11.default.useCallback(
|
|
9011
10090
|
(node) => {
|
|
9012
10091
|
localRef.current = node;
|
|
9013
10092
|
if (typeof elRef === "function") elRef(node);
|
|
@@ -9019,7 +10098,7 @@ function FloatingToolbar({
|
|
|
9019
10098
|
},
|
|
9020
10099
|
[elRef]
|
|
9021
10100
|
);
|
|
9022
|
-
|
|
10101
|
+
import_react11.default.useLayoutEffect(() => {
|
|
9023
10102
|
const node = localRef.current;
|
|
9024
10103
|
if (!node) return;
|
|
9025
10104
|
const update = () => {
|
|
@@ -9032,7 +10111,7 @@ function FloatingToolbar({
|
|
|
9032
10111
|
return () => ro.disconnect();
|
|
9033
10112
|
}, [showEditLink, activeCommands]);
|
|
9034
10113
|
const { top, left, transform } = calcToolbarPos(rect, parentScroll, measuredW);
|
|
9035
|
-
return /* @__PURE__ */ (0,
|
|
10114
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
9036
10115
|
"div",
|
|
9037
10116
|
{
|
|
9038
10117
|
ref: setRefs,
|
|
@@ -9044,12 +10123,12 @@ function FloatingToolbar({
|
|
|
9044
10123
|
zIndex: 2147483647,
|
|
9045
10124
|
pointerEvents: "auto"
|
|
9046
10125
|
},
|
|
9047
|
-
children: /* @__PURE__ */ (0,
|
|
9048
|
-
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ (0,
|
|
9049
|
-
gi > 0 && /* @__PURE__ */ (0,
|
|
10126
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(CustomToolbar, { children: [
|
|
10127
|
+
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_react11.default.Fragment, { children: [
|
|
10128
|
+
gi > 0 && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(CustomToolbarDivider, {}),
|
|
9050
10129
|
btns.map((btn) => {
|
|
9051
10130
|
const isActive = activeCommands.has(btn.cmd);
|
|
9052
|
-
return /* @__PURE__ */ (0,
|
|
10131
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
9053
10132
|
CustomToolbarButton,
|
|
9054
10133
|
{
|
|
9055
10134
|
title: btn.title,
|
|
@@ -9058,7 +10137,7 @@ function FloatingToolbar({
|
|
|
9058
10137
|
e.preventDefault();
|
|
9059
10138
|
onCommand(btn.cmd);
|
|
9060
10139
|
},
|
|
9061
|
-
children: /* @__PURE__ */ (0,
|
|
10140
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
9062
10141
|
"svg",
|
|
9063
10142
|
{
|
|
9064
10143
|
width: "16",
|
|
@@ -9079,7 +10158,7 @@ function FloatingToolbar({
|
|
|
9079
10158
|
);
|
|
9080
10159
|
})
|
|
9081
10160
|
] }, gi)),
|
|
9082
|
-
showEditLink ? /* @__PURE__ */ (0,
|
|
10161
|
+
showEditLink ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
9083
10162
|
CustomToolbarButton,
|
|
9084
10163
|
{
|
|
9085
10164
|
type: "button",
|
|
@@ -9093,7 +10172,7 @@ function FloatingToolbar({
|
|
|
9093
10172
|
e.preventDefault();
|
|
9094
10173
|
e.stopPropagation();
|
|
9095
10174
|
},
|
|
9096
|
-
children: /* @__PURE__ */ (0,
|
|
10175
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react13.Link, { className: "size-4 shrink-0", "aria-hidden": true })
|
|
9097
10176
|
}
|
|
9098
10177
|
) : null
|
|
9099
10178
|
] })
|
|
@@ -9110,7 +10189,7 @@ function StateToggle({
|
|
|
9110
10189
|
states,
|
|
9111
10190
|
onStateChange
|
|
9112
10191
|
}) {
|
|
9113
|
-
return /* @__PURE__ */ (0,
|
|
10192
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
9114
10193
|
ToggleGroup,
|
|
9115
10194
|
{
|
|
9116
10195
|
"data-ohw-state-toggle": "",
|
|
@@ -9124,7 +10203,7 @@ function StateToggle({
|
|
|
9124
10203
|
left: rect.right - 8,
|
|
9125
10204
|
transform: "translateX(-100%)"
|
|
9126
10205
|
},
|
|
9127
|
-
children: states.map((state) => /* @__PURE__ */ (0,
|
|
10206
|
+
children: states.map((state) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ToggleGroupItem, { value: state, size: "sm", children: state }, state))
|
|
9128
10207
|
}
|
|
9129
10208
|
);
|
|
9130
10209
|
}
|
|
@@ -9151,8 +10230,8 @@ function OhhwellsBridge() {
|
|
|
9151
10230
|
const router = (0, import_navigation2.useRouter)();
|
|
9152
10231
|
const searchParams = (0, import_navigation2.useSearchParams)();
|
|
9153
10232
|
const isEditMode = isEditSessionActive();
|
|
9154
|
-
const [bridgeRoot, setBridgeRoot] = (0,
|
|
9155
|
-
(0,
|
|
10233
|
+
const [bridgeRoot, setBridgeRoot] = (0, import_react11.useState)(null);
|
|
10234
|
+
(0, import_react11.useEffect)(() => {
|
|
9156
10235
|
const figtreeFontId = "ohw-figtree-font";
|
|
9157
10236
|
if (!document.getElementById(figtreeFontId)) {
|
|
9158
10237
|
const preconnect1 = Object.assign(document.createElement("link"), { rel: "preconnect", href: "https://fonts.googleapis.com" });
|
|
@@ -9180,99 +10259,104 @@ function OhhwellsBridge() {
|
|
|
9180
10259
|
const subdomainFromQuery = searchParams.get("subdomain");
|
|
9181
10260
|
const subdomain = resolveSubdomain(subdomainFromQuery);
|
|
9182
10261
|
useLinkHrefGuardian(pathname, subdomain, isEditMode);
|
|
9183
|
-
const postToParent2 = (0,
|
|
10262
|
+
const postToParent2 = (0, import_react11.useCallback)((data) => {
|
|
9184
10263
|
if (typeof window !== "undefined" && window.parent !== window) {
|
|
9185
10264
|
window.parent.postMessage(data, "*");
|
|
9186
10265
|
}
|
|
9187
10266
|
}, []);
|
|
9188
|
-
const [fetchState, setFetchState] = (0,
|
|
9189
|
-
const autoSaveTimers = (0,
|
|
9190
|
-
const activeElRef = (0,
|
|
9191
|
-
const pointerHeldRef = (0,
|
|
9192
|
-
const selectedElRef = (0,
|
|
9193
|
-
const selectedHrefKeyRef = (0,
|
|
9194
|
-
const selectedFooterColAttrRef = (0,
|
|
9195
|
-
const originalContentRef = (0,
|
|
9196
|
-
const activeStateElRef = (0,
|
|
9197
|
-
const parentScrollRef = (0,
|
|
9198
|
-
const visibleViewportRef = (0,
|
|
9199
|
-
const [dialogPortalContainer, setDialogPortalContainer] = (0,
|
|
9200
|
-
const attachVisibleViewport = (0,
|
|
10267
|
+
const [fetchState, setFetchState] = (0, import_react11.useState)("idle");
|
|
10268
|
+
const autoSaveTimers = (0, import_react11.useRef)(/* @__PURE__ */ new Map());
|
|
10269
|
+
const activeElRef = (0, import_react11.useRef)(null);
|
|
10270
|
+
const pointerHeldRef = (0, import_react11.useRef)(false);
|
|
10271
|
+
const selectedElRef = (0, import_react11.useRef)(null);
|
|
10272
|
+
const selectedHrefKeyRef = (0, import_react11.useRef)(null);
|
|
10273
|
+
const selectedFooterColAttrRef = (0, import_react11.useRef)(null);
|
|
10274
|
+
const originalContentRef = (0, import_react11.useRef)(null);
|
|
10275
|
+
const activeStateElRef = (0, import_react11.useRef)(null);
|
|
10276
|
+
const parentScrollRef = (0, import_react11.useRef)(null);
|
|
10277
|
+
const visibleViewportRef = (0, import_react11.useRef)(null);
|
|
10278
|
+
const [dialogPortalContainer, setDialogPortalContainer] = (0, import_react11.useState)(null);
|
|
10279
|
+
const attachVisibleViewport = (0, import_react11.useCallback)((node) => {
|
|
9201
10280
|
visibleViewportRef.current = node;
|
|
9202
10281
|
setDialogPortalContainer(node);
|
|
9203
10282
|
if (node) applyVisibleViewport(node, parentScrollRef.current);
|
|
9204
10283
|
}, []);
|
|
9205
|
-
const toolbarElRef = (0,
|
|
9206
|
-
const glowElRef = (0,
|
|
9207
|
-
const hoveredImageRef = (0,
|
|
9208
|
-
const hoveredImageHasTextOverlapRef = (0,
|
|
9209
|
-
const dragOverElRef = (0,
|
|
9210
|
-
const [mediaHover, setMediaHover] = (0,
|
|
9211
|
-
const [carouselHover, setCarouselHover] = (0,
|
|
9212
|
-
const [uploadingRects, setUploadingRects] = (0,
|
|
9213
|
-
const hoveredGapRef = (0,
|
|
9214
|
-
const imageUnhoverTimerRef = (0,
|
|
9215
|
-
const imageShowTimerRef = (0,
|
|
9216
|
-
const editStylesRef = (0,
|
|
9217
|
-
const activateRef = (0,
|
|
10284
|
+
const toolbarElRef = (0, import_react11.useRef)(null);
|
|
10285
|
+
const glowElRef = (0, import_react11.useRef)(null);
|
|
10286
|
+
const hoveredImageRef = (0, import_react11.useRef)(null);
|
|
10287
|
+
const hoveredImageHasTextOverlapRef = (0, import_react11.useRef)(false);
|
|
10288
|
+
const dragOverElRef = (0, import_react11.useRef)(null);
|
|
10289
|
+
const [mediaHover, setMediaHover] = (0, import_react11.useState)(null);
|
|
10290
|
+
const [carouselHover, setCarouselHover] = (0, import_react11.useState)(null);
|
|
10291
|
+
const [uploadingRects, setUploadingRects] = (0, import_react11.useState)({});
|
|
10292
|
+
const hoveredGapRef = (0, import_react11.useRef)(null);
|
|
10293
|
+
const imageUnhoverTimerRef = (0, import_react11.useRef)(null);
|
|
10294
|
+
const imageShowTimerRef = (0, import_react11.useRef)(null);
|
|
10295
|
+
const editStylesRef = (0, import_react11.useRef)(null);
|
|
10296
|
+
const activateRef = (0, import_react11.useRef)(() => {
|
|
9218
10297
|
});
|
|
9219
|
-
const deactivateRef = (0,
|
|
10298
|
+
const deactivateRef = (0, import_react11.useRef)(() => {
|
|
9220
10299
|
});
|
|
9221
|
-
const selectRef = (0,
|
|
10300
|
+
const selectRef = (0, import_react11.useRef)(() => {
|
|
9222
10301
|
});
|
|
9223
|
-
const selectFrameRef = (0,
|
|
10302
|
+
const selectFrameRef = (0, import_react11.useRef)(() => {
|
|
9224
10303
|
});
|
|
9225
|
-
const deselectRef = (0,
|
|
10304
|
+
const deselectRef = (0, import_react11.useRef)(() => {
|
|
9226
10305
|
});
|
|
9227
|
-
const reselectNavigationItemRef = (0,
|
|
10306
|
+
const reselectNavigationItemRef = (0, import_react11.useRef)(() => {
|
|
9228
10307
|
});
|
|
9229
|
-
const commitNavigationTextEditRef = (0,
|
|
10308
|
+
const commitNavigationTextEditRef = (0, import_react11.useRef)(() => {
|
|
9230
10309
|
});
|
|
9231
|
-
const
|
|
10310
|
+
const handleDeleteSelectedRef = (0, import_react11.useRef)(() => false);
|
|
10311
|
+
const runPendingDeleteUndoRef = (0, import_react11.useRef)(() => false);
|
|
10312
|
+
const isFooterFrameSelectionRef = (0, import_react11.useRef)(false);
|
|
10313
|
+
const refreshActiveCommandsRef = (0, import_react11.useRef)(() => {
|
|
9232
10314
|
});
|
|
9233
|
-
const postToParentRef = (0,
|
|
10315
|
+
const postToParentRef = (0, import_react11.useRef)(postToParent2);
|
|
9234
10316
|
postToParentRef.current = postToParent2;
|
|
9235
|
-
const sectionsLoadedRef = (0,
|
|
9236
|
-
const pendingScheduleConfigRequests = (0,
|
|
9237
|
-
const [toolbarRect, setToolbarRect] = (0,
|
|
9238
|
-
const [toolbarVariant, setToolbarVariant] = (0,
|
|
9239
|
-
const toolbarVariantRef = (0,
|
|
10317
|
+
const sectionsLoadedRef = (0, import_react11.useRef)(false);
|
|
10318
|
+
const pendingScheduleConfigRequests = (0, import_react11.useRef)([]);
|
|
10319
|
+
const [toolbarRect, setToolbarRect] = (0, import_react11.useState)(null);
|
|
10320
|
+
const [toolbarVariant, setToolbarVariant] = (0, import_react11.useState)("none");
|
|
10321
|
+
const toolbarVariantRef = (0, import_react11.useRef)("none");
|
|
9240
10322
|
toolbarVariantRef.current = toolbarVariant;
|
|
9241
|
-
const [selectedIsCta, setSelectedIsCta] = (0,
|
|
9242
|
-
const [reorderHrefKey, setReorderHrefKey] = (0,
|
|
9243
|
-
const [reorderDragDisabled, setReorderDragDisabled] = (0,
|
|
9244
|
-
const [toggleState, setToggleState] = (0,
|
|
9245
|
-
const [maxBadge, setMaxBadge] = (0,
|
|
9246
|
-
const [activeCommands, setActiveCommands] = (0,
|
|
9247
|
-
const [sectionGap, setSectionGap] = (0,
|
|
9248
|
-
const [toolbarShowEditLink, setToolbarShowEditLink] = (0,
|
|
9249
|
-
const hoveredNavContainerRef = (0,
|
|
9250
|
-
const [hoveredNavContainerRect, setHoveredNavContainerRect] = (0,
|
|
9251
|
-
const hoveredItemElRef = (0,
|
|
9252
|
-
const [hoveredItemRect, setHoveredItemRect] = (0,
|
|
9253
|
-
const siblingHintElRef = (0,
|
|
9254
|
-
const [siblingHintRect, setSiblingHintRect] = (0,
|
|
9255
|
-
const [siblingHintRects, setSiblingHintRects] = (0,
|
|
9256
|
-
const [isItemDragging, setIsItemDragging] = (0,
|
|
9257
|
-
const [isFooterFrameSelection, setIsFooterFrameSelection] = (0,
|
|
9258
|
-
|
|
9259
|
-
const
|
|
9260
|
-
const [
|
|
9261
|
-
const [
|
|
9262
|
-
const
|
|
9263
|
-
const
|
|
9264
|
-
const
|
|
9265
|
-
const
|
|
9266
|
-
const
|
|
9267
|
-
const
|
|
9268
|
-
const
|
|
9269
|
-
const
|
|
9270
|
-
const
|
|
9271
|
-
const
|
|
9272
|
-
const
|
|
9273
|
-
const
|
|
9274
|
-
const
|
|
9275
|
-
const
|
|
10323
|
+
const [selectedIsCta, setSelectedIsCta] = (0, import_react11.useState)(false);
|
|
10324
|
+
const [reorderHrefKey, setReorderHrefKey] = (0, import_react11.useState)(null);
|
|
10325
|
+
const [reorderDragDisabled, setReorderDragDisabled] = (0, import_react11.useState)(false);
|
|
10326
|
+
const [toggleState, setToggleState] = (0, import_react11.useState)(null);
|
|
10327
|
+
const [maxBadge, setMaxBadge] = (0, import_react11.useState)(null);
|
|
10328
|
+
const [activeCommands, setActiveCommands] = (0, import_react11.useState)(/* @__PURE__ */ new Set());
|
|
10329
|
+
const [sectionGap, setSectionGap] = (0, import_react11.useState)(null);
|
|
10330
|
+
const [toolbarShowEditLink, setToolbarShowEditLink] = (0, import_react11.useState)(false);
|
|
10331
|
+
const hoveredNavContainerRef = (0, import_react11.useRef)(null);
|
|
10332
|
+
const [hoveredNavContainerRect, setHoveredNavContainerRect] = (0, import_react11.useState)(null);
|
|
10333
|
+
const hoveredItemElRef = (0, import_react11.useRef)(null);
|
|
10334
|
+
const [hoveredItemRect, setHoveredItemRect] = (0, import_react11.useState)(null);
|
|
10335
|
+
const siblingHintElRef = (0, import_react11.useRef)(null);
|
|
10336
|
+
const [siblingHintRect, setSiblingHintRect] = (0, import_react11.useState)(null);
|
|
10337
|
+
const [siblingHintRects, setSiblingHintRects] = (0, import_react11.useState)([]);
|
|
10338
|
+
const [isItemDragging, setIsItemDragging] = (0, import_react11.useState)(false);
|
|
10339
|
+
const [isFooterFrameSelection, setIsFooterFrameSelection] = (0, import_react11.useState)(false);
|
|
10340
|
+
isFooterFrameSelectionRef.current = isFooterFrameSelection;
|
|
10341
|
+
const footerDragRef = (0, import_react11.useRef)(null);
|
|
10342
|
+
const [footerDropSlots, setFooterDropSlots] = (0, import_react11.useState)([]);
|
|
10343
|
+
const [activeFooterDropIndex, setActiveFooterDropIndex] = (0, import_react11.useState)(null);
|
|
10344
|
+
const [draggedItemRect, setDraggedItemRect] = (0, import_react11.useState)(null);
|
|
10345
|
+
const footerPointerDragRef = (0, import_react11.useRef)(null);
|
|
10346
|
+
const suppressNextClickRef = (0, import_react11.useRef)(false);
|
|
10347
|
+
const suppressClickUntilRef = (0, import_react11.useRef)(0);
|
|
10348
|
+
const [linkPopover, setLinkPopover] = (0, import_react11.useState)(null);
|
|
10349
|
+
const linkPopoverSessionRef = (0, import_react11.useRef)(null);
|
|
10350
|
+
const addNavAfterAnchorRef = (0, import_react11.useRef)(null);
|
|
10351
|
+
const editContentRef = (0, import_react11.useRef)({});
|
|
10352
|
+
const pendingDeleteUndoRef = (0, import_react11.useRef)(null);
|
|
10353
|
+
const [sitePages, setSitePages] = (0, import_react11.useState)([]);
|
|
10354
|
+
const [sectionsByPath, setSectionsByPath] = (0, import_react11.useState)({});
|
|
10355
|
+
const sectionsPrefetchGenRef = (0, import_react11.useRef)(0);
|
|
10356
|
+
const setLinkPopoverRef = (0, import_react11.useRef)(setLinkPopover);
|
|
10357
|
+
const linkPopoverPanelRef = (0, import_react11.useRef)(null);
|
|
10358
|
+
const linkPopoverOpenRef = (0, import_react11.useRef)(false);
|
|
10359
|
+
const linkPopoverGraceUntilRef = (0, import_react11.useRef)(0);
|
|
9276
10360
|
setLinkPopoverRef.current = setLinkPopover;
|
|
9277
10361
|
linkPopoverSessionRef.current = linkPopover;
|
|
9278
10362
|
const {
|
|
@@ -9311,7 +10395,7 @@ function OhhwellsBridge() {
|
|
|
9311
10395
|
const bumpLinkPopoverGrace = () => {
|
|
9312
10396
|
linkPopoverGraceUntilRef.current = Date.now() + 350;
|
|
9313
10397
|
};
|
|
9314
|
-
const runSectionsPrefetch = (0,
|
|
10398
|
+
const runSectionsPrefetch = (0, import_react11.useCallback)((pages) => {
|
|
9315
10399
|
if (!isEditMode || shouldUseDevFixtures() || pages.length === 0) return;
|
|
9316
10400
|
const gen = ++sectionsPrefetchGenRef.current;
|
|
9317
10401
|
const paths = pages.map((p) => p.path);
|
|
@@ -9330,9 +10414,9 @@ function OhhwellsBridge() {
|
|
|
9330
10414
|
);
|
|
9331
10415
|
});
|
|
9332
10416
|
}, [isEditMode, pathname]);
|
|
9333
|
-
const runSectionsPrefetchRef = (0,
|
|
10417
|
+
const runSectionsPrefetchRef = (0, import_react11.useRef)(runSectionsPrefetch);
|
|
9334
10418
|
runSectionsPrefetchRef.current = runSectionsPrefetch;
|
|
9335
|
-
(0,
|
|
10419
|
+
(0, import_react11.useEffect)(() => {
|
|
9336
10420
|
if (!linkPopover) {
|
|
9337
10421
|
document.documentElement.removeAttribute("data-ohw-link-popover-open");
|
|
9338
10422
|
return;
|
|
@@ -9355,34 +10439,12 @@ function OhhwellsBridge() {
|
|
|
9355
10439
|
hoveredGapRef.current = null;
|
|
9356
10440
|
setSectionGap(null);
|
|
9357
10441
|
setMediaHover(null);
|
|
9358
|
-
postToParent2({ type: "ow:link-modal-lock", locked: true });
|
|
9359
|
-
const html = document.documentElement;
|
|
9360
|
-
const body = document.body;
|
|
9361
|
-
const prevHtmlOverflow = html.style.overflow;
|
|
9362
|
-
const prevBodyOverflow = body.style.overflow;
|
|
9363
|
-
html.style.overflow = "hidden";
|
|
9364
|
-
body.style.overflow = "hidden";
|
|
9365
|
-
const preventBackgroundScroll = (e) => {
|
|
9366
|
-
const target = e.target;
|
|
9367
|
-
if (target instanceof Element && target.closest('[data-ohw-link-modal-root], [data-slot="dialog-overlay"]')) {
|
|
9368
|
-
return;
|
|
9369
|
-
}
|
|
9370
|
-
e.preventDefault();
|
|
9371
|
-
};
|
|
9372
|
-
const scrollOpts = { passive: false, capture: true };
|
|
9373
|
-
document.addEventListener("wheel", preventBackgroundScroll, scrollOpts);
|
|
9374
|
-
document.addEventListener("touchmove", preventBackgroundScroll, scrollOpts);
|
|
9375
10442
|
postToParent2({ type: "ow:image-unhover" });
|
|
9376
10443
|
return () => {
|
|
9377
10444
|
document.documentElement.removeAttribute("data-ohw-link-popover-open");
|
|
9378
|
-
postToParent2({ type: "ow:link-modal-lock", locked: false });
|
|
9379
|
-
html.style.overflow = prevHtmlOverflow;
|
|
9380
|
-
body.style.overflow = prevBodyOverflow;
|
|
9381
|
-
document.removeEventListener("wheel", preventBackgroundScroll, scrollOpts);
|
|
9382
|
-
document.removeEventListener("touchmove", preventBackgroundScroll, scrollOpts);
|
|
9383
10445
|
};
|
|
9384
10446
|
}, [linkPopover, postToParent2]);
|
|
9385
|
-
(0,
|
|
10447
|
+
(0, import_react11.useEffect)(() => {
|
|
9386
10448
|
if (!isEditMode) return;
|
|
9387
10449
|
const useFixtures = shouldUseDevFixtures();
|
|
9388
10450
|
if (useFixtures) {
|
|
@@ -9406,14 +10468,14 @@ function OhhwellsBridge() {
|
|
|
9406
10468
|
if (!useFixtures) postToParent2({ type: "ow:request-site-pages" });
|
|
9407
10469
|
return () => window.removeEventListener("message", onSitePages);
|
|
9408
10470
|
}, [isEditMode, postToParent2]);
|
|
9409
|
-
(0,
|
|
10471
|
+
(0, import_react11.useEffect)(() => {
|
|
9410
10472
|
if (!isEditMode || shouldUseDevFixtures()) return;
|
|
9411
10473
|
void loadAllSectionsManifest().then((manifest) => {
|
|
9412
10474
|
if (Object.keys(manifest).length === 0) return;
|
|
9413
10475
|
setSectionsByPath((prev) => ({ ...manifest, ...prev }));
|
|
9414
10476
|
});
|
|
9415
10477
|
}, [isEditMode]);
|
|
9416
|
-
(0,
|
|
10478
|
+
(0, import_react11.useEffect)(() => {
|
|
9417
10479
|
const update = () => {
|
|
9418
10480
|
const el = activeElRef.current ?? selectedElRef.current;
|
|
9419
10481
|
if (el) setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
|
|
@@ -9437,10 +10499,10 @@ function OhhwellsBridge() {
|
|
|
9437
10499
|
vvp.removeEventListener("resize", update);
|
|
9438
10500
|
};
|
|
9439
10501
|
}, []);
|
|
9440
|
-
const refreshStateRules = (0,
|
|
10502
|
+
const refreshStateRules = (0, import_react11.useCallback)(() => {
|
|
9441
10503
|
editStylesRef.current?.forceHover && (editStylesRef.current.forceHover.textContent = collectStateRules());
|
|
9442
10504
|
}, []);
|
|
9443
|
-
const processConfigRequest = (0,
|
|
10505
|
+
const processConfigRequest = (0, import_react11.useCallback)((insertAfterVal) => {
|
|
9444
10506
|
const tracker = getSectionsTracker();
|
|
9445
10507
|
let entries = [];
|
|
9446
10508
|
try {
|
|
@@ -9463,7 +10525,7 @@ function OhhwellsBridge() {
|
|
|
9463
10525
|
}
|
|
9464
10526
|
window.postMessage({ type: "ow:schedule-config", insertAfter: insertAfterVal, scheduleId: null }, "*");
|
|
9465
10527
|
}, [isEditMode]);
|
|
9466
|
-
const deactivate = (0,
|
|
10528
|
+
const deactivate = (0, import_react11.useCallback)(() => {
|
|
9467
10529
|
const el = activeElRef.current;
|
|
9468
10530
|
if (!el) return;
|
|
9469
10531
|
const key = el.dataset.ohwKey;
|
|
@@ -9495,12 +10557,12 @@ function OhhwellsBridge() {
|
|
|
9495
10557
|
setToolbarShowEditLink(false);
|
|
9496
10558
|
postToParent2({ type: "ow:exit-edit" });
|
|
9497
10559
|
}, [postToParent2]);
|
|
9498
|
-
const clearSelectedAttr = (0,
|
|
10560
|
+
const clearSelectedAttr = (0, import_react11.useCallback)(() => {
|
|
9499
10561
|
document.querySelectorAll("[data-ohw-selected]").forEach((el) => {
|
|
9500
10562
|
el.removeAttribute("data-ohw-selected");
|
|
9501
10563
|
});
|
|
9502
10564
|
}, []);
|
|
9503
|
-
const deselect = (0,
|
|
10565
|
+
const deselect = (0, import_react11.useCallback)(() => {
|
|
9504
10566
|
clearSelectedAttr();
|
|
9505
10567
|
selectedElRef.current = null;
|
|
9506
10568
|
selectedHrefKeyRef.current = null;
|
|
@@ -9520,11 +10582,11 @@ function OhhwellsBridge() {
|
|
|
9520
10582
|
setToolbarVariant("none");
|
|
9521
10583
|
}
|
|
9522
10584
|
}, [clearSelectedAttr]);
|
|
9523
|
-
const markSelected = (0,
|
|
10585
|
+
const markSelected = (0, import_react11.useCallback)((el) => {
|
|
9524
10586
|
clearSelectedAttr();
|
|
9525
10587
|
el.setAttribute("data-ohw-selected", "");
|
|
9526
10588
|
}, [clearSelectedAttr]);
|
|
9527
|
-
const resolveHrefKeyElement = (0,
|
|
10589
|
+
const resolveHrefKeyElement = (0, import_react11.useCallback)((hrefKey) => {
|
|
9528
10590
|
if (isFooterHrefKey(hrefKey)) {
|
|
9529
10591
|
return document.querySelector(
|
|
9530
10592
|
`footer [data-ohw-href-key="${CSS.escape(hrefKey)}"]`
|
|
@@ -9539,11 +10601,11 @@ function OhhwellsBridge() {
|
|
|
9539
10601
|
`[data-ohw-href-key="${CSS.escape(hrefKey)}"]`
|
|
9540
10602
|
);
|
|
9541
10603
|
}, []);
|
|
9542
|
-
const resyncSelectedNavigationItem = (0,
|
|
10604
|
+
const resyncSelectedNavigationItem = (0, import_react11.useCallback)(() => {
|
|
9543
10605
|
const hrefKey = selectedHrefKeyRef.current;
|
|
9544
10606
|
if (hrefKey) {
|
|
9545
10607
|
const link = resolveHrefKeyElement(hrefKey);
|
|
9546
|
-
if (!link || !
|
|
10608
|
+
if (!link || !isNavigationItem2(link)) return;
|
|
9547
10609
|
selectedElRef.current = link;
|
|
9548
10610
|
const { key, disabled } = getNavigationItemReorderState(link);
|
|
9549
10611
|
setReorderHrefKey(key);
|
|
@@ -9567,7 +10629,7 @@ function OhhwellsBridge() {
|
|
|
9567
10629
|
);
|
|
9568
10630
|
}
|
|
9569
10631
|
}, [resolveHrefKeyElement]);
|
|
9570
|
-
const reselectNavigationItem = (0,
|
|
10632
|
+
const reselectNavigationItem = (0, import_react11.useCallback)((navAnchor) => {
|
|
9571
10633
|
selectedElRef.current = navAnchor;
|
|
9572
10634
|
selectedHrefKeyRef.current = navAnchor.getAttribute("data-ohw-href-key");
|
|
9573
10635
|
selectedFooterColAttrRef.current = null;
|
|
@@ -9582,7 +10644,7 @@ function OhhwellsBridge() {
|
|
|
9582
10644
|
setToolbarShowEditLink(false);
|
|
9583
10645
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
9584
10646
|
}, [markSelected]);
|
|
9585
|
-
const commitNavigationTextEdit = (0,
|
|
10647
|
+
const commitNavigationTextEdit = (0, import_react11.useCallback)((navAnchor) => {
|
|
9586
10648
|
const el = activeElRef.current;
|
|
9587
10649
|
if (!el) return;
|
|
9588
10650
|
const key = el.dataset.ohwKey;
|
|
@@ -9609,7 +10671,7 @@ function OhhwellsBridge() {
|
|
|
9609
10671
|
postToParent2({ type: "ow:exit-edit" });
|
|
9610
10672
|
reselectNavigationItem(navAnchor);
|
|
9611
10673
|
}, [postToParent2, reselectNavigationItem]);
|
|
9612
|
-
const handleAddTopLevelNavItem = (0,
|
|
10674
|
+
const handleAddTopLevelNavItem = (0, import_react11.useCallback)(() => {
|
|
9613
10675
|
const items = listNavbarItems();
|
|
9614
10676
|
addNavAfterAnchorRef.current = items[items.length - 1] ?? null;
|
|
9615
10677
|
deselectRef.current();
|
|
@@ -9621,7 +10683,28 @@ function OhhwellsBridge() {
|
|
|
9621
10683
|
intent: "add-nav"
|
|
9622
10684
|
});
|
|
9623
10685
|
}, []);
|
|
9624
|
-
const
|
|
10686
|
+
const handleAddFooterColumn = (0, import_react11.useCallback)(() => {
|
|
10687
|
+
if (!canAddFooterColumn()) {
|
|
10688
|
+
postToParent2({
|
|
10689
|
+
type: "ow:toast",
|
|
10690
|
+
title: `Maximum ${MAX_FOOTER_COLUMNS} columns`,
|
|
10691
|
+
toastType: "error"
|
|
10692
|
+
});
|
|
10693
|
+
return;
|
|
10694
|
+
}
|
|
10695
|
+
deselectRef.current();
|
|
10696
|
+
deactivateRef.current();
|
|
10697
|
+
const result = addFooterColumnWithPersist({ postToParent: postToParent2 });
|
|
10698
|
+
if (!result) return;
|
|
10699
|
+
editContentRef.current = {
|
|
10700
|
+
...editContentRef.current,
|
|
10701
|
+
...buildFooterColumnEditContentPatch(result)
|
|
10702
|
+
};
|
|
10703
|
+
requestAnimationFrame(() => {
|
|
10704
|
+
selectRef.current(result.firstLink);
|
|
10705
|
+
});
|
|
10706
|
+
}, [postToParent2]);
|
|
10707
|
+
const clearFooterDragVisuals = (0, import_react11.useCallback)(() => {
|
|
9625
10708
|
footerDragRef.current = null;
|
|
9626
10709
|
setSiblingHintRects([]);
|
|
9627
10710
|
setFooterDropSlots([]);
|
|
@@ -9630,7 +10713,7 @@ function OhhwellsBridge() {
|
|
|
9630
10713
|
setIsItemDragging(false);
|
|
9631
10714
|
unlockFooterDragInteraction();
|
|
9632
10715
|
}, []);
|
|
9633
|
-
const refreshFooterDragVisuals = (0,
|
|
10716
|
+
const refreshFooterDragVisuals = (0, import_react11.useCallback)((session, activeSlot, clientX, clientY) => {
|
|
9634
10717
|
const dragged = session.draggedEl;
|
|
9635
10718
|
setDraggedItemRect(dragged.getBoundingClientRect());
|
|
9636
10719
|
if (typeof clientX === "number" && typeof clientY === "number") {
|
|
@@ -9655,13 +10738,13 @@ function OhhwellsBridge() {
|
|
|
9655
10738
|
const activeIdx = activeSlot ? slots.findIndex((s) => s.insertIndex === activeSlot.insertIndex) : -1;
|
|
9656
10739
|
setActiveFooterDropIndex(activeIdx >= 0 ? activeIdx : null);
|
|
9657
10740
|
}, []);
|
|
9658
|
-
const refreshFooterDragVisualsRef = (0,
|
|
10741
|
+
const refreshFooterDragVisualsRef = (0, import_react11.useRef)(refreshFooterDragVisuals);
|
|
9659
10742
|
refreshFooterDragVisualsRef.current = refreshFooterDragVisuals;
|
|
9660
|
-
const commitFooterDragRef = (0,
|
|
10743
|
+
const commitFooterDragRef = (0, import_react11.useRef)(() => {
|
|
9661
10744
|
});
|
|
9662
|
-
const beginFooterDragRef = (0,
|
|
10745
|
+
const beginFooterDragRef = (0, import_react11.useRef)(() => {
|
|
9663
10746
|
});
|
|
9664
|
-
const beginFooterDrag = (0,
|
|
10747
|
+
const beginFooterDrag = (0, import_react11.useCallback)(
|
|
9665
10748
|
(session) => {
|
|
9666
10749
|
const rect = session.draggedEl.getBoundingClientRect();
|
|
9667
10750
|
session.lastClientX = session.lastClientX || rect.left + rect.width / 2;
|
|
@@ -9681,7 +10764,7 @@ function OhhwellsBridge() {
|
|
|
9681
10764
|
[refreshFooterDragVisuals]
|
|
9682
10765
|
);
|
|
9683
10766
|
beginFooterDragRef.current = beginFooterDrag;
|
|
9684
|
-
const commitFooterDrag = (0,
|
|
10767
|
+
const commitFooterDrag = (0, import_react11.useCallback)(
|
|
9685
10768
|
(clientX, clientY) => {
|
|
9686
10769
|
const session = footerDragRef.current;
|
|
9687
10770
|
if (!session) {
|
|
@@ -9715,7 +10798,7 @@ function OhhwellsBridge() {
|
|
|
9715
10798
|
selectedHrefKeyRef.current = hrefKey;
|
|
9716
10799
|
selectedFooterColAttrRef.current = null;
|
|
9717
10800
|
const link = resolveHrefKeyElement(hrefKey);
|
|
9718
|
-
if (link &&
|
|
10801
|
+
if (link && isNavigationItem2(link)) {
|
|
9719
10802
|
selectRef.current(link);
|
|
9720
10803
|
return;
|
|
9721
10804
|
}
|
|
@@ -9739,7 +10822,7 @@ function OhhwellsBridge() {
|
|
|
9739
10822
|
}
|
|
9740
10823
|
}
|
|
9741
10824
|
if (document.body.contains(draggedEl)) {
|
|
9742
|
-
if (
|
|
10825
|
+
if (isNavigationItem2(draggedEl)) {
|
|
9743
10826
|
selectRef.current(draggedEl);
|
|
9744
10827
|
return;
|
|
9745
10828
|
}
|
|
@@ -9785,7 +10868,7 @@ function OhhwellsBridge() {
|
|
|
9785
10868
|
[clearFooterDragVisuals, resolveHrefKeyElement, resyncSelectedNavigationItem]
|
|
9786
10869
|
);
|
|
9787
10870
|
commitFooterDragRef.current = commitFooterDrag;
|
|
9788
|
-
const startFooterLinkDrag = (0,
|
|
10871
|
+
const startFooterLinkDrag = (0, import_react11.useCallback)(
|
|
9789
10872
|
(anchor, clientX, clientY, wasSelected) => {
|
|
9790
10873
|
const hrefKey = anchor.getAttribute("data-ohw-href-key");
|
|
9791
10874
|
if (!hrefKey || !isFooterHrefKey(hrefKey)) return false;
|
|
@@ -9806,7 +10889,7 @@ function OhhwellsBridge() {
|
|
|
9806
10889
|
},
|
|
9807
10890
|
[beginFooterDrag]
|
|
9808
10891
|
);
|
|
9809
|
-
const startFooterColumnDrag = (0,
|
|
10892
|
+
const startFooterColumnDrag = (0, import_react11.useCallback)(
|
|
9810
10893
|
(columnEl, clientX, clientY, wasSelected) => {
|
|
9811
10894
|
const columns = listFooterColumns();
|
|
9812
10895
|
const idx = columns.indexOf(columnEl);
|
|
@@ -9826,7 +10909,7 @@ function OhhwellsBridge() {
|
|
|
9826
10909
|
},
|
|
9827
10910
|
[beginFooterDrag]
|
|
9828
10911
|
);
|
|
9829
|
-
const handleItemDragStart = (0,
|
|
10912
|
+
const handleItemDragStart = (0, import_react11.useCallback)(
|
|
9830
10913
|
(e) => {
|
|
9831
10914
|
const selected = selectedElRef.current;
|
|
9832
10915
|
if (!selected) {
|
|
@@ -9836,7 +10919,7 @@ function OhhwellsBridge() {
|
|
|
9836
10919
|
const clientX = e?.clientX ?? selected.getBoundingClientRect().left + 8;
|
|
9837
10920
|
const clientY = e?.clientY ?? selected.getBoundingClientRect().top + 8;
|
|
9838
10921
|
if (startFooterLinkDrag(selected, clientX, clientY, true)) return;
|
|
9839
|
-
if (selected.hasAttribute("data-ohw-footer-col") ||
|
|
10922
|
+
if (selected.hasAttribute("data-ohw-footer-col") || isInferredFooterGroup2(selected) && selected.closest("footer")) {
|
|
9840
10923
|
if (startFooterColumnDrag(selected, clientX, clientY, true)) return;
|
|
9841
10924
|
}
|
|
9842
10925
|
if (startNavLinkDrag(selected, clientX, clientY, true)) return;
|
|
@@ -9846,7 +10929,7 @@ function OhhwellsBridge() {
|
|
|
9846
10929
|
},
|
|
9847
10930
|
[startFooterColumnDrag, startFooterLinkDrag, startNavLinkDrag]
|
|
9848
10931
|
);
|
|
9849
|
-
const handleItemDragEnd = (0,
|
|
10932
|
+
const handleItemDragEnd = (0, import_react11.useCallback)(
|
|
9850
10933
|
(e) => {
|
|
9851
10934
|
if (footerDragRef.current) {
|
|
9852
10935
|
const x = e?.clientX;
|
|
@@ -9872,7 +10955,7 @@ function OhhwellsBridge() {
|
|
|
9872
10955
|
},
|
|
9873
10956
|
[commitFooterDrag, commitNavDrag, navDragRef]
|
|
9874
10957
|
);
|
|
9875
|
-
const handleItemChromePointerDown = (0,
|
|
10958
|
+
const handleItemChromePointerDown = (0, import_react11.useCallback)((e) => {
|
|
9876
10959
|
if (e.button !== 0) return;
|
|
9877
10960
|
const selected = selectedElRef.current;
|
|
9878
10961
|
if (!selected) return;
|
|
@@ -9889,7 +10972,7 @@ function OhhwellsBridge() {
|
|
|
9889
10972
|
};
|
|
9890
10973
|
return;
|
|
9891
10974
|
}
|
|
9892
|
-
if (selected.hasAttribute("data-ohw-footer-col") ||
|
|
10975
|
+
if (selected.hasAttribute("data-ohw-footer-col") || isInferredFooterGroup2(selected) && selected.closest("footer")) {
|
|
9893
10976
|
footerPointerDragRef.current = {
|
|
9894
10977
|
el: selected,
|
|
9895
10978
|
kind: "column",
|
|
@@ -9903,21 +10986,21 @@ function OhhwellsBridge() {
|
|
|
9903
10986
|
}
|
|
9904
10987
|
if (armNavPressFromChrome(selected, e.clientX, e.clientY, e.pointerId)) return;
|
|
9905
10988
|
}, [armNavPressFromChrome]);
|
|
9906
|
-
const handleItemChromeClick = (0,
|
|
10989
|
+
const handleItemChromeClick = (0, import_react11.useCallback)((clientX, clientY) => {
|
|
9907
10990
|
if (suppressNextClickRef.current || Date.now() < suppressClickUntilRef.current) {
|
|
9908
10991
|
suppressNextClickRef.current = false;
|
|
9909
10992
|
return;
|
|
9910
10993
|
}
|
|
9911
10994
|
const selected = selectedElRef.current;
|
|
9912
|
-
if (!selected || !
|
|
10995
|
+
if (!selected || !isNavigationItem2(selected)) return;
|
|
9913
10996
|
const editable = selected.querySelector('[data-ohw-editable="text"]') ?? selected.querySelector("[data-ohw-editable]");
|
|
9914
10997
|
if (!editable) return;
|
|
9915
10998
|
activateRef.current(editable, { caretX: clientX, caretY: clientY });
|
|
9916
10999
|
}, []);
|
|
9917
11000
|
reselectNavigationItemRef.current = reselectNavigationItem;
|
|
9918
11001
|
commitNavigationTextEditRef.current = commitNavigationTextEdit;
|
|
9919
|
-
const select = (0,
|
|
9920
|
-
if (!
|
|
11002
|
+
const select = (0, import_react11.useCallback)((anchor) => {
|
|
11003
|
+
if (!isNavigationItem2(anchor)) return;
|
|
9921
11004
|
if (activeElRef.current) deactivate();
|
|
9922
11005
|
selectedElRef.current = anchor;
|
|
9923
11006
|
selectedHrefKeyRef.current = anchor.getAttribute("data-ohw-href-key");
|
|
@@ -9942,10 +11025,10 @@ function OhhwellsBridge() {
|
|
|
9942
11025
|
setToolbarShowEditLink(false);
|
|
9943
11026
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
9944
11027
|
}, [deactivate, markSelected]);
|
|
9945
|
-
const selectFrame = (0,
|
|
11028
|
+
const selectFrame = (0, import_react11.useCallback)((el) => {
|
|
9946
11029
|
if (!isNavigationContainer(el)) return;
|
|
9947
11030
|
if (activeElRef.current) deactivate();
|
|
9948
|
-
const isFooterColumn = el.hasAttribute("data-ohw-footer-col") || Boolean(el.closest("footer") &&
|
|
11031
|
+
const isFooterColumn = !isFooterLinksContainer(el) && (el.hasAttribute("data-ohw-footer-col") || Boolean(el.closest("footer") && isInferredFooterGroup2(el)));
|
|
9949
11032
|
selectedElRef.current = el;
|
|
9950
11033
|
selectedHrefKeyRef.current = null;
|
|
9951
11034
|
selectedFooterColAttrRef.current = isFooterColumn ? el.getAttribute("data-ohw-footer-col") ?? String(listFooterColumns().indexOf(el)) : null;
|
|
@@ -9970,7 +11053,7 @@ function OhhwellsBridge() {
|
|
|
9970
11053
|
setToolbarShowEditLink(false);
|
|
9971
11054
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
9972
11055
|
}, [deactivate, markSelected]);
|
|
9973
|
-
const activate = (0,
|
|
11056
|
+
const activate = (0, import_react11.useCallback)((el, options) => {
|
|
9974
11057
|
if (activeElRef.current === el) return;
|
|
9975
11058
|
clearSelectedAttr();
|
|
9976
11059
|
selectedElRef.current = null;
|
|
@@ -10035,7 +11118,7 @@ function OhhwellsBridge() {
|
|
|
10035
11118
|
selectRef.current = select;
|
|
10036
11119
|
selectFrameRef.current = selectFrame;
|
|
10037
11120
|
deselectRef.current = deselect;
|
|
10038
|
-
(0,
|
|
11121
|
+
(0, import_react11.useLayoutEffect)(() => {
|
|
10039
11122
|
if (!subdomain || isEditMode) {
|
|
10040
11123
|
setFetchState("done");
|
|
10041
11124
|
return;
|
|
@@ -10060,7 +11143,7 @@ function OhhwellsBridge() {
|
|
|
10060
11143
|
const next = `url('${val}')`;
|
|
10061
11144
|
if (el.style.backgroundImage !== next) el.style.backgroundImage = next;
|
|
10062
11145
|
} else if (el.dataset.ohwEditable === "video") {
|
|
10063
|
-
const video =
|
|
11146
|
+
const video = getVideoEl2(el);
|
|
10064
11147
|
if (video && video.src !== val) {
|
|
10065
11148
|
applyVideoSrc(video, val);
|
|
10066
11149
|
imageLoads.push(new Promise((resolve) => {
|
|
@@ -10106,7 +11189,7 @@ function OhhwellsBridge() {
|
|
|
10106
11189
|
cancelled = true;
|
|
10107
11190
|
};
|
|
10108
11191
|
}, [subdomain, isEditMode]);
|
|
10109
|
-
(0,
|
|
11192
|
+
(0, import_react11.useEffect)(() => {
|
|
10110
11193
|
if (!subdomain || isEditMode) return;
|
|
10111
11194
|
let debounceTimer = null;
|
|
10112
11195
|
let observer = null;
|
|
@@ -10128,7 +11211,7 @@ function OhhwellsBridge() {
|
|
|
10128
11211
|
const next = `url('${val}')`;
|
|
10129
11212
|
if (el.style.backgroundImage !== next) el.style.backgroundImage = next;
|
|
10130
11213
|
} else if (el.dataset.ohwEditable === "video") {
|
|
10131
|
-
const video =
|
|
11214
|
+
const video = getVideoEl2(el);
|
|
10132
11215
|
if (video && video.src !== val) applyVideoSrc(video, val);
|
|
10133
11216
|
} else if (el.dataset.ohwEditable === "link") {
|
|
10134
11217
|
applyLinkHref(el, val);
|
|
@@ -10157,16 +11240,16 @@ function OhhwellsBridge() {
|
|
|
10157
11240
|
if (debounceTimer) clearTimeout(debounceTimer);
|
|
10158
11241
|
};
|
|
10159
11242
|
}, [subdomain, isEditMode, pathname]);
|
|
10160
|
-
(0,
|
|
11243
|
+
(0, import_react11.useLayoutEffect)(() => {
|
|
10161
11244
|
const el = document.getElementById("ohw-loader");
|
|
10162
11245
|
if (!el) return;
|
|
10163
11246
|
const visible = Boolean(subdomain) && fetchState !== "done";
|
|
10164
11247
|
el.style.display = visible ? "flex" : "none";
|
|
10165
11248
|
}, [subdomain, fetchState]);
|
|
10166
|
-
(0,
|
|
11249
|
+
(0, import_react11.useEffect)(() => {
|
|
10167
11250
|
postToParent2({ type: "ow:navigation", path: pathname });
|
|
10168
11251
|
}, [pathname, postToParent2]);
|
|
10169
|
-
(0,
|
|
11252
|
+
(0, import_react11.useEffect)(() => {
|
|
10170
11253
|
if (!isEditMode) return;
|
|
10171
11254
|
if (linkPopoverSessionRef.current?.intent === "add-nav") return;
|
|
10172
11255
|
if (document.querySelector("[data-ohw-section-picker]")) return;
|
|
@@ -10174,7 +11257,7 @@ function OhhwellsBridge() {
|
|
|
10174
11257
|
deselectRef.current();
|
|
10175
11258
|
deactivateRef.current();
|
|
10176
11259
|
}, [pathname, isEditMode]);
|
|
10177
|
-
(0,
|
|
11260
|
+
(0, import_react11.useEffect)(() => {
|
|
10178
11261
|
const contentForNav = () => {
|
|
10179
11262
|
if (isEditMode) return editContentRef.current;
|
|
10180
11263
|
if (!subdomain) return {};
|
|
@@ -10239,7 +11322,7 @@ function OhhwellsBridge() {
|
|
|
10239
11322
|
observer?.disconnect();
|
|
10240
11323
|
};
|
|
10241
11324
|
}, [isEditMode, pathname, subdomain, fetchState, resyncSelectedNavigationItem]);
|
|
10242
|
-
(0,
|
|
11325
|
+
(0, import_react11.useEffect)(() => {
|
|
10243
11326
|
if (!isEditMode) return;
|
|
10244
11327
|
const measure = () => {
|
|
10245
11328
|
const h = document.body.scrollHeight;
|
|
@@ -10263,7 +11346,7 @@ function OhhwellsBridge() {
|
|
|
10263
11346
|
window.removeEventListener("resize", handleResize);
|
|
10264
11347
|
};
|
|
10265
11348
|
}, [pathname, isEditMode, postToParent2]);
|
|
10266
|
-
(0,
|
|
11349
|
+
(0, import_react11.useEffect)(() => {
|
|
10267
11350
|
if (!subdomainFromQuery || isEditMode) return;
|
|
10268
11351
|
const handleClick = (e) => {
|
|
10269
11352
|
const anchor = e.target.closest("a");
|
|
@@ -10279,7 +11362,7 @@ function OhhwellsBridge() {
|
|
|
10279
11362
|
document.addEventListener("click", handleClick, true);
|
|
10280
11363
|
return () => document.removeEventListener("click", handleClick, true);
|
|
10281
11364
|
}, [subdomainFromQuery, isEditMode, router]);
|
|
10282
|
-
(0,
|
|
11365
|
+
(0, import_react11.useEffect)(() => {
|
|
10283
11366
|
if (!isEditMode) {
|
|
10284
11367
|
editStylesRef.current?.base.remove();
|
|
10285
11368
|
editStylesRef.current?.forceHover.remove();
|
|
@@ -10413,7 +11496,7 @@ function OhhwellsBridge() {
|
|
|
10413
11496
|
e.preventDefault();
|
|
10414
11497
|
e.stopPropagation();
|
|
10415
11498
|
const selected = selectedElRef.current;
|
|
10416
|
-
if (selected &&
|
|
11499
|
+
if (selected && isNavigationItem2(selected)) {
|
|
10417
11500
|
const editable2 = selected.querySelector('[data-ohw-editable="text"]') ?? selected.querySelector("[data-ohw-editable]");
|
|
10418
11501
|
if (editable2) {
|
|
10419
11502
|
activateRef.current(editable2, {
|
|
@@ -10478,7 +11561,7 @@ function OhhwellsBridge() {
|
|
|
10478
11561
|
setLinkPopoverRef.current({
|
|
10479
11562
|
key: editable.dataset.ohwKey ?? "",
|
|
10480
11563
|
mode: "edit",
|
|
10481
|
-
target:
|
|
11564
|
+
target: getLinkHref4(editable)
|
|
10482
11565
|
});
|
|
10483
11566
|
return;
|
|
10484
11567
|
}
|
|
@@ -10503,7 +11586,7 @@ function OhhwellsBridge() {
|
|
|
10503
11586
|
}
|
|
10504
11587
|
e.preventDefault();
|
|
10505
11588
|
e.stopPropagation();
|
|
10506
|
-
activateRef.current(editable);
|
|
11589
|
+
activateRef.current(editable, { caretX: e.clientX, caretY: e.clientY });
|
|
10507
11590
|
return;
|
|
10508
11591
|
}
|
|
10509
11592
|
const hrefAnchor = getNavigationItemAnchor(target);
|
|
@@ -10530,6 +11613,18 @@ function OhhwellsBridge() {
|
|
|
10530
11613
|
selectFrameRef.current(footerColClick);
|
|
10531
11614
|
return;
|
|
10532
11615
|
}
|
|
11616
|
+
const footerLinksToSelect = resolveFooterLinksContainerSelectionTarget(
|
|
11617
|
+
target,
|
|
11618
|
+
e.clientX,
|
|
11619
|
+
e.clientY,
|
|
11620
|
+
isPointOverNavItem
|
|
11621
|
+
);
|
|
11622
|
+
if (footerLinksToSelect) {
|
|
11623
|
+
e.preventDefault();
|
|
11624
|
+
e.stopPropagation();
|
|
11625
|
+
selectFrameRef.current(footerLinksToSelect);
|
|
11626
|
+
return;
|
|
11627
|
+
}
|
|
10533
11628
|
const navContainerToSelect = resolveNavContainerSelectionTarget(target, e.clientX, e.clientY);
|
|
10534
11629
|
if (navContainerToSelect) {
|
|
10535
11630
|
e.preventDefault();
|
|
@@ -10588,8 +11683,8 @@ function OhhwellsBridge() {
|
|
|
10588
11683
|
return;
|
|
10589
11684
|
}
|
|
10590
11685
|
const navLabel = getNavigationLabelEditable(target);
|
|
10591
|
-
|
|
10592
|
-
|
|
11686
|
+
const editable = navLabel?.editable ?? target.closest('[data-ohw-editable="text"], [data-ohw-editable="plain"]');
|
|
11687
|
+
if (!editable || isMediaEditable(editable) || editable.dataset.ohwEditable === "link") return;
|
|
10593
11688
|
e.preventDefault();
|
|
10594
11689
|
e.stopPropagation();
|
|
10595
11690
|
if (activeElRef.current !== editable) {
|
|
@@ -10610,16 +11705,38 @@ function OhhwellsBridge() {
|
|
|
10610
11705
|
setHoveredNavContainerRect(null);
|
|
10611
11706
|
return;
|
|
10612
11707
|
}
|
|
10613
|
-
|
|
10614
|
-
const
|
|
10615
|
-
|
|
10616
|
-
|
|
10617
|
-
|
|
10618
|
-
|
|
10619
|
-
|
|
10620
|
-
|
|
11708
|
+
{
|
|
11709
|
+
const selected2 = selectedElRef.current;
|
|
11710
|
+
const selectedIsFooterColumn = Boolean(selected2) && !isFooterLinksContainer(selected2) && (selected2.hasAttribute("data-ohw-footer-col") || selected2.hasAttribute("data-ohw-footer-column") || Boolean(selected2.closest("footer") && isInferredFooterGroup2(selected2)));
|
|
11711
|
+
const allowNavContainerHover = toolbarVariantRef.current !== "select-frame";
|
|
11712
|
+
const allowFooterLinksHover = toolbarVariantRef.current !== "select-frame" || selectedIsFooterColumn;
|
|
11713
|
+
if (allowNavContainerHover) {
|
|
11714
|
+
const navContainer = target.closest("[data-ohw-nav-container]");
|
|
11715
|
+
if (navContainer && !getNavigationItemAnchor(target)) {
|
|
11716
|
+
hoveredNavContainerRef.current = navContainer;
|
|
11717
|
+
setHoveredNavContainerRect(navContainer.getBoundingClientRect());
|
|
11718
|
+
hoveredItemElRef.current = null;
|
|
11719
|
+
setHoveredItemRect(null);
|
|
11720
|
+
return;
|
|
11721
|
+
}
|
|
10621
11722
|
}
|
|
10622
|
-
if (
|
|
11723
|
+
if (allowFooterLinksHover) {
|
|
11724
|
+
const navContainer = target.closest("[data-ohw-nav-container]");
|
|
11725
|
+
if (!navContainer) {
|
|
11726
|
+
const footerLinks = target.closest("[data-ohw-footer-links], .rb-footer-links") ?? null;
|
|
11727
|
+
if (footerLinks && selected2 !== footerLinks && !getNavigationItemAnchor(target) && !target.closest("[data-ohw-footer-col], [data-ohw-footer-column]")) {
|
|
11728
|
+
hoveredNavContainerRef.current = footerLinks;
|
|
11729
|
+
setHoveredNavContainerRect(footerLinks.getBoundingClientRect());
|
|
11730
|
+
hoveredItemElRef.current = null;
|
|
11731
|
+
setHoveredItemRect(null);
|
|
11732
|
+
return;
|
|
11733
|
+
}
|
|
11734
|
+
if (!footerLinks) {
|
|
11735
|
+
hoveredNavContainerRef.current = null;
|
|
11736
|
+
setHoveredNavContainerRect(null);
|
|
11737
|
+
}
|
|
11738
|
+
}
|
|
11739
|
+
} else if (toolbarVariantRef.current === "select-frame") {
|
|
10623
11740
|
hoveredNavContainerRef.current = null;
|
|
10624
11741
|
setHoveredNavContainerRect(null);
|
|
10625
11742
|
}
|
|
@@ -10661,9 +11778,9 @@ function OhhwellsBridge() {
|
|
|
10661
11778
|
};
|
|
10662
11779
|
const handleMouseOut = (e) => {
|
|
10663
11780
|
const target = e.target;
|
|
10664
|
-
if (target.closest("[data-ohw-nav-container], [data-ohw-footer-col], [data-ohw-footer-column]")) {
|
|
11781
|
+
if (target.closest("[data-ohw-nav-container], [data-ohw-footer-col], [data-ohw-footer-column], [data-ohw-footer-links], .rb-footer-links")) {
|
|
10665
11782
|
const related2 = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
10666
|
-
if (related2?.closest("[data-ohw-nav-container], [data-ohw-footer-col], [data-ohw-footer-column], [data-ohw-navbar-container-chrome], [data-ohw-navbar-add-button]")) {
|
|
11783
|
+
if (related2?.closest("[data-ohw-nav-container], [data-ohw-footer-col], [data-ohw-footer-column], [data-ohw-footer-links], .rb-footer-links, [data-ohw-navbar-container-chrome], [data-ohw-navbar-add-button], [data-ohw-footer-container-chrome], [data-ohw-footer-add-button]")) {
|
|
10667
11784
|
return;
|
|
10668
11785
|
}
|
|
10669
11786
|
hoveredNavContainerRef.current = null;
|
|
@@ -10745,7 +11862,7 @@ function OhhwellsBridge() {
|
|
|
10745
11862
|
const r2 = getVisibleRect(imgEl);
|
|
10746
11863
|
const hasTextOverlap = forceTextOverlap ?? false;
|
|
10747
11864
|
hoveredImageHasTextOverlapRef.current = hasTextOverlap;
|
|
10748
|
-
const video = imgEl.dataset.ohwEditable === "video" ?
|
|
11865
|
+
const video = imgEl.dataset.ohwEditable === "video" ? getVideoEl2(imgEl) : null;
|
|
10749
11866
|
setMediaHover({
|
|
10750
11867
|
key: imgEl.dataset.ohwKey ?? "",
|
|
10751
11868
|
rect: { top: r2.top, left: r2.left, width: r2.width, height: r2.height },
|
|
@@ -10758,6 +11875,15 @@ function OhhwellsBridge() {
|
|
|
10758
11875
|
if (track) track.setAttribute("data-ohw-hover-paused", "");
|
|
10759
11876
|
};
|
|
10760
11877
|
const clearImageHover = () => setMediaHover(null);
|
|
11878
|
+
const dismissImageHover = () => {
|
|
11879
|
+
if (hoveredImageRef.current) {
|
|
11880
|
+
hoveredImageRef.current = null;
|
|
11881
|
+
hoveredImageHasTextOverlapRef.current = false;
|
|
11882
|
+
resumeAnimTracks();
|
|
11883
|
+
postToParentRef.current({ type: "ow:image-unhover" });
|
|
11884
|
+
}
|
|
11885
|
+
clearImageHover();
|
|
11886
|
+
};
|
|
10761
11887
|
const findImageAtPoint = (clientX, clientY, fromParentViewport) => {
|
|
10762
11888
|
const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
10763
11889
|
const images = Array.from(document.querySelectorAll(MEDIA_SELECTOR));
|
|
@@ -10801,16 +11927,13 @@ function OhhwellsBridge() {
|
|
|
10801
11927
|
}
|
|
10802
11928
|
return smallest;
|
|
10803
11929
|
};
|
|
10804
|
-
const dismissImageHover = () => {
|
|
10805
|
-
if (hoveredImageRef.current) {
|
|
10806
|
-
hoveredImageRef.current = null;
|
|
10807
|
-
hoveredImageHasTextOverlapRef.current = false;
|
|
10808
|
-
resumeAnimTracks();
|
|
10809
|
-
postToParentRef.current({ type: "ow:image-unhover" });
|
|
10810
|
-
}
|
|
10811
|
-
};
|
|
10812
11930
|
const probeNavigationHoverAt = (x, y) => {
|
|
10813
|
-
|
|
11931
|
+
const selected = selectedElRef.current;
|
|
11932
|
+
const selectedIsFooterColumn = Boolean(selected) && !isFooterLinksContainer(selected) && (selected.hasAttribute("data-ohw-footer-col") || selected.hasAttribute("data-ohw-footer-column") || Boolean(selected.closest("footer") && isInferredFooterGroup2(selected)));
|
|
11933
|
+
const selectedIsFooterLinks = Boolean(selected && isFooterLinksContainer(selected));
|
|
11934
|
+
const allowNavContainerHover = toolbarVariantRef.current !== "select-frame";
|
|
11935
|
+
const allowFooterLinksHover = (toolbarVariantRef.current !== "select-frame" || selectedIsFooterColumn) && !selectedIsFooterLinks;
|
|
11936
|
+
if (toolbarVariantRef.current === "select-frame" && !allowFooterLinksHover) {
|
|
10814
11937
|
hoveredNavContainerRef.current = null;
|
|
10815
11938
|
setHoveredNavContainerRect(null);
|
|
10816
11939
|
}
|
|
@@ -10825,14 +11948,13 @@ function OhhwellsBridge() {
|
|
|
10825
11948
|
const navItemHit = Array.from(
|
|
10826
11949
|
container.querySelectorAll("[data-ohw-href-key]")
|
|
10827
11950
|
).find((el) => {
|
|
10828
|
-
if (!
|
|
11951
|
+
if (!isNavigationItem2(el) || isNavbarButton2(el)) return false;
|
|
10829
11952
|
const itemRect = el.getBoundingClientRect();
|
|
10830
11953
|
return x >= itemRect.left && x <= itemRect.right && y >= itemRect.top && y <= itemRect.bottom;
|
|
10831
11954
|
});
|
|
10832
11955
|
if (navItemHit) {
|
|
10833
11956
|
hoveredNavContainerRef.current = null;
|
|
10834
11957
|
setHoveredNavContainerRect(null);
|
|
10835
|
-
const selected = selectedElRef.current;
|
|
10836
11958
|
if (selected !== navItemHit) {
|
|
10837
11959
|
clearHrefKeyHover(navItemHit);
|
|
10838
11960
|
hoveredItemElRef.current = navItemHit;
|
|
@@ -10844,7 +11966,7 @@ function OhhwellsBridge() {
|
|
|
10844
11966
|
return;
|
|
10845
11967
|
}
|
|
10846
11968
|
}
|
|
10847
|
-
if (
|
|
11969
|
+
if (allowNavContainerHover) {
|
|
10848
11970
|
for (const container of navContainers) {
|
|
10849
11971
|
const containerRect = container.getBoundingClientRect();
|
|
10850
11972
|
const overContainer = x >= containerRect.left && x <= containerRect.right && y >= containerRect.top && y <= containerRect.bottom;
|
|
@@ -10856,12 +11978,23 @@ function OhhwellsBridge() {
|
|
|
10856
11978
|
setHoveredItemRect(null);
|
|
10857
11979
|
return;
|
|
10858
11980
|
}
|
|
10859
|
-
hoveredNavContainerRef.current = null;
|
|
10860
|
-
setHoveredNavContainerRect(null);
|
|
10861
|
-
} else {
|
|
10862
|
-
hoveredNavContainerRef.current = null;
|
|
10863
|
-
setHoveredNavContainerRect(null);
|
|
10864
11981
|
}
|
|
11982
|
+
if (allowFooterLinksHover) {
|
|
11983
|
+
const footerLinks = getFooterLinksContainer();
|
|
11984
|
+
if (footerLinks) {
|
|
11985
|
+
const containerRect = footerLinks.getBoundingClientRect();
|
|
11986
|
+
const overContainer = x >= containerRect.left && x <= containerRect.right && y >= containerRect.top && y <= containerRect.bottom;
|
|
11987
|
+
if (overContainer && !isPointOverNavItem(footerLinks, x, y) && !isPointOverFooterColumn(x, y)) {
|
|
11988
|
+
hoveredNavContainerRef.current = footerLinks;
|
|
11989
|
+
setHoveredNavContainerRect(footerLinks.getBoundingClientRect());
|
|
11990
|
+
hoveredItemElRef.current = null;
|
|
11991
|
+
setHoveredItemRect(null);
|
|
11992
|
+
return;
|
|
11993
|
+
}
|
|
11994
|
+
}
|
|
11995
|
+
}
|
|
11996
|
+
hoveredNavContainerRef.current = null;
|
|
11997
|
+
setHoveredNavContainerRect(null);
|
|
10865
11998
|
for (const column of footerColumns) {
|
|
10866
11999
|
const containerRect = column.getBoundingClientRect();
|
|
10867
12000
|
const overContainer = x >= containerRect.left && x <= containerRect.right && y >= containerRect.top && y <= containerRect.bottom;
|
|
@@ -10900,6 +12033,13 @@ function OhhwellsBridge() {
|
|
|
10900
12033
|
probeNavigationHoverAt(x, y);
|
|
10901
12034
|
return;
|
|
10902
12035
|
}
|
|
12036
|
+
const overMoreMenu = document.elementFromPoint(x, y)?.closest?.(
|
|
12037
|
+
'[data-ohw-more-menu], [data-slot="dropdown-menu-content"], [data-slot="dropdown-menu-item"]'
|
|
12038
|
+
);
|
|
12039
|
+
if (overMoreMenu) {
|
|
12040
|
+
dismissImageHover();
|
|
12041
|
+
return;
|
|
12042
|
+
}
|
|
10903
12043
|
hoveredNavContainerRef.current = null;
|
|
10904
12044
|
setHoveredNavContainerRect(null);
|
|
10905
12045
|
if (hoveredItemElRef.current?.hasAttribute("data-ohw-footer-col") || hoveredItemElRef.current?.hasAttribute("data-ohw-footer-column")) {
|
|
@@ -10946,7 +12086,7 @@ function OhhwellsBridge() {
|
|
|
10946
12086
|
return;
|
|
10947
12087
|
}
|
|
10948
12088
|
const topEl = document.elementFromPoint(x2, y2);
|
|
10949
|
-
if (topEl?.closest('[data-ohw-toolbar], [data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
|
|
12089
|
+
if (topEl?.closest('[data-ohw-toolbar], [data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"], [data-ohw-more-menu], [data-slot="dropdown-menu-content"], [data-slot="dropdown-menu-item"]')) {
|
|
10950
12090
|
if (hoveredImageRef.current) {
|
|
10951
12091
|
hoveredImageRef.current = null;
|
|
10952
12092
|
resumeAnimTracks();
|
|
@@ -11266,7 +12406,7 @@ function OhhwellsBridge() {
|
|
|
11266
12406
|
}
|
|
11267
12407
|
}
|
|
11268
12408
|
} else if (el.dataset.ohwEditable === "video") {
|
|
11269
|
-
const video =
|
|
12409
|
+
const video = getVideoEl2(el);
|
|
11270
12410
|
if (video) {
|
|
11271
12411
|
found = true;
|
|
11272
12412
|
const onReady = () => {
|
|
@@ -11353,7 +12493,7 @@ function OhhwellsBridge() {
|
|
|
11353
12493
|
} else if (el.dataset.ohwEditable === "bg-image") {
|
|
11354
12494
|
el.style.backgroundImage = `url('${val}')`;
|
|
11355
12495
|
} else if (el.dataset.ohwEditable === "video") {
|
|
11356
|
-
const video =
|
|
12496
|
+
const video = getVideoEl2(el);
|
|
11357
12497
|
if (video && video.src !== val) applyVideoSrc(video, val);
|
|
11358
12498
|
} else if (el.dataset.ohwEditable === "link") {
|
|
11359
12499
|
applyLinkHref(el, val);
|
|
@@ -11370,6 +12510,7 @@ function OhhwellsBridge() {
|
|
|
11370
12510
|
}
|
|
11371
12511
|
editContentRef.current = { ...editContentRef.current, ...content };
|
|
11372
12512
|
reconcileNavbarItemsFromContent(editContentRef.current);
|
|
12513
|
+
reconcileFooterOrderFromContent(editContentRef.current);
|
|
11373
12514
|
syncNavigationDragCursorAttrs();
|
|
11374
12515
|
enforceLinkHrefs();
|
|
11375
12516
|
postToParentRef.current({ type: "ow:hydrate-done" });
|
|
@@ -11387,8 +12528,17 @@ function OhhwellsBridge() {
|
|
|
11387
12528
|
deactivateRef.current();
|
|
11388
12529
|
};
|
|
11389
12530
|
window.addEventListener("message", handleDeactivate);
|
|
12531
|
+
const handleToastAction = (e) => {
|
|
12532
|
+
if (e.data?.type !== "ow:toast-action") return;
|
|
12533
|
+
const actionId = typeof e.data.actionId === "string" ? e.data.actionId : null;
|
|
12534
|
+
const pending = pendingDeleteUndoRef.current;
|
|
12535
|
+
if (!pending || !actionId || pending.actionId !== actionId) return;
|
|
12536
|
+
runPendingDeleteUndoRef.current();
|
|
12537
|
+
};
|
|
12538
|
+
window.addEventListener("message", handleToastAction);
|
|
11390
12539
|
const handleUiEscape = (e) => {
|
|
11391
12540
|
if (e.data?.type !== "ui:escape") return;
|
|
12541
|
+
if (document.querySelector("[data-ohw-more-menu]")) return;
|
|
11392
12542
|
if (linkPopoverOpenRef.current) {
|
|
11393
12543
|
setLinkPopoverRef.current(null);
|
|
11394
12544
|
return;
|
|
@@ -11424,6 +12574,11 @@ function OhhwellsBridge() {
|
|
|
11424
12574
|
}
|
|
11425
12575
|
if (selectedElRef.current) {
|
|
11426
12576
|
if (toolbarVariantRef.current === "select-frame") {
|
|
12577
|
+
const parent2 = getNavigationSelectionParent(selectedElRef.current);
|
|
12578
|
+
if (parent2 && isNavigationContainer(parent2) && isFooterLinksContainer(parent2) && !isFooterLinksContainer(selectedElRef.current)) {
|
|
12579
|
+
selectFrameRef.current(parent2);
|
|
12580
|
+
return;
|
|
12581
|
+
}
|
|
11427
12582
|
deselectRef.current();
|
|
11428
12583
|
return;
|
|
11429
12584
|
}
|
|
@@ -11438,14 +12593,12 @@ function OhhwellsBridge() {
|
|
|
11438
12593
|
window.addEventListener("message", handleUiEscape);
|
|
11439
12594
|
const handleKeyDown = (e) => {
|
|
11440
12595
|
if (e.key === "Escape" && document.querySelector("[data-ohw-section-picker]")) return;
|
|
12596
|
+
if (e.key === "Escape" && document.querySelector("[data-ohw-more-menu]")) return;
|
|
11441
12597
|
if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === "a" && activeElRef.current) {
|
|
11442
|
-
|
|
11443
|
-
|
|
11444
|
-
|
|
11445
|
-
|
|
11446
|
-
refreshActiveCommandsRef.current();
|
|
11447
|
-
return;
|
|
11448
|
-
}
|
|
12598
|
+
e.preventDefault();
|
|
12599
|
+
selectAllTextInEditable(activeElRef.current);
|
|
12600
|
+
refreshActiveCommandsRef.current();
|
|
12601
|
+
return;
|
|
11449
12602
|
}
|
|
11450
12603
|
if (e.key === "Escape" && linkPopoverOpenRef.current) {
|
|
11451
12604
|
setLinkPopoverRef.current(null);
|
|
@@ -11453,6 +12606,12 @@ function OhhwellsBridge() {
|
|
|
11453
12606
|
}
|
|
11454
12607
|
if (e.key === "Escape" && selectedElRef.current && !activeElRef.current) {
|
|
11455
12608
|
if (toolbarVariantRef.current === "select-frame") {
|
|
12609
|
+
const parent2 = getNavigationSelectionParent(selectedElRef.current);
|
|
12610
|
+
if (parent2 && isNavigationContainer(parent2) && isFooterLinksContainer(parent2) && !isFooterLinksContainer(selectedElRef.current)) {
|
|
12611
|
+
e.preventDefault();
|
|
12612
|
+
selectFrameRef.current(parent2);
|
|
12613
|
+
return;
|
|
12614
|
+
}
|
|
11456
12615
|
deselectRef.current();
|
|
11457
12616
|
return;
|
|
11458
12617
|
}
|
|
@@ -11493,6 +12652,18 @@ function OhhwellsBridge() {
|
|
|
11493
12652
|
return;
|
|
11494
12653
|
}
|
|
11495
12654
|
}
|
|
12655
|
+
if ((e.key === "Delete" || e.key === "Backspace") && selectedElRef.current && !activeElRef.current && !linkPopoverOpenRef.current) {
|
|
12656
|
+
if (handleDeleteSelectedRef.current()) {
|
|
12657
|
+
e.preventDefault();
|
|
12658
|
+
return;
|
|
12659
|
+
}
|
|
12660
|
+
}
|
|
12661
|
+
if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === "z" && !activeElRef.current) {
|
|
12662
|
+
if (runPendingDeleteUndoRef.current()) {
|
|
12663
|
+
e.preventDefault();
|
|
12664
|
+
return;
|
|
12665
|
+
}
|
|
12666
|
+
}
|
|
11496
12667
|
if (e.key !== "Escape") return;
|
|
11497
12668
|
const el = activeElRef.current;
|
|
11498
12669
|
if (el && originalContentRef.current !== null) {
|
|
@@ -11529,11 +12700,11 @@ function OhhwellsBridge() {
|
|
|
11529
12700
|
}
|
|
11530
12701
|
const selected = selectedElRef.current;
|
|
11531
12702
|
if (selected && !footerDragRef.current && !navDragRef.current) {
|
|
11532
|
-
if (selected.hasAttribute("data-ohw-footer-col") || Boolean(selected.closest("footer") &&
|
|
12703
|
+
if (selected.hasAttribute("data-ohw-footer-col") || Boolean(selected.closest("footer") && isInferredFooterGroup2(selected))) {
|
|
11533
12704
|
setSiblingHintRects(
|
|
11534
12705
|
listFooterColumns().filter((column) => column !== selected).map((column) => column.getBoundingClientRect())
|
|
11535
12706
|
);
|
|
11536
|
-
} else if (
|
|
12707
|
+
} else if (isNavigationItem2(selected)) {
|
|
11537
12708
|
setSiblingHintRects(collectNavigationItemSiblingHintRects(selected));
|
|
11538
12709
|
}
|
|
11539
12710
|
}
|
|
@@ -11895,6 +13066,7 @@ function OhhwellsBridge() {
|
|
|
11895
13066
|
window.removeEventListener("message", handleClickAt);
|
|
11896
13067
|
window.removeEventListener("message", handleHydrate);
|
|
11897
13068
|
window.removeEventListener("message", handleDeactivate);
|
|
13069
|
+
window.removeEventListener("message", handleToastAction);
|
|
11898
13070
|
window.removeEventListener("message", handleUiEscape);
|
|
11899
13071
|
autoSaveTimers.current.forEach(clearTimeout);
|
|
11900
13072
|
autoSaveTimers.current.clear();
|
|
@@ -11902,7 +13074,7 @@ function OhhwellsBridge() {
|
|
|
11902
13074
|
if (imageShowTimerRef.current) clearTimeout(imageShowTimerRef.current);
|
|
11903
13075
|
};
|
|
11904
13076
|
}, [isEditMode, refreshStateRules]);
|
|
11905
|
-
(0,
|
|
13077
|
+
(0, import_react11.useEffect)(() => {
|
|
11906
13078
|
if (!isEditMode) return;
|
|
11907
13079
|
const THRESHOLD = 10;
|
|
11908
13080
|
const resolveWasSelected = (el) => {
|
|
@@ -12056,7 +13228,7 @@ function OhhwellsBridge() {
|
|
|
12056
13228
|
unlockFooterDragInteraction();
|
|
12057
13229
|
};
|
|
12058
13230
|
}, [isEditMode]);
|
|
12059
|
-
(0,
|
|
13231
|
+
(0, import_react11.useEffect)(() => {
|
|
12060
13232
|
const handler = (e) => {
|
|
12061
13233
|
if (e.data?.type !== "ow:request-schedule-config") return;
|
|
12062
13234
|
const insertAfterVal = e.data.insertAfter;
|
|
@@ -12072,7 +13244,7 @@ function OhhwellsBridge() {
|
|
|
12072
13244
|
window.addEventListener("message", handler);
|
|
12073
13245
|
return () => window.removeEventListener("message", handler);
|
|
12074
13246
|
}, [processConfigRequest]);
|
|
12075
|
-
(0,
|
|
13247
|
+
(0, import_react11.useEffect)(() => {
|
|
12076
13248
|
if (!isEditMode) return;
|
|
12077
13249
|
document.querySelectorAll("[data-ohw-active-state]").forEach((el) => {
|
|
12078
13250
|
el.removeAttribute("data-ohw-active-state");
|
|
@@ -12107,13 +13279,13 @@ function OhhwellsBridge() {
|
|
|
12107
13279
|
clearTimeout(timer);
|
|
12108
13280
|
};
|
|
12109
13281
|
}, [pathname, isEditMode, refreshStateRules, postToParent2]);
|
|
12110
|
-
(0,
|
|
13282
|
+
(0, import_react11.useEffect)(() => {
|
|
12111
13283
|
scrollToHashSectionWhenReady();
|
|
12112
13284
|
const onHashChange = () => scrollToHashSectionWhenReady();
|
|
12113
13285
|
window.addEventListener("hashchange", onHashChange);
|
|
12114
13286
|
return () => window.removeEventListener("hashchange", onHashChange);
|
|
12115
13287
|
}, [pathname]);
|
|
12116
|
-
const handleCommand = (0,
|
|
13288
|
+
const handleCommand = (0, import_react11.useCallback)((cmd) => {
|
|
12117
13289
|
const el = activeElRef.current;
|
|
12118
13290
|
const selBefore = window.getSelection();
|
|
12119
13291
|
let savedOffsets = null;
|
|
@@ -12149,7 +13321,7 @@ function OhhwellsBridge() {
|
|
|
12149
13321
|
if (el) setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
|
|
12150
13322
|
refreshActiveCommandsRef.current();
|
|
12151
13323
|
}, []);
|
|
12152
|
-
const handleStateChange = (0,
|
|
13324
|
+
const handleStateChange = (0, import_react11.useCallback)((state) => {
|
|
12153
13325
|
if (!activeStateElRef.current) return;
|
|
12154
13326
|
const el = activeStateElRef.current;
|
|
12155
13327
|
if (state === "Default") {
|
|
@@ -12162,22 +13334,22 @@ function OhhwellsBridge() {
|
|
|
12162
13334
|
}
|
|
12163
13335
|
setToggleState((prev) => prev ? { ...prev, activeState: state } : null);
|
|
12164
13336
|
}, [deactivate]);
|
|
12165
|
-
const closeLinkPopover = (0,
|
|
13337
|
+
const closeLinkPopover = (0, import_react11.useCallback)(() => {
|
|
12166
13338
|
addNavAfterAnchorRef.current = null;
|
|
12167
13339
|
setLinkPopover(null);
|
|
12168
13340
|
}, []);
|
|
12169
|
-
const openLinkPopoverForActive = (0,
|
|
13341
|
+
const openLinkPopoverForActive = (0, import_react11.useCallback)(() => {
|
|
12170
13342
|
const hrefCtx = getHrefKeyFromElement(activeElRef.current);
|
|
12171
13343
|
if (!hrefCtx) return;
|
|
12172
13344
|
bumpLinkPopoverGrace();
|
|
12173
13345
|
setLinkPopover({
|
|
12174
13346
|
key: hrefCtx.key,
|
|
12175
13347
|
mode: "edit",
|
|
12176
|
-
target:
|
|
13348
|
+
target: getLinkHref4(hrefCtx.anchor)
|
|
12177
13349
|
});
|
|
12178
13350
|
deactivate();
|
|
12179
13351
|
}, [deactivate]);
|
|
12180
|
-
const openLinkPopoverForSelected = (0,
|
|
13352
|
+
const openLinkPopoverForSelected = (0, import_react11.useCallback)(() => {
|
|
12181
13353
|
const anchor = selectedElRef.current;
|
|
12182
13354
|
if (!anchor) return;
|
|
12183
13355
|
const key = anchor.getAttribute("data-ohw-href-key");
|
|
@@ -12186,11 +13358,142 @@ function OhhwellsBridge() {
|
|
|
12186
13358
|
setLinkPopover({
|
|
12187
13359
|
key,
|
|
12188
13360
|
mode: "edit",
|
|
12189
|
-
target:
|
|
13361
|
+
target: getLinkHref4(anchor)
|
|
12190
13362
|
});
|
|
12191
13363
|
deselect();
|
|
12192
13364
|
}, [deselect]);
|
|
12193
|
-
const
|
|
13365
|
+
const handleSelectParent = (0, import_react11.useCallback)(() => {
|
|
13366
|
+
const selected = selectedElRef.current;
|
|
13367
|
+
if (!selected) return;
|
|
13368
|
+
if (toolbarVariantRef.current === "select-frame") {
|
|
13369
|
+
const parent2 = getNavigationSelectionParent(selected);
|
|
13370
|
+
if (parent2 && isNavigationContainer(parent2) && isFooterLinksContainer(parent2) && !isFooterLinksContainer(selected)) {
|
|
13371
|
+
selectFrameRef.current(parent2);
|
|
13372
|
+
return;
|
|
13373
|
+
}
|
|
13374
|
+
deselectRef.current();
|
|
13375
|
+
return;
|
|
13376
|
+
}
|
|
13377
|
+
const parent = getNavigationSelectionParent(selected);
|
|
13378
|
+
if (parent && isNavigationContainer(parent)) {
|
|
13379
|
+
selectFrameRef.current(parent);
|
|
13380
|
+
} else {
|
|
13381
|
+
deselectRef.current();
|
|
13382
|
+
}
|
|
13383
|
+
}, []);
|
|
13384
|
+
const handleDuplicateSelected = (0, import_react11.useCallback)(() => {
|
|
13385
|
+
const selected = selectedElRef.current;
|
|
13386
|
+
if (!selected || !isNavigationItem2(selected)) return;
|
|
13387
|
+
const hrefKey = selected.getAttribute("data-ohw-href-key");
|
|
13388
|
+
if (!hrefKey) return;
|
|
13389
|
+
if (isNavbarHrefKey(hrefKey)) {
|
|
13390
|
+
const result = duplicateNavbarItem(selected);
|
|
13391
|
+
if (!result) return;
|
|
13392
|
+
applyLinkByKey(result.hrefKey, result.href);
|
|
13393
|
+
document.querySelectorAll(`[data-ohw-key="${result.labelKey}"]`).forEach((el) => {
|
|
13394
|
+
el.textContent = result.label;
|
|
13395
|
+
});
|
|
13396
|
+
const nodes = [
|
|
13397
|
+
{ key: result.hrefKey, text: result.href },
|
|
13398
|
+
{ key: result.labelKey, text: result.label }
|
|
13399
|
+
];
|
|
13400
|
+
for (const child of result.childResults) {
|
|
13401
|
+
applyLinkByKey(child.hrefKey, child.href);
|
|
13402
|
+
document.querySelectorAll(`[data-ohw-key="${child.labelKey}"]`).forEach((el) => {
|
|
13403
|
+
el.textContent = child.label;
|
|
13404
|
+
});
|
|
13405
|
+
nodes.push(
|
|
13406
|
+
{ key: child.hrefKey, text: child.href },
|
|
13407
|
+
{ key: child.labelKey, text: child.label }
|
|
13408
|
+
);
|
|
13409
|
+
}
|
|
13410
|
+
const maxIndex = Math.max(
|
|
13411
|
+
result.index,
|
|
13412
|
+
...result.childResults.map((c) => c.index)
|
|
13413
|
+
);
|
|
13414
|
+
const navCount = String(maxIndex + 1);
|
|
13415
|
+
nodes.push(
|
|
13416
|
+
{ key: NAV_COUNT_KEY, text: navCount },
|
|
13417
|
+
{ key: NAV_ORDER_KEY, text: result.orderJson }
|
|
13418
|
+
);
|
|
13419
|
+
editContentRef.current = {
|
|
13420
|
+
...editContentRef.current,
|
|
13421
|
+
[result.hrefKey]: result.href,
|
|
13422
|
+
[result.labelKey]: result.label,
|
|
13423
|
+
...Object.fromEntries(
|
|
13424
|
+
result.childResults.flatMap((c) => [
|
|
13425
|
+
[c.hrefKey, c.href],
|
|
13426
|
+
[c.labelKey, c.label]
|
|
13427
|
+
])
|
|
13428
|
+
),
|
|
13429
|
+
[NAV_COUNT_KEY]: navCount,
|
|
13430
|
+
[NAV_ORDER_KEY]: result.orderJson
|
|
13431
|
+
};
|
|
13432
|
+
postToParent2({ type: "ow:change", nodes });
|
|
13433
|
+
enforceLinkHrefs();
|
|
13434
|
+
requestAnimationFrame(() => {
|
|
13435
|
+
selectRef.current(result.anchor);
|
|
13436
|
+
});
|
|
13437
|
+
return;
|
|
13438
|
+
}
|
|
13439
|
+
if (isFooterHrefKey(hrefKey)) {
|
|
13440
|
+
const result = duplicateFooterItem(selected);
|
|
13441
|
+
if (!result) return;
|
|
13442
|
+
applyLinkByKey(result.hrefKey, result.href);
|
|
13443
|
+
document.querySelectorAll(`[data-ohw-key="${result.labelKey}"]`).forEach((el) => {
|
|
13444
|
+
el.textContent = result.label;
|
|
13445
|
+
});
|
|
13446
|
+
const orderJson = JSON.stringify(result.order);
|
|
13447
|
+
editContentRef.current = {
|
|
13448
|
+
...editContentRef.current,
|
|
13449
|
+
[result.hrefKey]: result.href,
|
|
13450
|
+
[result.labelKey]: result.label,
|
|
13451
|
+
[FOOTER_ORDER_KEY]: orderJson
|
|
13452
|
+
};
|
|
13453
|
+
postToParent2({
|
|
13454
|
+
type: "ow:change",
|
|
13455
|
+
nodes: [
|
|
13456
|
+
{ key: result.hrefKey, text: result.href },
|
|
13457
|
+
{ key: result.labelKey, text: result.label },
|
|
13458
|
+
{ key: FOOTER_ORDER_KEY, text: orderJson }
|
|
13459
|
+
]
|
|
13460
|
+
});
|
|
13461
|
+
enforceLinkHrefs();
|
|
13462
|
+
requestAnimationFrame(() => {
|
|
13463
|
+
selectRef.current(result.anchor);
|
|
13464
|
+
});
|
|
13465
|
+
}
|
|
13466
|
+
}, [postToParent2]);
|
|
13467
|
+
const runPendingDeleteUndo = (0, import_react11.useCallback)(() => {
|
|
13468
|
+
const pending = pendingDeleteUndoRef.current;
|
|
13469
|
+
if (!pending) return false;
|
|
13470
|
+
pendingDeleteUndoRef.current = null;
|
|
13471
|
+
pending.restore();
|
|
13472
|
+
enforceLinkHrefs();
|
|
13473
|
+
return true;
|
|
13474
|
+
}, []);
|
|
13475
|
+
const handleDeleteSelected = (0, import_react11.useCallback)(() => {
|
|
13476
|
+
const selected = selectedElRef.current;
|
|
13477
|
+
if (!selected) return false;
|
|
13478
|
+
return deleteSelectedNavFooterItem({
|
|
13479
|
+
selected,
|
|
13480
|
+
isTextEditing: Boolean(activeElRef.current),
|
|
13481
|
+
isSelectFrame: toolbarVariantRef.current === "select-frame",
|
|
13482
|
+
getEditContent: () => editContentRef.current,
|
|
13483
|
+
applyLinkByKey,
|
|
13484
|
+
postToParent: postToParent2,
|
|
13485
|
+
deselect: () => deselectRef.current(),
|
|
13486
|
+
setEditContent: (next) => {
|
|
13487
|
+
editContentRef.current = next;
|
|
13488
|
+
},
|
|
13489
|
+
setPendingUndo: (undo) => {
|
|
13490
|
+
pendingDeleteUndoRef.current = undo;
|
|
13491
|
+
}
|
|
13492
|
+
});
|
|
13493
|
+
}, [postToParent2]);
|
|
13494
|
+
handleDeleteSelectedRef.current = handleDeleteSelected;
|
|
13495
|
+
runPendingDeleteUndoRef.current = runPendingDeleteUndo;
|
|
13496
|
+
const handleLinkPopoverSubmit = (0, import_react11.useCallback)(
|
|
12194
13497
|
(target) => {
|
|
12195
13498
|
const session = linkPopoverSessionRef.current;
|
|
12196
13499
|
if (!session) return;
|
|
@@ -12249,19 +13552,19 @@ function OhhwellsBridge() {
|
|
|
12249
13552
|
const showEditLink = toolbarShowEditLink;
|
|
12250
13553
|
const currentSections = sectionsByPath[pathname] ?? [];
|
|
12251
13554
|
linkPopoverOpenRef.current = linkPopover !== null;
|
|
12252
|
-
const handleMediaReplace = (0,
|
|
13555
|
+
const handleMediaReplace = (0, import_react11.useCallback)(
|
|
12253
13556
|
(key) => {
|
|
12254
13557
|
postToParent2({ type: "ow:image-pick", key, elementType: mediaHover?.elementType ?? "image" });
|
|
12255
13558
|
},
|
|
12256
13559
|
[postToParent2, mediaHover?.elementType]
|
|
12257
13560
|
);
|
|
12258
|
-
const handleEditCarousel = (0,
|
|
13561
|
+
const handleEditCarousel = (0, import_react11.useCallback)(
|
|
12259
13562
|
(key) => {
|
|
12260
13563
|
postToParent2({ type: "ow:carousel-open", key, images: readCarouselValue(key) });
|
|
12261
13564
|
},
|
|
12262
13565
|
[postToParent2]
|
|
12263
13566
|
);
|
|
12264
|
-
const handleMediaFadeOutComplete = (0,
|
|
13567
|
+
const handleMediaFadeOutComplete = (0, import_react11.useCallback)((key) => {
|
|
12265
13568
|
setUploadingRects((prev) => {
|
|
12266
13569
|
if (!(key in prev)) return prev;
|
|
12267
13570
|
const next = { ...prev };
|
|
@@ -12269,10 +13572,10 @@ function OhhwellsBridge() {
|
|
|
12269
13572
|
return next;
|
|
12270
13573
|
});
|
|
12271
13574
|
}, []);
|
|
12272
|
-
const handleVideoSettingsChange = (0,
|
|
13575
|
+
const handleVideoSettingsChange = (0, import_react11.useCallback)(
|
|
12273
13576
|
(key, settings) => {
|
|
12274
13577
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
12275
|
-
const video =
|
|
13578
|
+
const video = getVideoEl2(el);
|
|
12276
13579
|
if (!video) return;
|
|
12277
13580
|
if (typeof settings.autoplay === "boolean") video.autoplay = settings.autoplay;
|
|
12278
13581
|
if (typeof settings.muted === "boolean") video.muted = settings.muted;
|
|
@@ -12292,9 +13595,9 @@ function OhhwellsBridge() {
|
|
|
12292
13595
|
[postToParent2]
|
|
12293
13596
|
);
|
|
12294
13597
|
return bridgeRoot ? (0, import_react_dom3.createPortal)(
|
|
12295
|
-
/* @__PURE__ */ (0,
|
|
12296
|
-
/* @__PURE__ */ (0,
|
|
12297
|
-
Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ (0,
|
|
13598
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_jsx_runtime27.Fragment, { children: [
|
|
13599
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
|
|
13600
|
+
Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
12298
13601
|
MediaOverlay,
|
|
12299
13602
|
{
|
|
12300
13603
|
hover: { key, rect, elementType: "image", isDragOver: false, hasTextOverlap: false },
|
|
@@ -12305,7 +13608,7 @@ function OhhwellsBridge() {
|
|
|
12305
13608
|
},
|
|
12306
13609
|
`uploading-${key}`
|
|
12307
13610
|
)),
|
|
12308
|
-
mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */ (0,
|
|
13611
|
+
mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
12309
13612
|
MediaOverlay,
|
|
12310
13613
|
{
|
|
12311
13614
|
hover: mediaHover,
|
|
@@ -12314,11 +13617,11 @@ function OhhwellsBridge() {
|
|
|
12314
13617
|
onVideoSettingsChange: handleVideoSettingsChange
|
|
12315
13618
|
}
|
|
12316
13619
|
),
|
|
12317
|
-
carouselHover && !linkPopover && !isItemDragging && /* @__PURE__ */ (0,
|
|
12318
|
-
siblingHintRect && !linkPopover && !isItemDragging && siblingHintRects.length === 0 && /* @__PURE__ */ (0,
|
|
12319
|
-
siblingHintRects.length > 0 && !linkPopover && !isItemDragging && siblingHintRects.map((rect, i) => /* @__PURE__ */ (0,
|
|
12320
|
-
isItemDragging && draggedItemRect && selectedElRef.current !== footerDragRef.current?.draggedEl && selectedElRef.current !== navDragRef.current?.draggedEl && /* @__PURE__ */ (0,
|
|
12321
|
-
isItemDragging && footerDropSlots.map((slot, i) => /* @__PURE__ */ (0,
|
|
13620
|
+
carouselHover && !linkPopover && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(CarouselOverlay, { hover: carouselHover, onEdit: handleEditCarousel }),
|
|
13621
|
+
siblingHintRect && !linkPopover && !isItemDragging && siblingHintRects.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
|
|
13622
|
+
siblingHintRects.length > 0 && !linkPopover && !isItemDragging && siblingHintRects.map((rect, i) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ItemInteractionLayer, { rect, state: "sibling-hint" }, `sibling-hint-${i}`)),
|
|
13623
|
+
isItemDragging && draggedItemRect && selectedElRef.current !== footerDragRef.current?.draggedEl && selectedElRef.current !== navDragRef.current?.draggedEl && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ItemInteractionLayer, { rect: draggedItemRect, state: "dragging" }),
|
|
13624
|
+
isItemDragging && footerDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
12322
13625
|
"div",
|
|
12323
13626
|
{
|
|
12324
13627
|
className: "pointer-events-none fixed z-2147483646",
|
|
@@ -12328,7 +13631,7 @@ function OhhwellsBridge() {
|
|
|
12328
13631
|
width: slot.width,
|
|
12329
13632
|
height: slot.height
|
|
12330
13633
|
},
|
|
12331
|
-
children: /* @__PURE__ */ (0,
|
|
13634
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
12332
13635
|
DropIndicator,
|
|
12333
13636
|
{
|
|
12334
13637
|
direction: slot.direction,
|
|
@@ -12339,7 +13642,7 @@ function OhhwellsBridge() {
|
|
|
12339
13642
|
},
|
|
12340
13643
|
`footer-drop-${slot.direction}-${slot.columnIndex}-${slot.insertIndex}-${i}`
|
|
12341
13644
|
)),
|
|
12342
|
-
isItemDragging && navDropSlots.map((slot, i) => /* @__PURE__ */ (0,
|
|
13645
|
+
isItemDragging && navDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
12343
13646
|
"div",
|
|
12344
13647
|
{
|
|
12345
13648
|
className: "pointer-events-none fixed z-2147483646",
|
|
@@ -12349,7 +13652,7 @@ function OhhwellsBridge() {
|
|
|
12349
13652
|
width: slot.width,
|
|
12350
13653
|
height: slot.height
|
|
12351
13654
|
},
|
|
12352
|
-
children: /* @__PURE__ */ (0,
|
|
13655
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
12353
13656
|
DropIndicator,
|
|
12354
13657
|
{
|
|
12355
13658
|
direction: slot.direction,
|
|
@@ -12360,10 +13663,18 @@ function OhhwellsBridge() {
|
|
|
12360
13663
|
},
|
|
12361
13664
|
`nav-drop-${slot.direction}-${slot.parentId ?? "root"}-${slot.insertIndex}-${i}`
|
|
12362
13665
|
)),
|
|
12363
|
-
hoveredNavContainerRect && toolbarVariant !== "select-frame" && !linkPopover && !isItemDragging && /* @__PURE__ */ (0,
|
|
12364
|
-
hoveredItemRect && !linkPopover && !hoveredNavContainerRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ (0,
|
|
12365
|
-
toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current &&
|
|
12366
|
-
toolbarRect && !linkPopover &&
|
|
13666
|
+
hoveredNavContainerRect && (toolbarVariant !== "select-frame" || isFooterFrameSelection) && !linkPopover && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ItemInteractionLayer, { rect: hoveredNavContainerRect, state: "hover" }),
|
|
13667
|
+
hoveredItemRect && !linkPopover && !hoveredNavContainerRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
|
|
13668
|
+
toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isNavbarLinksContainer2(selectedElRef.current) && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(NavbarContainerChrome, { rect: toolbarRect, onAdd: handleAddTopLevelNavItem }),
|
|
13669
|
+
toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isFooterLinksContainer(selectedElRef.current) && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
13670
|
+
FooterContainerChrome,
|
|
13671
|
+
{
|
|
13672
|
+
rect: toolbarRect,
|
|
13673
|
+
onAdd: handleAddFooterColumn,
|
|
13674
|
+
addDisabled: !canAddFooterColumn()
|
|
13675
|
+
}
|
|
13676
|
+
),
|
|
13677
|
+
toolbarRect && !linkPopover && (toolbarVariant === "link-action" || toolbarVariant === "select-frame") && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
12367
13678
|
ItemInteractionLayer,
|
|
12368
13679
|
{
|
|
12369
13680
|
rect: isItemDragging && draggedItemRect && (footerDragRef.current?.wasSelected || navDragRef.current?.wasSelected) ? draggedItemRect : toolbarRect,
|
|
@@ -12377,21 +13688,26 @@ function OhhwellsBridge() {
|
|
|
12377
13688
|
onItemPointerDown: handleItemChromePointerDown,
|
|
12378
13689
|
onItemClick: handleItemChromeClick,
|
|
12379
13690
|
itemDragSurface: !isFooterFrameSelection,
|
|
12380
|
-
toolbar: toolbarVariant === "link-action" && !isItemDragging ? /* @__PURE__ */ (0,
|
|
13691
|
+
toolbar: toolbarVariant === "link-action" && !isItemDragging || toolbarVariant === "select-frame" && isFooterFrameSelection && !isItemDragging ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
12381
13692
|
ItemActionToolbar,
|
|
12382
13693
|
{
|
|
12383
13694
|
onEditLink: openLinkPopoverForSelected,
|
|
13695
|
+
onSelectParent: handleSelectParent,
|
|
13696
|
+
onDuplicate: handleDuplicateSelected,
|
|
13697
|
+
onDelete: handleDeleteSelected,
|
|
12384
13698
|
addItemDisabled: true,
|
|
12385
13699
|
editLinkDisabled: false,
|
|
12386
|
-
moreDisabled:
|
|
12387
|
-
|
|
12388
|
-
|
|
13700
|
+
moreDisabled: false,
|
|
13701
|
+
duplicateDisabled: isFooterFrameSelection,
|
|
13702
|
+
showEditLink: !isFooterFrameSelection,
|
|
13703
|
+
showAddItem: !selectedIsCta && !isFooterFrameSelection,
|
|
13704
|
+
showMore: !selectedIsCta || isFooterFrameSelection
|
|
12389
13705
|
}
|
|
12390
13706
|
) : void 0
|
|
12391
13707
|
}
|
|
12392
13708
|
),
|
|
12393
|
-
toolbarRect && toolbarVariant === "rich-text" && !linkPopover && /* @__PURE__ */ (0,
|
|
12394
|
-
/* @__PURE__ */ (0,
|
|
13709
|
+
toolbarRect && toolbarVariant === "rich-text" && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_jsx_runtime27.Fragment, { children: [
|
|
13710
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
12395
13711
|
EditGlowChrome,
|
|
12396
13712
|
{
|
|
12397
13713
|
rect: toolbarRect,
|
|
@@ -12401,7 +13717,7 @@ function OhhwellsBridge() {
|
|
|
12401
13717
|
hideHandle: isItemDragging
|
|
12402
13718
|
}
|
|
12403
13719
|
),
|
|
12404
|
-
/* @__PURE__ */ (0,
|
|
13720
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
12405
13721
|
FloatingToolbar,
|
|
12406
13722
|
{
|
|
12407
13723
|
rect: toolbarRect,
|
|
@@ -12414,7 +13730,7 @@ function OhhwellsBridge() {
|
|
|
12414
13730
|
}
|
|
12415
13731
|
)
|
|
12416
13732
|
] }),
|
|
12417
|
-
maxBadge && /* @__PURE__ */ (0,
|
|
13733
|
+
maxBadge && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
|
|
12418
13734
|
"div",
|
|
12419
13735
|
{
|
|
12420
13736
|
"data-ohw-max-badge": "",
|
|
@@ -12440,7 +13756,7 @@ function OhhwellsBridge() {
|
|
|
12440
13756
|
]
|
|
12441
13757
|
}
|
|
12442
13758
|
),
|
|
12443
|
-
toggleState && !linkPopover && /* @__PURE__ */ (0,
|
|
13759
|
+
toggleState && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
12444
13760
|
StateToggle,
|
|
12445
13761
|
{
|
|
12446
13762
|
rect: toggleState.rect,
|
|
@@ -12449,15 +13765,15 @@ function OhhwellsBridge() {
|
|
|
12449
13765
|
onStateChange: handleStateChange
|
|
12450
13766
|
}
|
|
12451
13767
|
),
|
|
12452
|
-
sectionGap && !linkPopover && /* @__PURE__ */ (0,
|
|
13768
|
+
sectionGap && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
|
|
12453
13769
|
"div",
|
|
12454
13770
|
{
|
|
12455
13771
|
"data-ohw-section-insert-line": "",
|
|
12456
13772
|
className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
|
|
12457
13773
|
style: { top: sectionGap.y, transform: "translateY(-50%)" },
|
|
12458
13774
|
children: [
|
|
12459
|
-
/* @__PURE__ */ (0,
|
|
12460
|
-
/* @__PURE__ */ (0,
|
|
13775
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
|
|
13776
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
12461
13777
|
Badge,
|
|
12462
13778
|
{
|
|
12463
13779
|
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",
|
|
@@ -12474,11 +13790,11 @@ function OhhwellsBridge() {
|
|
|
12474
13790
|
children: "Add Section"
|
|
12475
13791
|
}
|
|
12476
13792
|
),
|
|
12477
|
-
/* @__PURE__ */ (0,
|
|
13793
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } })
|
|
12478
13794
|
]
|
|
12479
13795
|
}
|
|
12480
13796
|
),
|
|
12481
|
-
linkPopover && dialogPortalContainer ? /* @__PURE__ */ (0,
|
|
13797
|
+
linkPopover && dialogPortalContainer ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
12482
13798
|
LinkPopover,
|
|
12483
13799
|
{
|
|
12484
13800
|
panelRef: linkPopoverPanelRef,
|
|
@@ -12506,6 +13822,12 @@ function OhhwellsBridge() {
|
|
|
12506
13822
|
CustomToolbarDivider,
|
|
12507
13823
|
DragHandle,
|
|
12508
13824
|
DropIndicator,
|
|
13825
|
+
DropdownMenu,
|
|
13826
|
+
DropdownMenuContent,
|
|
13827
|
+
DropdownMenuGroup,
|
|
13828
|
+
DropdownMenuItem,
|
|
13829
|
+
DropdownMenuSeparator,
|
|
13830
|
+
DropdownMenuTrigger,
|
|
12509
13831
|
ItemActionToolbar,
|
|
12510
13832
|
ItemInteractionLayer,
|
|
12511
13833
|
LinkEditorPanel,
|