@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.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
// src/OhhwellsBridge.tsx
|
|
4
|
-
import React11, { useCallback as useCallback5, useEffect as useEffect9, useLayoutEffect as useLayoutEffect3, useRef as useRef7, useState as
|
|
4
|
+
import React11, { useCallback as useCallback5, useEffect as useEffect9, useLayoutEffect as useLayoutEffect3, useRef as useRef7, useState as useState9 } from "react";
|
|
5
5
|
import { createRoot } from "react-dom/client";
|
|
6
6
|
import { flushSync } from "react-dom";
|
|
7
7
|
|
|
@@ -13,6 +13,9 @@ function setStoredLinkHref(key, href) {
|
|
|
13
13
|
function getStoredLinkHref(key) {
|
|
14
14
|
return linkHrefStore.get(key);
|
|
15
15
|
}
|
|
16
|
+
function clearStoredLinkHref(key) {
|
|
17
|
+
linkHrefStore.delete(key);
|
|
18
|
+
}
|
|
16
19
|
function enforceLinkHrefs() {
|
|
17
20
|
document.querySelectorAll("[data-ohw-href-key]").forEach((el) => {
|
|
18
21
|
const key = el.getAttribute("data-ohw-href-key") ?? "";
|
|
@@ -4338,22 +4341,116 @@ var CustomToolbarButton = React4.forwardRef(
|
|
|
4338
4341
|
CustomToolbarButton.displayName = "CustomToolbarButton";
|
|
4339
4342
|
|
|
4340
4343
|
// src/ui/item-action-toolbar.tsx
|
|
4341
|
-
import {
|
|
4344
|
+
import { useState as useState3 } from "react";
|
|
4345
|
+
import { Copy, CornerLeftUp, Link, MoreHorizontal, Plus, Trash2 } from "lucide-react";
|
|
4346
|
+
|
|
4347
|
+
// src/ui/dropdown-menu.tsx
|
|
4348
|
+
import { DropdownMenu as DropdownMenuPrimitive } from "radix-ui";
|
|
4349
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
4350
|
+
function DropdownMenu({ ...props }) {
|
|
4351
|
+
return /* @__PURE__ */ jsx7(DropdownMenuPrimitive.Root, { "data-slot": "dropdown-menu", ...props });
|
|
4352
|
+
}
|
|
4353
|
+
function DropdownMenuTrigger({
|
|
4354
|
+
...props
|
|
4355
|
+
}) {
|
|
4356
|
+
return /* @__PURE__ */ jsx7(DropdownMenuPrimitive.Trigger, { "data-slot": "dropdown-menu-trigger", ...props });
|
|
4357
|
+
}
|
|
4358
|
+
function DropdownMenuGroup({
|
|
4359
|
+
className,
|
|
4360
|
+
...props
|
|
4361
|
+
}) {
|
|
4362
|
+
return /* @__PURE__ */ jsx7(
|
|
4363
|
+
DropdownMenuPrimitive.Group,
|
|
4364
|
+
{
|
|
4365
|
+
"data-slot": "dropdown-menu-group",
|
|
4366
|
+
className: cn("flex w-full flex-col items-start p-1", className),
|
|
4367
|
+
...props
|
|
4368
|
+
}
|
|
4369
|
+
);
|
|
4370
|
+
}
|
|
4371
|
+
function DropdownMenuContent({
|
|
4372
|
+
className,
|
|
4373
|
+
sideOffset = 6,
|
|
4374
|
+
...props
|
|
4375
|
+
}) {
|
|
4376
|
+
return /* @__PURE__ */ jsx7(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx7(
|
|
4377
|
+
DropdownMenuPrimitive.Content,
|
|
4378
|
+
{
|
|
4379
|
+
"data-slot": "dropdown-menu-content",
|
|
4380
|
+
"data-ohw-more-menu": "",
|
|
4381
|
+
sideOffset,
|
|
4382
|
+
className: cn(
|
|
4383
|
+
"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",
|
|
4384
|
+
"shadow-[0px_4px_6px_0px_rgba(0,0,0,0.1),0px_2px_4px_0px_rgba(0,0,0,0.1)]",
|
|
4385
|
+
"origin-[var(--radix-dropdown-menu-content-transform-origin)]",
|
|
4386
|
+
"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",
|
|
4387
|
+
"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",
|
|
4388
|
+
className
|
|
4389
|
+
),
|
|
4390
|
+
...props
|
|
4391
|
+
}
|
|
4392
|
+
) });
|
|
4393
|
+
}
|
|
4394
|
+
function DropdownMenuItem({
|
|
4395
|
+
className,
|
|
4396
|
+
inset,
|
|
4397
|
+
variant = "default",
|
|
4398
|
+
...props
|
|
4399
|
+
}) {
|
|
4400
|
+
return /* @__PURE__ */ jsx7(
|
|
4401
|
+
DropdownMenuPrimitive.Item,
|
|
4402
|
+
{
|
|
4403
|
+
"data-slot": "dropdown-menu-item",
|
|
4404
|
+
"data-inset": inset ? "" : void 0,
|
|
4405
|
+
"data-variant": variant,
|
|
4406
|
+
className: cn(
|
|
4407
|
+
"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",
|
|
4408
|
+
"text-popover-foreground",
|
|
4409
|
+
"focus:bg-muted data-[highlighted]:bg-muted",
|
|
4410
|
+
"data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
4411
|
+
"[&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
|
4412
|
+
"[&_svg:not([class*=absolute])]:relative",
|
|
4413
|
+
// Leading icon — Figma absolute left-2 / top-1/2
|
|
4414
|
+
"[&>svg:first-child]:absolute [&>svg:first-child]:left-2 [&>svg:first-child]:top-1/2 [&>svg:first-child]:-translate-y-1/2",
|
|
4415
|
+
"data-[variant=destructive]:text-destructive",
|
|
4416
|
+
"data-[variant=destructive]:focus:bg-bg-destructive-10 data-[variant=destructive]:focus:text-destructive",
|
|
4417
|
+
"data-[variant=destructive]:data-[highlighted]:bg-bg-destructive-10 data-[variant=destructive]:data-[highlighted]:text-destructive",
|
|
4418
|
+
"data-[variant=destructive]:[&_svg]:text-destructive",
|
|
4419
|
+
inset && "pl-8",
|
|
4420
|
+
className
|
|
4421
|
+
),
|
|
4422
|
+
...props
|
|
4423
|
+
}
|
|
4424
|
+
);
|
|
4425
|
+
}
|
|
4426
|
+
function DropdownMenuSeparator({
|
|
4427
|
+
className,
|
|
4428
|
+
...props
|
|
4429
|
+
}) {
|
|
4430
|
+
return /* @__PURE__ */ jsx7(
|
|
4431
|
+
DropdownMenuPrimitive.Separator,
|
|
4432
|
+
{
|
|
4433
|
+
"data-slot": "dropdown-menu-separator",
|
|
4434
|
+
className: cn("h-px w-full bg-border", className),
|
|
4435
|
+
...props
|
|
4436
|
+
}
|
|
4437
|
+
);
|
|
4438
|
+
}
|
|
4342
4439
|
|
|
4343
4440
|
// src/ui/tooltip.tsx
|
|
4344
4441
|
import { Tooltip as TooltipPrimitive } from "radix-ui";
|
|
4345
|
-
import { jsx as
|
|
4442
|
+
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
4346
4443
|
function TooltipProvider({
|
|
4347
4444
|
delayDuration = 0,
|
|
4348
4445
|
...props
|
|
4349
4446
|
}) {
|
|
4350
|
-
return /* @__PURE__ */
|
|
4447
|
+
return /* @__PURE__ */ jsx8(TooltipPrimitive.Provider, { "data-slot": "tooltip-provider", delayDuration, ...props });
|
|
4351
4448
|
}
|
|
4352
4449
|
function Tooltip({ ...props }) {
|
|
4353
|
-
return /* @__PURE__ */
|
|
4450
|
+
return /* @__PURE__ */ jsx8(TooltipPrimitive.Root, { "data-slot": "tooltip", ...props });
|
|
4354
4451
|
}
|
|
4355
4452
|
function TooltipTrigger({ ...props }) {
|
|
4356
|
-
return /* @__PURE__ */
|
|
4453
|
+
return /* @__PURE__ */ jsx8(TooltipPrimitive.Trigger, { "data-slot": "tooltip-trigger", ...props });
|
|
4357
4454
|
}
|
|
4358
4455
|
var arrowClassBySide = {
|
|
4359
4456
|
top: "before:bottom-0 before:left-1/2 before:-translate-x-1/2 before:translate-y-1/2",
|
|
@@ -4370,7 +4467,7 @@ function TooltipContent({
|
|
|
4370
4467
|
...props
|
|
4371
4468
|
}) {
|
|
4372
4469
|
const resolvedSide = side ?? "bottom";
|
|
4373
|
-
return /* @__PURE__ */
|
|
4470
|
+
return /* @__PURE__ */ jsx8(TooltipPrimitive.Portal, { children: /* @__PURE__ */ jsx8(
|
|
4374
4471
|
TooltipPrimitive.Content,
|
|
4375
4472
|
{
|
|
4376
4473
|
"data-slot": "tooltip-content",
|
|
@@ -4393,7 +4490,7 @@ function TooltipContent({
|
|
|
4393
4490
|
}
|
|
4394
4491
|
|
|
4395
4492
|
// src/ui/item-action-toolbar.tsx
|
|
4396
|
-
import { jsx as
|
|
4493
|
+
import { jsx as jsx9, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
4397
4494
|
function ToolbarActionTooltip({
|
|
4398
4495
|
label,
|
|
4399
4496
|
side = "bottom",
|
|
@@ -4401,25 +4498,32 @@ function ToolbarActionTooltip({
|
|
|
4401
4498
|
buttonProps,
|
|
4402
4499
|
children
|
|
4403
4500
|
}) {
|
|
4404
|
-
const button = /* @__PURE__ */
|
|
4501
|
+
const button = /* @__PURE__ */ jsx9(CustomToolbarButton, { type: "button", "aria-label": label, disabled, ...buttonProps, children });
|
|
4405
4502
|
return /* @__PURE__ */ jsxs3(Tooltip, { children: [
|
|
4406
|
-
/* @__PURE__ */
|
|
4407
|
-
/* @__PURE__ */
|
|
4503
|
+
/* @__PURE__ */ jsx9(TooltipTrigger, { asChild: true, children: disabled ? /* @__PURE__ */ jsx9("span", { className: "inline-flex", children: button }) : button }),
|
|
4504
|
+
/* @__PURE__ */ jsx9(TooltipContent, { side, sideOffset: 9, children: label })
|
|
4408
4505
|
] });
|
|
4409
4506
|
}
|
|
4410
4507
|
function ItemActionToolbar({
|
|
4411
4508
|
onEditLink,
|
|
4412
4509
|
onAddItem,
|
|
4413
|
-
|
|
4510
|
+
onSelectParent,
|
|
4511
|
+
onDuplicate,
|
|
4512
|
+
onDelete,
|
|
4414
4513
|
editLinkDisabled = false,
|
|
4415
4514
|
addItemDisabled = true,
|
|
4416
|
-
moreDisabled =
|
|
4515
|
+
moreDisabled = false,
|
|
4516
|
+
selectParentDisabled = false,
|
|
4517
|
+
duplicateDisabled = false,
|
|
4518
|
+
deleteDisabled = false,
|
|
4519
|
+
showEditLink = true,
|
|
4417
4520
|
showAddItem = true,
|
|
4418
4521
|
showMore = true,
|
|
4419
4522
|
tooltipSide = "bottom"
|
|
4420
4523
|
}) {
|
|
4421
|
-
|
|
4422
|
-
|
|
4524
|
+
const [moreOpen, setMoreOpen] = useState3(false);
|
|
4525
|
+
return /* @__PURE__ */ jsx9(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ jsxs3(CustomToolbar, { children: [
|
|
4526
|
+
showEditLink ? /* @__PURE__ */ jsx9(
|
|
4423
4527
|
ToolbarActionTooltip,
|
|
4424
4528
|
{
|
|
4425
4529
|
label: "Edit link",
|
|
@@ -4437,10 +4541,10 @@ function ItemActionToolbar({
|
|
|
4437
4541
|
e.stopPropagation();
|
|
4438
4542
|
}
|
|
4439
4543
|
},
|
|
4440
|
-
children: /* @__PURE__ */
|
|
4544
|
+
children: /* @__PURE__ */ jsx9(Link, { className: "size-4 shrink-0", "aria-hidden": true })
|
|
4441
4545
|
}
|
|
4442
|
-
),
|
|
4443
|
-
showAddItem ? /* @__PURE__ */
|
|
4546
|
+
) : null,
|
|
4547
|
+
showAddItem ? /* @__PURE__ */ jsx9(
|
|
4444
4548
|
ToolbarActionTooltip,
|
|
4445
4549
|
{
|
|
4446
4550
|
label: "Add item",
|
|
@@ -4454,32 +4558,84 @@ function ItemActionToolbar({
|
|
|
4454
4558
|
onAddItem?.();
|
|
4455
4559
|
}
|
|
4456
4560
|
},
|
|
4457
|
-
children: /* @__PURE__ */
|
|
4561
|
+
children: /* @__PURE__ */ jsx9(Plus, { className: "size-4 shrink-0", "aria-hidden": true })
|
|
4458
4562
|
}
|
|
4459
4563
|
) : null,
|
|
4460
|
-
showMore ? /* @__PURE__ */
|
|
4461
|
-
|
|
4462
|
-
|
|
4463
|
-
|
|
4464
|
-
|
|
4465
|
-
|
|
4466
|
-
|
|
4564
|
+
showMore ? /* @__PURE__ */ jsxs3(DropdownMenu, { open: moreOpen, onOpenChange: setMoreOpen, children: [
|
|
4565
|
+
/* @__PURE__ */ jsxs3(Tooltip, { open: moreOpen ? false : void 0, children: [
|
|
4566
|
+
/* @__PURE__ */ jsx9(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx9(DropdownMenuTrigger, { asChild: true, disabled: moreDisabled, children: /* @__PURE__ */ jsx9(
|
|
4567
|
+
CustomToolbarButton,
|
|
4568
|
+
{
|
|
4569
|
+
type: "button",
|
|
4570
|
+
"aria-label": "More",
|
|
4571
|
+
disabled: moreDisabled,
|
|
4572
|
+
onMouseDown: (e) => {
|
|
4573
|
+
e.preventDefault();
|
|
4574
|
+
e.stopPropagation();
|
|
4575
|
+
},
|
|
4576
|
+
children: /* @__PURE__ */ jsx9(MoreHorizontal, { className: "size-4 shrink-0", "aria-hidden": true })
|
|
4577
|
+
}
|
|
4578
|
+
) }) }),
|
|
4579
|
+
/* @__PURE__ */ jsx9(TooltipContent, { side: tooltipSide, sideOffset: 9, children: "More" })
|
|
4580
|
+
] }),
|
|
4581
|
+
/* @__PURE__ */ jsxs3(
|
|
4582
|
+
DropdownMenuContent,
|
|
4583
|
+
{
|
|
4584
|
+
align: "end",
|
|
4585
|
+
side: "bottom",
|
|
4586
|
+
onCloseAutoFocus: (e) => e.preventDefault(),
|
|
4467
4587
|
onMouseDown: (e) => {
|
|
4468
|
-
if (moreDisabled) return;
|
|
4469
4588
|
e.preventDefault();
|
|
4470
4589
|
e.stopPropagation();
|
|
4471
|
-
|
|
4472
|
-
|
|
4473
|
-
|
|
4474
|
-
|
|
4475
|
-
|
|
4476
|
-
|
|
4590
|
+
},
|
|
4591
|
+
children: [
|
|
4592
|
+
/* @__PURE__ */ jsxs3(DropdownMenuGroup, { children: [
|
|
4593
|
+
/* @__PURE__ */ jsxs3(
|
|
4594
|
+
DropdownMenuItem,
|
|
4595
|
+
{
|
|
4596
|
+
disabled: selectParentDisabled,
|
|
4597
|
+
onSelect: () => onSelectParent?.(),
|
|
4598
|
+
children: [
|
|
4599
|
+
/* @__PURE__ */ jsx9(CornerLeftUp, { size: 12, "aria-hidden": true }),
|
|
4600
|
+
"Select parent"
|
|
4601
|
+
]
|
|
4602
|
+
}
|
|
4603
|
+
),
|
|
4604
|
+
/* @__PURE__ */ jsxs3(
|
|
4605
|
+
DropdownMenuItem,
|
|
4606
|
+
{
|
|
4607
|
+
disabled: duplicateDisabled,
|
|
4608
|
+
onSelect: () => onDuplicate?.(),
|
|
4609
|
+
children: [
|
|
4610
|
+
/* @__PURE__ */ jsx9(Copy, { size: 12, "aria-hidden": true }),
|
|
4611
|
+
"Duplicate"
|
|
4612
|
+
]
|
|
4613
|
+
}
|
|
4614
|
+
)
|
|
4615
|
+
] }),
|
|
4616
|
+
/* @__PURE__ */ jsx9(DropdownMenuSeparator, {}),
|
|
4617
|
+
/* @__PURE__ */ jsx9(DropdownMenuGroup, { children: /* @__PURE__ */ jsxs3(
|
|
4618
|
+
DropdownMenuItem,
|
|
4619
|
+
{
|
|
4620
|
+
variant: "destructive",
|
|
4621
|
+
disabled: deleteDisabled,
|
|
4622
|
+
onSelect: () => onDelete?.(),
|
|
4623
|
+
children: [
|
|
4624
|
+
/* @__PURE__ */ jsx9(Trash2, { size: 15, "aria-hidden": true }),
|
|
4625
|
+
"Delete"
|
|
4626
|
+
]
|
|
4627
|
+
}
|
|
4628
|
+
) })
|
|
4629
|
+
]
|
|
4630
|
+
}
|
|
4631
|
+
)
|
|
4632
|
+
] }) : null
|
|
4477
4633
|
] }) });
|
|
4478
4634
|
}
|
|
4479
4635
|
|
|
4480
4636
|
// src/ui/item-interaction-layer.tsx
|
|
4481
4637
|
import * as React5 from "react";
|
|
4482
|
-
import { jsx as
|
|
4638
|
+
import { jsx as jsx10, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
4483
4639
|
var PRIMARY = "var(--ohw-primary, #0885FE)";
|
|
4484
4640
|
var FOCUS_RING = `0 0 0 4px color-mix(in srgb, ${PRIMARY} 12%, transparent)`;
|
|
4485
4641
|
var DRAG_SHADOW = "0px 4px 6px -1px rgba(0, 0, 0, 0.1), 0px 2px 4px -2px rgba(0, 0, 0, 0.1)";
|
|
@@ -4561,7 +4717,7 @@ function ClampedToolbarSlot({
|
|
|
4561
4717
|
window.removeEventListener("resize", clamp);
|
|
4562
4718
|
};
|
|
4563
4719
|
}, [placement, children]);
|
|
4564
|
-
return /* @__PURE__ */
|
|
4720
|
+
return /* @__PURE__ */ jsx10(
|
|
4565
4721
|
"div",
|
|
4566
4722
|
{
|
|
4567
4723
|
ref: slotRef,
|
|
@@ -4617,7 +4773,7 @@ function ItemInteractionLayer({
|
|
|
4617
4773
|
zIndex: getChromeZIndex(state)
|
|
4618
4774
|
},
|
|
4619
4775
|
children: [
|
|
4620
|
-
/* @__PURE__ */
|
|
4776
|
+
/* @__PURE__ */ jsx10(
|
|
4621
4777
|
"div",
|
|
4622
4778
|
{
|
|
4623
4779
|
"aria-hidden": true,
|
|
@@ -4625,7 +4781,7 @@ function ItemInteractionLayer({
|
|
|
4625
4781
|
style: getChromeStyle(state)
|
|
4626
4782
|
}
|
|
4627
4783
|
),
|
|
4628
|
-
itemDragEnabled && /* @__PURE__ */
|
|
4784
|
+
itemDragEnabled && /* @__PURE__ */ jsx10(
|
|
4629
4785
|
"div",
|
|
4630
4786
|
{
|
|
4631
4787
|
"data-ohw-item-drag-surface": "",
|
|
@@ -4641,14 +4797,14 @@ function ItemInteractionLayer({
|
|
|
4641
4797
|
}
|
|
4642
4798
|
}
|
|
4643
4799
|
),
|
|
4644
|
-
showDragHandle && /* @__PURE__ */
|
|
4800
|
+
showDragHandle && /* @__PURE__ */ jsx10(
|
|
4645
4801
|
"div",
|
|
4646
4802
|
{
|
|
4647
4803
|
"data-ohw-drag-handle-container": "",
|
|
4648
4804
|
className: "pointer-events-auto absolute left-0 top-1/2 z-10 -translate-x-[calc(100%+7px)] -translate-y-1/2",
|
|
4649
4805
|
style: isDragging ? { opacity: 0 } : void 0,
|
|
4650
4806
|
"aria-hidden": isDragging || void 0,
|
|
4651
|
-
children: /* @__PURE__ */
|
|
4807
|
+
children: /* @__PURE__ */ jsx10(
|
|
4652
4808
|
DragHandle,
|
|
4653
4809
|
{
|
|
4654
4810
|
draggable: !dragDisabled,
|
|
@@ -4678,8 +4834,8 @@ function ItemInteractionLayer({
|
|
|
4678
4834
|
)
|
|
4679
4835
|
}
|
|
4680
4836
|
),
|
|
4681
|
-
showToolbar && state === "active-top" && /* @__PURE__ */
|
|
4682
|
-
showToolbar && state === "active-bottom" && /* @__PURE__ */
|
|
4837
|
+
showToolbar && state === "active-top" && /* @__PURE__ */ jsx10(ClampedToolbarSlot, { placement: "top", children: toolbar }),
|
|
4838
|
+
showToolbar && state === "active-bottom" && /* @__PURE__ */ jsx10(ClampedToolbarSlot, { placement: "bottom", children: toolbar })
|
|
4683
4839
|
]
|
|
4684
4840
|
}
|
|
4685
4841
|
);
|
|
@@ -4692,7 +4848,7 @@ import { Film, ImageIcon, Pause, Play, Volume2, VolumeX } from "lucide-react";
|
|
|
4692
4848
|
// src/ui/button.tsx
|
|
4693
4849
|
import * as React6 from "react";
|
|
4694
4850
|
import { Slot } from "radix-ui";
|
|
4695
|
-
import { jsx as
|
|
4851
|
+
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
4696
4852
|
var buttonVariants = cva(
|
|
4697
4853
|
"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",
|
|
4698
4854
|
{
|
|
@@ -4716,7 +4872,7 @@ var buttonVariants = cva(
|
|
|
4716
4872
|
var Button = React6.forwardRef(
|
|
4717
4873
|
({ className, variant, size, asChild = false, ...props }, ref) => {
|
|
4718
4874
|
const Comp = asChild ? Slot.Root : "button";
|
|
4719
|
-
return /* @__PURE__ */
|
|
4875
|
+
return /* @__PURE__ */ jsx11(
|
|
4720
4876
|
Comp,
|
|
4721
4877
|
{
|
|
4722
4878
|
ref,
|
|
@@ -4730,7 +4886,7 @@ var Button = React6.forwardRef(
|
|
|
4730
4886
|
Button.displayName = "Button";
|
|
4731
4887
|
|
|
4732
4888
|
// src/ui/MediaOverlay.tsx
|
|
4733
|
-
import { Fragment as Fragment2, jsx as
|
|
4889
|
+
import { Fragment as Fragment2, jsx as jsx12, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
4734
4890
|
var MEDIA_UPLOAD_FADE_MS = 300;
|
|
4735
4891
|
var VIDEO_SETTINGS_BAR_INSET = 8;
|
|
4736
4892
|
var OVERLAY_BUTTON_STYLE = {
|
|
@@ -4788,7 +4944,7 @@ function MediaOverlay({
|
|
|
4788
4944
|
return () => anim.cancel();
|
|
4789
4945
|
}, [isUploading, fadingOut, onFadeOutComplete, hover.key]);
|
|
4790
4946
|
if (isUploading) {
|
|
4791
|
-
return /* @__PURE__ */
|
|
4947
|
+
return /* @__PURE__ */ jsx12(
|
|
4792
4948
|
"div",
|
|
4793
4949
|
{
|
|
4794
4950
|
ref: skeletonRef,
|
|
@@ -4797,7 +4953,7 @@ function MediaOverlay({
|
|
|
4797
4953
|
"data-ohw-media-skeleton": "",
|
|
4798
4954
|
"aria-hidden": true,
|
|
4799
4955
|
style: { ...box, pointerEvents: "none" },
|
|
4800
|
-
children: /* @__PURE__ */
|
|
4956
|
+
children: /* @__PURE__ */ jsx12("style", { children: SKELETON_CSS })
|
|
4801
4957
|
}
|
|
4802
4958
|
);
|
|
4803
4959
|
}
|
|
@@ -4817,7 +4973,7 @@ function MediaOverlay({
|
|
|
4817
4973
|
},
|
|
4818
4974
|
onClick: (e) => e.stopPropagation(),
|
|
4819
4975
|
children: [
|
|
4820
|
-
/* @__PURE__ */
|
|
4976
|
+
/* @__PURE__ */ jsx12(
|
|
4821
4977
|
Button,
|
|
4822
4978
|
{
|
|
4823
4979
|
"data-ohw-media-overlay": "",
|
|
@@ -4832,10 +4988,10 @@ function MediaOverlay({
|
|
|
4832
4988
|
e.stopPropagation();
|
|
4833
4989
|
onVideoSettingsChange?.(hover.key, { autoplay: !autoplay });
|
|
4834
4990
|
},
|
|
4835
|
-
children: autoplay ? /* @__PURE__ */
|
|
4991
|
+
children: autoplay ? /* @__PURE__ */ jsx12(Pause, { size: 14 }) : /* @__PURE__ */ jsx12(Play, { size: 14 })
|
|
4836
4992
|
}
|
|
4837
4993
|
),
|
|
4838
|
-
/* @__PURE__ */
|
|
4994
|
+
/* @__PURE__ */ jsx12(
|
|
4839
4995
|
Button,
|
|
4840
4996
|
{
|
|
4841
4997
|
"data-ohw-media-overlay": "",
|
|
@@ -4850,7 +5006,7 @@ function MediaOverlay({
|
|
|
4850
5006
|
e.stopPropagation();
|
|
4851
5007
|
onVideoSettingsChange?.(hover.key, { muted: !muted });
|
|
4852
5008
|
},
|
|
4853
|
-
children: muted ? /* @__PURE__ */
|
|
5009
|
+
children: muted ? /* @__PURE__ */ jsx12(VolumeX, { size: 14 }) : /* @__PURE__ */ jsx12(Volume2, { size: 14 })
|
|
4854
5010
|
}
|
|
4855
5011
|
)
|
|
4856
5012
|
]
|
|
@@ -4858,7 +5014,7 @@ function MediaOverlay({
|
|
|
4858
5014
|
) : null;
|
|
4859
5015
|
return /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
4860
5016
|
settingsBar,
|
|
4861
|
-
/* @__PURE__ */
|
|
5017
|
+
/* @__PURE__ */ jsx12(
|
|
4862
5018
|
"div",
|
|
4863
5019
|
{
|
|
4864
5020
|
"data-ohw-bridge": "",
|
|
@@ -4882,14 +5038,18 @@ function MediaOverlay({
|
|
|
4882
5038
|
variant: "outline",
|
|
4883
5039
|
size: "sm",
|
|
4884
5040
|
className: "gap-1.5 cursor-pointer hover:bg-background",
|
|
4885
|
-
style:
|
|
5041
|
+
style: {
|
|
5042
|
+
...OVERLAY_BUTTON_STYLE,
|
|
5043
|
+
// Don't let Replace steal clicks when text (e.g. nav) sits on top of this media.
|
|
5044
|
+
pointerEvents: hover.hasTextOverlap ? "none" : "auto"
|
|
5045
|
+
},
|
|
4886
5046
|
onMouseDown: (e) => e.preventDefault(),
|
|
4887
5047
|
onClick: (e) => {
|
|
4888
5048
|
e.stopPropagation();
|
|
4889
5049
|
onReplace(hover.key);
|
|
4890
5050
|
},
|
|
4891
5051
|
children: [
|
|
4892
|
-
isVideo ? /* @__PURE__ */
|
|
5052
|
+
isVideo ? /* @__PURE__ */ jsx12(Film, { size: 14 }) : /* @__PURE__ */ jsx12(ImageIcon, { size: 14 }),
|
|
4893
5053
|
isVideo ? "Replace video" : "Replace image"
|
|
4894
5054
|
]
|
|
4895
5055
|
}
|
|
@@ -4901,7 +5061,7 @@ function MediaOverlay({
|
|
|
4901
5061
|
|
|
4902
5062
|
// src/ui/CarouselOverlay.tsx
|
|
4903
5063
|
import { GalleryHorizontal } from "lucide-react";
|
|
4904
|
-
import { jsx as
|
|
5064
|
+
import { jsx as jsx13, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
4905
5065
|
var OVERLAY_BUTTON_STYLE2 = {
|
|
4906
5066
|
pointerEvents: "auto",
|
|
4907
5067
|
fontFamily: "Inter, sans-serif",
|
|
@@ -4913,7 +5073,7 @@ function CarouselOverlay({
|
|
|
4913
5073
|
onEdit
|
|
4914
5074
|
}) {
|
|
4915
5075
|
const { rect } = hover;
|
|
4916
|
-
return /* @__PURE__ */
|
|
5076
|
+
return /* @__PURE__ */ jsx13(
|
|
4917
5077
|
"div",
|
|
4918
5078
|
{
|
|
4919
5079
|
"data-ohw-bridge": "",
|
|
@@ -4945,7 +5105,7 @@ function CarouselOverlay({
|
|
|
4945
5105
|
onEdit(hover.key);
|
|
4946
5106
|
},
|
|
4947
5107
|
children: [
|
|
4948
|
-
/* @__PURE__ */
|
|
5108
|
+
/* @__PURE__ */ jsx13(GalleryHorizontal, { size: 14 }),
|
|
4949
5109
|
"Edit gallery"
|
|
4950
5110
|
]
|
|
4951
5111
|
}
|
|
@@ -5240,22 +5400,22 @@ import { useEffect as useEffect6 } from "react";
|
|
|
5240
5400
|
import * as React8 from "react";
|
|
5241
5401
|
import { Dialog as DialogPrimitive } from "radix-ui";
|
|
5242
5402
|
import { X } from "lucide-react";
|
|
5243
|
-
import { jsx as
|
|
5403
|
+
import { jsx as jsx14, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
5244
5404
|
function Dialog2({
|
|
5245
5405
|
...props
|
|
5246
5406
|
}) {
|
|
5247
|
-
return /* @__PURE__ */
|
|
5407
|
+
return /* @__PURE__ */ jsx14(DialogPrimitive.Root, { "data-slot": "dialog", ...props });
|
|
5248
5408
|
}
|
|
5249
5409
|
function DialogPortal({
|
|
5250
5410
|
...props
|
|
5251
5411
|
}) {
|
|
5252
|
-
return /* @__PURE__ */
|
|
5412
|
+
return /* @__PURE__ */ jsx14(DialogPrimitive.Portal, { ...props });
|
|
5253
5413
|
}
|
|
5254
5414
|
function DialogOverlay({
|
|
5255
5415
|
className,
|
|
5256
5416
|
...props
|
|
5257
5417
|
}) {
|
|
5258
|
-
return /* @__PURE__ */
|
|
5418
|
+
return /* @__PURE__ */ jsx14(
|
|
5259
5419
|
DialogPrimitive.Overlay,
|
|
5260
5420
|
{
|
|
5261
5421
|
"data-slot": "dialog-overlay",
|
|
@@ -5269,7 +5429,7 @@ var DialogContent = React8.forwardRef(
|
|
|
5269
5429
|
({ className, children, showCloseButton = true, container, ...props }, ref) => {
|
|
5270
5430
|
const positionMode = container ? "absolute" : "fixed";
|
|
5271
5431
|
return /* @__PURE__ */ jsxs7(DialogPortal, { container: container ?? void 0, children: [
|
|
5272
|
-
/* @__PURE__ */
|
|
5432
|
+
/* @__PURE__ */ jsx14(DialogOverlay, { className: cn(positionMode, "inset-0") }),
|
|
5273
5433
|
/* @__PURE__ */ jsxs7(
|
|
5274
5434
|
DialogPrimitive.Content,
|
|
5275
5435
|
{
|
|
@@ -5286,13 +5446,13 @@ var DialogContent = React8.forwardRef(
|
|
|
5286
5446
|
...props,
|
|
5287
5447
|
children: [
|
|
5288
5448
|
children,
|
|
5289
|
-
showCloseButton ? /* @__PURE__ */
|
|
5449
|
+
showCloseButton ? /* @__PURE__ */ jsx14(
|
|
5290
5450
|
DialogPrimitive.Close,
|
|
5291
5451
|
{
|
|
5292
5452
|
type: "button",
|
|
5293
5453
|
className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50",
|
|
5294
5454
|
"aria-label": "Close",
|
|
5295
|
-
children: /* @__PURE__ */
|
|
5455
|
+
children: /* @__PURE__ */ jsx14(X, { size: 16, "aria-hidden": true })
|
|
5296
5456
|
}
|
|
5297
5457
|
) : null
|
|
5298
5458
|
]
|
|
@@ -5306,13 +5466,13 @@ function DialogHeader({
|
|
|
5306
5466
|
className,
|
|
5307
5467
|
...props
|
|
5308
5468
|
}) {
|
|
5309
|
-
return /* @__PURE__ */
|
|
5469
|
+
return /* @__PURE__ */ jsx14("div", { className: cn("flex flex-col gap-1.5", className), ...props });
|
|
5310
5470
|
}
|
|
5311
5471
|
function DialogFooter({
|
|
5312
5472
|
className,
|
|
5313
5473
|
...props
|
|
5314
5474
|
}) {
|
|
5315
|
-
return /* @__PURE__ */
|
|
5475
|
+
return /* @__PURE__ */ jsx14(
|
|
5316
5476
|
"div",
|
|
5317
5477
|
{
|
|
5318
5478
|
className: cn("flex items-center justify-end gap-2", className),
|
|
@@ -5320,7 +5480,7 @@ function DialogFooter({
|
|
|
5320
5480
|
}
|
|
5321
5481
|
);
|
|
5322
5482
|
}
|
|
5323
|
-
var DialogTitle = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
5483
|
+
var DialogTitle = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx14(
|
|
5324
5484
|
DialogPrimitive.Title,
|
|
5325
5485
|
{
|
|
5326
5486
|
ref,
|
|
@@ -5332,7 +5492,7 @@ var DialogTitle = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE
|
|
|
5332
5492
|
}
|
|
5333
5493
|
));
|
|
5334
5494
|
DialogTitle.displayName = DialogPrimitive.Title.displayName;
|
|
5335
|
-
var DialogDescription = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
5495
|
+
var DialogDescription = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx14(
|
|
5336
5496
|
DialogPrimitive.Description,
|
|
5337
5497
|
{
|
|
5338
5498
|
ref,
|
|
@@ -5348,19 +5508,19 @@ import { Info, X as X3 } from "lucide-react";
|
|
|
5348
5508
|
|
|
5349
5509
|
// src/ui/link-modal/DestinationBreadcrumb.tsx
|
|
5350
5510
|
import { ArrowRight, File, GalleryVertical } from "lucide-react";
|
|
5351
|
-
import { jsx as
|
|
5511
|
+
import { jsx as jsx15, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
5352
5512
|
function DestinationBreadcrumb({
|
|
5353
5513
|
pageTitle,
|
|
5354
5514
|
sectionLabel
|
|
5355
5515
|
}) {
|
|
5356
5516
|
return /* @__PURE__ */ jsxs8("div", { className: "flex w-full flex-col gap-2", children: [
|
|
5357
|
-
/* @__PURE__ */
|
|
5517
|
+
/* @__PURE__ */ jsx15("p", { className: "text-sm font-medium! text-foreground m-0", children: "Destination" }),
|
|
5358
5518
|
/* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-3", children: [
|
|
5359
5519
|
/* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2", children: [
|
|
5360
|
-
/* @__PURE__ */
|
|
5361
|
-
/* @__PURE__ */
|
|
5520
|
+
/* @__PURE__ */ jsx15(File, { size: 16, className: "shrink-0 text-foreground", "aria-hidden": true }),
|
|
5521
|
+
/* @__PURE__ */ jsx15("span", { className: "text-sm font-medium leading-none text-foreground!", children: pageTitle })
|
|
5362
5522
|
] }),
|
|
5363
|
-
/* @__PURE__ */
|
|
5523
|
+
/* @__PURE__ */ jsx15(
|
|
5364
5524
|
ArrowRight,
|
|
5365
5525
|
{
|
|
5366
5526
|
size: 16,
|
|
@@ -5369,7 +5529,7 @@ function DestinationBreadcrumb({
|
|
|
5369
5529
|
}
|
|
5370
5530
|
),
|
|
5371
5531
|
/* @__PURE__ */ jsxs8("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
|
|
5372
|
-
/* @__PURE__ */
|
|
5532
|
+
/* @__PURE__ */ jsx15(
|
|
5373
5533
|
GalleryVertical,
|
|
5374
5534
|
{
|
|
5375
5535
|
size: 16,
|
|
@@ -5377,7 +5537,7 @@ function DestinationBreadcrumb({
|
|
|
5377
5537
|
"aria-hidden": true
|
|
5378
5538
|
}
|
|
5379
5539
|
),
|
|
5380
|
-
/* @__PURE__ */
|
|
5540
|
+
/* @__PURE__ */ jsx15("span", { className: "truncate text-sm font-medium leading-none text-foreground", children: sectionLabel })
|
|
5381
5541
|
] })
|
|
5382
5542
|
] })
|
|
5383
5543
|
] });
|
|
@@ -5385,7 +5545,7 @@ function DestinationBreadcrumb({
|
|
|
5385
5545
|
|
|
5386
5546
|
// src/ui/link-modal/SectionTreeItem.tsx
|
|
5387
5547
|
import { GalleryVertical as GalleryVertical2 } from "lucide-react";
|
|
5388
|
-
import { jsx as
|
|
5548
|
+
import { jsx as jsx16, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
5389
5549
|
function SectionTreeItem({
|
|
5390
5550
|
section,
|
|
5391
5551
|
onSelect,
|
|
@@ -5393,7 +5553,7 @@ function SectionTreeItem({
|
|
|
5393
5553
|
}) {
|
|
5394
5554
|
const interactive = Boolean(onSelect);
|
|
5395
5555
|
return /* @__PURE__ */ jsxs9("div", { className: "flex h-9 w-full items-end pl-3", children: [
|
|
5396
|
-
/* @__PURE__ */
|
|
5556
|
+
/* @__PURE__ */ jsx16(
|
|
5397
5557
|
"div",
|
|
5398
5558
|
{
|
|
5399
5559
|
className: "mr-[-1px] h-9 w-2 shrink-0 rounded-bl-sm border-b border-l border-border mb-4",
|
|
@@ -5418,7 +5578,7 @@ function SectionTreeItem({
|
|
|
5418
5578
|
interactive && selected && "border-primary"
|
|
5419
5579
|
),
|
|
5420
5580
|
children: [
|
|
5421
|
-
/* @__PURE__ */
|
|
5581
|
+
/* @__PURE__ */ jsx16(
|
|
5422
5582
|
GalleryVertical2,
|
|
5423
5583
|
{
|
|
5424
5584
|
size: 16,
|
|
@@ -5426,7 +5586,7 @@ function SectionTreeItem({
|
|
|
5426
5586
|
"aria-hidden": true
|
|
5427
5587
|
}
|
|
5428
5588
|
),
|
|
5429
|
-
/* @__PURE__ */
|
|
5589
|
+
/* @__PURE__ */ jsx16("span", { className: "truncate text-sm font-normal leading-5 text-foreground", children: section.label })
|
|
5430
5590
|
]
|
|
5431
5591
|
}
|
|
5432
5592
|
)
|
|
@@ -5434,14 +5594,14 @@ function SectionTreeItem({
|
|
|
5434
5594
|
}
|
|
5435
5595
|
|
|
5436
5596
|
// src/ui/link-modal/UrlOrPageInput.tsx
|
|
5437
|
-
import { useEffect as useEffect3, useId as useId2, useRef as useRef4, useState as
|
|
5597
|
+
import { useEffect as useEffect3, useId as useId2, useRef as useRef4, useState as useState4 } from "react";
|
|
5438
5598
|
|
|
5439
5599
|
// src/ui/input.tsx
|
|
5440
5600
|
import * as React9 from "react";
|
|
5441
|
-
import { jsx as
|
|
5601
|
+
import { jsx as jsx17 } from "react/jsx-runtime";
|
|
5442
5602
|
var Input = React9.forwardRef(
|
|
5443
5603
|
({ className, type, ...props }, ref) => {
|
|
5444
|
-
return /* @__PURE__ */
|
|
5604
|
+
return /* @__PURE__ */ jsx17(
|
|
5445
5605
|
"input",
|
|
5446
5606
|
{
|
|
5447
5607
|
type,
|
|
@@ -5460,9 +5620,9 @@ Input.displayName = "Input";
|
|
|
5460
5620
|
|
|
5461
5621
|
// src/ui/label.tsx
|
|
5462
5622
|
import { Label as LabelPrimitive } from "radix-ui";
|
|
5463
|
-
import { jsx as
|
|
5623
|
+
import { jsx as jsx18 } from "react/jsx-runtime";
|
|
5464
5624
|
function Label({ className, ...props }) {
|
|
5465
|
-
return /* @__PURE__ */
|
|
5625
|
+
return /* @__PURE__ */ jsx18(
|
|
5466
5626
|
LabelPrimitive.Root,
|
|
5467
5627
|
{
|
|
5468
5628
|
"data-slot": "label",
|
|
@@ -5474,11 +5634,11 @@ function Label({ className, ...props }) {
|
|
|
5474
5634
|
|
|
5475
5635
|
// src/ui/link-modal/UrlOrPageInput.tsx
|
|
5476
5636
|
import { ChevronDown, File as File2, X as X2 } from "lucide-react";
|
|
5477
|
-
import { jsx as
|
|
5637
|
+
import { jsx as jsx19, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
5478
5638
|
function FieldChevron({
|
|
5479
5639
|
onClick
|
|
5480
5640
|
}) {
|
|
5481
|
-
return /* @__PURE__ */
|
|
5641
|
+
return /* @__PURE__ */ jsx19(
|
|
5482
5642
|
"button",
|
|
5483
5643
|
{
|
|
5484
5644
|
type: "button",
|
|
@@ -5486,7 +5646,7 @@ function FieldChevron({
|
|
|
5486
5646
|
onClick,
|
|
5487
5647
|
"aria-label": "Open page list",
|
|
5488
5648
|
tabIndex: -1,
|
|
5489
|
-
children: /* @__PURE__ */
|
|
5649
|
+
children: /* @__PURE__ */ jsx19(ChevronDown, { size: 16 })
|
|
5490
5650
|
}
|
|
5491
5651
|
);
|
|
5492
5652
|
}
|
|
@@ -5505,7 +5665,7 @@ function UrlOrPageInput({
|
|
|
5505
5665
|
const inputId = useId2();
|
|
5506
5666
|
const inputRef = useRef4(null);
|
|
5507
5667
|
const rootRef = useRef4(null);
|
|
5508
|
-
const [isFocused, setIsFocused] =
|
|
5668
|
+
const [isFocused, setIsFocused] = useState4(false);
|
|
5509
5669
|
useEffect3(() => {
|
|
5510
5670
|
if (!dropdownOpen) return;
|
|
5511
5671
|
const isOutside = (e) => {
|
|
@@ -5548,10 +5708,10 @@ function UrlOrPageInput({
|
|
|
5548
5708
|
urlError ? "border-destructive shadow-[0_0_0_1px_var(--ohw-destructive)]" : isFocused ? "border-primary shadow-[0_0_0_1px_var(--ohw-primary)]" : "border-input"
|
|
5549
5709
|
);
|
|
5550
5710
|
return /* @__PURE__ */ jsxs10("div", { className: "flex w-full flex-col gap-2 p-0", children: [
|
|
5551
|
-
/* @__PURE__ */
|
|
5711
|
+
/* @__PURE__ */ jsx19(Label, { htmlFor: inputId, className: cn(urlError && "text-destructive"), children: "Destination" }),
|
|
5552
5712
|
/* @__PURE__ */ jsxs10("div", { ref: rootRef, className: "relative w-full", children: [
|
|
5553
5713
|
/* @__PURE__ */ jsxs10("div", { "data-ohw-link-field": true, className: fieldClassName, children: [
|
|
5554
|
-
selectedPage ? /* @__PURE__ */
|
|
5714
|
+
selectedPage ? /* @__PURE__ */ jsx19("div", { className: "flex shrink-0 items-center pr-2", children: /* @__PURE__ */ jsx19(
|
|
5555
5715
|
File2,
|
|
5556
5716
|
{
|
|
5557
5717
|
size: 16,
|
|
@@ -5559,7 +5719,7 @@ function UrlOrPageInput({
|
|
|
5559
5719
|
"aria-hidden": true
|
|
5560
5720
|
}
|
|
5561
5721
|
) }) : null,
|
|
5562
|
-
readOnly ? /* @__PURE__ */
|
|
5722
|
+
readOnly ? /* @__PURE__ */ jsx19("span", { className: "min-w-0 flex-1 truncate text-sm leading-5 text-foreground", children: selectedPage?.title ?? value }) : /* @__PURE__ */ jsx19(
|
|
5563
5723
|
Input,
|
|
5564
5724
|
{
|
|
5565
5725
|
ref: inputRef,
|
|
@@ -5585,7 +5745,7 @@ function UrlOrPageInput({
|
|
|
5585
5745
|
)
|
|
5586
5746
|
}
|
|
5587
5747
|
),
|
|
5588
|
-
selectedPage && !readOnly ? /* @__PURE__ */
|
|
5748
|
+
selectedPage && !readOnly ? /* @__PURE__ */ jsx19(
|
|
5589
5749
|
"button",
|
|
5590
5750
|
{
|
|
5591
5751
|
type: "button",
|
|
@@ -5593,12 +5753,12 @@ function UrlOrPageInput({
|
|
|
5593
5753
|
onMouseDown: clearSelection,
|
|
5594
5754
|
"aria-label": "Clear selected page",
|
|
5595
5755
|
tabIndex: -1,
|
|
5596
|
-
children: /* @__PURE__ */
|
|
5756
|
+
children: /* @__PURE__ */ jsx19(X2, { size: 16, "aria-hidden": true })
|
|
5597
5757
|
}
|
|
5598
5758
|
) : null,
|
|
5599
|
-
!readOnly ? /* @__PURE__ */
|
|
5759
|
+
!readOnly ? /* @__PURE__ */ jsx19(FieldChevron, { onClick: toggleDropdown }) : null
|
|
5600
5760
|
] }),
|
|
5601
|
-
dropdownOpen && !readOnly && filteredPages.length > 0 ? /* @__PURE__ */
|
|
5761
|
+
dropdownOpen && !readOnly && filteredPages.length > 0 ? /* @__PURE__ */ jsx19(
|
|
5602
5762
|
"div",
|
|
5603
5763
|
{
|
|
5604
5764
|
"data-ohw-link-page-dropdown": "",
|
|
@@ -5611,8 +5771,8 @@ function UrlOrPageInput({
|
|
|
5611
5771
|
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",
|
|
5612
5772
|
onClick: () => onPageSelect(page),
|
|
5613
5773
|
children: [
|
|
5614
|
-
/* @__PURE__ */
|
|
5615
|
-
/* @__PURE__ */
|
|
5774
|
+
/* @__PURE__ */ jsx19(File2, { size: 16, className: "shrink-0", "aria-hidden": true }),
|
|
5775
|
+
/* @__PURE__ */ jsx19("span", { className: "truncate", children: page.title })
|
|
5616
5776
|
]
|
|
5617
5777
|
},
|
|
5618
5778
|
page.path
|
|
@@ -5620,34 +5780,34 @@ function UrlOrPageInput({
|
|
|
5620
5780
|
}
|
|
5621
5781
|
) : null
|
|
5622
5782
|
] }),
|
|
5623
|
-
urlError ? /* @__PURE__ */
|
|
5783
|
+
urlError ? /* @__PURE__ */ jsx19("p", { className: "text-sm font-medium text-destructive", children: urlError }) : null
|
|
5624
5784
|
] });
|
|
5625
5785
|
}
|
|
5626
5786
|
|
|
5627
5787
|
// src/ui/link-modal/LinkEditorPanel.tsx
|
|
5628
|
-
import { Fragment as Fragment3, jsx as
|
|
5788
|
+
import { Fragment as Fragment3, jsx as jsx20, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
5629
5789
|
function LinkEditorPanel({ state, onClose }) {
|
|
5630
5790
|
const isCancel = state.secondaryLabel === "Cancel" || state.secondaryLabel === "Back to sections";
|
|
5631
5791
|
return /* @__PURE__ */ jsxs11(Fragment3, { children: [
|
|
5632
|
-
/* @__PURE__ */
|
|
5792
|
+
/* @__PURE__ */ jsx20(DialogClose, { asChild: true, children: /* @__PURE__ */ jsx20(
|
|
5633
5793
|
"button",
|
|
5634
5794
|
{
|
|
5635
5795
|
type: "button",
|
|
5636
5796
|
className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50 h-7",
|
|
5637
5797
|
"aria-label": "Close",
|
|
5638
5798
|
onClick: onClose,
|
|
5639
|
-
children: /* @__PURE__ */
|
|
5799
|
+
children: /* @__PURE__ */ jsx20(X3, { size: 16, "aria-hidden": true })
|
|
5640
5800
|
}
|
|
5641
5801
|
) }),
|
|
5642
|
-
/* @__PURE__ */
|
|
5802
|
+
/* @__PURE__ */ jsx20(DialogHeader, { className: "w-full gap-1.5 p-6 pr-12", children: /* @__PURE__ */ jsx20(DialogTitle, { className: "m-0 w-full break-words", children: state.title }) }),
|
|
5643
5803
|
/* @__PURE__ */ jsxs11("div", { className: "flex w-full flex-col gap-3 px-6 pb-8 pt-1", children: [
|
|
5644
|
-
state.showBreadcrumb && state.selectedPage && state.selectedSection ? /* @__PURE__ */
|
|
5804
|
+
state.showBreadcrumb && state.selectedPage && state.selectedSection ? /* @__PURE__ */ jsx20(
|
|
5645
5805
|
DestinationBreadcrumb,
|
|
5646
5806
|
{
|
|
5647
5807
|
pageTitle: state.selectedPage.title,
|
|
5648
5808
|
sectionLabel: state.selectedSection.label
|
|
5649
5809
|
}
|
|
5650
|
-
) : /* @__PURE__ */
|
|
5810
|
+
) : /* @__PURE__ */ jsx20(
|
|
5651
5811
|
UrlOrPageInput,
|
|
5652
5812
|
{
|
|
5653
5813
|
value: state.searchValue,
|
|
@@ -5661,7 +5821,7 @@ function LinkEditorPanel({ state, onClose }) {
|
|
|
5661
5821
|
}
|
|
5662
5822
|
),
|
|
5663
5823
|
state.showChooseSection ? /* @__PURE__ */ jsxs11("div", { className: "flex flex-col justify-center gap-2", children: [
|
|
5664
|
-
/* @__PURE__ */
|
|
5824
|
+
/* @__PURE__ */ jsx20(
|
|
5665
5825
|
Button,
|
|
5666
5826
|
{
|
|
5667
5827
|
type: "button",
|
|
@@ -5673,14 +5833,14 @@ function LinkEditorPanel({ state, onClose }) {
|
|
|
5673
5833
|
}
|
|
5674
5834
|
),
|
|
5675
5835
|
/* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-1 text-sm text-muted-foreground", children: [
|
|
5676
|
-
/* @__PURE__ */
|
|
5677
|
-
/* @__PURE__ */
|
|
5836
|
+
/* @__PURE__ */ jsx20(Info, { size: 16, className: "shrink-0", "aria-hidden": true }),
|
|
5837
|
+
/* @__PURE__ */ jsx20("span", { children: "Pick a section this link should scroll to." })
|
|
5678
5838
|
] })
|
|
5679
5839
|
] }) : null,
|
|
5680
|
-
state.showSectionRow && state.selectedSection ? /* @__PURE__ */
|
|
5840
|
+
state.showSectionRow && state.selectedSection ? /* @__PURE__ */ jsx20(SectionTreeItem, { section: state.selectedSection, selected: true }) : null
|
|
5681
5841
|
] }),
|
|
5682
5842
|
/* @__PURE__ */ jsxs11(DialogFooter, { className: "w-full px-6 pb-6", children: [
|
|
5683
|
-
/* @__PURE__ */
|
|
5843
|
+
/* @__PURE__ */ jsx20(
|
|
5684
5844
|
Button,
|
|
5685
5845
|
{
|
|
5686
5846
|
type: "button",
|
|
@@ -5695,7 +5855,7 @@ function LinkEditorPanel({ state, onClose }) {
|
|
|
5695
5855
|
children: state.secondaryLabel
|
|
5696
5856
|
}
|
|
5697
5857
|
),
|
|
5698
|
-
/* @__PURE__ */
|
|
5858
|
+
/* @__PURE__ */ jsx20(
|
|
5699
5859
|
Button,
|
|
5700
5860
|
{
|
|
5701
5861
|
type: "button",
|
|
@@ -5714,11 +5874,11 @@ function LinkEditorPanel({ state, onClose }) {
|
|
|
5714
5874
|
}
|
|
5715
5875
|
|
|
5716
5876
|
// src/ui/link-modal/SectionPickerOverlay.tsx
|
|
5717
|
-
import { useCallback as useCallback2, useEffect as useEffect4, useMemo as useMemo2, useRef as useRef5, useState as
|
|
5877
|
+
import { useCallback as useCallback2, useEffect as useEffect4, useMemo as useMemo2, useRef as useRef5, useState as useState5 } from "react";
|
|
5718
5878
|
import { createPortal } from "react-dom";
|
|
5719
5879
|
import { ArrowLeft, Check } from "lucide-react";
|
|
5720
5880
|
import { usePathname, useRouter } from "next/navigation";
|
|
5721
|
-
import { jsx as
|
|
5881
|
+
import { jsx as jsx21, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
5722
5882
|
var DIM_OVERLAY = "rgba(0, 0, 0, 0.45)";
|
|
5723
5883
|
function rectsEqual(a, b) {
|
|
5724
5884
|
if (a.size !== b.size) return false;
|
|
@@ -5751,7 +5911,7 @@ function hitTestSectionId(x, y, sectionIds, rects) {
|
|
|
5751
5911
|
return null;
|
|
5752
5912
|
}
|
|
5753
5913
|
function useSectionRects(sectionIdsKey, enabled) {
|
|
5754
|
-
const [rects, setRects] =
|
|
5914
|
+
const [rects, setRects] = useState5(/* @__PURE__ */ new Map());
|
|
5755
5915
|
const sectionIds = useMemo2(
|
|
5756
5916
|
() => sectionIdsKey ? sectionIdsKey.split("\0") : [],
|
|
5757
5917
|
[sectionIdsKey]
|
|
@@ -5797,13 +5957,13 @@ function SectionPickerOverlay({
|
|
|
5797
5957
|
}) {
|
|
5798
5958
|
const router = useRouter();
|
|
5799
5959
|
const pathname = usePathname();
|
|
5800
|
-
const [selectedId, setSelectedId] =
|
|
5801
|
-
const [hoveredId, setHoveredId] =
|
|
5960
|
+
const [selectedId, setSelectedId] = useState5(null);
|
|
5961
|
+
const [hoveredId, setHoveredId] = useState5(null);
|
|
5802
5962
|
const pointerRef = useRef5(null);
|
|
5803
5963
|
const pointerScreenRef = useRef5(null);
|
|
5804
5964
|
const iframeOffsetTopRef = useRef5(null);
|
|
5805
5965
|
const sectionIdsRef = useRef5([]);
|
|
5806
|
-
const [chromeClip, setChromeClip] =
|
|
5966
|
+
const [chromeClip, setChromeClip] = useState5(
|
|
5807
5967
|
() => ({
|
|
5808
5968
|
top: 0,
|
|
5809
5969
|
bottom: typeof window !== "undefined" ? window.innerHeight : 0
|
|
@@ -5957,7 +6117,7 @@ function SectionPickerOverlay({
|
|
|
5957
6117
|
role: "dialog",
|
|
5958
6118
|
"aria-label": "Choose a section",
|
|
5959
6119
|
children: [
|
|
5960
|
-
/* @__PURE__ */
|
|
6120
|
+
/* @__PURE__ */ jsx21(
|
|
5961
6121
|
"div",
|
|
5962
6122
|
{
|
|
5963
6123
|
className: "pointer-events-auto fixed left-5 z-[2]",
|
|
@@ -5971,14 +6131,14 @@ function SectionPickerOverlay({
|
|
|
5971
6131
|
className: "h-8 min-w-0 gap-1 border-border bg-background px-2 py-1.5 shadow-sm hover:bg-muted cursor-pointer",
|
|
5972
6132
|
onClick: onBack,
|
|
5973
6133
|
children: [
|
|
5974
|
-
/* @__PURE__ */
|
|
6134
|
+
/* @__PURE__ */ jsx21(ArrowLeft, { className: "size-4 shrink-0", "aria-hidden": true }),
|
|
5975
6135
|
"Back"
|
|
5976
6136
|
]
|
|
5977
6137
|
}
|
|
5978
6138
|
)
|
|
5979
6139
|
}
|
|
5980
6140
|
),
|
|
5981
|
-
/* @__PURE__ */
|
|
6141
|
+
/* @__PURE__ */ jsx21(
|
|
5982
6142
|
"div",
|
|
5983
6143
|
{
|
|
5984
6144
|
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",
|
|
@@ -5991,7 +6151,7 @@ function SectionPickerOverlay({
|
|
|
5991
6151
|
children: "Click on section to select"
|
|
5992
6152
|
}
|
|
5993
6153
|
),
|
|
5994
|
-
!isOnTargetPage ? /* @__PURE__ */
|
|
6154
|
+
!isOnTargetPage ? /* @__PURE__ */ jsx21(
|
|
5995
6155
|
"div",
|
|
5996
6156
|
{
|
|
5997
6157
|
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",
|
|
@@ -5999,7 +6159,7 @@ function SectionPickerOverlay({
|
|
|
5999
6159
|
children: "Loading page preview\u2026"
|
|
6000
6160
|
}
|
|
6001
6161
|
) : null,
|
|
6002
|
-
isOnTargetPage && liveSections.length === 0 ? /* @__PURE__ */
|
|
6162
|
+
isOnTargetPage && liveSections.length === 0 ? /* @__PURE__ */ jsx21("div", { className: "pointer-events-auto fixed inset-0 z-[1] flex items-center justify-center bg-muted/40", children: /* @__PURE__ */ jsx21("p", { className: "text-sm text-muted-foreground", children: "No sections found on this page." }) }) : null,
|
|
6003
6163
|
isOnTargetPage ? liveSections.map((section) => {
|
|
6004
6164
|
const rect = rects.get(section.id);
|
|
6005
6165
|
if (!rect || rect.width <= 0 || rect.height <= 0) return null;
|
|
@@ -6021,7 +6181,7 @@ function SectionPickerOverlay({
|
|
|
6021
6181
|
"aria-label": `Select section ${section.label}`,
|
|
6022
6182
|
onClick: () => handleSelect(section),
|
|
6023
6183
|
children: [
|
|
6024
|
-
isLit ? /* @__PURE__ */
|
|
6184
|
+
isLit ? /* @__PURE__ */ jsx21(
|
|
6025
6185
|
"span",
|
|
6026
6186
|
{
|
|
6027
6187
|
className: "pointer-events-none absolute",
|
|
@@ -6034,13 +6194,13 @@ function SectionPickerOverlay({
|
|
|
6034
6194
|
"aria-hidden": true
|
|
6035
6195
|
}
|
|
6036
6196
|
) : null,
|
|
6037
|
-
isSelected ? /* @__PURE__ */
|
|
6197
|
+
isSelected ? /* @__PURE__ */ jsx21(
|
|
6038
6198
|
"span",
|
|
6039
6199
|
{
|
|
6040
6200
|
className: "absolute right-3 top-3 flex size-8 items-center justify-center rounded-full text-white",
|
|
6041
6201
|
style: { backgroundColor: "var(--ohw-primary, #0885fe)" },
|
|
6042
6202
|
"aria-hidden": true,
|
|
6043
|
-
children: /* @__PURE__ */
|
|
6203
|
+
children: /* @__PURE__ */ jsx21(Check, { className: "size-5" })
|
|
6044
6204
|
}
|
|
6045
6205
|
) : null
|
|
6046
6206
|
]
|
|
@@ -6056,7 +6216,7 @@ function SectionPickerOverlay({
|
|
|
6056
6216
|
}
|
|
6057
6217
|
|
|
6058
6218
|
// src/ui/link-modal/useLinkModalState.ts
|
|
6059
|
-
import { useCallback as useCallback3, useEffect as useEffect5, useMemo as useMemo3, useState as
|
|
6219
|
+
import { useCallback as useCallback3, useEffect as useEffect5, useMemo as useMemo3, useState as useState6 } from "react";
|
|
6060
6220
|
function useLinkModalState({
|
|
6061
6221
|
open,
|
|
6062
6222
|
mode,
|
|
@@ -6069,12 +6229,12 @@ function useLinkModalState({
|
|
|
6069
6229
|
onSubmit
|
|
6070
6230
|
}) {
|
|
6071
6231
|
const availablePages = useMemo3(() => pages, [pages]);
|
|
6072
|
-
const [searchValue, setSearchValue] =
|
|
6073
|
-
const [selectedPage, setSelectedPage] =
|
|
6074
|
-
const [selectedSection, setSelectedSection] =
|
|
6075
|
-
const [step, setStep] =
|
|
6076
|
-
const [dropdownOpen, setDropdownOpen] =
|
|
6077
|
-
const [urlError, setUrlError] =
|
|
6232
|
+
const [searchValue, setSearchValue] = useState6("");
|
|
6233
|
+
const [selectedPage, setSelectedPage] = useState6(null);
|
|
6234
|
+
const [selectedSection, setSelectedSection] = useState6(null);
|
|
6235
|
+
const [step, setStep] = useState6("input");
|
|
6236
|
+
const [dropdownOpen, setDropdownOpen] = useState6(false);
|
|
6237
|
+
const [urlError, setUrlError] = useState6("");
|
|
6078
6238
|
const reset = useCallback3(() => {
|
|
6079
6239
|
setSearchValue("");
|
|
6080
6240
|
setSelectedPage(null);
|
|
@@ -6220,7 +6380,7 @@ function useLinkModalState({
|
|
|
6220
6380
|
}
|
|
6221
6381
|
|
|
6222
6382
|
// src/ui/link-modal/LinkPopover.tsx
|
|
6223
|
-
import { Fragment as Fragment4, jsx as
|
|
6383
|
+
import { Fragment as Fragment4, jsx as jsx22, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
6224
6384
|
function postToParent(data) {
|
|
6225
6385
|
window.parent?.postMessage(data, "*");
|
|
6226
6386
|
}
|
|
@@ -6317,14 +6477,14 @@ function LinkPopover({
|
|
|
6317
6477
|
};
|
|
6318
6478
|
}, [open, sectionPickerActive]);
|
|
6319
6479
|
return /* @__PURE__ */ jsxs13(Fragment4, { children: [
|
|
6320
|
-
/* @__PURE__ */
|
|
6480
|
+
/* @__PURE__ */ jsx22(
|
|
6321
6481
|
Dialog2,
|
|
6322
6482
|
{
|
|
6323
6483
|
open: open && !sectionPickerActive,
|
|
6324
6484
|
onOpenChange: (next) => {
|
|
6325
6485
|
if (!next) onClose?.();
|
|
6326
6486
|
},
|
|
6327
|
-
children: /* @__PURE__ */
|
|
6487
|
+
children: /* @__PURE__ */ jsx22(
|
|
6328
6488
|
DialogContent,
|
|
6329
6489
|
{
|
|
6330
6490
|
ref: panelRef,
|
|
@@ -6334,12 +6494,12 @@ function LinkPopover({
|
|
|
6334
6494
|
"data-ohw-bridge": "",
|
|
6335
6495
|
showCloseButton: false,
|
|
6336
6496
|
className: "gap-0 p-0 w-full max-w-[448px] pointer-events-auto z-[2147483646] overflow-visible",
|
|
6337
|
-
children: /* @__PURE__ */
|
|
6497
|
+
children: /* @__PURE__ */ jsx22(LinkEditorPanel, { state, onClose })
|
|
6338
6498
|
}
|
|
6339
6499
|
)
|
|
6340
6500
|
}
|
|
6341
6501
|
),
|
|
6342
|
-
sectionPickerActive && state.selectedPage ? /* @__PURE__ */
|
|
6502
|
+
sectionPickerActive && state.selectedPage ? /* @__PURE__ */ jsx22(
|
|
6343
6503
|
SectionPickerOverlay,
|
|
6344
6504
|
{
|
|
6345
6505
|
pagePath: state.selectedPage.path,
|
|
@@ -6828,6 +6988,22 @@ function navbarIndexExistsInDom(index) {
|
|
|
6828
6988
|
return document.querySelector(`[data-ohw-href-key="nav-${index}-href"]`) !== null;
|
|
6829
6989
|
}
|
|
6830
6990
|
function reconcileNavbarItemsFromContent(content) {
|
|
6991
|
+
const orderForest = parseNavOrderJson(content[NAV_ORDER_KEY]);
|
|
6992
|
+
if (orderForest?.length) {
|
|
6993
|
+
const allowed = new Set(flattenNavOrder(orderForest));
|
|
6994
|
+
for (const hrefKey of allowed) {
|
|
6995
|
+
const index = parseNavIndexFromKey(hrefKey);
|
|
6996
|
+
if (index === null) continue;
|
|
6997
|
+
if (navbarIndexExistsInDom(index)) continue;
|
|
6998
|
+
const href = content[`nav-${index}-href`];
|
|
6999
|
+
const label = content[`nav-${index}-label`];
|
|
7000
|
+
if (!href && !label) continue;
|
|
7001
|
+
insertNavbarItemDom(index, href ?? "/", label ?? "Untitled", null);
|
|
7002
|
+
}
|
|
7003
|
+
pruneNavbarItemsNotInOrder(allowed);
|
|
7004
|
+
applyNavForest(orderForest);
|
|
7005
|
+
return;
|
|
7006
|
+
}
|
|
6831
7007
|
const indices = collectNavbarIndicesFromContent(content);
|
|
6832
7008
|
for (const index of indices) {
|
|
6833
7009
|
if (navbarIndexExistsInDom(index)) continue;
|
|
@@ -6836,9 +7012,22 @@ function reconcileNavbarItemsFromContent(content) {
|
|
|
6836
7012
|
if (!href && !label) continue;
|
|
6837
7013
|
insertNavbarItemDom(index, href ?? "/", label ?? "Untitled", null);
|
|
6838
7014
|
}
|
|
6839
|
-
|
|
6840
|
-
|
|
6841
|
-
|
|
7015
|
+
}
|
|
7016
|
+
function pruneNavbarItemsNotInOrder(allowed) {
|
|
7017
|
+
const roots = [getNavbarDesktopContainer(), getNavbarDrawerContainer()].filter(
|
|
7018
|
+
(el) => Boolean(el)
|
|
7019
|
+
);
|
|
7020
|
+
const searchRoots = roots.length > 0 ? roots : [document.body];
|
|
7021
|
+
for (const root of searchRoots) {
|
|
7022
|
+
const items = Array.from(root.querySelectorAll("[data-ohw-href-key]")).filter(
|
|
7023
|
+
isNavbarLinkItem
|
|
7024
|
+
);
|
|
7025
|
+
for (const item of items) {
|
|
7026
|
+
if (!item.isConnected) continue;
|
|
7027
|
+
const key = item.getAttribute("data-ohw-href-key");
|
|
7028
|
+
if (!key || !isNavbarHrefKey(key) || allowed.has(key)) continue;
|
|
7029
|
+
resolveRemovableNavUnit(item).remove();
|
|
7030
|
+
}
|
|
6842
7031
|
}
|
|
6843
7032
|
}
|
|
6844
7033
|
function buildNavOrderAfterInsert(afterAnchor, newHrefKey) {
|
|
@@ -6878,9 +7067,126 @@ function insertNavbarItem(href, label, afterAnchor = null) {
|
|
|
6878
7067
|
order
|
|
6879
7068
|
};
|
|
6880
7069
|
}
|
|
7070
|
+
function duplicateNavbarItem(sourceAnchor) {
|
|
7071
|
+
if (!isNavbarLinkItem(sourceAnchor)) return null;
|
|
7072
|
+
const sourceHrefKey = sourceAnchor.getAttribute("data-ohw-href-key");
|
|
7073
|
+
if (!sourceHrefKey || !isNavbarHrefKey(sourceHrefKey)) return null;
|
|
7074
|
+
const href = getLinkHref(sourceAnchor);
|
|
7075
|
+
const labelEl = sourceAnchor.querySelector('[data-ohw-editable="text"]');
|
|
7076
|
+
const label = (labelEl?.textContent ?? "").trim() || "Untitled";
|
|
7077
|
+
const forest = getNavForestFromDom();
|
|
7078
|
+
const sourceNode = forest.find((n) => n.id === sourceHrefKey);
|
|
7079
|
+
const childIds = sourceNode?.children.map((c) => c.id) ?? [];
|
|
7080
|
+
const primary = insertNavbarItem(href, label, sourceAnchor);
|
|
7081
|
+
const childResults = [];
|
|
7082
|
+
let after = primary.anchor;
|
|
7083
|
+
for (const childId of childIds) {
|
|
7084
|
+
const childEl = findCounterpartByHrefKey(childId, document) ?? document.querySelector(`[data-ohw-href-key="${CSS.escape(childId)}"]`);
|
|
7085
|
+
if (!childEl || !isNavbarLinkItem(childEl)) continue;
|
|
7086
|
+
const childHref = getLinkHref(childEl);
|
|
7087
|
+
const childLabelEl = childEl.querySelector('[data-ohw-editable="text"]');
|
|
7088
|
+
const childLabel = (childLabelEl?.textContent ?? "").trim() || "Untitled";
|
|
7089
|
+
const inserted = insertNavbarItem(childHref, childLabel, after);
|
|
7090
|
+
childResults.push(inserted);
|
|
7091
|
+
after = inserted.anchor;
|
|
7092
|
+
}
|
|
7093
|
+
let orderJson;
|
|
7094
|
+
if (childResults.length > 0) {
|
|
7095
|
+
const nextForest = getNavForestFromDom();
|
|
7096
|
+
const withoutNew = nextForest.filter(
|
|
7097
|
+
(n) => n.id !== primary.hrefKey && !childResults.some((c) => c.hrefKey === n.id)
|
|
7098
|
+
);
|
|
7099
|
+
const sourceIdx = withoutNew.findIndex((n) => n.id === sourceHrefKey);
|
|
7100
|
+
const insertAt = sourceIdx >= 0 ? sourceIdx + 1 : withoutNew.length;
|
|
7101
|
+
withoutNew.splice(insertAt, 0, {
|
|
7102
|
+
id: primary.hrefKey,
|
|
7103
|
+
children: childResults.map((c) => ({ id: c.hrefKey, children: [] }))
|
|
7104
|
+
});
|
|
7105
|
+
applyNavForest(withoutNew);
|
|
7106
|
+
orderJson = serializeNavOrder(withoutNew);
|
|
7107
|
+
} else {
|
|
7108
|
+
orderJson = serializeNavOrder(getNavForestFromDom());
|
|
7109
|
+
}
|
|
7110
|
+
return {
|
|
7111
|
+
...primary,
|
|
7112
|
+
order: flattenNavOrder(parseNavOrderJson(orderJson) ?? getNavForestFromDom()),
|
|
7113
|
+
childResults,
|
|
7114
|
+
orderJson
|
|
7115
|
+
};
|
|
7116
|
+
}
|
|
7117
|
+
function collectSubtreeHrefKeys(node) {
|
|
7118
|
+
const keys = [node.id];
|
|
7119
|
+
for (const child of node.children) {
|
|
7120
|
+
keys.push(...collectSubtreeHrefKeys(child));
|
|
7121
|
+
}
|
|
7122
|
+
return keys;
|
|
7123
|
+
}
|
|
7124
|
+
function labelKeyFromHrefKey(hrefKey) {
|
|
7125
|
+
return hrefKey.replace(/-href$/, "-label");
|
|
7126
|
+
}
|
|
7127
|
+
function resolveRemovableNavUnit(anchor) {
|
|
7128
|
+
if (anchor.closest("[data-ohw-nav-children]")) return anchor;
|
|
7129
|
+
const group = anchor.closest("[data-ohw-nav-group]");
|
|
7130
|
+
if (group?.querySelector(":scope > [data-ohw-nav-children]")) return group;
|
|
7131
|
+
return anchor;
|
|
7132
|
+
}
|
|
7133
|
+
function deleteNavbarItem(sourceAnchor) {
|
|
7134
|
+
if (!isNavbarLinkItem(sourceAnchor)) return null;
|
|
7135
|
+
const sourceHrefKey = sourceAnchor.getAttribute("data-ohw-href-key");
|
|
7136
|
+
if (!sourceHrefKey || !isNavbarHrefKey(sourceHrefKey)) return null;
|
|
7137
|
+
const labelEl = sourceAnchor.querySelector('[data-ohw-editable="text"]');
|
|
7138
|
+
const label = (labelEl?.textContent ?? "").trim() || "Untitled";
|
|
7139
|
+
const previousForest = getNavForestFromDom();
|
|
7140
|
+
const previousOrderJson = serializeNavOrder(previousForest);
|
|
7141
|
+
const taken = takeNode(previousForest, sourceHrefKey);
|
|
7142
|
+
if (!taken) return null;
|
|
7143
|
+
const removedHrefKeys = collectSubtreeHrefKeys(taken.taken);
|
|
7144
|
+
const removedKeys = removedHrefKeys.flatMap((hrefKey) => [hrefKey, labelKeyFromHrefKey(hrefKey)]);
|
|
7145
|
+
const previousContent = {};
|
|
7146
|
+
for (const hrefKey of removedHrefKeys) {
|
|
7147
|
+
const el = findCounterpartByHrefKey(hrefKey, document) ?? document.querySelector(`[data-ohw-href-key="${CSS.escape(hrefKey)}"]`);
|
|
7148
|
+
previousContent[hrefKey] = el ? getLinkHref(el) : "";
|
|
7149
|
+
const labEl = el?.querySelector('[data-ohw-editable="text"]');
|
|
7150
|
+
previousContent[labelKeyFromHrefKey(hrefKey)] = (labEl?.textContent ?? "").trim();
|
|
7151
|
+
}
|
|
7152
|
+
const roots = [getNavbarDesktopContainer(), getNavbarDrawerContainer()].filter(
|
|
7153
|
+
(el) => Boolean(el)
|
|
7154
|
+
);
|
|
7155
|
+
const searchRoots = roots.length > 0 ? roots : [document.body];
|
|
7156
|
+
const placements = [];
|
|
7157
|
+
for (const root of searchRoots) {
|
|
7158
|
+
const primary = findCounterpartByHrefKey(sourceHrefKey, root);
|
|
7159
|
+
if (!primary?.isConnected || !primary.parentElement) continue;
|
|
7160
|
+
const unit = resolveRemovableNavUnit(primary);
|
|
7161
|
+
if (!unit.parentElement) continue;
|
|
7162
|
+
placements.push({
|
|
7163
|
+
node: unit,
|
|
7164
|
+
parent: unit.parentElement,
|
|
7165
|
+
nextSibling: unit.nextSibling
|
|
7166
|
+
});
|
|
7167
|
+
unit.remove();
|
|
7168
|
+
}
|
|
7169
|
+
applyNavForest(taken.forest);
|
|
7170
|
+
const orderJson = serializeNavOrder(taken.forest);
|
|
7171
|
+
return {
|
|
7172
|
+
label,
|
|
7173
|
+
hrefKey: sourceHrefKey,
|
|
7174
|
+
removedKeys,
|
|
7175
|
+
previousContent,
|
|
7176
|
+
orderJson,
|
|
7177
|
+
previousOrderJson,
|
|
7178
|
+
undo: () => {
|
|
7179
|
+
for (const placement of placements) {
|
|
7180
|
+
placement.parent.insertBefore(placement.node, placement.nextSibling);
|
|
7181
|
+
}
|
|
7182
|
+
applyNavForest(previousForest);
|
|
7183
|
+
}
|
|
7184
|
+
};
|
|
7185
|
+
}
|
|
6881
7186
|
|
|
6882
7187
|
// src/lib/footer-items.ts
|
|
6883
7188
|
var FOOTER_ORDER_KEY = "__ohw_footer_order";
|
|
7189
|
+
var MAX_FOOTER_COLUMNS = 18;
|
|
6884
7190
|
var FOOTER_HREF_RE = /^footer-(\d+)-(\d+)-href$/;
|
|
6885
7191
|
function parseFooterHrefKey(key) {
|
|
6886
7192
|
if (!key) return null;
|
|
@@ -7061,16 +7367,260 @@ function parseFooterOrder(content) {
|
|
|
7061
7367
|
return null;
|
|
7062
7368
|
}
|
|
7063
7369
|
}
|
|
7370
|
+
var FOOTER_HEADING_RE = /^footer-(\d+)-heading$/;
|
|
7371
|
+
var FOOTER_LABEL_RE = /^footer-(\d+)-(\d+)-label$/;
|
|
7372
|
+
var DEFAULT_FOOTER_COLUMN_HEADING = "New";
|
|
7373
|
+
var DEFAULT_FOOTER_COLUMN_LINK_LABEL = "New link";
|
|
7374
|
+
var DEFAULT_FOOTER_COLUMN_LINK_HREF = "";
|
|
7375
|
+
function isFooterLinksContainer(el) {
|
|
7376
|
+
return el.hasAttribute("data-ohw-footer-links") || el.classList.contains("rb-footer-links");
|
|
7377
|
+
}
|
|
7378
|
+
function getFooterColumnIndicesInDom() {
|
|
7379
|
+
const indices = /* @__PURE__ */ new Set();
|
|
7380
|
+
for (const col of listFooterColumns()) {
|
|
7381
|
+
const attr = col.getAttribute("data-ohw-footer-col");
|
|
7382
|
+
if (attr != null) {
|
|
7383
|
+
const n = parseInt(attr, 10);
|
|
7384
|
+
if (Number.isFinite(n)) indices.add(n);
|
|
7385
|
+
}
|
|
7386
|
+
for (const link of listFooterLinksInColumn(col)) {
|
|
7387
|
+
const parsed = parseFooterHrefKey(link.getAttribute("data-ohw-href-key"));
|
|
7388
|
+
if (parsed) indices.add(parsed.col);
|
|
7389
|
+
}
|
|
7390
|
+
const heading = col.querySelector('[data-ohw-key^="footer-"][data-ohw-key$="-heading"]');
|
|
7391
|
+
const headingKey = heading?.getAttribute("data-ohw-key");
|
|
7392
|
+
if (headingKey) {
|
|
7393
|
+
const match = headingKey.match(FOOTER_HEADING_RE);
|
|
7394
|
+
if (match) indices.add(parseInt(match[1], 10));
|
|
7395
|
+
}
|
|
7396
|
+
}
|
|
7397
|
+
return [...indices].sort((a, b) => a - b);
|
|
7398
|
+
}
|
|
7399
|
+
function getNextFooterColumnIndex() {
|
|
7400
|
+
const indices = getFooterColumnIndicesInDom();
|
|
7401
|
+
if (indices.length === 0) return 0;
|
|
7402
|
+
return Math.max(...indices) + 1;
|
|
7403
|
+
}
|
|
7404
|
+
function canAddFooterColumn() {
|
|
7405
|
+
return listFooterColumns().length < MAX_FOOTER_COLUMNS;
|
|
7406
|
+
}
|
|
7407
|
+
function buildFooterHeading(colIndex, text) {
|
|
7408
|
+
const heading = document.createElement("p");
|
|
7409
|
+
heading.setAttribute("data-ohw-editable", "text");
|
|
7410
|
+
heading.setAttribute("data-ohw-key", `footer-${colIndex}-heading`);
|
|
7411
|
+
heading.textContent = text;
|
|
7412
|
+
heading.style.cssText = [
|
|
7413
|
+
"color: var(--espresso, #3d312b)",
|
|
7414
|
+
"font-size: 14px",
|
|
7415
|
+
"font-weight: 800",
|
|
7416
|
+
"opacity: 0.82",
|
|
7417
|
+
"margin: 0 0 6px",
|
|
7418
|
+
"padding: 0",
|
|
7419
|
+
"line-height: 1.2"
|
|
7420
|
+
].join(";");
|
|
7421
|
+
return heading;
|
|
7422
|
+
}
|
|
7423
|
+
function buildFooterLink(colIndex, itemIndex, href, label, template) {
|
|
7424
|
+
const anchor = cloneFooterLinkShell(template);
|
|
7425
|
+
anchor.setAttribute("href", href);
|
|
7426
|
+
anchor.setAttribute("data-ohw-href-key", `footer-${colIndex}-${itemIndex}-href`);
|
|
7427
|
+
const span = document.createElement("span");
|
|
7428
|
+
span.setAttribute("data-ohw-editable", "text");
|
|
7429
|
+
span.setAttribute("data-ohw-key", `footer-${colIndex}-${itemIndex}-label`);
|
|
7430
|
+
span.textContent = label;
|
|
7431
|
+
anchor.appendChild(span);
|
|
7432
|
+
return anchor;
|
|
7433
|
+
}
|
|
7434
|
+
function footerColumnExistsInDom(colIndex) {
|
|
7435
|
+
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;
|
|
7436
|
+
}
|
|
7437
|
+
function getFooterLinkTemplate() {
|
|
7438
|
+
for (const col of listFooterColumns()) {
|
|
7439
|
+
const link = listFooterLinksInColumn(col)[0];
|
|
7440
|
+
if (link) return link;
|
|
7441
|
+
}
|
|
7442
|
+
return null;
|
|
7443
|
+
}
|
|
7444
|
+
function getFooterColumnTemplate() {
|
|
7445
|
+
return listFooterColumns()[0] ?? null;
|
|
7446
|
+
}
|
|
7447
|
+
function insertFooterColumnDom(colIndex, heading, items) {
|
|
7448
|
+
const container = getFooterLinksContainer();
|
|
7449
|
+
if (!container) return null;
|
|
7450
|
+
const colTemplate = getFooterColumnTemplate();
|
|
7451
|
+
const linkTemplate = getFooterLinkTemplate();
|
|
7452
|
+
const column = document.createElement("div");
|
|
7453
|
+
if (colTemplate?.className) column.className = colTemplate.className;
|
|
7454
|
+
else column.className = "rb-footer-link-col";
|
|
7455
|
+
column.setAttribute("data-ohw-footer-col", String(colIndex));
|
|
7456
|
+
if (colTemplate) {
|
|
7457
|
+
const gap = getComputedStyle(colTemplate).gap;
|
|
7458
|
+
if (gap && gap !== "normal") column.style.gap = gap;
|
|
7459
|
+
column.style.display = getComputedStyle(colTemplate).display || "flex";
|
|
7460
|
+
column.style.flexDirection = "column";
|
|
7461
|
+
}
|
|
7462
|
+
column.appendChild(buildFooterHeading(colIndex, heading));
|
|
7463
|
+
let firstLink = null;
|
|
7464
|
+
items.forEach((item, itemIndex) => {
|
|
7465
|
+
const link = buildFooterLink(colIndex, itemIndex, item.href, item.label, linkTemplate);
|
|
7466
|
+
column.appendChild(link);
|
|
7467
|
+
if (!firstLink) firstLink = link;
|
|
7468
|
+
});
|
|
7469
|
+
container.appendChild(column);
|
|
7470
|
+
return { column, firstLink };
|
|
7471
|
+
}
|
|
7472
|
+
function insertFooterColumn(heading = DEFAULT_FOOTER_COLUMN_HEADING, linkLabel = DEFAULT_FOOTER_COLUMN_LINK_LABEL, linkHref = DEFAULT_FOOTER_COLUMN_LINK_HREF) {
|
|
7473
|
+
if (!canAddFooterColumn()) {
|
|
7474
|
+
throw new Error(`Footer column limit reached (${MAX_FOOTER_COLUMNS})`);
|
|
7475
|
+
}
|
|
7476
|
+
const colIndex = getNextFooterColumnIndex();
|
|
7477
|
+
const inserted = insertFooterColumnDom(colIndex, heading, [{ href: linkHref, label: linkLabel }]);
|
|
7478
|
+
if (!inserted?.firstLink) throw new Error("Failed to insert footer column");
|
|
7479
|
+
syncFooterColumnIndices(listFooterColumns());
|
|
7480
|
+
return {
|
|
7481
|
+
column: inserted.column,
|
|
7482
|
+
firstLink: inserted.firstLink,
|
|
7483
|
+
colIndex,
|
|
7484
|
+
headingKey: `footer-${colIndex}-heading`,
|
|
7485
|
+
hrefKey: `footer-${colIndex}-0-href`,
|
|
7486
|
+
labelKey: `footer-${colIndex}-0-label`,
|
|
7487
|
+
heading,
|
|
7488
|
+
label: linkLabel,
|
|
7489
|
+
href: linkHref,
|
|
7490
|
+
order: getFooterOrderFromDom()
|
|
7491
|
+
};
|
|
7492
|
+
}
|
|
7493
|
+
function collectFooterColumnIndicesFromContent(content) {
|
|
7494
|
+
const indices = /* @__PURE__ */ new Set();
|
|
7495
|
+
for (const key of Object.keys(content)) {
|
|
7496
|
+
const href = parseFooterHrefKey(key);
|
|
7497
|
+
if (href) indices.add(href.col);
|
|
7498
|
+
const heading = key.match(FOOTER_HEADING_RE);
|
|
7499
|
+
if (heading) indices.add(parseInt(heading[1], 10));
|
|
7500
|
+
const label = key.match(FOOTER_LABEL_RE);
|
|
7501
|
+
if (label) indices.add(parseInt(label[1], 10));
|
|
7502
|
+
}
|
|
7503
|
+
const order = parseFooterOrder(content);
|
|
7504
|
+
if (order) {
|
|
7505
|
+
for (const col of order) {
|
|
7506
|
+
for (const hrefKey of col) {
|
|
7507
|
+
const parsed = parseFooterHrefKey(hrefKey);
|
|
7508
|
+
if (parsed) indices.add(parsed.col);
|
|
7509
|
+
}
|
|
7510
|
+
}
|
|
7511
|
+
}
|
|
7512
|
+
return [...indices].sort((a, b) => a - b);
|
|
7513
|
+
}
|
|
7514
|
+
function collectFooterItemsForColumn(content, colIndex) {
|
|
7515
|
+
const itemIndices = /* @__PURE__ */ new Set();
|
|
7516
|
+
for (const key of Object.keys(content)) {
|
|
7517
|
+
const href = parseFooterHrefKey(key);
|
|
7518
|
+
if (href?.col === colIndex) itemIndices.add(href.item);
|
|
7519
|
+
const label = key.match(FOOTER_LABEL_RE);
|
|
7520
|
+
if (label && parseInt(label[1], 10) === colIndex) {
|
|
7521
|
+
itemIndices.add(parseInt(label[2], 10));
|
|
7522
|
+
}
|
|
7523
|
+
}
|
|
7524
|
+
const sorted = [...itemIndices].sort((a, b) => a - b);
|
|
7525
|
+
if (sorted.length === 0) {
|
|
7526
|
+
return [
|
|
7527
|
+
{
|
|
7528
|
+
href: content[`footer-${colIndex}-0-href`] ?? DEFAULT_FOOTER_COLUMN_LINK_HREF,
|
|
7529
|
+
label: content[`footer-${colIndex}-0-label`] ?? DEFAULT_FOOTER_COLUMN_LINK_LABEL
|
|
7530
|
+
}
|
|
7531
|
+
];
|
|
7532
|
+
}
|
|
7533
|
+
return sorted.map((itemIndex) => ({
|
|
7534
|
+
href: content[`footer-${colIndex}-${itemIndex}-href`] ?? DEFAULT_FOOTER_COLUMN_LINK_HREF,
|
|
7535
|
+
label: content[`footer-${colIndex}-${itemIndex}-label`] ?? DEFAULT_FOOTER_COLUMN_LINK_LABEL
|
|
7536
|
+
}));
|
|
7537
|
+
}
|
|
7538
|
+
function reconcileFooterColumnsFromContent(content) {
|
|
7539
|
+
const order = parseFooterOrder(content);
|
|
7540
|
+
const allowedCols = order ? new Set(
|
|
7541
|
+
order.flatMap(
|
|
7542
|
+
(col) => col.map((k) => parseFooterHrefKey(k)?.col).filter((n) => n !== void 0 && n !== null)
|
|
7543
|
+
)
|
|
7544
|
+
) : null;
|
|
7545
|
+
const indices = collectFooterColumnIndicesFromContent(content);
|
|
7546
|
+
for (const colIndex of indices) {
|
|
7547
|
+
if (allowedCols && !allowedCols.has(colIndex)) continue;
|
|
7548
|
+
if (footerColumnExistsInDom(colIndex)) continue;
|
|
7549
|
+
const heading = content[`footer-${colIndex}-heading`] ?? DEFAULT_FOOTER_COLUMN_HEADING;
|
|
7550
|
+
const items = collectFooterItemsForColumn(content, colIndex);
|
|
7551
|
+
const hasPayload = Boolean(content[`footer-${colIndex}-heading`]) || items.some(
|
|
7552
|
+
(_, i) => content[`footer-${colIndex}-${i}-href`] !== void 0 || content[`footer-${colIndex}-${i}-label`] !== void 0
|
|
7553
|
+
) || (order?.some((col) => col.some((k) => parseFooterHrefKey(k)?.col === colIndex)) ?? false);
|
|
7554
|
+
if (!hasPayload) continue;
|
|
7555
|
+
insertFooterColumnDom(colIndex, heading, items);
|
|
7556
|
+
}
|
|
7557
|
+
}
|
|
7064
7558
|
function reconcileFooterOrderFromContent(content) {
|
|
7559
|
+
reconcileFooterColumnsFromContent(content);
|
|
7065
7560
|
const order = parseFooterOrder(content);
|
|
7066
7561
|
if (!order?.length) return;
|
|
7067
|
-
const
|
|
7068
|
-
|
|
7069
|
-
|
|
7070
|
-
|
|
7562
|
+
const linkTemplate = getFooterLinkTemplate();
|
|
7563
|
+
for (let c = 0; c < order.length; c++) {
|
|
7564
|
+
const colOrder = order[c];
|
|
7565
|
+
for (const hrefKey of colOrder) {
|
|
7566
|
+
if (findFooterLinkByKey(hrefKey)) continue;
|
|
7567
|
+
const parsed = parseFooterHrefKey(hrefKey);
|
|
7568
|
+
if (!parsed) continue;
|
|
7569
|
+
const columns = listFooterColumns();
|
|
7570
|
+
const column = columns.find((col) => col.getAttribute("data-ohw-footer-col") === String(parsed.col)) ?? columns[c] ?? null;
|
|
7571
|
+
if (!column) continue;
|
|
7572
|
+
const href = content[hrefKey] ?? DEFAULT_FOOTER_COLUMN_LINK_HREF;
|
|
7573
|
+
const labelKey = `footer-${parsed.col}-${parsed.item}-label`;
|
|
7574
|
+
const label = content[labelKey] ?? DEFAULT_FOOTER_COLUMN_LINK_LABEL;
|
|
7575
|
+
if (!href && !label) continue;
|
|
7576
|
+
column.appendChild(buildFooterLink(parsed.col, parsed.item, href || "/", label, linkTemplate));
|
|
7577
|
+
}
|
|
7071
7578
|
}
|
|
7579
|
+
pruneFooterToOrder(order);
|
|
7072
7580
|
applyFooterOrder(order);
|
|
7073
7581
|
}
|
|
7582
|
+
function pruneFooterToOrder(order) {
|
|
7583
|
+
const allowedKeys = new Set(order.flat());
|
|
7584
|
+
const allowedColIndices = new Set(
|
|
7585
|
+
[...allowedKeys].map((k) => parseFooterHrefKey(k)?.col).filter((n) => n !== void 0 && n !== null)
|
|
7586
|
+
);
|
|
7587
|
+
for (const column of [...listFooterColumns()]) {
|
|
7588
|
+
if (!column.isConnected) continue;
|
|
7589
|
+
for (const link of [...listFooterLinksInColumn(column)]) {
|
|
7590
|
+
const key = link.getAttribute("data-ohw-href-key");
|
|
7591
|
+
if (!key || allowedKeys.has(key)) continue;
|
|
7592
|
+
link.remove();
|
|
7593
|
+
}
|
|
7594
|
+
const remaining = listFooterLinksInColumn(column);
|
|
7595
|
+
const colAttr = column.getAttribute("data-ohw-footer-col");
|
|
7596
|
+
const colIndex = colAttr != null ? parseInt(colAttr, 10) : NaN;
|
|
7597
|
+
const referenced = remaining.some((link) => allowedKeys.has(link.getAttribute("data-ohw-href-key") ?? ""));
|
|
7598
|
+
if (!referenced && (!Number.isFinite(colIndex) || !allowedColIndices.has(colIndex))) {
|
|
7599
|
+
column.remove();
|
|
7600
|
+
}
|
|
7601
|
+
}
|
|
7602
|
+
syncFooterColumnIndices(listFooterColumns());
|
|
7603
|
+
}
|
|
7604
|
+
function resolveFooterLinksContainerSelectionTarget(target, clientX, clientY, isPointOverItem) {
|
|
7605
|
+
const container = getFooterLinksContainer();
|
|
7606
|
+
if (!container) return null;
|
|
7607
|
+
const inContainer = target === container || container.contains(target) && Boolean(target.closest("[data-ohw-footer-links], .rb-footer-links"));
|
|
7608
|
+
if (!inContainer && target !== container) {
|
|
7609
|
+
const r2 = container.getBoundingClientRect();
|
|
7610
|
+
const over = clientX >= r2.left && clientX <= r2.right && clientY >= r2.top && clientY <= r2.bottom;
|
|
7611
|
+
if (!over) return null;
|
|
7612
|
+
}
|
|
7613
|
+
if (isPointOverItem(container, clientX, clientY)) return null;
|
|
7614
|
+
const column = target.closest("[data-ohw-footer-col], [data-ohw-footer-column]") ?? null;
|
|
7615
|
+
if (column && container.contains(column)) {
|
|
7616
|
+
if (target === column || column.contains(target)) return null;
|
|
7617
|
+
}
|
|
7618
|
+
if (target === container || container.contains(target) || inContainer) {
|
|
7619
|
+
if (target === container || isFooterLinksContainer(target)) return container;
|
|
7620
|
+
if (!column) return container;
|
|
7621
|
+
}
|
|
7622
|
+
return null;
|
|
7623
|
+
}
|
|
7074
7624
|
function isRowLayoutColumn(links) {
|
|
7075
7625
|
if (links.length < 2) return false;
|
|
7076
7626
|
const firstTop = links[0].getBoundingClientRect().top;
|
|
@@ -7225,34 +7775,225 @@ function hitTestColumnDropSlot(clientX, _clientY) {
|
|
|
7225
7775
|
}
|
|
7226
7776
|
return best?.slot ?? null;
|
|
7227
7777
|
}
|
|
7228
|
-
|
|
7229
|
-
|
|
7230
|
-
|
|
7231
|
-
|
|
7232
|
-
|
|
7233
|
-
el.setAttribute("draggable", "false");
|
|
7778
|
+
function getLinkHref2(el) {
|
|
7779
|
+
const key = el.getAttribute("data-ohw-href-key");
|
|
7780
|
+
if (key) {
|
|
7781
|
+
const stored = getStoredLinkHref(key);
|
|
7782
|
+
if (stored !== void 0) return stored;
|
|
7234
7783
|
}
|
|
7784
|
+
return el.getAttribute("href") ?? "";
|
|
7235
7785
|
}
|
|
7236
|
-
function
|
|
7237
|
-
|
|
7238
|
-
|
|
7239
|
-
|
|
7240
|
-
|
|
7241
|
-
|
|
7786
|
+
function getNextFooterItemIndex(col) {
|
|
7787
|
+
let max = -1;
|
|
7788
|
+
for (const el of document.querySelectorAll("footer [data-ohw-href-key]")) {
|
|
7789
|
+
const parsed = parseFooterHrefKey(el.getAttribute("data-ohw-href-key"));
|
|
7790
|
+
if (!parsed || parsed.col !== col) continue;
|
|
7791
|
+
if (parsed.item > max) max = parsed.item;
|
|
7792
|
+
}
|
|
7793
|
+
return max + 1;
|
|
7242
7794
|
}
|
|
7243
|
-
function
|
|
7244
|
-
document.
|
|
7245
|
-
|
|
7246
|
-
|
|
7795
|
+
function cloneFooterLinkShell(template) {
|
|
7796
|
+
const anchor = document.createElement("a");
|
|
7797
|
+
if (template) {
|
|
7798
|
+
anchor.style.cssText = template.style.cssText;
|
|
7799
|
+
if (template.className) anchor.className = template.className;
|
|
7800
|
+
}
|
|
7801
|
+
anchor.style.cursor = "pointer";
|
|
7802
|
+
anchor.style.textDecoration = "none";
|
|
7803
|
+
return anchor;
|
|
7247
7804
|
}
|
|
7248
|
-
function
|
|
7249
|
-
const
|
|
7250
|
-
|
|
7251
|
-
|
|
7252
|
-
|
|
7805
|
+
function insertFooterItem(column, href, label, afterAnchor = null) {
|
|
7806
|
+
const columns = listFooterColumns();
|
|
7807
|
+
const colIndex = columns.indexOf(column);
|
|
7808
|
+
if (colIndex < 0) throw new Error("Footer column not found");
|
|
7809
|
+
const item = getNextFooterItemIndex(colIndex);
|
|
7810
|
+
const hrefKey = `footer-${colIndex}-${item}-href`;
|
|
7811
|
+
const labelKey = `footer-${colIndex}-${item}-label`;
|
|
7812
|
+
const template = listFooterLinksInColumn(column)[0] ?? null;
|
|
7813
|
+
const anchor = cloneFooterLinkShell(template);
|
|
7814
|
+
anchor.href = href;
|
|
7815
|
+
anchor.setAttribute("data-ohw-href-key", hrefKey);
|
|
7816
|
+
const span = document.createElement("span");
|
|
7817
|
+
span.setAttribute("data-ohw-editable", "text");
|
|
7818
|
+
span.setAttribute("data-ohw-key", labelKey);
|
|
7819
|
+
span.textContent = label;
|
|
7820
|
+
anchor.appendChild(span);
|
|
7821
|
+
if (afterAnchor && afterAnchor.parentElement === column) {
|
|
7822
|
+
afterAnchor.insertAdjacentElement("afterend", anchor);
|
|
7823
|
+
} else {
|
|
7824
|
+
column.appendChild(anchor);
|
|
7825
|
+
}
|
|
7826
|
+
const order = getFooterOrderFromDom();
|
|
7827
|
+
applyFooterOrder(order);
|
|
7828
|
+
return {
|
|
7829
|
+
anchor,
|
|
7830
|
+
col: colIndex,
|
|
7831
|
+
item,
|
|
7832
|
+
hrefKey,
|
|
7833
|
+
labelKey,
|
|
7834
|
+
href,
|
|
7835
|
+
label,
|
|
7836
|
+
order
|
|
7837
|
+
};
|
|
7253
7838
|
}
|
|
7254
|
-
|
|
7255
|
-
|
|
7839
|
+
function duplicateFooterItem(sourceAnchor) {
|
|
7840
|
+
if (!isFooterLinkAnchor(sourceAnchor)) return null;
|
|
7841
|
+
const column = findFooterColumnForLink(sourceAnchor);
|
|
7842
|
+
if (!column) return null;
|
|
7843
|
+
const href = getLinkHref2(sourceAnchor);
|
|
7844
|
+
const labelEl = sourceAnchor.querySelector('[data-ohw-editable="text"]');
|
|
7845
|
+
const label = (labelEl?.textContent ?? "").trim() || "Untitled";
|
|
7846
|
+
return insertFooterItem(column, href || "/", label, sourceAnchor);
|
|
7847
|
+
}
|
|
7848
|
+
function footerLabelKeyFromHrefKey(hrefKey) {
|
|
7849
|
+
return hrefKey.replace(/-href$/, "-label");
|
|
7850
|
+
}
|
|
7851
|
+
function deleteFooterItem(sourceAnchor) {
|
|
7852
|
+
if (!isFooterLinkAnchor(sourceAnchor)) return null;
|
|
7853
|
+
const hrefKey = sourceAnchor.getAttribute("data-ohw-href-key");
|
|
7854
|
+
if (!hrefKey || !isFooterHrefKey(hrefKey)) return null;
|
|
7855
|
+
const labelEl = sourceAnchor.querySelector('[data-ohw-editable="text"]');
|
|
7856
|
+
const label = (labelEl?.textContent ?? "").trim() || "Untitled";
|
|
7857
|
+
const labelKey = footerLabelKeyFromHrefKey(hrefKey);
|
|
7858
|
+
const previousOrder = getFooterOrderFromDom();
|
|
7859
|
+
const previousOrderJson = JSON.stringify(previousOrder);
|
|
7860
|
+
const previousContent = {
|
|
7861
|
+
[hrefKey]: getLinkHref2(sourceAnchor),
|
|
7862
|
+
[labelKey]: label
|
|
7863
|
+
};
|
|
7864
|
+
if (!sourceAnchor.parentElement) return null;
|
|
7865
|
+
const placement = {
|
|
7866
|
+
node: sourceAnchor,
|
|
7867
|
+
parent: sourceAnchor.parentElement,
|
|
7868
|
+
nextSibling: sourceAnchor.nextSibling
|
|
7869
|
+
};
|
|
7870
|
+
sourceAnchor.remove();
|
|
7871
|
+
const order = getFooterOrderFromDom();
|
|
7872
|
+
applyFooterOrder(order);
|
|
7873
|
+
const orderJson = JSON.stringify(order);
|
|
7874
|
+
return {
|
|
7875
|
+
label,
|
|
7876
|
+
removedKeys: [hrefKey, labelKey],
|
|
7877
|
+
previousContent,
|
|
7878
|
+
orderJson,
|
|
7879
|
+
previousOrderJson,
|
|
7880
|
+
undo: () => {
|
|
7881
|
+
placement.parent.insertBefore(placement.node, placement.nextSibling);
|
|
7882
|
+
applyFooterOrder(previousOrder);
|
|
7883
|
+
}
|
|
7884
|
+
};
|
|
7885
|
+
}
|
|
7886
|
+
function deleteFooterColumn(column) {
|
|
7887
|
+
const columns = listFooterColumns();
|
|
7888
|
+
if (!columns.includes(column)) return null;
|
|
7889
|
+
if (!column.parentElement) return null;
|
|
7890
|
+
const links = listFooterLinksInColumn(column);
|
|
7891
|
+
const heading = column.querySelector(
|
|
7892
|
+
'[data-ohw-key^="footer-"][data-ohw-key$="-heading"]'
|
|
7893
|
+
);
|
|
7894
|
+
const headingKey = heading?.getAttribute("data-ohw-key") ?? null;
|
|
7895
|
+
const headingText = (heading?.textContent ?? "").trim();
|
|
7896
|
+
const label = headingText || (links[0]?.querySelector('[data-ohw-editable="text"]')?.textContent ?? "").trim() || "Untitled";
|
|
7897
|
+
const previousOrder = getFooterOrderFromDom();
|
|
7898
|
+
const previousOrderJson = JSON.stringify(previousOrder);
|
|
7899
|
+
const previousContent = {};
|
|
7900
|
+
const removedKeys = [];
|
|
7901
|
+
if (headingKey) {
|
|
7902
|
+
removedKeys.push(headingKey);
|
|
7903
|
+
previousContent[headingKey] = headingText;
|
|
7904
|
+
}
|
|
7905
|
+
for (const link of links) {
|
|
7906
|
+
const hrefKey = link.getAttribute("data-ohw-href-key");
|
|
7907
|
+
if (!hrefKey) continue;
|
|
7908
|
+
const labelKey = footerLabelKeyFromHrefKey(hrefKey);
|
|
7909
|
+
removedKeys.push(hrefKey, labelKey);
|
|
7910
|
+
previousContent[hrefKey] = getLinkHref2(link);
|
|
7911
|
+
previousContent[labelKey] = (link.querySelector('[data-ohw-editable="text"]')?.textContent ?? "").trim();
|
|
7912
|
+
}
|
|
7913
|
+
const placement = {
|
|
7914
|
+
node: column,
|
|
7915
|
+
parent: column.parentElement,
|
|
7916
|
+
nextSibling: column.nextSibling
|
|
7917
|
+
};
|
|
7918
|
+
column.remove();
|
|
7919
|
+
const remaining = listFooterColumns();
|
|
7920
|
+
syncFooterColumnIndices(remaining);
|
|
7921
|
+
const order = getFooterOrderFromDom();
|
|
7922
|
+
applyFooterOrder(order);
|
|
7923
|
+
const orderJson = JSON.stringify(order);
|
|
7924
|
+
return {
|
|
7925
|
+
label,
|
|
7926
|
+
removedKeys,
|
|
7927
|
+
previousContent,
|
|
7928
|
+
orderJson,
|
|
7929
|
+
previousOrderJson,
|
|
7930
|
+
undo: () => {
|
|
7931
|
+
placement.parent.insertBefore(placement.node, placement.nextSibling);
|
|
7932
|
+
syncFooterColumnIndices(listFooterColumns());
|
|
7933
|
+
applyFooterOrder(previousOrder);
|
|
7934
|
+
}
|
|
7935
|
+
};
|
|
7936
|
+
}
|
|
7937
|
+
|
|
7938
|
+
// src/lib/add-footer-column.ts
|
|
7939
|
+
function buildFooterColumnEditContentPatch(result) {
|
|
7940
|
+
return {
|
|
7941
|
+
[result.headingKey]: result.heading,
|
|
7942
|
+
[result.hrefKey]: result.href,
|
|
7943
|
+
[result.labelKey]: result.label,
|
|
7944
|
+
[FOOTER_ORDER_KEY]: JSON.stringify(result.order)
|
|
7945
|
+
};
|
|
7946
|
+
}
|
|
7947
|
+
function addFooterColumnWithPersist({
|
|
7948
|
+
postToParent: postToParent2
|
|
7949
|
+
}) {
|
|
7950
|
+
if (!canAddFooterColumn()) {
|
|
7951
|
+
postToParent2({
|
|
7952
|
+
type: "ow:toast",
|
|
7953
|
+
title: `Maximum ${MAX_FOOTER_COLUMNS} columns`,
|
|
7954
|
+
toastType: "error"
|
|
7955
|
+
});
|
|
7956
|
+
return null;
|
|
7957
|
+
}
|
|
7958
|
+
const result = insertFooterColumn();
|
|
7959
|
+
const patch = buildFooterColumnEditContentPatch(result);
|
|
7960
|
+
setStoredLinkHref(result.hrefKey, result.href);
|
|
7961
|
+
postToParent2({
|
|
7962
|
+
type: "ow:change",
|
|
7963
|
+
nodes: Object.entries(patch).map(([key, text]) => ({ key, text }))
|
|
7964
|
+
});
|
|
7965
|
+
postToParent2({ type: "ow:toast", title: "Item added", toastType: "success" });
|
|
7966
|
+
enforceLinkHrefs();
|
|
7967
|
+
return result;
|
|
7968
|
+
}
|
|
7969
|
+
|
|
7970
|
+
// src/lib/item-drag-interaction.ts
|
|
7971
|
+
function disableNativeHrefDrag(el) {
|
|
7972
|
+
if (el.draggable) el.draggable = false;
|
|
7973
|
+
if (el.getAttribute("draggable") !== "false") {
|
|
7974
|
+
el.setAttribute("draggable", "false");
|
|
7975
|
+
}
|
|
7976
|
+
}
|
|
7977
|
+
function clearTextSelection() {
|
|
7978
|
+
const sel = window.getSelection();
|
|
7979
|
+
if (sel && !sel.isCollapsed) sel.removeAllRanges();
|
|
7980
|
+
}
|
|
7981
|
+
function armItemPressDrag() {
|
|
7982
|
+
document.documentElement.setAttribute("data-ohw-footer-press-drag", "");
|
|
7983
|
+
}
|
|
7984
|
+
function lockItemDuringDrag() {
|
|
7985
|
+
document.documentElement.removeAttribute("data-ohw-footer-press-drag");
|
|
7986
|
+
document.documentElement.setAttribute("data-ohw-item-dragging", "");
|
|
7987
|
+
clearTextSelection();
|
|
7988
|
+
}
|
|
7989
|
+
function unlockItemDragInteraction() {
|
|
7990
|
+
const wasDragging = document.documentElement.hasAttribute("data-ohw-item-dragging");
|
|
7991
|
+
document.documentElement.removeAttribute("data-ohw-footer-press-drag");
|
|
7992
|
+
document.documentElement.removeAttribute("data-ohw-item-dragging");
|
|
7993
|
+
if (wasDragging) clearTextSelection();
|
|
7994
|
+
}
|
|
7995
|
+
var armFooterPressDrag = armItemPressDrag;
|
|
7996
|
+
var lockFooterDuringDrag = lockItemDuringDrag;
|
|
7256
7997
|
var unlockFooterDragInteraction = unlockItemDragInteraction;
|
|
7257
7998
|
|
|
7258
7999
|
// src/lib/nav-dnd.ts
|
|
@@ -7423,7 +8164,7 @@ function hitTestNavDropSlot(clientX, clientY, draggedHrefKey) {
|
|
|
7423
8164
|
}
|
|
7424
8165
|
|
|
7425
8166
|
// src/useNavItemDrag.ts
|
|
7426
|
-
import { useCallback as useCallback4, useEffect as useEffect7, useRef as useRef6, useState as
|
|
8167
|
+
import { useCallback as useCallback4, useEffect as useEffect7, useRef as useRef6, useState as useState7 } from "react";
|
|
7427
8168
|
function useNavItemDrag({
|
|
7428
8169
|
isEditMode,
|
|
7429
8170
|
editContentRef,
|
|
@@ -7449,8 +8190,8 @@ function useNavItemDrag({
|
|
|
7449
8190
|
isNavbarButton: isNavbarButton3
|
|
7450
8191
|
}) {
|
|
7451
8192
|
const navDragRef = useRef6(null);
|
|
7452
|
-
const [navDropSlots, setNavDropSlots] =
|
|
7453
|
-
const [activeNavDropIndex, setActiveNavDropIndex] =
|
|
8193
|
+
const [navDropSlots, setNavDropSlots] = useState7([]);
|
|
8194
|
+
const [activeNavDropIndex, setActiveNavDropIndex] = useState7(null);
|
|
7454
8195
|
const navPointerDragRef = useRef6(null);
|
|
7455
8196
|
const clearNavDragVisuals = useCallback4(() => {
|
|
7456
8197
|
navDragRef.current = null;
|
|
@@ -7758,8 +8499,59 @@ function useNavItemDrag({
|
|
|
7758
8499
|
};
|
|
7759
8500
|
}
|
|
7760
8501
|
|
|
8502
|
+
// src/ui/footer-container-chrome.tsx
|
|
8503
|
+
import { Plus as Plus2 } from "lucide-react";
|
|
8504
|
+
import { jsx as jsx23, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
8505
|
+
function FooterContainerChrome({
|
|
8506
|
+
rect,
|
|
8507
|
+
onAdd,
|
|
8508
|
+
addDisabled = false
|
|
8509
|
+
}) {
|
|
8510
|
+
const chromeGap = 6;
|
|
8511
|
+
const buttonMargin = 7;
|
|
8512
|
+
return /* @__PURE__ */ jsx23(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ jsx23(
|
|
8513
|
+
"div",
|
|
8514
|
+
{
|
|
8515
|
+
"data-ohw-footer-container-chrome": "",
|
|
8516
|
+
"data-ohw-bridge": "",
|
|
8517
|
+
className: "pointer-events-none fixed z-[2147483647]",
|
|
8518
|
+
style: {
|
|
8519
|
+
top: rect.top - chromeGap,
|
|
8520
|
+
left: rect.left - chromeGap,
|
|
8521
|
+
width: rect.width + chromeGap * 2,
|
|
8522
|
+
height: rect.height + chromeGap * 2
|
|
8523
|
+
},
|
|
8524
|
+
children: /* @__PURE__ */ jsxs14(Tooltip, { children: [
|
|
8525
|
+
/* @__PURE__ */ jsx23(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx23(
|
|
8526
|
+
"button",
|
|
8527
|
+
{
|
|
8528
|
+
type: "button",
|
|
8529
|
+
"data-ohw-footer-add-button": "",
|
|
8530
|
+
disabled: addDisabled,
|
|
8531
|
+
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",
|
|
8532
|
+
style: { top: chromeGap - buttonMargin },
|
|
8533
|
+
"aria-label": "Add item",
|
|
8534
|
+
onMouseDown: (e) => {
|
|
8535
|
+
e.preventDefault();
|
|
8536
|
+
e.stopPropagation();
|
|
8537
|
+
},
|
|
8538
|
+
onClick: (e) => {
|
|
8539
|
+
e.preventDefault();
|
|
8540
|
+
e.stopPropagation();
|
|
8541
|
+
if (addDisabled) return;
|
|
8542
|
+
onAdd();
|
|
8543
|
+
},
|
|
8544
|
+
children: /* @__PURE__ */ jsx23(Plus2, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
|
|
8545
|
+
}
|
|
8546
|
+
) }),
|
|
8547
|
+
/* @__PURE__ */ jsx23(TooltipContent, { side: "bottom", sideOffset: 9, children: addDisabled ? "Maximum columns reached" : "Add item" })
|
|
8548
|
+
] })
|
|
8549
|
+
}
|
|
8550
|
+
) });
|
|
8551
|
+
}
|
|
8552
|
+
|
|
7761
8553
|
// src/lib/carousel.ts
|
|
7762
|
-
import { useEffect as useEffect8, useState as
|
|
8554
|
+
import { useEffect as useEffect8, useState as useState8 } from "react";
|
|
7763
8555
|
var CAROUSEL_ATTR = "data-ohw-carousel";
|
|
7764
8556
|
var CAROUSEL_VALUE_ATTR = "data-ohw-carousel-value";
|
|
7765
8557
|
var CAROUSEL_SLIDE_ATTR = "data-ohw-carousel-slide";
|
|
@@ -7821,7 +8613,7 @@ function applyCarouselNode(key, val) {
|
|
|
7821
8613
|
return true;
|
|
7822
8614
|
}
|
|
7823
8615
|
function useOhwCarousel(key, initial) {
|
|
7824
|
-
const [images, setImages] =
|
|
8616
|
+
const [images, setImages] = useState8(initial);
|
|
7825
8617
|
useEffect8(() => {
|
|
7826
8618
|
const el = document.querySelector(
|
|
7827
8619
|
`[${CAROUSEL_ATTR}][data-ohw-key="${CSS.escape(key)}"]`
|
|
@@ -7842,15 +8634,340 @@ function useOhwCarousel(key, initial) {
|
|
|
7842
8634
|
return { images, setImages, bind };
|
|
7843
8635
|
}
|
|
7844
8636
|
|
|
8637
|
+
// src/lib/collect-editable-nodes.ts
|
|
8638
|
+
var VIDEO_AUTOPLAY_SUFFIX = "__ohw_autoplay";
|
|
8639
|
+
var VIDEO_MUTED_SUFFIX = "__ohw_muted";
|
|
8640
|
+
function getVideoEl(el) {
|
|
8641
|
+
return el instanceof HTMLVideoElement ? el : el.querySelector("video");
|
|
8642
|
+
}
|
|
8643
|
+
function getLinkHref3(el) {
|
|
8644
|
+
const key = el.getAttribute("data-ohw-href-key");
|
|
8645
|
+
if (key) {
|
|
8646
|
+
const stored = getStoredLinkHref(key);
|
|
8647
|
+
if (stored !== void 0) return stored;
|
|
8648
|
+
}
|
|
8649
|
+
const anchor = el instanceof HTMLAnchorElement ? el : el.querySelector("a");
|
|
8650
|
+
return anchor?.getAttribute("href") ?? "";
|
|
8651
|
+
}
|
|
8652
|
+
function collectEditableNodes(extraContent) {
|
|
8653
|
+
const nodes = Array.from(
|
|
8654
|
+
document.querySelectorAll("[data-ohw-editable]")
|
|
8655
|
+
).map((el) => {
|
|
8656
|
+
if (el.dataset.ohwEditable === "image") {
|
|
8657
|
+
const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
|
|
8658
|
+
return { key: el.dataset.ohwKey ?? "", type: "image", text: img?.src ?? "" };
|
|
8659
|
+
}
|
|
8660
|
+
if (el.dataset.ohwEditable === "bg-image") {
|
|
8661
|
+
const raw = el.style.backgroundImage;
|
|
8662
|
+
const url = raw.replace(/^url\(['"]?/, "").replace(/['"]?\)$/, "");
|
|
8663
|
+
return { key: el.dataset.ohwKey ?? "", type: "bg-image", text: url };
|
|
8664
|
+
}
|
|
8665
|
+
if (el.dataset.ohwEditable === "video") {
|
|
8666
|
+
return { key: el.dataset.ohwKey ?? "", type: "video", text: getVideoEl(el)?.src ?? "" };
|
|
8667
|
+
}
|
|
8668
|
+
if (el.dataset.ohwEditable === "link") {
|
|
8669
|
+
return { key: el.dataset.ohwKey ?? "", type: "link", text: getLinkHref3(el) };
|
|
8670
|
+
}
|
|
8671
|
+
return {
|
|
8672
|
+
key: el.dataset.ohwKey ?? "",
|
|
8673
|
+
type: el.dataset.ohwEditable ?? "text",
|
|
8674
|
+
text: el.dataset.ohwEditable === "plain" ? el.innerText ?? "" : el.innerHTML
|
|
8675
|
+
};
|
|
8676
|
+
});
|
|
8677
|
+
document.querySelectorAll("[data-ohw-href-key]").forEach((el) => {
|
|
8678
|
+
const key = el.getAttribute("data-ohw-href-key") ?? "";
|
|
8679
|
+
if (!key) return;
|
|
8680
|
+
nodes.push({ key, type: "link", text: getLinkHref3(el) });
|
|
8681
|
+
});
|
|
8682
|
+
if (extraContent) {
|
|
8683
|
+
for (const key of [NAV_ORDER_KEY, FOOTER_ORDER_KEY, NAV_COUNT_KEY]) {
|
|
8684
|
+
const text = extraContent[key];
|
|
8685
|
+
if (typeof text === "string" && text.length > 0) {
|
|
8686
|
+
nodes.push({ key, type: "meta", text });
|
|
8687
|
+
}
|
|
8688
|
+
}
|
|
8689
|
+
}
|
|
8690
|
+
document.querySelectorAll('[data-ohw-editable="video"]').forEach((el) => {
|
|
8691
|
+
const key = el.dataset.ohwKey ?? "";
|
|
8692
|
+
const video = getVideoEl(el);
|
|
8693
|
+
if (!key || !video) return;
|
|
8694
|
+
nodes.push({
|
|
8695
|
+
key: `${key}${VIDEO_AUTOPLAY_SUFFIX}`,
|
|
8696
|
+
type: "video-setting",
|
|
8697
|
+
text: String(video.autoplay)
|
|
8698
|
+
});
|
|
8699
|
+
nodes.push({
|
|
8700
|
+
key: `${key}${VIDEO_MUTED_SUFFIX}`,
|
|
8701
|
+
type: "video-setting",
|
|
8702
|
+
text: String(video.muted)
|
|
8703
|
+
});
|
|
8704
|
+
});
|
|
8705
|
+
for (const key of listCarouselKeys()) {
|
|
8706
|
+
nodes.push({ key, type: "carousel", text: JSON.stringify(readCarouselValue(key)) });
|
|
8707
|
+
}
|
|
8708
|
+
const byKey = /* @__PURE__ */ new Map();
|
|
8709
|
+
for (const node of nodes) {
|
|
8710
|
+
if (!node.key) continue;
|
|
8711
|
+
if (!byKey.has(node.key)) byKey.set(node.key, node);
|
|
8712
|
+
}
|
|
8713
|
+
if (extraContent) {
|
|
8714
|
+
applyNavFooterDeleteOverrides(byKey, extraContent);
|
|
8715
|
+
}
|
|
8716
|
+
return Array.from(byKey.values());
|
|
8717
|
+
}
|
|
8718
|
+
function applyNavFooterDeleteOverrides(byKey, content) {
|
|
8719
|
+
for (const [key, text] of Object.entries(content)) {
|
|
8720
|
+
if (text !== "") continue;
|
|
8721
|
+
if (!key.startsWith("nav-") && !key.startsWith("footer-")) continue;
|
|
8722
|
+
if (key === "nav-book-href" || key === "nav-book-label") continue;
|
|
8723
|
+
byKey.set(key, { key, type: "meta", text: "" });
|
|
8724
|
+
}
|
|
8725
|
+
const navOrder = content[NAV_ORDER_KEY];
|
|
8726
|
+
if (navOrder) {
|
|
8727
|
+
try {
|
|
8728
|
+
const allowed = parseAllowedNavHrefKeys(navOrder);
|
|
8729
|
+
const clearKey = (key) => {
|
|
8730
|
+
byKey.set(key, { key, type: "meta", text: "" });
|
|
8731
|
+
};
|
|
8732
|
+
for (const key of /* @__PURE__ */ new Set([...byKey.keys(), ...Object.keys(content)])) {
|
|
8733
|
+
if (key === "nav-book-href" || key === "nav-book-label") continue;
|
|
8734
|
+
if (isNavbarHrefKey(key) && !allowed.has(key)) {
|
|
8735
|
+
clearKey(key);
|
|
8736
|
+
clearKey(key.replace(/-href$/, "-label"));
|
|
8737
|
+
} else if (/^nav-\d+-label$/.test(key)) {
|
|
8738
|
+
const hrefKey = key.replace(/-label$/, "-href");
|
|
8739
|
+
if (!allowed.has(hrefKey)) clearKey(key);
|
|
8740
|
+
}
|
|
8741
|
+
}
|
|
8742
|
+
} catch {
|
|
8743
|
+
}
|
|
8744
|
+
}
|
|
8745
|
+
const footerOrder = content[FOOTER_ORDER_KEY];
|
|
8746
|
+
if (footerOrder) {
|
|
8747
|
+
try {
|
|
8748
|
+
const { allowedKeys, allowedCols } = parseAllowedFooterKeys(footerOrder);
|
|
8749
|
+
const clearKey = (key) => {
|
|
8750
|
+
byKey.set(key, { key, type: "meta", text: "" });
|
|
8751
|
+
};
|
|
8752
|
+
for (const key of /* @__PURE__ */ new Set([...byKey.keys(), ...Object.keys(content)])) {
|
|
8753
|
+
if (isFooterHrefKey(key) && !allowedKeys.has(key)) {
|
|
8754
|
+
clearKey(key);
|
|
8755
|
+
clearKey(key.replace(/-href$/, "-label"));
|
|
8756
|
+
continue;
|
|
8757
|
+
}
|
|
8758
|
+
const labelMatch = key.match(/^footer-(\d+)-(\d+)-label$/);
|
|
8759
|
+
if (labelMatch) {
|
|
8760
|
+
const hrefKey = `footer-${labelMatch[1]}-${labelMatch[2]}-href`;
|
|
8761
|
+
if (!allowedKeys.has(hrefKey)) clearKey(key);
|
|
8762
|
+
continue;
|
|
8763
|
+
}
|
|
8764
|
+
const headingMatch = key.match(/^footer-(\d+)-heading$/);
|
|
8765
|
+
if (headingMatch && !allowedCols.has(parseInt(headingMatch[1], 10))) {
|
|
8766
|
+
clearKey(key);
|
|
8767
|
+
}
|
|
8768
|
+
}
|
|
8769
|
+
} catch {
|
|
8770
|
+
}
|
|
8771
|
+
}
|
|
8772
|
+
}
|
|
8773
|
+
function parseAllowedNavHrefKeys(raw) {
|
|
8774
|
+
const parsed = JSON.parse(raw);
|
|
8775
|
+
const allowed = /* @__PURE__ */ new Set();
|
|
8776
|
+
const walk = (nodes) => {
|
|
8777
|
+
if (!Array.isArray(nodes)) return;
|
|
8778
|
+
for (const node of nodes) {
|
|
8779
|
+
if (typeof node === "string" && node.length > 0) {
|
|
8780
|
+
allowed.add(node);
|
|
8781
|
+
continue;
|
|
8782
|
+
}
|
|
8783
|
+
if (node && typeof node === "object" && typeof node.id === "string") {
|
|
8784
|
+
allowed.add(node.id);
|
|
8785
|
+
walk(node.children);
|
|
8786
|
+
}
|
|
8787
|
+
}
|
|
8788
|
+
};
|
|
8789
|
+
walk(parsed);
|
|
8790
|
+
return allowed;
|
|
8791
|
+
}
|
|
8792
|
+
function parseAllowedFooterKeys(raw) {
|
|
8793
|
+
const parsed = JSON.parse(raw);
|
|
8794
|
+
const allowedKeys = /* @__PURE__ */ new Set();
|
|
8795
|
+
const allowedCols = /* @__PURE__ */ new Set();
|
|
8796
|
+
if (Array.isArray(parsed)) {
|
|
8797
|
+
for (const col of parsed) {
|
|
8798
|
+
if (!Array.isArray(col)) continue;
|
|
8799
|
+
for (const key of col) {
|
|
8800
|
+
if (typeof key !== "string" || !key) continue;
|
|
8801
|
+
allowedKeys.add(key);
|
|
8802
|
+
const m = key.match(/^footer-(\d+)-\d+-href$/);
|
|
8803
|
+
if (m) allowedCols.add(parseInt(m[1], 10));
|
|
8804
|
+
}
|
|
8805
|
+
}
|
|
8806
|
+
}
|
|
8807
|
+
return { allowedKeys, allowedCols };
|
|
8808
|
+
}
|
|
8809
|
+
|
|
8810
|
+
// src/lib/delete-nav-footer-selection.ts
|
|
8811
|
+
function isNavbarLinksContainer(el) {
|
|
8812
|
+
return el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-nav-drawer");
|
|
8813
|
+
}
|
|
8814
|
+
function isNavigationItem(el) {
|
|
8815
|
+
const anchor = el.matches("[data-ohw-href-key]") ? el : el.closest("[data-ohw-href-key]");
|
|
8816
|
+
if (!anchor) return false;
|
|
8817
|
+
return Boolean(anchor.querySelector('[data-ohw-editable="text"]'));
|
|
8818
|
+
}
|
|
8819
|
+
function findFooterItemGroup(item) {
|
|
8820
|
+
const explicit = item.closest("[data-ohw-footer-col], [data-ohw-footer-column]");
|
|
8821
|
+
if (explicit) return explicit;
|
|
8822
|
+
const footer = item.closest("footer");
|
|
8823
|
+
if (!footer) return null;
|
|
8824
|
+
let node = item.parentElement;
|
|
8825
|
+
while (node && node !== footer) {
|
|
8826
|
+
const count = Array.from(node.querySelectorAll("[data-ohw-href-key]")).filter(
|
|
8827
|
+
isNavigationItem
|
|
8828
|
+
).length;
|
|
8829
|
+
if (count >= 2) return node;
|
|
8830
|
+
node = node.parentElement;
|
|
8831
|
+
}
|
|
8832
|
+
return footer;
|
|
8833
|
+
}
|
|
8834
|
+
function isInferredFooterGroup(el) {
|
|
8835
|
+
const footer = el.closest("footer");
|
|
8836
|
+
if (!footer || el === footer) return false;
|
|
8837
|
+
if (el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column")) return true;
|
|
8838
|
+
const count = Array.from(el.querySelectorAll("[data-ohw-href-key]")).filter(
|
|
8839
|
+
isNavigationItem
|
|
8840
|
+
).length;
|
|
8841
|
+
return count >= 2;
|
|
8842
|
+
}
|
|
8843
|
+
function newActionId() {
|
|
8844
|
+
return typeof crypto !== "undefined" && "randomUUID" in crypto ? crypto.randomUUID() : `delete-${Date.now()}`;
|
|
8845
|
+
}
|
|
8846
|
+
function deleteSelectedNavFooterItem(deps) {
|
|
8847
|
+
const {
|
|
8848
|
+
selected,
|
|
8849
|
+
isTextEditing,
|
|
8850
|
+
isSelectFrame,
|
|
8851
|
+
getEditContent,
|
|
8852
|
+
applyLinkByKey: applyLinkByKey2,
|
|
8853
|
+
postToParent: postToParent2,
|
|
8854
|
+
deselect,
|
|
8855
|
+
setEditContent,
|
|
8856
|
+
setPendingUndo
|
|
8857
|
+
} = deps;
|
|
8858
|
+
if (isTextEditing) return false;
|
|
8859
|
+
if (isNavbarLinksContainer(selected) || isFooterLinksContainer(selected)) return false;
|
|
8860
|
+
const finishDelete = (opts) => {
|
|
8861
|
+
const actionId = newActionId();
|
|
8862
|
+
const clearedNodes = opts.removedKeys.map((key) => ({
|
|
8863
|
+
key,
|
|
8864
|
+
text: ""
|
|
8865
|
+
}));
|
|
8866
|
+
clearedNodes.push({ key: opts.orderKey, text: opts.orderJson });
|
|
8867
|
+
const nextContent = { ...getEditContent() };
|
|
8868
|
+
for (const key of opts.removedKeys) {
|
|
8869
|
+
nextContent[key] = "";
|
|
8870
|
+
clearStoredLinkHref(key);
|
|
8871
|
+
}
|
|
8872
|
+
nextContent[opts.orderKey] = opts.orderJson;
|
|
8873
|
+
setEditContent(nextContent);
|
|
8874
|
+
postToParent2({ type: "ow:change", nodes: clearedNodes });
|
|
8875
|
+
setPendingUndo({
|
|
8876
|
+
actionId,
|
|
8877
|
+
restore: () => {
|
|
8878
|
+
opts.undoDom();
|
|
8879
|
+
for (const [key, text] of Object.entries(opts.previousContent)) {
|
|
8880
|
+
if (key.endsWith("-href")) applyLinkByKey2(key, text);
|
|
8881
|
+
else {
|
|
8882
|
+
document.querySelectorAll(`[data-ohw-key="${CSS.escape(key)}"]`).forEach((el) => {
|
|
8883
|
+
el.textContent = text;
|
|
8884
|
+
});
|
|
8885
|
+
}
|
|
8886
|
+
}
|
|
8887
|
+
setEditContent({
|
|
8888
|
+
...getEditContent(),
|
|
8889
|
+
...opts.previousContent,
|
|
8890
|
+
[opts.orderKey]: opts.previousOrderJson
|
|
8891
|
+
});
|
|
8892
|
+
postToParent2({
|
|
8893
|
+
type: "ow:change",
|
|
8894
|
+
nodes: [
|
|
8895
|
+
...Object.entries(opts.previousContent).map(([key, text]) => ({ key, text })),
|
|
8896
|
+
{ key: opts.orderKey, text: opts.previousOrderJson }
|
|
8897
|
+
]
|
|
8898
|
+
});
|
|
8899
|
+
}
|
|
8900
|
+
});
|
|
8901
|
+
deselect();
|
|
8902
|
+
postToParent2({
|
|
8903
|
+
type: "ow:toast",
|
|
8904
|
+
title: opts.toastTitle,
|
|
8905
|
+
toastType: "success",
|
|
8906
|
+
actionLabel: "Undo",
|
|
8907
|
+
actionId,
|
|
8908
|
+
duration: 6e3
|
|
8909
|
+
});
|
|
8910
|
+
};
|
|
8911
|
+
const isFooterColumnSelection = selected.hasAttribute("data-ohw-footer-col") || selected.hasAttribute("data-ohw-footer-column") || isSelectFrame && isInferredFooterGroup(selected) && Boolean(selected.closest("footer"));
|
|
8912
|
+
if (isFooterColumnSelection) {
|
|
8913
|
+
const column = selected.hasAttribute("data-ohw-footer-col") || selected.hasAttribute("data-ohw-footer-column") ? selected : findFooterItemGroup(selected);
|
|
8914
|
+
if (!column) return false;
|
|
8915
|
+
const result = deleteFooterColumn(column);
|
|
8916
|
+
if (!result) return false;
|
|
8917
|
+
finishDelete({
|
|
8918
|
+
toastTitle: "Item deleted",
|
|
8919
|
+
removedKeys: result.removedKeys,
|
|
8920
|
+
previousContent: result.previousContent,
|
|
8921
|
+
orderKey: FOOTER_ORDER_KEY,
|
|
8922
|
+
orderJson: result.orderJson,
|
|
8923
|
+
previousOrderJson: result.previousOrderJson,
|
|
8924
|
+
undoDom: result.undo
|
|
8925
|
+
});
|
|
8926
|
+
return true;
|
|
8927
|
+
}
|
|
8928
|
+
if (!isNavigationItem(selected)) return false;
|
|
8929
|
+
const hrefKey = selected.getAttribute("data-ohw-href-key");
|
|
8930
|
+
if (!hrefKey) return false;
|
|
8931
|
+
if (isNavbarHrefKey(hrefKey)) {
|
|
8932
|
+
const result = deleteNavbarItem(selected);
|
|
8933
|
+
if (!result) return false;
|
|
8934
|
+
finishDelete({
|
|
8935
|
+
toastTitle: "Nav item deleted",
|
|
8936
|
+
removedKeys: result.removedKeys,
|
|
8937
|
+
previousContent: result.previousContent,
|
|
8938
|
+
orderKey: NAV_ORDER_KEY,
|
|
8939
|
+
orderJson: result.orderJson,
|
|
8940
|
+
previousOrderJson: result.previousOrderJson,
|
|
8941
|
+
undoDom: result.undo
|
|
8942
|
+
});
|
|
8943
|
+
return true;
|
|
8944
|
+
}
|
|
8945
|
+
if (isFooterHrefKey(hrefKey)) {
|
|
8946
|
+
const result = deleteFooterItem(selected);
|
|
8947
|
+
if (!result) return false;
|
|
8948
|
+
finishDelete({
|
|
8949
|
+
toastTitle: "Item deleted",
|
|
8950
|
+
removedKeys: result.removedKeys,
|
|
8951
|
+
previousContent: result.previousContent,
|
|
8952
|
+
orderKey: FOOTER_ORDER_KEY,
|
|
8953
|
+
orderJson: result.orderJson,
|
|
8954
|
+
previousOrderJson: result.previousOrderJson,
|
|
8955
|
+
undoDom: result.undo
|
|
8956
|
+
});
|
|
8957
|
+
return true;
|
|
8958
|
+
}
|
|
8959
|
+
return false;
|
|
8960
|
+
}
|
|
8961
|
+
|
|
7845
8962
|
// src/ui/navbar-container-chrome.tsx
|
|
7846
|
-
import { Plus as
|
|
7847
|
-
import { jsx as
|
|
8963
|
+
import { Plus as Plus3 } from "lucide-react";
|
|
8964
|
+
import { jsx as jsx24 } from "react/jsx-runtime";
|
|
7848
8965
|
function NavbarContainerChrome({
|
|
7849
8966
|
rect,
|
|
7850
8967
|
onAdd
|
|
7851
8968
|
}) {
|
|
7852
8969
|
const chromeGap = 6;
|
|
7853
|
-
return /* @__PURE__ */
|
|
8970
|
+
return /* @__PURE__ */ jsx24(
|
|
7854
8971
|
"div",
|
|
7855
8972
|
{
|
|
7856
8973
|
"data-ohw-navbar-container-chrome": "",
|
|
@@ -7862,7 +8979,7 @@ function NavbarContainerChrome({
|
|
|
7862
8979
|
width: rect.width + chromeGap * 2,
|
|
7863
8980
|
height: rect.height + chromeGap * 2
|
|
7864
8981
|
},
|
|
7865
|
-
children: /* @__PURE__ */
|
|
8982
|
+
children: /* @__PURE__ */ jsx24(
|
|
7866
8983
|
"button",
|
|
7867
8984
|
{
|
|
7868
8985
|
type: "button",
|
|
@@ -7879,7 +8996,7 @@ function NavbarContainerChrome({
|
|
|
7879
8996
|
e.stopPropagation();
|
|
7880
8997
|
onAdd();
|
|
7881
8998
|
},
|
|
7882
|
-
children: /* @__PURE__ */
|
|
8999
|
+
children: /* @__PURE__ */ jsx24(Plus3, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
|
|
7883
9000
|
}
|
|
7884
9001
|
)
|
|
7885
9002
|
}
|
|
@@ -7888,7 +9005,7 @@ function NavbarContainerChrome({
|
|
|
7888
9005
|
|
|
7889
9006
|
// src/ui/drop-indicator.tsx
|
|
7890
9007
|
import * as React10 from "react";
|
|
7891
|
-
import { jsx as
|
|
9008
|
+
import { jsx as jsx25 } from "react/jsx-runtime";
|
|
7892
9009
|
var dropIndicatorVariants = cva(
|
|
7893
9010
|
"ov-gap-line pointer-events-none shrink-0 transition-opacity duration-150",
|
|
7894
9011
|
{
|
|
@@ -7912,7 +9029,7 @@ var dropIndicatorVariants = cva(
|
|
|
7912
9029
|
);
|
|
7913
9030
|
var DropIndicator = React10.forwardRef(
|
|
7914
9031
|
({ className, direction, state, ...props }, ref) => {
|
|
7915
|
-
return /* @__PURE__ */
|
|
9032
|
+
return /* @__PURE__ */ jsx25(
|
|
7916
9033
|
"div",
|
|
7917
9034
|
{
|
|
7918
9035
|
ref,
|
|
@@ -7929,7 +9046,7 @@ var DropIndicator = React10.forwardRef(
|
|
|
7929
9046
|
DropIndicator.displayName = "DropIndicator";
|
|
7930
9047
|
|
|
7931
9048
|
// src/ui/badge.tsx
|
|
7932
|
-
import { jsx as
|
|
9049
|
+
import { jsx as jsx26 } from "react/jsx-runtime";
|
|
7933
9050
|
var badgeVariants = cva(
|
|
7934
9051
|
"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",
|
|
7935
9052
|
{
|
|
@@ -7947,12 +9064,12 @@ var badgeVariants = cva(
|
|
|
7947
9064
|
}
|
|
7948
9065
|
);
|
|
7949
9066
|
function Badge({ className, variant, ...props }) {
|
|
7950
|
-
return /* @__PURE__ */
|
|
9067
|
+
return /* @__PURE__ */ jsx26("div", { className: cn(badgeVariants({ variant }), className), ...props });
|
|
7951
9068
|
}
|
|
7952
9069
|
|
|
7953
9070
|
// src/OhhwellsBridge.tsx
|
|
7954
9071
|
import { Link as Link2 } from "lucide-react";
|
|
7955
|
-
import { Fragment as Fragment5, jsx as
|
|
9072
|
+
import { Fragment as Fragment5, jsx as jsx27, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
7956
9073
|
var PRIMARY2 = "#0885FE";
|
|
7957
9074
|
var IMAGE_FADE_MS = 300;
|
|
7958
9075
|
function runOpacityFade(el, onDone) {
|
|
@@ -8131,7 +9248,7 @@ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId,
|
|
|
8131
9248
|
const root = createRoot(container);
|
|
8132
9249
|
flushSync(() => {
|
|
8133
9250
|
root.render(
|
|
8134
|
-
/* @__PURE__ */
|
|
9251
|
+
/* @__PURE__ */ jsx27(
|
|
8135
9252
|
SchedulingWidget,
|
|
8136
9253
|
{
|
|
8137
9254
|
notifyOnConnect,
|
|
@@ -8171,7 +9288,7 @@ function mountSchedulingEntries(entries, notifyOnConnect = false) {
|
|
|
8171
9288
|
}
|
|
8172
9289
|
}
|
|
8173
9290
|
}
|
|
8174
|
-
function
|
|
9291
|
+
function getLinkHref4(el) {
|
|
8175
9292
|
const anchor = el instanceof HTMLAnchorElement ? el : el.querySelector("a");
|
|
8176
9293
|
return anchor?.getAttribute("href") ?? "";
|
|
8177
9294
|
}
|
|
@@ -8199,78 +9316,22 @@ function canDragNavigationItem(anchor) {
|
|
|
8199
9316
|
}
|
|
8200
9317
|
function syncNavigationDragCursorAttrs() {
|
|
8201
9318
|
document.querySelectorAll("nav [data-ohw-href-key], footer [data-ohw-href-key]").forEach((el) => {
|
|
8202
|
-
if (!
|
|
9319
|
+
if (!isNavigationItem2(el) || !canDragNavigationItem(el)) {
|
|
8203
9320
|
el.removeAttribute("data-ohw-can-drag");
|
|
8204
9321
|
return;
|
|
8205
9322
|
}
|
|
8206
9323
|
el.setAttribute("data-ohw-can-drag", "");
|
|
8207
9324
|
});
|
|
8208
9325
|
}
|
|
8209
|
-
function collectEditableNodes(extraContent) {
|
|
8210
|
-
const nodes = Array.from(document.querySelectorAll("[data-ohw-editable]")).map((el) => {
|
|
8211
|
-
if (el.dataset.ohwEditable === "image") {
|
|
8212
|
-
const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
|
|
8213
|
-
return { key: el.dataset.ohwKey ?? "", type: "image", text: img?.src ?? "" };
|
|
8214
|
-
}
|
|
8215
|
-
if (el.dataset.ohwEditable === "bg-image") {
|
|
8216
|
-
const raw = el.style.backgroundImage;
|
|
8217
|
-
const url = raw.replace(/^url\(['"]?/, "").replace(/['"]?\)$/, "");
|
|
8218
|
-
return { key: el.dataset.ohwKey ?? "", type: "bg-image", text: url };
|
|
8219
|
-
}
|
|
8220
|
-
if (el.dataset.ohwEditable === "video") {
|
|
8221
|
-
return { key: el.dataset.ohwKey ?? "", type: "video", text: getVideoEl(el)?.src ?? "" };
|
|
8222
|
-
}
|
|
8223
|
-
if (el.dataset.ohwEditable === "link") {
|
|
8224
|
-
return { key: el.dataset.ohwKey ?? "", type: "link", text: getLinkHref2(el) };
|
|
8225
|
-
}
|
|
8226
|
-
return {
|
|
8227
|
-
key: el.dataset.ohwKey ?? "",
|
|
8228
|
-
type: el.dataset.ohwEditable ?? "text",
|
|
8229
|
-
text: el.dataset.ohwEditable === "plain" ? el.innerText ?? "" : el.innerHTML
|
|
8230
|
-
};
|
|
8231
|
-
});
|
|
8232
|
-
document.querySelectorAll("[data-ohw-href-key]").forEach((el) => {
|
|
8233
|
-
const key = el.getAttribute("data-ohw-href-key") ?? "";
|
|
8234
|
-
if (!key) return;
|
|
8235
|
-
nodes.push({ key, type: "link", text: getLinkHref2(el) });
|
|
8236
|
-
});
|
|
8237
|
-
if (extraContent) {
|
|
8238
|
-
for (const key of [NAV_ORDER_KEY, FOOTER_ORDER_KEY, NAV_COUNT_KEY]) {
|
|
8239
|
-
const text = extraContent[key];
|
|
8240
|
-
if (typeof text === "string" && text.length > 0) {
|
|
8241
|
-
nodes.push({ key, type: "meta", text });
|
|
8242
|
-
}
|
|
8243
|
-
}
|
|
8244
|
-
}
|
|
8245
|
-
document.querySelectorAll('[data-ohw-editable="video"]').forEach((el) => {
|
|
8246
|
-
const key = el.dataset.ohwKey ?? "";
|
|
8247
|
-
const video = getVideoEl(el);
|
|
8248
|
-
if (!key || !video) return;
|
|
8249
|
-
nodes.push({ key: `${key}${VIDEO_AUTOPLAY_SUFFIX}`, type: "video-setting", text: String(video.autoplay) });
|
|
8250
|
-
nodes.push({ key: `${key}${VIDEO_MUTED_SUFFIX}`, type: "video-setting", text: String(video.muted) });
|
|
8251
|
-
});
|
|
8252
|
-
for (const key of listCarouselKeys()) {
|
|
8253
|
-
nodes.push({ key, type: "carousel", text: JSON.stringify(readCarouselValue(key)) });
|
|
8254
|
-
}
|
|
8255
|
-
const seen = /* @__PURE__ */ new Set();
|
|
8256
|
-
return nodes.filter((node) => {
|
|
8257
|
-
if (!node.key) return true;
|
|
8258
|
-
if (seen.has(node.key)) return false;
|
|
8259
|
-
seen.add(node.key);
|
|
8260
|
-
return true;
|
|
8261
|
-
});
|
|
8262
|
-
}
|
|
8263
9326
|
function isMediaEditable(el) {
|
|
8264
9327
|
const t = el.dataset.ohwEditable;
|
|
8265
9328
|
return t === "image" || t === "bg-image" || t === "video";
|
|
8266
9329
|
}
|
|
8267
9330
|
var MEDIA_SELECTOR = '[data-ohw-editable="image"], [data-ohw-editable="bg-image"], [data-ohw-editable="video"]';
|
|
8268
9331
|
var NON_MEDIA_SELECTOR = '[data-ohw-editable]:not([data-ohw-editable="image"]):not([data-ohw-editable="bg-image"]):not([data-ohw-editable="video"])';
|
|
8269
|
-
function
|
|
9332
|
+
function getVideoEl2(el) {
|
|
8270
9333
|
return el instanceof HTMLVideoElement ? el : el.querySelector("video");
|
|
8271
9334
|
}
|
|
8272
|
-
var VIDEO_AUTOPLAY_SUFFIX = "__ohw_autoplay";
|
|
8273
|
-
var VIDEO_MUTED_SUFFIX = "__ohw_muted";
|
|
8274
9335
|
function isBackgroundVideo(video) {
|
|
8275
9336
|
return video.autoplay && video.muted;
|
|
8276
9337
|
}
|
|
@@ -8315,7 +9376,7 @@ function applyVideoSettingNode(key, val) {
|
|
|
8315
9376
|
const baseKey = key.slice(0, key.length - suffixLen);
|
|
8316
9377
|
const on = val === "true";
|
|
8317
9378
|
document.querySelectorAll(`[data-ohw-key="${baseKey}"]`).forEach((el) => {
|
|
8318
|
-
const video =
|
|
9379
|
+
const video = getVideoEl2(el);
|
|
8319
9380
|
if (!video) return;
|
|
8320
9381
|
if (isAutoplay) video.autoplay = on;
|
|
8321
9382
|
else video.muted = on;
|
|
@@ -8335,7 +9396,7 @@ function applyLinkByKey(key, val) {
|
|
|
8335
9396
|
}
|
|
8336
9397
|
function isInsideLinkEditor(target) {
|
|
8337
9398
|
return Boolean(
|
|
8338
|
-
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"]')
|
|
9399
|
+
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"]')
|
|
8339
9400
|
);
|
|
8340
9401
|
}
|
|
8341
9402
|
function getHrefKeyFromElement(el) {
|
|
@@ -8355,13 +9416,13 @@ function getNavigationItemAnchor(el) {
|
|
|
8355
9416
|
if (!anchor.querySelector('[data-ohw-editable="text"]')) return null;
|
|
8356
9417
|
return anchor;
|
|
8357
9418
|
}
|
|
8358
|
-
function
|
|
9419
|
+
function isNavigationItem2(el) {
|
|
8359
9420
|
return getNavigationItemAnchor(el) !== null;
|
|
8360
9421
|
}
|
|
8361
9422
|
function listNavigationItems() {
|
|
8362
9423
|
return Array.from(
|
|
8363
9424
|
document.querySelectorAll("nav [data-ohw-href-key], footer [data-ohw-href-key]")
|
|
8364
|
-
).filter((el) =>
|
|
9425
|
+
).filter((el) => isNavigationItem2(el));
|
|
8365
9426
|
}
|
|
8366
9427
|
function getNavigationItemReorderState(anchor) {
|
|
8367
9428
|
if (isNavbarButton2(anchor)) return { key: null, disabled: false };
|
|
@@ -8392,9 +9453,9 @@ function getNavigationRoot(el) {
|
|
|
8392
9453
|
return el.closest("nav, footer, aside");
|
|
8393
9454
|
}
|
|
8394
9455
|
function countFooterNavItems(el) {
|
|
8395
|
-
return Array.from(el.querySelectorAll("[data-ohw-href-key]")).filter(
|
|
9456
|
+
return Array.from(el.querySelectorAll("[data-ohw-href-key]")).filter(isNavigationItem2).length;
|
|
8396
9457
|
}
|
|
8397
|
-
function
|
|
9458
|
+
function findFooterItemGroup2(item) {
|
|
8398
9459
|
const explicit = item.closest("[data-ohw-footer-col], [data-ohw-footer-column]");
|
|
8399
9460
|
if (explicit) return explicit;
|
|
8400
9461
|
const footer = item.closest("footer");
|
|
@@ -8409,16 +9470,16 @@ function findFooterItemGroup(item) {
|
|
|
8409
9470
|
function isNavigationRoot(el) {
|
|
8410
9471
|
return el.hasAttribute("data-ohw-nav-root") || el.matches("nav, footer, aside");
|
|
8411
9472
|
}
|
|
8412
|
-
function
|
|
9473
|
+
function isInferredFooterGroup2(el) {
|
|
8413
9474
|
const footer = el.closest("footer");
|
|
8414
9475
|
if (!footer || el === footer) return false;
|
|
8415
9476
|
if (el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column")) return true;
|
|
8416
9477
|
return countFooterNavItems(el) >= 2;
|
|
8417
9478
|
}
|
|
8418
9479
|
function isNavigationContainer(el) {
|
|
8419
|
-
return el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isNavigationRoot(el) ||
|
|
9480
|
+
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);
|
|
8420
9481
|
}
|
|
8421
|
-
function
|
|
9482
|
+
function isNavbarLinksContainer2(el) {
|
|
8422
9483
|
return el.hasAttribute("data-ohw-nav-container");
|
|
8423
9484
|
}
|
|
8424
9485
|
function getFooterColumn(el) {
|
|
@@ -8435,6 +9496,9 @@ function isPointOverNavigation(x, y) {
|
|
|
8435
9496
|
const roots = /* @__PURE__ */ new Set();
|
|
8436
9497
|
const navRoot = document.querySelector("[data-ohw-nav-root]") ?? document.querySelector("nav");
|
|
8437
9498
|
if (navRoot) roots.add(navRoot);
|
|
9499
|
+
document.querySelectorAll("[data-ohw-nav-drawer], [data-ohw-nav-container]").forEach((el) => {
|
|
9500
|
+
roots.add(el);
|
|
9501
|
+
});
|
|
8438
9502
|
const footer = document.querySelector("footer");
|
|
8439
9503
|
if (footer) roots.add(footer);
|
|
8440
9504
|
for (const root of roots) {
|
|
@@ -8458,11 +9522,17 @@ function findHoveredNavOrFooterContainer(x, y) {
|
|
|
8458
9522
|
}
|
|
8459
9523
|
function isPointOverNavItem(container, x, y) {
|
|
8460
9524
|
return Array.from(container.querySelectorAll("[data-ohw-href-key]")).some((el) => {
|
|
8461
|
-
if (!
|
|
9525
|
+
if (!isNavigationItem2(el) || isNavbarButton2(el)) return false;
|
|
8462
9526
|
const itemRect = el.getBoundingClientRect();
|
|
8463
9527
|
return x >= itemRect.left && x <= itemRect.right && y >= itemRect.top && y <= itemRect.bottom;
|
|
8464
9528
|
});
|
|
8465
9529
|
}
|
|
9530
|
+
function isPointOverFooterColumn(x, y) {
|
|
9531
|
+
return listFooterColumns().some((col) => {
|
|
9532
|
+
const r2 = col.getBoundingClientRect();
|
|
9533
|
+
return x >= r2.left && x <= r2.right && y >= r2.top && y <= r2.bottom;
|
|
9534
|
+
});
|
|
9535
|
+
}
|
|
8466
9536
|
function resolveNavContainerSelectionTarget(target, clientX, clientY) {
|
|
8467
9537
|
if (getNavigationItemAnchor(target)) return null;
|
|
8468
9538
|
if (target.closest('[data-ohw-role="navbar-button"]')) return null;
|
|
@@ -8484,29 +9554,32 @@ function resolveNavContainerSelectionTarget(target, clientX, clientY) {
|
|
|
8484
9554
|
return null;
|
|
8485
9555
|
}
|
|
8486
9556
|
function getNavigationSelectionParent(el) {
|
|
8487
|
-
if (
|
|
9557
|
+
if (isNavigationItem2(el)) {
|
|
8488
9558
|
const explicit = el.closest("[data-ohw-nav-container]");
|
|
8489
9559
|
if (explicit) return explicit;
|
|
8490
9560
|
const footerColumn = getFooterColumn(el);
|
|
8491
9561
|
if (footerColumn) return footerColumn;
|
|
8492
|
-
const footerGroup =
|
|
9562
|
+
const footerGroup = findFooterItemGroup2(el);
|
|
8493
9563
|
if (footerGroup) return footerGroup;
|
|
8494
9564
|
return getNavigationRoot(el);
|
|
8495
9565
|
}
|
|
8496
|
-
if (el
|
|
9566
|
+
if (!isFooterLinksContainer(el) && (el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isInferredFooterGroup2(el))) {
|
|
9567
|
+
return getFooterLinksContainer();
|
|
9568
|
+
}
|
|
9569
|
+
if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isFooterLinksContainer(el) || isInferredFooterGroup2(el)) {
|
|
8497
9570
|
return getNavigationRoot(el);
|
|
8498
9571
|
}
|
|
8499
9572
|
return null;
|
|
8500
9573
|
}
|
|
8501
9574
|
function collectNavigationItemSiblingHintRects(selected) {
|
|
8502
|
-
if (!
|
|
9575
|
+
if (!isNavigationItem2(selected)) return [];
|
|
8503
9576
|
const footerColumn = getFooterColumn(selected);
|
|
8504
9577
|
if (footerColumn) {
|
|
8505
9578
|
return listFooterLinksInColumn(footerColumn).filter((link) => link !== selected).map((link) => link.getBoundingClientRect());
|
|
8506
9579
|
}
|
|
8507
9580
|
const navContainer = selected.closest("[data-ohw-nav-container], [data-ohw-nav-drawer]");
|
|
8508
9581
|
if (navContainer) {
|
|
8509
|
-
return Array.from(navContainer.querySelectorAll("[data-ohw-href-key]")).filter((el) =>
|
|
9582
|
+
return Array.from(navContainer.querySelectorAll("[data-ohw-href-key]")).filter((el) => isNavigationItem2(el) && el !== selected).map((el) => el.getBoundingClientRect());
|
|
8510
9583
|
}
|
|
8511
9584
|
return listNavigationItems().filter((el) => el !== selected).map((el) => el.getBoundingClientRect());
|
|
8512
9585
|
}
|
|
@@ -8720,7 +9793,7 @@ function EditGlowChrome({
|
|
|
8720
9793
|
hideHandle = false
|
|
8721
9794
|
}) {
|
|
8722
9795
|
const GAP = SELECTION_CHROME_GAP2;
|
|
8723
|
-
return /* @__PURE__ */
|
|
9796
|
+
return /* @__PURE__ */ jsxs15(
|
|
8724
9797
|
"div",
|
|
8725
9798
|
{
|
|
8726
9799
|
ref: elRef,
|
|
@@ -8735,7 +9808,7 @@ function EditGlowChrome({
|
|
|
8735
9808
|
zIndex: 2147483646
|
|
8736
9809
|
},
|
|
8737
9810
|
children: [
|
|
8738
|
-
/* @__PURE__ */
|
|
9811
|
+
/* @__PURE__ */ jsx27(
|
|
8739
9812
|
"div",
|
|
8740
9813
|
{
|
|
8741
9814
|
style: {
|
|
@@ -8748,7 +9821,7 @@ function EditGlowChrome({
|
|
|
8748
9821
|
}
|
|
8749
9822
|
}
|
|
8750
9823
|
),
|
|
8751
|
-
reorderHrefKey && !hideHandle && /* @__PURE__ */
|
|
9824
|
+
reorderHrefKey && !hideHandle && /* @__PURE__ */ jsx27(
|
|
8752
9825
|
"div",
|
|
8753
9826
|
{
|
|
8754
9827
|
"data-ohw-drag-handle-container": "",
|
|
@@ -8760,7 +9833,7 @@ function EditGlowChrome({
|
|
|
8760
9833
|
transform: "translate(calc(-100% - 7px), -50%)",
|
|
8761
9834
|
pointerEvents: dragDisabled ? "none" : "auto"
|
|
8762
9835
|
},
|
|
8763
|
-
children: /* @__PURE__ */
|
|
9836
|
+
children: /* @__PURE__ */ jsx27(
|
|
8764
9837
|
DragHandle,
|
|
8765
9838
|
{
|
|
8766
9839
|
"aria-label": `Reorder ${reorderHrefKey}`,
|
|
@@ -8970,7 +10043,7 @@ function FloatingToolbar({
|
|
|
8970
10043
|
return () => ro.disconnect();
|
|
8971
10044
|
}, [showEditLink, activeCommands]);
|
|
8972
10045
|
const { top, left, transform } = calcToolbarPos(rect, parentScroll, measuredW);
|
|
8973
|
-
return /* @__PURE__ */
|
|
10046
|
+
return /* @__PURE__ */ jsx27(
|
|
8974
10047
|
"div",
|
|
8975
10048
|
{
|
|
8976
10049
|
ref: setRefs,
|
|
@@ -8982,12 +10055,12 @@ function FloatingToolbar({
|
|
|
8982
10055
|
zIndex: 2147483647,
|
|
8983
10056
|
pointerEvents: "auto"
|
|
8984
10057
|
},
|
|
8985
|
-
children: /* @__PURE__ */
|
|
8986
|
-
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */
|
|
8987
|
-
gi > 0 && /* @__PURE__ */
|
|
10058
|
+
children: /* @__PURE__ */ jsxs15(CustomToolbar, { children: [
|
|
10059
|
+
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ jsxs15(React11.Fragment, { children: [
|
|
10060
|
+
gi > 0 && /* @__PURE__ */ jsx27(CustomToolbarDivider, {}),
|
|
8988
10061
|
btns.map((btn) => {
|
|
8989
10062
|
const isActive = activeCommands.has(btn.cmd);
|
|
8990
|
-
return /* @__PURE__ */
|
|
10063
|
+
return /* @__PURE__ */ jsx27(
|
|
8991
10064
|
CustomToolbarButton,
|
|
8992
10065
|
{
|
|
8993
10066
|
title: btn.title,
|
|
@@ -8996,7 +10069,7 @@ function FloatingToolbar({
|
|
|
8996
10069
|
e.preventDefault();
|
|
8997
10070
|
onCommand(btn.cmd);
|
|
8998
10071
|
},
|
|
8999
|
-
children: /* @__PURE__ */
|
|
10072
|
+
children: /* @__PURE__ */ jsx27(
|
|
9000
10073
|
"svg",
|
|
9001
10074
|
{
|
|
9002
10075
|
width: "16",
|
|
@@ -9017,7 +10090,7 @@ function FloatingToolbar({
|
|
|
9017
10090
|
);
|
|
9018
10091
|
})
|
|
9019
10092
|
] }, gi)),
|
|
9020
|
-
showEditLink ? /* @__PURE__ */
|
|
10093
|
+
showEditLink ? /* @__PURE__ */ jsx27(
|
|
9021
10094
|
CustomToolbarButton,
|
|
9022
10095
|
{
|
|
9023
10096
|
type: "button",
|
|
@@ -9031,7 +10104,7 @@ function FloatingToolbar({
|
|
|
9031
10104
|
e.preventDefault();
|
|
9032
10105
|
e.stopPropagation();
|
|
9033
10106
|
},
|
|
9034
|
-
children: /* @__PURE__ */
|
|
10107
|
+
children: /* @__PURE__ */ jsx27(Link2, { className: "size-4 shrink-0", "aria-hidden": true })
|
|
9035
10108
|
}
|
|
9036
10109
|
) : null
|
|
9037
10110
|
] })
|
|
@@ -9048,7 +10121,7 @@ function StateToggle({
|
|
|
9048
10121
|
states,
|
|
9049
10122
|
onStateChange
|
|
9050
10123
|
}) {
|
|
9051
|
-
return /* @__PURE__ */
|
|
10124
|
+
return /* @__PURE__ */ jsx27(
|
|
9052
10125
|
ToggleGroup,
|
|
9053
10126
|
{
|
|
9054
10127
|
"data-ohw-state-toggle": "",
|
|
@@ -9062,7 +10135,7 @@ function StateToggle({
|
|
|
9062
10135
|
left: rect.right - 8,
|
|
9063
10136
|
transform: "translateX(-100%)"
|
|
9064
10137
|
},
|
|
9065
|
-
children: states.map((state) => /* @__PURE__ */
|
|
10138
|
+
children: states.map((state) => /* @__PURE__ */ jsx27(ToggleGroupItem, { value: state, size: "sm", children: state }, state))
|
|
9066
10139
|
}
|
|
9067
10140
|
);
|
|
9068
10141
|
}
|
|
@@ -9089,7 +10162,7 @@ function OhhwellsBridge() {
|
|
|
9089
10162
|
const router = useRouter2();
|
|
9090
10163
|
const searchParams = useSearchParams();
|
|
9091
10164
|
const isEditMode = isEditSessionActive();
|
|
9092
|
-
const [bridgeRoot, setBridgeRoot] =
|
|
10165
|
+
const [bridgeRoot, setBridgeRoot] = useState9(null);
|
|
9093
10166
|
useEffect9(() => {
|
|
9094
10167
|
const figtreeFontId = "ohw-figtree-font";
|
|
9095
10168
|
if (!document.getElementById(figtreeFontId)) {
|
|
@@ -9123,7 +10196,7 @@ function OhhwellsBridge() {
|
|
|
9123
10196
|
window.parent.postMessage(data, "*");
|
|
9124
10197
|
}
|
|
9125
10198
|
}, []);
|
|
9126
|
-
const [fetchState, setFetchState] =
|
|
10199
|
+
const [fetchState, setFetchState] = useState9("idle");
|
|
9127
10200
|
const autoSaveTimers = useRef7(/* @__PURE__ */ new Map());
|
|
9128
10201
|
const activeElRef = useRef7(null);
|
|
9129
10202
|
const pointerHeldRef = useRef7(false);
|
|
@@ -9134,7 +10207,7 @@ function OhhwellsBridge() {
|
|
|
9134
10207
|
const activeStateElRef = useRef7(null);
|
|
9135
10208
|
const parentScrollRef = useRef7(null);
|
|
9136
10209
|
const visibleViewportRef = useRef7(null);
|
|
9137
|
-
const [dialogPortalContainer, setDialogPortalContainer] =
|
|
10210
|
+
const [dialogPortalContainer, setDialogPortalContainer] = useState9(null);
|
|
9138
10211
|
const attachVisibleViewport = useCallback5((node) => {
|
|
9139
10212
|
visibleViewportRef.current = node;
|
|
9140
10213
|
setDialogPortalContainer(node);
|
|
@@ -9145,9 +10218,9 @@ function OhhwellsBridge() {
|
|
|
9145
10218
|
const hoveredImageRef = useRef7(null);
|
|
9146
10219
|
const hoveredImageHasTextOverlapRef = useRef7(false);
|
|
9147
10220
|
const dragOverElRef = useRef7(null);
|
|
9148
|
-
const [mediaHover, setMediaHover] =
|
|
9149
|
-
const [carouselHover, setCarouselHover] =
|
|
9150
|
-
const [uploadingRects, setUploadingRects] =
|
|
10221
|
+
const [mediaHover, setMediaHover] = useState9(null);
|
|
10222
|
+
const [carouselHover, setCarouselHover] = useState9(null);
|
|
10223
|
+
const [uploadingRects, setUploadingRects] = useState9({});
|
|
9151
10224
|
const hoveredGapRef = useRef7(null);
|
|
9152
10225
|
const imageUnhoverTimerRef = useRef7(null);
|
|
9153
10226
|
const imageShowTimerRef = useRef7(null);
|
|
@@ -9166,46 +10239,51 @@ function OhhwellsBridge() {
|
|
|
9166
10239
|
});
|
|
9167
10240
|
const commitNavigationTextEditRef = useRef7(() => {
|
|
9168
10241
|
});
|
|
10242
|
+
const handleDeleteSelectedRef = useRef7(() => false);
|
|
10243
|
+
const runPendingDeleteUndoRef = useRef7(() => false);
|
|
10244
|
+
const isFooterFrameSelectionRef = useRef7(false);
|
|
9169
10245
|
const refreshActiveCommandsRef = useRef7(() => {
|
|
9170
10246
|
});
|
|
9171
10247
|
const postToParentRef = useRef7(postToParent2);
|
|
9172
10248
|
postToParentRef.current = postToParent2;
|
|
9173
10249
|
const sectionsLoadedRef = useRef7(false);
|
|
9174
10250
|
const pendingScheduleConfigRequests = useRef7([]);
|
|
9175
|
-
const [toolbarRect, setToolbarRect] =
|
|
9176
|
-
const [toolbarVariant, setToolbarVariant] =
|
|
10251
|
+
const [toolbarRect, setToolbarRect] = useState9(null);
|
|
10252
|
+
const [toolbarVariant, setToolbarVariant] = useState9("none");
|
|
9177
10253
|
const toolbarVariantRef = useRef7("none");
|
|
9178
10254
|
toolbarVariantRef.current = toolbarVariant;
|
|
9179
|
-
const [selectedIsCta, setSelectedIsCta] =
|
|
9180
|
-
const [reorderHrefKey, setReorderHrefKey] =
|
|
9181
|
-
const [reorderDragDisabled, setReorderDragDisabled] =
|
|
9182
|
-
const [toggleState, setToggleState] =
|
|
9183
|
-
const [maxBadge, setMaxBadge] =
|
|
9184
|
-
const [activeCommands, setActiveCommands] =
|
|
9185
|
-
const [sectionGap, setSectionGap] =
|
|
9186
|
-
const [toolbarShowEditLink, setToolbarShowEditLink] =
|
|
10255
|
+
const [selectedIsCta, setSelectedIsCta] = useState9(false);
|
|
10256
|
+
const [reorderHrefKey, setReorderHrefKey] = useState9(null);
|
|
10257
|
+
const [reorderDragDisabled, setReorderDragDisabled] = useState9(false);
|
|
10258
|
+
const [toggleState, setToggleState] = useState9(null);
|
|
10259
|
+
const [maxBadge, setMaxBadge] = useState9(null);
|
|
10260
|
+
const [activeCommands, setActiveCommands] = useState9(/* @__PURE__ */ new Set());
|
|
10261
|
+
const [sectionGap, setSectionGap] = useState9(null);
|
|
10262
|
+
const [toolbarShowEditLink, setToolbarShowEditLink] = useState9(false);
|
|
9187
10263
|
const hoveredNavContainerRef = useRef7(null);
|
|
9188
|
-
const [hoveredNavContainerRect, setHoveredNavContainerRect] =
|
|
10264
|
+
const [hoveredNavContainerRect, setHoveredNavContainerRect] = useState9(null);
|
|
9189
10265
|
const hoveredItemElRef = useRef7(null);
|
|
9190
|
-
const [hoveredItemRect, setHoveredItemRect] =
|
|
10266
|
+
const [hoveredItemRect, setHoveredItemRect] = useState9(null);
|
|
9191
10267
|
const siblingHintElRef = useRef7(null);
|
|
9192
|
-
const [siblingHintRect, setSiblingHintRect] =
|
|
9193
|
-
const [siblingHintRects, setSiblingHintRects] =
|
|
9194
|
-
const [isItemDragging, setIsItemDragging] =
|
|
9195
|
-
const [isFooterFrameSelection, setIsFooterFrameSelection] =
|
|
10268
|
+
const [siblingHintRect, setSiblingHintRect] = useState9(null);
|
|
10269
|
+
const [siblingHintRects, setSiblingHintRects] = useState9([]);
|
|
10270
|
+
const [isItemDragging, setIsItemDragging] = useState9(false);
|
|
10271
|
+
const [isFooterFrameSelection, setIsFooterFrameSelection] = useState9(false);
|
|
10272
|
+
isFooterFrameSelectionRef.current = isFooterFrameSelection;
|
|
9196
10273
|
const footerDragRef = useRef7(null);
|
|
9197
|
-
const [footerDropSlots, setFooterDropSlots] =
|
|
9198
|
-
const [activeFooterDropIndex, setActiveFooterDropIndex] =
|
|
9199
|
-
const [draggedItemRect, setDraggedItemRect] =
|
|
10274
|
+
const [footerDropSlots, setFooterDropSlots] = useState9([]);
|
|
10275
|
+
const [activeFooterDropIndex, setActiveFooterDropIndex] = useState9(null);
|
|
10276
|
+
const [draggedItemRect, setDraggedItemRect] = useState9(null);
|
|
9200
10277
|
const footerPointerDragRef = useRef7(null);
|
|
9201
10278
|
const suppressNextClickRef = useRef7(false);
|
|
9202
10279
|
const suppressClickUntilRef = useRef7(0);
|
|
9203
|
-
const [linkPopover, setLinkPopover] =
|
|
10280
|
+
const [linkPopover, setLinkPopover] = useState9(null);
|
|
9204
10281
|
const linkPopoverSessionRef = useRef7(null);
|
|
9205
10282
|
const addNavAfterAnchorRef = useRef7(null);
|
|
9206
10283
|
const editContentRef = useRef7({});
|
|
9207
|
-
const
|
|
9208
|
-
const [
|
|
10284
|
+
const pendingDeleteUndoRef = useRef7(null);
|
|
10285
|
+
const [sitePages, setSitePages] = useState9([]);
|
|
10286
|
+
const [sectionsByPath, setSectionsByPath] = useState9({});
|
|
9209
10287
|
const sectionsPrefetchGenRef = useRef7(0);
|
|
9210
10288
|
const setLinkPopoverRef = useRef7(setLinkPopover);
|
|
9211
10289
|
const linkPopoverPanelRef = useRef7(null);
|
|
@@ -9293,31 +10371,9 @@ function OhhwellsBridge() {
|
|
|
9293
10371
|
hoveredGapRef.current = null;
|
|
9294
10372
|
setSectionGap(null);
|
|
9295
10373
|
setMediaHover(null);
|
|
9296
|
-
postToParent2({ type: "ow:link-modal-lock", locked: true });
|
|
9297
|
-
const html = document.documentElement;
|
|
9298
|
-
const body = document.body;
|
|
9299
|
-
const prevHtmlOverflow = html.style.overflow;
|
|
9300
|
-
const prevBodyOverflow = body.style.overflow;
|
|
9301
|
-
html.style.overflow = "hidden";
|
|
9302
|
-
body.style.overflow = "hidden";
|
|
9303
|
-
const preventBackgroundScroll = (e) => {
|
|
9304
|
-
const target = e.target;
|
|
9305
|
-
if (target instanceof Element && target.closest('[data-ohw-link-modal-root], [data-slot="dialog-overlay"]')) {
|
|
9306
|
-
return;
|
|
9307
|
-
}
|
|
9308
|
-
e.preventDefault();
|
|
9309
|
-
};
|
|
9310
|
-
const scrollOpts = { passive: false, capture: true };
|
|
9311
|
-
document.addEventListener("wheel", preventBackgroundScroll, scrollOpts);
|
|
9312
|
-
document.addEventListener("touchmove", preventBackgroundScroll, scrollOpts);
|
|
9313
10374
|
postToParent2({ type: "ow:image-unhover" });
|
|
9314
10375
|
return () => {
|
|
9315
10376
|
document.documentElement.removeAttribute("data-ohw-link-popover-open");
|
|
9316
|
-
postToParent2({ type: "ow:link-modal-lock", locked: false });
|
|
9317
|
-
html.style.overflow = prevHtmlOverflow;
|
|
9318
|
-
body.style.overflow = prevBodyOverflow;
|
|
9319
|
-
document.removeEventListener("wheel", preventBackgroundScroll, scrollOpts);
|
|
9320
|
-
document.removeEventListener("touchmove", preventBackgroundScroll, scrollOpts);
|
|
9321
10377
|
};
|
|
9322
10378
|
}, [linkPopover, postToParent2]);
|
|
9323
10379
|
useEffect9(() => {
|
|
@@ -9481,7 +10537,7 @@ function OhhwellsBridge() {
|
|
|
9481
10537
|
const hrefKey = selectedHrefKeyRef.current;
|
|
9482
10538
|
if (hrefKey) {
|
|
9483
10539
|
const link = resolveHrefKeyElement(hrefKey);
|
|
9484
|
-
if (!link || !
|
|
10540
|
+
if (!link || !isNavigationItem2(link)) return;
|
|
9485
10541
|
selectedElRef.current = link;
|
|
9486
10542
|
const { key, disabled } = getNavigationItemReorderState(link);
|
|
9487
10543
|
setReorderHrefKey(key);
|
|
@@ -9559,6 +10615,27 @@ function OhhwellsBridge() {
|
|
|
9559
10615
|
intent: "add-nav"
|
|
9560
10616
|
});
|
|
9561
10617
|
}, []);
|
|
10618
|
+
const handleAddFooterColumn = useCallback5(() => {
|
|
10619
|
+
if (!canAddFooterColumn()) {
|
|
10620
|
+
postToParent2({
|
|
10621
|
+
type: "ow:toast",
|
|
10622
|
+
title: `Maximum ${MAX_FOOTER_COLUMNS} columns`,
|
|
10623
|
+
toastType: "error"
|
|
10624
|
+
});
|
|
10625
|
+
return;
|
|
10626
|
+
}
|
|
10627
|
+
deselectRef.current();
|
|
10628
|
+
deactivateRef.current();
|
|
10629
|
+
const result = addFooterColumnWithPersist({ postToParent: postToParent2 });
|
|
10630
|
+
if (!result) return;
|
|
10631
|
+
editContentRef.current = {
|
|
10632
|
+
...editContentRef.current,
|
|
10633
|
+
...buildFooterColumnEditContentPatch(result)
|
|
10634
|
+
};
|
|
10635
|
+
requestAnimationFrame(() => {
|
|
10636
|
+
selectRef.current(result.firstLink);
|
|
10637
|
+
});
|
|
10638
|
+
}, [postToParent2]);
|
|
9562
10639
|
const clearFooterDragVisuals = useCallback5(() => {
|
|
9563
10640
|
footerDragRef.current = null;
|
|
9564
10641
|
setSiblingHintRects([]);
|
|
@@ -9653,7 +10730,7 @@ function OhhwellsBridge() {
|
|
|
9653
10730
|
selectedHrefKeyRef.current = hrefKey;
|
|
9654
10731
|
selectedFooterColAttrRef.current = null;
|
|
9655
10732
|
const link = resolveHrefKeyElement(hrefKey);
|
|
9656
|
-
if (link &&
|
|
10733
|
+
if (link && isNavigationItem2(link)) {
|
|
9657
10734
|
selectRef.current(link);
|
|
9658
10735
|
return;
|
|
9659
10736
|
}
|
|
@@ -9677,7 +10754,7 @@ function OhhwellsBridge() {
|
|
|
9677
10754
|
}
|
|
9678
10755
|
}
|
|
9679
10756
|
if (document.body.contains(draggedEl)) {
|
|
9680
|
-
if (
|
|
10757
|
+
if (isNavigationItem2(draggedEl)) {
|
|
9681
10758
|
selectRef.current(draggedEl);
|
|
9682
10759
|
return;
|
|
9683
10760
|
}
|
|
@@ -9774,7 +10851,7 @@ function OhhwellsBridge() {
|
|
|
9774
10851
|
const clientX = e?.clientX ?? selected.getBoundingClientRect().left + 8;
|
|
9775
10852
|
const clientY = e?.clientY ?? selected.getBoundingClientRect().top + 8;
|
|
9776
10853
|
if (startFooterLinkDrag(selected, clientX, clientY, true)) return;
|
|
9777
|
-
if (selected.hasAttribute("data-ohw-footer-col") ||
|
|
10854
|
+
if (selected.hasAttribute("data-ohw-footer-col") || isInferredFooterGroup2(selected) && selected.closest("footer")) {
|
|
9778
10855
|
if (startFooterColumnDrag(selected, clientX, clientY, true)) return;
|
|
9779
10856
|
}
|
|
9780
10857
|
if (startNavLinkDrag(selected, clientX, clientY, true)) return;
|
|
@@ -9827,7 +10904,7 @@ function OhhwellsBridge() {
|
|
|
9827
10904
|
};
|
|
9828
10905
|
return;
|
|
9829
10906
|
}
|
|
9830
|
-
if (selected.hasAttribute("data-ohw-footer-col") ||
|
|
10907
|
+
if (selected.hasAttribute("data-ohw-footer-col") || isInferredFooterGroup2(selected) && selected.closest("footer")) {
|
|
9831
10908
|
footerPointerDragRef.current = {
|
|
9832
10909
|
el: selected,
|
|
9833
10910
|
kind: "column",
|
|
@@ -9847,7 +10924,7 @@ function OhhwellsBridge() {
|
|
|
9847
10924
|
return;
|
|
9848
10925
|
}
|
|
9849
10926
|
const selected = selectedElRef.current;
|
|
9850
|
-
if (!selected || !
|
|
10927
|
+
if (!selected || !isNavigationItem2(selected)) return;
|
|
9851
10928
|
const editable = selected.querySelector('[data-ohw-editable="text"]') ?? selected.querySelector("[data-ohw-editable]");
|
|
9852
10929
|
if (!editable) return;
|
|
9853
10930
|
activateRef.current(editable, { caretX: clientX, caretY: clientY });
|
|
@@ -9855,7 +10932,7 @@ function OhhwellsBridge() {
|
|
|
9855
10932
|
reselectNavigationItemRef.current = reselectNavigationItem;
|
|
9856
10933
|
commitNavigationTextEditRef.current = commitNavigationTextEdit;
|
|
9857
10934
|
const select = useCallback5((anchor) => {
|
|
9858
|
-
if (!
|
|
10935
|
+
if (!isNavigationItem2(anchor)) return;
|
|
9859
10936
|
if (activeElRef.current) deactivate();
|
|
9860
10937
|
selectedElRef.current = anchor;
|
|
9861
10938
|
selectedHrefKeyRef.current = anchor.getAttribute("data-ohw-href-key");
|
|
@@ -9883,7 +10960,7 @@ function OhhwellsBridge() {
|
|
|
9883
10960
|
const selectFrame = useCallback5((el) => {
|
|
9884
10961
|
if (!isNavigationContainer(el)) return;
|
|
9885
10962
|
if (activeElRef.current) deactivate();
|
|
9886
|
-
const isFooterColumn = el.hasAttribute("data-ohw-footer-col") || Boolean(el.closest("footer") &&
|
|
10963
|
+
const isFooterColumn = !isFooterLinksContainer(el) && (el.hasAttribute("data-ohw-footer-col") || Boolean(el.closest("footer") && isInferredFooterGroup2(el)));
|
|
9887
10964
|
selectedElRef.current = el;
|
|
9888
10965
|
selectedHrefKeyRef.current = null;
|
|
9889
10966
|
selectedFooterColAttrRef.current = isFooterColumn ? el.getAttribute("data-ohw-footer-col") ?? String(listFooterColumns().indexOf(el)) : null;
|
|
@@ -9998,7 +11075,7 @@ function OhhwellsBridge() {
|
|
|
9998
11075
|
const next = `url('${val}')`;
|
|
9999
11076
|
if (el.style.backgroundImage !== next) el.style.backgroundImage = next;
|
|
10000
11077
|
} else if (el.dataset.ohwEditable === "video") {
|
|
10001
|
-
const video =
|
|
11078
|
+
const video = getVideoEl2(el);
|
|
10002
11079
|
if (video && video.src !== val) {
|
|
10003
11080
|
applyVideoSrc(video, val);
|
|
10004
11081
|
imageLoads.push(new Promise((resolve) => {
|
|
@@ -10066,7 +11143,7 @@ function OhhwellsBridge() {
|
|
|
10066
11143
|
const next = `url('${val}')`;
|
|
10067
11144
|
if (el.style.backgroundImage !== next) el.style.backgroundImage = next;
|
|
10068
11145
|
} else if (el.dataset.ohwEditable === "video") {
|
|
10069
|
-
const video =
|
|
11146
|
+
const video = getVideoEl2(el);
|
|
10070
11147
|
if (video && video.src !== val) applyVideoSrc(video, val);
|
|
10071
11148
|
} else if (el.dataset.ohwEditable === "link") {
|
|
10072
11149
|
applyLinkHref(el, val);
|
|
@@ -10351,7 +11428,7 @@ function OhhwellsBridge() {
|
|
|
10351
11428
|
e.preventDefault();
|
|
10352
11429
|
e.stopPropagation();
|
|
10353
11430
|
const selected = selectedElRef.current;
|
|
10354
|
-
if (selected &&
|
|
11431
|
+
if (selected && isNavigationItem2(selected)) {
|
|
10355
11432
|
const editable2 = selected.querySelector('[data-ohw-editable="text"]') ?? selected.querySelector("[data-ohw-editable]");
|
|
10356
11433
|
if (editable2) {
|
|
10357
11434
|
activateRef.current(editable2, {
|
|
@@ -10416,7 +11493,7 @@ function OhhwellsBridge() {
|
|
|
10416
11493
|
setLinkPopoverRef.current({
|
|
10417
11494
|
key: editable.dataset.ohwKey ?? "",
|
|
10418
11495
|
mode: "edit",
|
|
10419
|
-
target:
|
|
11496
|
+
target: getLinkHref4(editable)
|
|
10420
11497
|
});
|
|
10421
11498
|
return;
|
|
10422
11499
|
}
|
|
@@ -10441,7 +11518,7 @@ function OhhwellsBridge() {
|
|
|
10441
11518
|
}
|
|
10442
11519
|
e.preventDefault();
|
|
10443
11520
|
e.stopPropagation();
|
|
10444
|
-
activateRef.current(editable);
|
|
11521
|
+
activateRef.current(editable, { caretX: e.clientX, caretY: e.clientY });
|
|
10445
11522
|
return;
|
|
10446
11523
|
}
|
|
10447
11524
|
const hrefAnchor = getNavigationItemAnchor(target);
|
|
@@ -10468,6 +11545,18 @@ function OhhwellsBridge() {
|
|
|
10468
11545
|
selectFrameRef.current(footerColClick);
|
|
10469
11546
|
return;
|
|
10470
11547
|
}
|
|
11548
|
+
const footerLinksToSelect = resolveFooterLinksContainerSelectionTarget(
|
|
11549
|
+
target,
|
|
11550
|
+
e.clientX,
|
|
11551
|
+
e.clientY,
|
|
11552
|
+
isPointOverNavItem
|
|
11553
|
+
);
|
|
11554
|
+
if (footerLinksToSelect) {
|
|
11555
|
+
e.preventDefault();
|
|
11556
|
+
e.stopPropagation();
|
|
11557
|
+
selectFrameRef.current(footerLinksToSelect);
|
|
11558
|
+
return;
|
|
11559
|
+
}
|
|
10471
11560
|
const navContainerToSelect = resolveNavContainerSelectionTarget(target, e.clientX, e.clientY);
|
|
10472
11561
|
if (navContainerToSelect) {
|
|
10473
11562
|
e.preventDefault();
|
|
@@ -10526,8 +11615,8 @@ function OhhwellsBridge() {
|
|
|
10526
11615
|
return;
|
|
10527
11616
|
}
|
|
10528
11617
|
const navLabel = getNavigationLabelEditable(target);
|
|
10529
|
-
|
|
10530
|
-
|
|
11618
|
+
const editable = navLabel?.editable ?? target.closest('[data-ohw-editable="text"], [data-ohw-editable="plain"]');
|
|
11619
|
+
if (!editable || isMediaEditable(editable) || editable.dataset.ohwEditable === "link") return;
|
|
10531
11620
|
e.preventDefault();
|
|
10532
11621
|
e.stopPropagation();
|
|
10533
11622
|
if (activeElRef.current !== editable) {
|
|
@@ -10548,16 +11637,38 @@ function OhhwellsBridge() {
|
|
|
10548
11637
|
setHoveredNavContainerRect(null);
|
|
10549
11638
|
return;
|
|
10550
11639
|
}
|
|
10551
|
-
|
|
10552
|
-
const
|
|
10553
|
-
|
|
10554
|
-
|
|
10555
|
-
|
|
10556
|
-
|
|
10557
|
-
|
|
10558
|
-
|
|
11640
|
+
{
|
|
11641
|
+
const selected2 = selectedElRef.current;
|
|
11642
|
+
const selectedIsFooterColumn = Boolean(selected2) && !isFooterLinksContainer(selected2) && (selected2.hasAttribute("data-ohw-footer-col") || selected2.hasAttribute("data-ohw-footer-column") || Boolean(selected2.closest("footer") && isInferredFooterGroup2(selected2)));
|
|
11643
|
+
const allowNavContainerHover = toolbarVariantRef.current !== "select-frame";
|
|
11644
|
+
const allowFooterLinksHover = toolbarVariantRef.current !== "select-frame" || selectedIsFooterColumn;
|
|
11645
|
+
if (allowNavContainerHover) {
|
|
11646
|
+
const navContainer = target.closest("[data-ohw-nav-container]");
|
|
11647
|
+
if (navContainer && !getNavigationItemAnchor(target)) {
|
|
11648
|
+
hoveredNavContainerRef.current = navContainer;
|
|
11649
|
+
setHoveredNavContainerRect(navContainer.getBoundingClientRect());
|
|
11650
|
+
hoveredItemElRef.current = null;
|
|
11651
|
+
setHoveredItemRect(null);
|
|
11652
|
+
return;
|
|
11653
|
+
}
|
|
10559
11654
|
}
|
|
10560
|
-
if (
|
|
11655
|
+
if (allowFooterLinksHover) {
|
|
11656
|
+
const navContainer = target.closest("[data-ohw-nav-container]");
|
|
11657
|
+
if (!navContainer) {
|
|
11658
|
+
const footerLinks = target.closest("[data-ohw-footer-links], .rb-footer-links") ?? null;
|
|
11659
|
+
if (footerLinks && selected2 !== footerLinks && !getNavigationItemAnchor(target) && !target.closest("[data-ohw-footer-col], [data-ohw-footer-column]")) {
|
|
11660
|
+
hoveredNavContainerRef.current = footerLinks;
|
|
11661
|
+
setHoveredNavContainerRect(footerLinks.getBoundingClientRect());
|
|
11662
|
+
hoveredItemElRef.current = null;
|
|
11663
|
+
setHoveredItemRect(null);
|
|
11664
|
+
return;
|
|
11665
|
+
}
|
|
11666
|
+
if (!footerLinks) {
|
|
11667
|
+
hoveredNavContainerRef.current = null;
|
|
11668
|
+
setHoveredNavContainerRect(null);
|
|
11669
|
+
}
|
|
11670
|
+
}
|
|
11671
|
+
} else if (toolbarVariantRef.current === "select-frame") {
|
|
10561
11672
|
hoveredNavContainerRef.current = null;
|
|
10562
11673
|
setHoveredNavContainerRect(null);
|
|
10563
11674
|
}
|
|
@@ -10599,9 +11710,9 @@ function OhhwellsBridge() {
|
|
|
10599
11710
|
};
|
|
10600
11711
|
const handleMouseOut = (e) => {
|
|
10601
11712
|
const target = e.target;
|
|
10602
|
-
if (target.closest("[data-ohw-nav-container], [data-ohw-footer-col], [data-ohw-footer-column]")) {
|
|
11713
|
+
if (target.closest("[data-ohw-nav-container], [data-ohw-footer-col], [data-ohw-footer-column], [data-ohw-footer-links], .rb-footer-links")) {
|
|
10603
11714
|
const related2 = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
10604
|
-
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]")) {
|
|
11715
|
+
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]")) {
|
|
10605
11716
|
return;
|
|
10606
11717
|
}
|
|
10607
11718
|
hoveredNavContainerRef.current = null;
|
|
@@ -10683,7 +11794,7 @@ function OhhwellsBridge() {
|
|
|
10683
11794
|
const r2 = getVisibleRect(imgEl);
|
|
10684
11795
|
const hasTextOverlap = forceTextOverlap ?? false;
|
|
10685
11796
|
hoveredImageHasTextOverlapRef.current = hasTextOverlap;
|
|
10686
|
-
const video = imgEl.dataset.ohwEditable === "video" ?
|
|
11797
|
+
const video = imgEl.dataset.ohwEditable === "video" ? getVideoEl2(imgEl) : null;
|
|
10687
11798
|
setMediaHover({
|
|
10688
11799
|
key: imgEl.dataset.ohwKey ?? "",
|
|
10689
11800
|
rect: { top: r2.top, left: r2.left, width: r2.width, height: r2.height },
|
|
@@ -10696,6 +11807,15 @@ function OhhwellsBridge() {
|
|
|
10696
11807
|
if (track) track.setAttribute("data-ohw-hover-paused", "");
|
|
10697
11808
|
};
|
|
10698
11809
|
const clearImageHover = () => setMediaHover(null);
|
|
11810
|
+
const dismissImageHover = () => {
|
|
11811
|
+
if (hoveredImageRef.current) {
|
|
11812
|
+
hoveredImageRef.current = null;
|
|
11813
|
+
hoveredImageHasTextOverlapRef.current = false;
|
|
11814
|
+
resumeAnimTracks();
|
|
11815
|
+
postToParentRef.current({ type: "ow:image-unhover" });
|
|
11816
|
+
}
|
|
11817
|
+
clearImageHover();
|
|
11818
|
+
};
|
|
10699
11819
|
const findImageAtPoint = (clientX, clientY, fromParentViewport) => {
|
|
10700
11820
|
const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
10701
11821
|
const images = Array.from(document.querySelectorAll(MEDIA_SELECTOR));
|
|
@@ -10739,16 +11859,13 @@ function OhhwellsBridge() {
|
|
|
10739
11859
|
}
|
|
10740
11860
|
return smallest;
|
|
10741
11861
|
};
|
|
10742
|
-
const dismissImageHover = () => {
|
|
10743
|
-
if (hoveredImageRef.current) {
|
|
10744
|
-
hoveredImageRef.current = null;
|
|
10745
|
-
hoveredImageHasTextOverlapRef.current = false;
|
|
10746
|
-
resumeAnimTracks();
|
|
10747
|
-
postToParentRef.current({ type: "ow:image-unhover" });
|
|
10748
|
-
}
|
|
10749
|
-
};
|
|
10750
11862
|
const probeNavigationHoverAt = (x, y) => {
|
|
10751
|
-
|
|
11863
|
+
const selected = selectedElRef.current;
|
|
11864
|
+
const selectedIsFooterColumn = Boolean(selected) && !isFooterLinksContainer(selected) && (selected.hasAttribute("data-ohw-footer-col") || selected.hasAttribute("data-ohw-footer-column") || Boolean(selected.closest("footer") && isInferredFooterGroup2(selected)));
|
|
11865
|
+
const selectedIsFooterLinks = Boolean(selected && isFooterLinksContainer(selected));
|
|
11866
|
+
const allowNavContainerHover = toolbarVariantRef.current !== "select-frame";
|
|
11867
|
+
const allowFooterLinksHover = (toolbarVariantRef.current !== "select-frame" || selectedIsFooterColumn) && !selectedIsFooterLinks;
|
|
11868
|
+
if (toolbarVariantRef.current === "select-frame" && !allowFooterLinksHover) {
|
|
10752
11869
|
hoveredNavContainerRef.current = null;
|
|
10753
11870
|
setHoveredNavContainerRect(null);
|
|
10754
11871
|
}
|
|
@@ -10763,14 +11880,13 @@ function OhhwellsBridge() {
|
|
|
10763
11880
|
const navItemHit = Array.from(
|
|
10764
11881
|
container.querySelectorAll("[data-ohw-href-key]")
|
|
10765
11882
|
).find((el) => {
|
|
10766
|
-
if (!
|
|
11883
|
+
if (!isNavigationItem2(el) || isNavbarButton2(el)) return false;
|
|
10767
11884
|
const itemRect = el.getBoundingClientRect();
|
|
10768
11885
|
return x >= itemRect.left && x <= itemRect.right && y >= itemRect.top && y <= itemRect.bottom;
|
|
10769
11886
|
});
|
|
10770
11887
|
if (navItemHit) {
|
|
10771
11888
|
hoveredNavContainerRef.current = null;
|
|
10772
11889
|
setHoveredNavContainerRect(null);
|
|
10773
|
-
const selected = selectedElRef.current;
|
|
10774
11890
|
if (selected !== navItemHit) {
|
|
10775
11891
|
clearHrefKeyHover(navItemHit);
|
|
10776
11892
|
hoveredItemElRef.current = navItemHit;
|
|
@@ -10782,7 +11898,7 @@ function OhhwellsBridge() {
|
|
|
10782
11898
|
return;
|
|
10783
11899
|
}
|
|
10784
11900
|
}
|
|
10785
|
-
if (
|
|
11901
|
+
if (allowNavContainerHover) {
|
|
10786
11902
|
for (const container of navContainers) {
|
|
10787
11903
|
const containerRect = container.getBoundingClientRect();
|
|
10788
11904
|
const overContainer = x >= containerRect.left && x <= containerRect.right && y >= containerRect.top && y <= containerRect.bottom;
|
|
@@ -10794,12 +11910,23 @@ function OhhwellsBridge() {
|
|
|
10794
11910
|
setHoveredItemRect(null);
|
|
10795
11911
|
return;
|
|
10796
11912
|
}
|
|
10797
|
-
hoveredNavContainerRef.current = null;
|
|
10798
|
-
setHoveredNavContainerRect(null);
|
|
10799
|
-
} else {
|
|
10800
|
-
hoveredNavContainerRef.current = null;
|
|
10801
|
-
setHoveredNavContainerRect(null);
|
|
10802
11913
|
}
|
|
11914
|
+
if (allowFooterLinksHover) {
|
|
11915
|
+
const footerLinks = getFooterLinksContainer();
|
|
11916
|
+
if (footerLinks) {
|
|
11917
|
+
const containerRect = footerLinks.getBoundingClientRect();
|
|
11918
|
+
const overContainer = x >= containerRect.left && x <= containerRect.right && y >= containerRect.top && y <= containerRect.bottom;
|
|
11919
|
+
if (overContainer && !isPointOverNavItem(footerLinks, x, y) && !isPointOverFooterColumn(x, y)) {
|
|
11920
|
+
hoveredNavContainerRef.current = footerLinks;
|
|
11921
|
+
setHoveredNavContainerRect(footerLinks.getBoundingClientRect());
|
|
11922
|
+
hoveredItemElRef.current = null;
|
|
11923
|
+
setHoveredItemRect(null);
|
|
11924
|
+
return;
|
|
11925
|
+
}
|
|
11926
|
+
}
|
|
11927
|
+
}
|
|
11928
|
+
hoveredNavContainerRef.current = null;
|
|
11929
|
+
setHoveredNavContainerRect(null);
|
|
10803
11930
|
for (const column of footerColumns) {
|
|
10804
11931
|
const containerRect = column.getBoundingClientRect();
|
|
10805
11932
|
const overContainer = x >= containerRect.left && x <= containerRect.right && y >= containerRect.top && y <= containerRect.bottom;
|
|
@@ -10838,6 +11965,13 @@ function OhhwellsBridge() {
|
|
|
10838
11965
|
probeNavigationHoverAt(x, y);
|
|
10839
11966
|
return;
|
|
10840
11967
|
}
|
|
11968
|
+
const overMoreMenu = document.elementFromPoint(x, y)?.closest?.(
|
|
11969
|
+
'[data-ohw-more-menu], [data-slot="dropdown-menu-content"], [data-slot="dropdown-menu-item"]'
|
|
11970
|
+
);
|
|
11971
|
+
if (overMoreMenu) {
|
|
11972
|
+
dismissImageHover();
|
|
11973
|
+
return;
|
|
11974
|
+
}
|
|
10841
11975
|
hoveredNavContainerRef.current = null;
|
|
10842
11976
|
setHoveredNavContainerRect(null);
|
|
10843
11977
|
if (hoveredItemElRef.current?.hasAttribute("data-ohw-footer-col") || hoveredItemElRef.current?.hasAttribute("data-ohw-footer-column")) {
|
|
@@ -10884,7 +12018,7 @@ function OhhwellsBridge() {
|
|
|
10884
12018
|
return;
|
|
10885
12019
|
}
|
|
10886
12020
|
const topEl = document.elementFromPoint(x2, y2);
|
|
10887
|
-
if (topEl?.closest('[data-ohw-toolbar], [data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
|
|
12021
|
+
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"]')) {
|
|
10888
12022
|
if (hoveredImageRef.current) {
|
|
10889
12023
|
hoveredImageRef.current = null;
|
|
10890
12024
|
resumeAnimTracks();
|
|
@@ -11204,7 +12338,7 @@ function OhhwellsBridge() {
|
|
|
11204
12338
|
}
|
|
11205
12339
|
}
|
|
11206
12340
|
} else if (el.dataset.ohwEditable === "video") {
|
|
11207
|
-
const video =
|
|
12341
|
+
const video = getVideoEl2(el);
|
|
11208
12342
|
if (video) {
|
|
11209
12343
|
found = true;
|
|
11210
12344
|
const onReady = () => {
|
|
@@ -11291,7 +12425,7 @@ function OhhwellsBridge() {
|
|
|
11291
12425
|
} else if (el.dataset.ohwEditable === "bg-image") {
|
|
11292
12426
|
el.style.backgroundImage = `url('${val}')`;
|
|
11293
12427
|
} else if (el.dataset.ohwEditable === "video") {
|
|
11294
|
-
const video =
|
|
12428
|
+
const video = getVideoEl2(el);
|
|
11295
12429
|
if (video && video.src !== val) applyVideoSrc(video, val);
|
|
11296
12430
|
} else if (el.dataset.ohwEditable === "link") {
|
|
11297
12431
|
applyLinkHref(el, val);
|
|
@@ -11308,6 +12442,7 @@ function OhhwellsBridge() {
|
|
|
11308
12442
|
}
|
|
11309
12443
|
editContentRef.current = { ...editContentRef.current, ...content };
|
|
11310
12444
|
reconcileNavbarItemsFromContent(editContentRef.current);
|
|
12445
|
+
reconcileFooterOrderFromContent(editContentRef.current);
|
|
11311
12446
|
syncNavigationDragCursorAttrs();
|
|
11312
12447
|
enforceLinkHrefs();
|
|
11313
12448
|
postToParentRef.current({ type: "ow:hydrate-done" });
|
|
@@ -11325,8 +12460,17 @@ function OhhwellsBridge() {
|
|
|
11325
12460
|
deactivateRef.current();
|
|
11326
12461
|
};
|
|
11327
12462
|
window.addEventListener("message", handleDeactivate);
|
|
12463
|
+
const handleToastAction = (e) => {
|
|
12464
|
+
if (e.data?.type !== "ow:toast-action") return;
|
|
12465
|
+
const actionId = typeof e.data.actionId === "string" ? e.data.actionId : null;
|
|
12466
|
+
const pending = pendingDeleteUndoRef.current;
|
|
12467
|
+
if (!pending || !actionId || pending.actionId !== actionId) return;
|
|
12468
|
+
runPendingDeleteUndoRef.current();
|
|
12469
|
+
};
|
|
12470
|
+
window.addEventListener("message", handleToastAction);
|
|
11328
12471
|
const handleUiEscape = (e) => {
|
|
11329
12472
|
if (e.data?.type !== "ui:escape") return;
|
|
12473
|
+
if (document.querySelector("[data-ohw-more-menu]")) return;
|
|
11330
12474
|
if (linkPopoverOpenRef.current) {
|
|
11331
12475
|
setLinkPopoverRef.current(null);
|
|
11332
12476
|
return;
|
|
@@ -11362,6 +12506,11 @@ function OhhwellsBridge() {
|
|
|
11362
12506
|
}
|
|
11363
12507
|
if (selectedElRef.current) {
|
|
11364
12508
|
if (toolbarVariantRef.current === "select-frame") {
|
|
12509
|
+
const parent2 = getNavigationSelectionParent(selectedElRef.current);
|
|
12510
|
+
if (parent2 && isNavigationContainer(parent2) && isFooterLinksContainer(parent2) && !isFooterLinksContainer(selectedElRef.current)) {
|
|
12511
|
+
selectFrameRef.current(parent2);
|
|
12512
|
+
return;
|
|
12513
|
+
}
|
|
11365
12514
|
deselectRef.current();
|
|
11366
12515
|
return;
|
|
11367
12516
|
}
|
|
@@ -11376,14 +12525,12 @@ function OhhwellsBridge() {
|
|
|
11376
12525
|
window.addEventListener("message", handleUiEscape);
|
|
11377
12526
|
const handleKeyDown = (e) => {
|
|
11378
12527
|
if (e.key === "Escape" && document.querySelector("[data-ohw-section-picker]")) return;
|
|
12528
|
+
if (e.key === "Escape" && document.querySelector("[data-ohw-more-menu]")) return;
|
|
11379
12529
|
if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === "a" && activeElRef.current) {
|
|
11380
|
-
|
|
11381
|
-
|
|
11382
|
-
|
|
11383
|
-
|
|
11384
|
-
refreshActiveCommandsRef.current();
|
|
11385
|
-
return;
|
|
11386
|
-
}
|
|
12530
|
+
e.preventDefault();
|
|
12531
|
+
selectAllTextInEditable(activeElRef.current);
|
|
12532
|
+
refreshActiveCommandsRef.current();
|
|
12533
|
+
return;
|
|
11387
12534
|
}
|
|
11388
12535
|
if (e.key === "Escape" && linkPopoverOpenRef.current) {
|
|
11389
12536
|
setLinkPopoverRef.current(null);
|
|
@@ -11391,6 +12538,12 @@ function OhhwellsBridge() {
|
|
|
11391
12538
|
}
|
|
11392
12539
|
if (e.key === "Escape" && selectedElRef.current && !activeElRef.current) {
|
|
11393
12540
|
if (toolbarVariantRef.current === "select-frame") {
|
|
12541
|
+
const parent2 = getNavigationSelectionParent(selectedElRef.current);
|
|
12542
|
+
if (parent2 && isNavigationContainer(parent2) && isFooterLinksContainer(parent2) && !isFooterLinksContainer(selectedElRef.current)) {
|
|
12543
|
+
e.preventDefault();
|
|
12544
|
+
selectFrameRef.current(parent2);
|
|
12545
|
+
return;
|
|
12546
|
+
}
|
|
11394
12547
|
deselectRef.current();
|
|
11395
12548
|
return;
|
|
11396
12549
|
}
|
|
@@ -11431,6 +12584,18 @@ function OhhwellsBridge() {
|
|
|
11431
12584
|
return;
|
|
11432
12585
|
}
|
|
11433
12586
|
}
|
|
12587
|
+
if ((e.key === "Delete" || e.key === "Backspace") && selectedElRef.current && !activeElRef.current && !linkPopoverOpenRef.current) {
|
|
12588
|
+
if (handleDeleteSelectedRef.current()) {
|
|
12589
|
+
e.preventDefault();
|
|
12590
|
+
return;
|
|
12591
|
+
}
|
|
12592
|
+
}
|
|
12593
|
+
if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === "z" && !activeElRef.current) {
|
|
12594
|
+
if (runPendingDeleteUndoRef.current()) {
|
|
12595
|
+
e.preventDefault();
|
|
12596
|
+
return;
|
|
12597
|
+
}
|
|
12598
|
+
}
|
|
11434
12599
|
if (e.key !== "Escape") return;
|
|
11435
12600
|
const el = activeElRef.current;
|
|
11436
12601
|
if (el && originalContentRef.current !== null) {
|
|
@@ -11467,11 +12632,11 @@ function OhhwellsBridge() {
|
|
|
11467
12632
|
}
|
|
11468
12633
|
const selected = selectedElRef.current;
|
|
11469
12634
|
if (selected && !footerDragRef.current && !navDragRef.current) {
|
|
11470
|
-
if (selected.hasAttribute("data-ohw-footer-col") || Boolean(selected.closest("footer") &&
|
|
12635
|
+
if (selected.hasAttribute("data-ohw-footer-col") || Boolean(selected.closest("footer") && isInferredFooterGroup2(selected))) {
|
|
11471
12636
|
setSiblingHintRects(
|
|
11472
12637
|
listFooterColumns().filter((column) => column !== selected).map((column) => column.getBoundingClientRect())
|
|
11473
12638
|
);
|
|
11474
|
-
} else if (
|
|
12639
|
+
} else if (isNavigationItem2(selected)) {
|
|
11475
12640
|
setSiblingHintRects(collectNavigationItemSiblingHintRects(selected));
|
|
11476
12641
|
}
|
|
11477
12642
|
}
|
|
@@ -11833,6 +12998,7 @@ function OhhwellsBridge() {
|
|
|
11833
12998
|
window.removeEventListener("message", handleClickAt);
|
|
11834
12999
|
window.removeEventListener("message", handleHydrate);
|
|
11835
13000
|
window.removeEventListener("message", handleDeactivate);
|
|
13001
|
+
window.removeEventListener("message", handleToastAction);
|
|
11836
13002
|
window.removeEventListener("message", handleUiEscape);
|
|
11837
13003
|
autoSaveTimers.current.forEach(clearTimeout);
|
|
11838
13004
|
autoSaveTimers.current.clear();
|
|
@@ -12111,7 +13277,7 @@ function OhhwellsBridge() {
|
|
|
12111
13277
|
setLinkPopover({
|
|
12112
13278
|
key: hrefCtx.key,
|
|
12113
13279
|
mode: "edit",
|
|
12114
|
-
target:
|
|
13280
|
+
target: getLinkHref4(hrefCtx.anchor)
|
|
12115
13281
|
});
|
|
12116
13282
|
deactivate();
|
|
12117
13283
|
}, [deactivate]);
|
|
@@ -12124,10 +13290,141 @@ function OhhwellsBridge() {
|
|
|
12124
13290
|
setLinkPopover({
|
|
12125
13291
|
key,
|
|
12126
13292
|
mode: "edit",
|
|
12127
|
-
target:
|
|
13293
|
+
target: getLinkHref4(anchor)
|
|
12128
13294
|
});
|
|
12129
13295
|
deselect();
|
|
12130
13296
|
}, [deselect]);
|
|
13297
|
+
const handleSelectParent = useCallback5(() => {
|
|
13298
|
+
const selected = selectedElRef.current;
|
|
13299
|
+
if (!selected) return;
|
|
13300
|
+
if (toolbarVariantRef.current === "select-frame") {
|
|
13301
|
+
const parent2 = getNavigationSelectionParent(selected);
|
|
13302
|
+
if (parent2 && isNavigationContainer(parent2) && isFooterLinksContainer(parent2) && !isFooterLinksContainer(selected)) {
|
|
13303
|
+
selectFrameRef.current(parent2);
|
|
13304
|
+
return;
|
|
13305
|
+
}
|
|
13306
|
+
deselectRef.current();
|
|
13307
|
+
return;
|
|
13308
|
+
}
|
|
13309
|
+
const parent = getNavigationSelectionParent(selected);
|
|
13310
|
+
if (parent && isNavigationContainer(parent)) {
|
|
13311
|
+
selectFrameRef.current(parent);
|
|
13312
|
+
} else {
|
|
13313
|
+
deselectRef.current();
|
|
13314
|
+
}
|
|
13315
|
+
}, []);
|
|
13316
|
+
const handleDuplicateSelected = useCallback5(() => {
|
|
13317
|
+
const selected = selectedElRef.current;
|
|
13318
|
+
if (!selected || !isNavigationItem2(selected)) return;
|
|
13319
|
+
const hrefKey = selected.getAttribute("data-ohw-href-key");
|
|
13320
|
+
if (!hrefKey) return;
|
|
13321
|
+
if (isNavbarHrefKey(hrefKey)) {
|
|
13322
|
+
const result = duplicateNavbarItem(selected);
|
|
13323
|
+
if (!result) return;
|
|
13324
|
+
applyLinkByKey(result.hrefKey, result.href);
|
|
13325
|
+
document.querySelectorAll(`[data-ohw-key="${result.labelKey}"]`).forEach((el) => {
|
|
13326
|
+
el.textContent = result.label;
|
|
13327
|
+
});
|
|
13328
|
+
const nodes = [
|
|
13329
|
+
{ key: result.hrefKey, text: result.href },
|
|
13330
|
+
{ key: result.labelKey, text: result.label }
|
|
13331
|
+
];
|
|
13332
|
+
for (const child of result.childResults) {
|
|
13333
|
+
applyLinkByKey(child.hrefKey, child.href);
|
|
13334
|
+
document.querySelectorAll(`[data-ohw-key="${child.labelKey}"]`).forEach((el) => {
|
|
13335
|
+
el.textContent = child.label;
|
|
13336
|
+
});
|
|
13337
|
+
nodes.push(
|
|
13338
|
+
{ key: child.hrefKey, text: child.href },
|
|
13339
|
+
{ key: child.labelKey, text: child.label }
|
|
13340
|
+
);
|
|
13341
|
+
}
|
|
13342
|
+
const maxIndex = Math.max(
|
|
13343
|
+
result.index,
|
|
13344
|
+
...result.childResults.map((c) => c.index)
|
|
13345
|
+
);
|
|
13346
|
+
const navCount = String(maxIndex + 1);
|
|
13347
|
+
nodes.push(
|
|
13348
|
+
{ key: NAV_COUNT_KEY, text: navCount },
|
|
13349
|
+
{ key: NAV_ORDER_KEY, text: result.orderJson }
|
|
13350
|
+
);
|
|
13351
|
+
editContentRef.current = {
|
|
13352
|
+
...editContentRef.current,
|
|
13353
|
+
[result.hrefKey]: result.href,
|
|
13354
|
+
[result.labelKey]: result.label,
|
|
13355
|
+
...Object.fromEntries(
|
|
13356
|
+
result.childResults.flatMap((c) => [
|
|
13357
|
+
[c.hrefKey, c.href],
|
|
13358
|
+
[c.labelKey, c.label]
|
|
13359
|
+
])
|
|
13360
|
+
),
|
|
13361
|
+
[NAV_COUNT_KEY]: navCount,
|
|
13362
|
+
[NAV_ORDER_KEY]: result.orderJson
|
|
13363
|
+
};
|
|
13364
|
+
postToParent2({ type: "ow:change", nodes });
|
|
13365
|
+
enforceLinkHrefs();
|
|
13366
|
+
requestAnimationFrame(() => {
|
|
13367
|
+
selectRef.current(result.anchor);
|
|
13368
|
+
});
|
|
13369
|
+
return;
|
|
13370
|
+
}
|
|
13371
|
+
if (isFooterHrefKey(hrefKey)) {
|
|
13372
|
+
const result = duplicateFooterItem(selected);
|
|
13373
|
+
if (!result) return;
|
|
13374
|
+
applyLinkByKey(result.hrefKey, result.href);
|
|
13375
|
+
document.querySelectorAll(`[data-ohw-key="${result.labelKey}"]`).forEach((el) => {
|
|
13376
|
+
el.textContent = result.label;
|
|
13377
|
+
});
|
|
13378
|
+
const orderJson = JSON.stringify(result.order);
|
|
13379
|
+
editContentRef.current = {
|
|
13380
|
+
...editContentRef.current,
|
|
13381
|
+
[result.hrefKey]: result.href,
|
|
13382
|
+
[result.labelKey]: result.label,
|
|
13383
|
+
[FOOTER_ORDER_KEY]: orderJson
|
|
13384
|
+
};
|
|
13385
|
+
postToParent2({
|
|
13386
|
+
type: "ow:change",
|
|
13387
|
+
nodes: [
|
|
13388
|
+
{ key: result.hrefKey, text: result.href },
|
|
13389
|
+
{ key: result.labelKey, text: result.label },
|
|
13390
|
+
{ key: FOOTER_ORDER_KEY, text: orderJson }
|
|
13391
|
+
]
|
|
13392
|
+
});
|
|
13393
|
+
enforceLinkHrefs();
|
|
13394
|
+
requestAnimationFrame(() => {
|
|
13395
|
+
selectRef.current(result.anchor);
|
|
13396
|
+
});
|
|
13397
|
+
}
|
|
13398
|
+
}, [postToParent2]);
|
|
13399
|
+
const runPendingDeleteUndo = useCallback5(() => {
|
|
13400
|
+
const pending = pendingDeleteUndoRef.current;
|
|
13401
|
+
if (!pending) return false;
|
|
13402
|
+
pendingDeleteUndoRef.current = null;
|
|
13403
|
+
pending.restore();
|
|
13404
|
+
enforceLinkHrefs();
|
|
13405
|
+
return true;
|
|
13406
|
+
}, []);
|
|
13407
|
+
const handleDeleteSelected = useCallback5(() => {
|
|
13408
|
+
const selected = selectedElRef.current;
|
|
13409
|
+
if (!selected) return false;
|
|
13410
|
+
return deleteSelectedNavFooterItem({
|
|
13411
|
+
selected,
|
|
13412
|
+
isTextEditing: Boolean(activeElRef.current),
|
|
13413
|
+
isSelectFrame: toolbarVariantRef.current === "select-frame",
|
|
13414
|
+
getEditContent: () => editContentRef.current,
|
|
13415
|
+
applyLinkByKey,
|
|
13416
|
+
postToParent: postToParent2,
|
|
13417
|
+
deselect: () => deselectRef.current(),
|
|
13418
|
+
setEditContent: (next) => {
|
|
13419
|
+
editContentRef.current = next;
|
|
13420
|
+
},
|
|
13421
|
+
setPendingUndo: (undo) => {
|
|
13422
|
+
pendingDeleteUndoRef.current = undo;
|
|
13423
|
+
}
|
|
13424
|
+
});
|
|
13425
|
+
}, [postToParent2]);
|
|
13426
|
+
handleDeleteSelectedRef.current = handleDeleteSelected;
|
|
13427
|
+
runPendingDeleteUndoRef.current = runPendingDeleteUndo;
|
|
12131
13428
|
const handleLinkPopoverSubmit = useCallback5(
|
|
12132
13429
|
(target) => {
|
|
12133
13430
|
const session = linkPopoverSessionRef.current;
|
|
@@ -12210,7 +13507,7 @@ function OhhwellsBridge() {
|
|
|
12210
13507
|
const handleVideoSettingsChange = useCallback5(
|
|
12211
13508
|
(key, settings) => {
|
|
12212
13509
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
12213
|
-
const video =
|
|
13510
|
+
const video = getVideoEl2(el);
|
|
12214
13511
|
if (!video) return;
|
|
12215
13512
|
if (typeof settings.autoplay === "boolean") video.autoplay = settings.autoplay;
|
|
12216
13513
|
if (typeof settings.muted === "boolean") video.muted = settings.muted;
|
|
@@ -12230,9 +13527,9 @@ function OhhwellsBridge() {
|
|
|
12230
13527
|
[postToParent2]
|
|
12231
13528
|
);
|
|
12232
13529
|
return bridgeRoot ? createPortal2(
|
|
12233
|
-
/* @__PURE__ */
|
|
12234
|
-
/* @__PURE__ */
|
|
12235
|
-
Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */
|
|
13530
|
+
/* @__PURE__ */ jsxs15(Fragment5, { children: [
|
|
13531
|
+
/* @__PURE__ */ jsx27("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
|
|
13532
|
+
Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ jsx27(
|
|
12236
13533
|
MediaOverlay,
|
|
12237
13534
|
{
|
|
12238
13535
|
hover: { key, rect, elementType: "image", isDragOver: false, hasTextOverlap: false },
|
|
@@ -12243,7 +13540,7 @@ function OhhwellsBridge() {
|
|
|
12243
13540
|
},
|
|
12244
13541
|
`uploading-${key}`
|
|
12245
13542
|
)),
|
|
12246
|
-
mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */
|
|
13543
|
+
mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */ jsx27(
|
|
12247
13544
|
MediaOverlay,
|
|
12248
13545
|
{
|
|
12249
13546
|
hover: mediaHover,
|
|
@@ -12252,11 +13549,11 @@ function OhhwellsBridge() {
|
|
|
12252
13549
|
onVideoSettingsChange: handleVideoSettingsChange
|
|
12253
13550
|
}
|
|
12254
13551
|
),
|
|
12255
|
-
carouselHover && !linkPopover && !isItemDragging && /* @__PURE__ */
|
|
12256
|
-
siblingHintRect && !linkPopover && !isItemDragging && siblingHintRects.length === 0 && /* @__PURE__ */
|
|
12257
|
-
siblingHintRects.length > 0 && !linkPopover && !isItemDragging && siblingHintRects.map((rect, i) => /* @__PURE__ */
|
|
12258
|
-
isItemDragging && draggedItemRect && selectedElRef.current !== footerDragRef.current?.draggedEl && selectedElRef.current !== navDragRef.current?.draggedEl && /* @__PURE__ */
|
|
12259
|
-
isItemDragging && footerDropSlots.map((slot, i) => /* @__PURE__ */
|
|
13552
|
+
carouselHover && !linkPopover && !isItemDragging && /* @__PURE__ */ jsx27(CarouselOverlay, { hover: carouselHover, onEdit: handleEditCarousel }),
|
|
13553
|
+
siblingHintRect && !linkPopover && !isItemDragging && siblingHintRects.length === 0 && /* @__PURE__ */ jsx27(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
|
|
13554
|
+
siblingHintRects.length > 0 && !linkPopover && !isItemDragging && siblingHintRects.map((rect, i) => /* @__PURE__ */ jsx27(ItemInteractionLayer, { rect, state: "sibling-hint" }, `sibling-hint-${i}`)),
|
|
13555
|
+
isItemDragging && draggedItemRect && selectedElRef.current !== footerDragRef.current?.draggedEl && selectedElRef.current !== navDragRef.current?.draggedEl && /* @__PURE__ */ jsx27(ItemInteractionLayer, { rect: draggedItemRect, state: "dragging" }),
|
|
13556
|
+
isItemDragging && footerDropSlots.map((slot, i) => /* @__PURE__ */ jsx27(
|
|
12260
13557
|
"div",
|
|
12261
13558
|
{
|
|
12262
13559
|
className: "pointer-events-none fixed z-2147483646",
|
|
@@ -12266,7 +13563,7 @@ function OhhwellsBridge() {
|
|
|
12266
13563
|
width: slot.width,
|
|
12267
13564
|
height: slot.height
|
|
12268
13565
|
},
|
|
12269
|
-
children: /* @__PURE__ */
|
|
13566
|
+
children: /* @__PURE__ */ jsx27(
|
|
12270
13567
|
DropIndicator,
|
|
12271
13568
|
{
|
|
12272
13569
|
direction: slot.direction,
|
|
@@ -12277,7 +13574,7 @@ function OhhwellsBridge() {
|
|
|
12277
13574
|
},
|
|
12278
13575
|
`footer-drop-${slot.direction}-${slot.columnIndex}-${slot.insertIndex}-${i}`
|
|
12279
13576
|
)),
|
|
12280
|
-
isItemDragging && navDropSlots.map((slot, i) => /* @__PURE__ */
|
|
13577
|
+
isItemDragging && navDropSlots.map((slot, i) => /* @__PURE__ */ jsx27(
|
|
12281
13578
|
"div",
|
|
12282
13579
|
{
|
|
12283
13580
|
className: "pointer-events-none fixed z-2147483646",
|
|
@@ -12287,7 +13584,7 @@ function OhhwellsBridge() {
|
|
|
12287
13584
|
width: slot.width,
|
|
12288
13585
|
height: slot.height
|
|
12289
13586
|
},
|
|
12290
|
-
children: /* @__PURE__ */
|
|
13587
|
+
children: /* @__PURE__ */ jsx27(
|
|
12291
13588
|
DropIndicator,
|
|
12292
13589
|
{
|
|
12293
13590
|
direction: slot.direction,
|
|
@@ -12298,10 +13595,18 @@ function OhhwellsBridge() {
|
|
|
12298
13595
|
},
|
|
12299
13596
|
`nav-drop-${slot.direction}-${slot.parentId ?? "root"}-${slot.insertIndex}-${i}`
|
|
12300
13597
|
)),
|
|
12301
|
-
hoveredNavContainerRect && toolbarVariant !== "select-frame" && !linkPopover && !isItemDragging && /* @__PURE__ */
|
|
12302
|
-
hoveredItemRect && !linkPopover && !hoveredNavContainerRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */
|
|
12303
|
-
toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current &&
|
|
12304
|
-
toolbarRect && !linkPopover &&
|
|
13598
|
+
hoveredNavContainerRect && (toolbarVariant !== "select-frame" || isFooterFrameSelection) && !linkPopover && !isItemDragging && /* @__PURE__ */ jsx27(ItemInteractionLayer, { rect: hoveredNavContainerRect, state: "hover" }),
|
|
13599
|
+
hoveredItemRect && !linkPopover && !hoveredNavContainerRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ jsx27(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
|
|
13600
|
+
toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isNavbarLinksContainer2(selectedElRef.current) && /* @__PURE__ */ jsx27(NavbarContainerChrome, { rect: toolbarRect, onAdd: handleAddTopLevelNavItem }),
|
|
13601
|
+
toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isFooterLinksContainer(selectedElRef.current) && /* @__PURE__ */ jsx27(
|
|
13602
|
+
FooterContainerChrome,
|
|
13603
|
+
{
|
|
13604
|
+
rect: toolbarRect,
|
|
13605
|
+
onAdd: handleAddFooterColumn,
|
|
13606
|
+
addDisabled: !canAddFooterColumn()
|
|
13607
|
+
}
|
|
13608
|
+
),
|
|
13609
|
+
toolbarRect && !linkPopover && (toolbarVariant === "link-action" || toolbarVariant === "select-frame") && /* @__PURE__ */ jsx27(
|
|
12305
13610
|
ItemInteractionLayer,
|
|
12306
13611
|
{
|
|
12307
13612
|
rect: isItemDragging && draggedItemRect && (footerDragRef.current?.wasSelected || navDragRef.current?.wasSelected) ? draggedItemRect : toolbarRect,
|
|
@@ -12315,21 +13620,26 @@ function OhhwellsBridge() {
|
|
|
12315
13620
|
onItemPointerDown: handleItemChromePointerDown,
|
|
12316
13621
|
onItemClick: handleItemChromeClick,
|
|
12317
13622
|
itemDragSurface: !isFooterFrameSelection,
|
|
12318
|
-
toolbar: toolbarVariant === "link-action" && !isItemDragging ? /* @__PURE__ */
|
|
13623
|
+
toolbar: toolbarVariant === "link-action" && !isItemDragging || toolbarVariant === "select-frame" && isFooterFrameSelection && !isItemDragging ? /* @__PURE__ */ jsx27(
|
|
12319
13624
|
ItemActionToolbar,
|
|
12320
13625
|
{
|
|
12321
13626
|
onEditLink: openLinkPopoverForSelected,
|
|
13627
|
+
onSelectParent: handleSelectParent,
|
|
13628
|
+
onDuplicate: handleDuplicateSelected,
|
|
13629
|
+
onDelete: handleDeleteSelected,
|
|
12322
13630
|
addItemDisabled: true,
|
|
12323
13631
|
editLinkDisabled: false,
|
|
12324
|
-
moreDisabled:
|
|
12325
|
-
|
|
12326
|
-
|
|
13632
|
+
moreDisabled: false,
|
|
13633
|
+
duplicateDisabled: isFooterFrameSelection,
|
|
13634
|
+
showEditLink: !isFooterFrameSelection,
|
|
13635
|
+
showAddItem: !selectedIsCta && !isFooterFrameSelection,
|
|
13636
|
+
showMore: !selectedIsCta || isFooterFrameSelection
|
|
12327
13637
|
}
|
|
12328
13638
|
) : void 0
|
|
12329
13639
|
}
|
|
12330
13640
|
),
|
|
12331
|
-
toolbarRect && toolbarVariant === "rich-text" && !linkPopover && /* @__PURE__ */
|
|
12332
|
-
/* @__PURE__ */
|
|
13641
|
+
toolbarRect && toolbarVariant === "rich-text" && !linkPopover && /* @__PURE__ */ jsxs15(Fragment5, { children: [
|
|
13642
|
+
/* @__PURE__ */ jsx27(
|
|
12333
13643
|
EditGlowChrome,
|
|
12334
13644
|
{
|
|
12335
13645
|
rect: toolbarRect,
|
|
@@ -12339,7 +13649,7 @@ function OhhwellsBridge() {
|
|
|
12339
13649
|
hideHandle: isItemDragging
|
|
12340
13650
|
}
|
|
12341
13651
|
),
|
|
12342
|
-
/* @__PURE__ */
|
|
13652
|
+
/* @__PURE__ */ jsx27(
|
|
12343
13653
|
FloatingToolbar,
|
|
12344
13654
|
{
|
|
12345
13655
|
rect: toolbarRect,
|
|
@@ -12352,7 +13662,7 @@ function OhhwellsBridge() {
|
|
|
12352
13662
|
}
|
|
12353
13663
|
)
|
|
12354
13664
|
] }),
|
|
12355
|
-
maxBadge && /* @__PURE__ */
|
|
13665
|
+
maxBadge && /* @__PURE__ */ jsxs15(
|
|
12356
13666
|
"div",
|
|
12357
13667
|
{
|
|
12358
13668
|
"data-ohw-max-badge": "",
|
|
@@ -12378,7 +13688,7 @@ function OhhwellsBridge() {
|
|
|
12378
13688
|
]
|
|
12379
13689
|
}
|
|
12380
13690
|
),
|
|
12381
|
-
toggleState && !linkPopover && /* @__PURE__ */
|
|
13691
|
+
toggleState && !linkPopover && /* @__PURE__ */ jsx27(
|
|
12382
13692
|
StateToggle,
|
|
12383
13693
|
{
|
|
12384
13694
|
rect: toggleState.rect,
|
|
@@ -12387,15 +13697,15 @@ function OhhwellsBridge() {
|
|
|
12387
13697
|
onStateChange: handleStateChange
|
|
12388
13698
|
}
|
|
12389
13699
|
),
|
|
12390
|
-
sectionGap && !linkPopover && /* @__PURE__ */
|
|
13700
|
+
sectionGap && !linkPopover && /* @__PURE__ */ jsxs15(
|
|
12391
13701
|
"div",
|
|
12392
13702
|
{
|
|
12393
13703
|
"data-ohw-section-insert-line": "",
|
|
12394
13704
|
className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
|
|
12395
13705
|
style: { top: sectionGap.y, transform: "translateY(-50%)" },
|
|
12396
13706
|
children: [
|
|
12397
|
-
/* @__PURE__ */
|
|
12398
|
-
/* @__PURE__ */
|
|
13707
|
+
/* @__PURE__ */ jsx27("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
|
|
13708
|
+
/* @__PURE__ */ jsx27(
|
|
12399
13709
|
Badge,
|
|
12400
13710
|
{
|
|
12401
13711
|
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",
|
|
@@ -12412,11 +13722,11 @@ function OhhwellsBridge() {
|
|
|
12412
13722
|
children: "Add Section"
|
|
12413
13723
|
}
|
|
12414
13724
|
),
|
|
12415
|
-
/* @__PURE__ */
|
|
13725
|
+
/* @__PURE__ */ jsx27("div", { className: "flex-1 bg-primary", style: { height: 3 } })
|
|
12416
13726
|
]
|
|
12417
13727
|
}
|
|
12418
13728
|
),
|
|
12419
|
-
linkPopover && dialogPortalContainer ? /* @__PURE__ */
|
|
13729
|
+
linkPopover && dialogPortalContainer ? /* @__PURE__ */ jsx27(
|
|
12420
13730
|
LinkPopover,
|
|
12421
13731
|
{
|
|
12422
13732
|
panelRef: linkPopoverPanelRef,
|
|
@@ -12443,6 +13753,12 @@ export {
|
|
|
12443
13753
|
CustomToolbarDivider,
|
|
12444
13754
|
DragHandle,
|
|
12445
13755
|
DropIndicator,
|
|
13756
|
+
DropdownMenu,
|
|
13757
|
+
DropdownMenuContent,
|
|
13758
|
+
DropdownMenuGroup,
|
|
13759
|
+
DropdownMenuItem,
|
|
13760
|
+
DropdownMenuSeparator,
|
|
13761
|
+
DropdownMenuTrigger,
|
|
12446
13762
|
ItemActionToolbar,
|
|
12447
13763
|
ItemInteractionLayer,
|
|
12448
13764
|
LinkEditorPanel,
|