@ohhwells/bridge 0.1.44 → 0.1.45
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 +2392 -453
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +12 -3
- package/dist/index.d.ts +12 -3
- package/dist/index.js +2429 -490
- package/dist/index.js.map +1 -1
- package/dist/styles.css +116 -17
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
// src/OhhwellsBridge.tsx
|
|
4
|
-
import
|
|
4
|
+
import React11, { useCallback as useCallback4, useEffect as useEffect8, useLayoutEffect as useLayoutEffect3, useRef as useRef7, useState as useState7 } from "react";
|
|
5
5
|
import { createRoot } from "react-dom/client";
|
|
6
6
|
import { flushSync } from "react-dom";
|
|
7
7
|
|
|
@@ -4286,7 +4286,7 @@ import { Link, MoreHorizontal, Plus } from "lucide-react";
|
|
|
4286
4286
|
|
|
4287
4287
|
// src/ui/tooltip.tsx
|
|
4288
4288
|
import { Tooltip as TooltipPrimitive } from "radix-ui";
|
|
4289
|
-
import { jsx as jsx7
|
|
4289
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
4290
4290
|
function TooltipProvider({
|
|
4291
4291
|
delayDuration = 0,
|
|
4292
4292
|
...props
|
|
@@ -4299,39 +4299,45 @@ function Tooltip({ ...props }) {
|
|
|
4299
4299
|
function TooltipTrigger({ ...props }) {
|
|
4300
4300
|
return /* @__PURE__ */ jsx7(TooltipPrimitive.Trigger, { "data-slot": "tooltip-trigger", ...props });
|
|
4301
4301
|
}
|
|
4302
|
+
var arrowClassBySide = {
|
|
4303
|
+
top: "before:bottom-0 before:left-1/2 before:-translate-x-1/2 before:translate-y-1/2",
|
|
4304
|
+
bottom: "before:top-0 before:left-1/2 before:-translate-x-1/2 before:-translate-y-1/2",
|
|
4305
|
+
left: "before:right-0 before:top-1/2 before:-translate-y-1/2 before:translate-x-1/2",
|
|
4306
|
+
right: "before:left-0 before:top-1/2 before:-translate-y-1/2 before:-translate-x-1/2"
|
|
4307
|
+
};
|
|
4302
4308
|
function TooltipContent({
|
|
4303
4309
|
className,
|
|
4304
|
-
sideOffset =
|
|
4310
|
+
sideOffset = 9,
|
|
4305
4311
|
side = "bottom",
|
|
4306
4312
|
children,
|
|
4307
4313
|
hideArrow,
|
|
4308
4314
|
...props
|
|
4309
4315
|
}) {
|
|
4310
|
-
|
|
4316
|
+
const resolvedSide = side ?? "bottom";
|
|
4317
|
+
return /* @__PURE__ */ jsx7(TooltipPrimitive.Portal, { children: /* @__PURE__ */ jsx7(
|
|
4311
4318
|
TooltipPrimitive.Content,
|
|
4312
4319
|
{
|
|
4313
4320
|
"data-slot": "tooltip-content",
|
|
4314
4321
|
side,
|
|
4315
4322
|
sideOffset,
|
|
4316
4323
|
className: cn(
|
|
4317
|
-
"z-[2147483647] inline-flex w-fit max-w-xs items-center rounded-md bg-foreground px-3 py-1.5 text-xs text-background",
|
|
4324
|
+
"relative z-[2147483647] inline-flex w-fit max-w-xs items-center rounded-md bg-foreground px-3 py-1.5 text-xs text-background",
|
|
4318
4325
|
"origin-[var(--radix-tooltip-content-transform-origin)] animate-in fade-in-0 zoom-in-95",
|
|
4319
4326
|
"data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
|
|
4320
4327
|
"data-[side=bottom]:slide-in-from-top-2 data-[side=top]:slide-in-from-bottom-2",
|
|
4321
4328
|
"data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2",
|
|
4329
|
+
!hideArrow && 'before:pointer-events-none before:absolute before:size-2 before:rotate-45 before:bg-foreground before:content-[""]',
|
|
4330
|
+
!hideArrow && arrowClassBySide[resolvedSide],
|
|
4322
4331
|
className
|
|
4323
4332
|
),
|
|
4324
4333
|
...props,
|
|
4325
|
-
children
|
|
4326
|
-
children,
|
|
4327
|
-
!hideArrow && /* @__PURE__ */ jsx7(TooltipPrimitive.Arrow, { className: "z-[2147483647] size-2.5 translate-y-[calc(-50%-2px)] rotate-45 rounded-[2px] bg-foreground fill-foreground" })
|
|
4328
|
-
]
|
|
4334
|
+
children
|
|
4329
4335
|
}
|
|
4330
4336
|
) });
|
|
4331
4337
|
}
|
|
4332
4338
|
|
|
4333
4339
|
// src/ui/item-action-toolbar.tsx
|
|
4334
|
-
import { jsx as jsx8, jsxs as
|
|
4340
|
+
import { jsx as jsx8, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
4335
4341
|
function ToolbarActionTooltip({
|
|
4336
4342
|
label,
|
|
4337
4343
|
side = "bottom",
|
|
@@ -4340,9 +4346,9 @@ function ToolbarActionTooltip({
|
|
|
4340
4346
|
children
|
|
4341
4347
|
}) {
|
|
4342
4348
|
const button = /* @__PURE__ */ jsx8(CustomToolbarButton, { type: "button", "aria-label": label, disabled, ...buttonProps, children });
|
|
4343
|
-
return /* @__PURE__ */
|
|
4349
|
+
return /* @__PURE__ */ jsxs3(Tooltip, { children: [
|
|
4344
4350
|
/* @__PURE__ */ jsx8(TooltipTrigger, { asChild: true, children: disabled ? /* @__PURE__ */ jsx8("span", { className: "inline-flex", children: button }) : button }),
|
|
4345
|
-
/* @__PURE__ */ jsx8(TooltipContent, { side, sideOffset:
|
|
4351
|
+
/* @__PURE__ */ jsx8(TooltipContent, { side, sideOffset: 9, children: label })
|
|
4346
4352
|
] });
|
|
4347
4353
|
}
|
|
4348
4354
|
function ItemActionToolbar({
|
|
@@ -4356,7 +4362,7 @@ function ItemActionToolbar({
|
|
|
4356
4362
|
showMore = true,
|
|
4357
4363
|
tooltipSide = "bottom"
|
|
4358
4364
|
}) {
|
|
4359
|
-
return /* @__PURE__ */ jsx8(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */
|
|
4365
|
+
return /* @__PURE__ */ jsx8(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ jsxs3(CustomToolbar, { children: [
|
|
4360
4366
|
/* @__PURE__ */ jsx8(
|
|
4361
4367
|
ToolbarActionTooltip,
|
|
4362
4368
|
{
|
|
@@ -4417,13 +4423,26 @@ function ItemActionToolbar({
|
|
|
4417
4423
|
|
|
4418
4424
|
// src/ui/item-interaction-layer.tsx
|
|
4419
4425
|
import * as React5 from "react";
|
|
4420
|
-
import { jsx as jsx9, jsxs as
|
|
4426
|
+
import { jsx as jsx9, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
4421
4427
|
var PRIMARY = "var(--ohw-primary, #0885FE)";
|
|
4422
4428
|
var FOCUS_RING = `0 0 0 4px color-mix(in srgb, ${PRIMARY} 12%, transparent)`;
|
|
4423
4429
|
var DRAG_SHADOW = "0px 4px 6px -1px rgba(0, 0, 0, 0.1), 0px 2px 4px -2px rgba(0, 0, 0, 0.1)";
|
|
4424
4430
|
var TOOLBAR_EDGE_MARGIN = 4;
|
|
4425
4431
|
var SELECTION_CHROME_GAP = 4;
|
|
4426
4432
|
var TOOLBAR_STROKE_GAP = 4;
|
|
4433
|
+
function getChromeZIndex(state) {
|
|
4434
|
+
switch (state) {
|
|
4435
|
+
case "active-top":
|
|
4436
|
+
case "active-bottom":
|
|
4437
|
+
case "dragging":
|
|
4438
|
+
return 2147483644;
|
|
4439
|
+
case "hover":
|
|
4440
|
+
case "sibling-hint":
|
|
4441
|
+
return 2147483643;
|
|
4442
|
+
default:
|
|
4443
|
+
return 2147483642;
|
|
4444
|
+
}
|
|
4445
|
+
}
|
|
4427
4446
|
function getChromeStyle(state) {
|
|
4428
4447
|
switch (state) {
|
|
4429
4448
|
case "hover":
|
|
@@ -4445,7 +4464,7 @@ function getChromeStyle(state) {
|
|
|
4445
4464
|
case "dragging":
|
|
4446
4465
|
return {
|
|
4447
4466
|
border: `2px solid ${PRIMARY}`,
|
|
4448
|
-
boxShadow: DRAG_SHADOW
|
|
4467
|
+
boxShadow: `${FOCUS_RING}, ${DRAG_SHADOW}`
|
|
4449
4468
|
};
|
|
4450
4469
|
default:
|
|
4451
4470
|
return {};
|
|
@@ -4514,6 +4533,9 @@ function ItemInteractionLayer({
|
|
|
4514
4533
|
dragHandleLabel = "Reorder item",
|
|
4515
4534
|
onDragHandleDragStart,
|
|
4516
4535
|
onDragHandleDragEnd,
|
|
4536
|
+
onItemPointerDown,
|
|
4537
|
+
onItemClick,
|
|
4538
|
+
itemDragSurface = true,
|
|
4517
4539
|
chromeGap = SELECTION_CHROME_GAP,
|
|
4518
4540
|
className
|
|
4519
4541
|
}) {
|
|
@@ -4521,8 +4543,9 @@ function ItemInteractionLayer({
|
|
|
4521
4543
|
const isActive = state === "active-top" || state === "active-bottom";
|
|
4522
4544
|
const isDragging = state === "dragging";
|
|
4523
4545
|
const showToolbar = isActive && toolbar;
|
|
4524
|
-
const showDragHandle = isActive
|
|
4525
|
-
|
|
4546
|
+
const showDragHandle = (isActive || isDragging) && showHandle;
|
|
4547
|
+
const itemDragEnabled = itemDragSurface && isActive && showHandle && !isDragging && !dragDisabled;
|
|
4548
|
+
return /* @__PURE__ */ jsxs4(
|
|
4526
4549
|
"div",
|
|
4527
4550
|
{
|
|
4528
4551
|
ref: elRef,
|
|
@@ -4535,7 +4558,7 @@ function ItemInteractionLayer({
|
|
|
4535
4558
|
left: rect.left - chromeGap,
|
|
4536
4559
|
width: rect.width + chromeGap * 2,
|
|
4537
4560
|
height: rect.height + chromeGap * 2,
|
|
4538
|
-
zIndex:
|
|
4561
|
+
zIndex: getChromeZIndex(state)
|
|
4539
4562
|
},
|
|
4540
4563
|
children: [
|
|
4541
4564
|
/* @__PURE__ */ jsx9(
|
|
@@ -4546,11 +4569,29 @@ function ItemInteractionLayer({
|
|
|
4546
4569
|
style: getChromeStyle(state)
|
|
4547
4570
|
}
|
|
4548
4571
|
),
|
|
4572
|
+
itemDragEnabled && /* @__PURE__ */ jsx9(
|
|
4573
|
+
"div",
|
|
4574
|
+
{
|
|
4575
|
+
"data-ohw-item-drag-surface": "",
|
|
4576
|
+
className: "pointer-events-auto absolute inset-0 cursor-text rounded-lg",
|
|
4577
|
+
onPointerDown: (e) => {
|
|
4578
|
+
if (e.button !== 0) return;
|
|
4579
|
+
onItemPointerDown?.(e);
|
|
4580
|
+
},
|
|
4581
|
+
onClick: (e) => {
|
|
4582
|
+
e.preventDefault();
|
|
4583
|
+
e.stopPropagation();
|
|
4584
|
+
onItemClick?.(e.clientX, e.clientY);
|
|
4585
|
+
}
|
|
4586
|
+
}
|
|
4587
|
+
),
|
|
4549
4588
|
showDragHandle && /* @__PURE__ */ jsx9(
|
|
4550
4589
|
"div",
|
|
4551
4590
|
{
|
|
4552
4591
|
"data-ohw-drag-handle-container": "",
|
|
4553
|
-
className: "pointer-events-auto absolute left-0 top-1/2 -translate-x-[calc(100%+7px)] -translate-y-1/2",
|
|
4592
|
+
className: "pointer-events-auto absolute left-0 top-1/2 z-10 -translate-x-[calc(100%+7px)] -translate-y-1/2",
|
|
4593
|
+
style: isDragging ? { opacity: 0 } : void 0,
|
|
4594
|
+
"aria-hidden": isDragging || void 0,
|
|
4554
4595
|
children: /* @__PURE__ */ jsx9(
|
|
4555
4596
|
DragHandle,
|
|
4556
4597
|
{
|
|
@@ -4562,7 +4603,17 @@ function ItemInteractionLayer({
|
|
|
4562
4603
|
e.preventDefault();
|
|
4563
4604
|
return;
|
|
4564
4605
|
}
|
|
4565
|
-
|
|
4606
|
+
const blank = document.createElement("canvas");
|
|
4607
|
+
blank.width = 1;
|
|
4608
|
+
blank.height = 1;
|
|
4609
|
+
blank.style.cssText = "position:fixed;left:-9999px;top:-9999px;width:1px;height:1px;pointer-events:none";
|
|
4610
|
+
document.body.appendChild(blank);
|
|
4611
|
+
try {
|
|
4612
|
+
e.dataTransfer.setDragImage(blank, 0, 0);
|
|
4613
|
+
} finally {
|
|
4614
|
+
requestAnimationFrame(() => blank.remove());
|
|
4615
|
+
}
|
|
4616
|
+
e.dataTransfer.setData("text/plain", dragHandleLabel);
|
|
4566
4617
|
e.dataTransfer.effectAllowed = "move";
|
|
4567
4618
|
onDragHandleDragStart?.(e);
|
|
4568
4619
|
},
|
|
@@ -4623,7 +4674,7 @@ var Button = React6.forwardRef(
|
|
|
4623
4674
|
Button.displayName = "Button";
|
|
4624
4675
|
|
|
4625
4676
|
// src/ui/MediaOverlay.tsx
|
|
4626
|
-
import { Fragment as Fragment2, jsx as jsx11, jsxs as
|
|
4677
|
+
import { Fragment as Fragment2, jsx as jsx11, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
4627
4678
|
var MEDIA_UPLOAD_FADE_MS = 300;
|
|
4628
4679
|
var VIDEO_SETTINGS_BAR_INSET = 8;
|
|
4629
4680
|
var OVERLAY_BUTTON_STYLE = {
|
|
@@ -4694,7 +4745,7 @@ function MediaOverlay({
|
|
|
4694
4745
|
}
|
|
4695
4746
|
);
|
|
4696
4747
|
}
|
|
4697
|
-
const settingsBar = isVideo && !hover.isDragOver ? /* @__PURE__ */
|
|
4748
|
+
const settingsBar = isVideo && !hover.isDragOver ? /* @__PURE__ */ jsxs5(
|
|
4698
4749
|
"div",
|
|
4699
4750
|
{
|
|
4700
4751
|
"data-ohw-bridge": "",
|
|
@@ -4749,7 +4800,7 @@ function MediaOverlay({
|
|
|
4749
4800
|
]
|
|
4750
4801
|
}
|
|
4751
4802
|
) : null;
|
|
4752
|
-
return /* @__PURE__ */
|
|
4803
|
+
return /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
4753
4804
|
settingsBar,
|
|
4754
4805
|
/* @__PURE__ */ jsx11(
|
|
4755
4806
|
"div",
|
|
@@ -4768,7 +4819,7 @@ function MediaOverlay({
|
|
|
4768
4819
|
background: "color-mix(in srgb, var(--color-primary) 20%, transparent)"
|
|
4769
4820
|
},
|
|
4770
4821
|
onClick: () => onReplace(hover.key),
|
|
4771
|
-
children: /* @__PURE__ */
|
|
4822
|
+
children: /* @__PURE__ */ jsxs5(
|
|
4772
4823
|
Button,
|
|
4773
4824
|
{
|
|
4774
4825
|
"data-ohw-media-overlay": "",
|
|
@@ -5078,7 +5129,7 @@ import { useEffect as useEffect6 } from "react";
|
|
|
5078
5129
|
import * as React8 from "react";
|
|
5079
5130
|
import { Dialog as DialogPrimitive } from "radix-ui";
|
|
5080
5131
|
import { X } from "lucide-react";
|
|
5081
|
-
import { jsx as jsx12, jsxs as
|
|
5132
|
+
import { jsx as jsx12, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
5082
5133
|
function Dialog2({
|
|
5083
5134
|
...props
|
|
5084
5135
|
}) {
|
|
@@ -5106,9 +5157,9 @@ function DialogOverlay({
|
|
|
5106
5157
|
var DialogContent = React8.forwardRef(
|
|
5107
5158
|
({ className, children, showCloseButton = true, container, ...props }, ref) => {
|
|
5108
5159
|
const positionMode = container ? "absolute" : "fixed";
|
|
5109
|
-
return /* @__PURE__ */
|
|
5160
|
+
return /* @__PURE__ */ jsxs6(DialogPortal, { container: container ?? void 0, children: [
|
|
5110
5161
|
/* @__PURE__ */ jsx12(DialogOverlay, { className: cn(positionMode, "inset-0") }),
|
|
5111
|
-
/* @__PURE__ */
|
|
5162
|
+
/* @__PURE__ */ jsxs6(
|
|
5112
5163
|
DialogPrimitive.Content,
|
|
5113
5164
|
{
|
|
5114
5165
|
ref,
|
|
@@ -5186,15 +5237,15 @@ import { Info, X as X3 } from "lucide-react";
|
|
|
5186
5237
|
|
|
5187
5238
|
// src/ui/link-modal/DestinationBreadcrumb.tsx
|
|
5188
5239
|
import { ArrowRight, File, GalleryVertical } from "lucide-react";
|
|
5189
|
-
import { jsx as jsx13, jsxs as
|
|
5240
|
+
import { jsx as jsx13, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
5190
5241
|
function DestinationBreadcrumb({
|
|
5191
5242
|
pageTitle,
|
|
5192
5243
|
sectionLabel
|
|
5193
5244
|
}) {
|
|
5194
|
-
return /* @__PURE__ */
|
|
5245
|
+
return /* @__PURE__ */ jsxs7("div", { className: "flex w-full flex-col gap-2", children: [
|
|
5195
5246
|
/* @__PURE__ */ jsx13("p", { className: "text-sm font-medium! text-foreground m-0", children: "Destination" }),
|
|
5196
|
-
/* @__PURE__ */
|
|
5197
|
-
/* @__PURE__ */
|
|
5247
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-3", children: [
|
|
5248
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-2", children: [
|
|
5198
5249
|
/* @__PURE__ */ jsx13(File, { size: 16, className: "shrink-0 text-foreground", "aria-hidden": true }),
|
|
5199
5250
|
/* @__PURE__ */ jsx13("span", { className: "text-sm font-medium leading-none text-foreground!", children: pageTitle })
|
|
5200
5251
|
] }),
|
|
@@ -5206,7 +5257,7 @@ function DestinationBreadcrumb({
|
|
|
5206
5257
|
"aria-hidden": true
|
|
5207
5258
|
}
|
|
5208
5259
|
),
|
|
5209
|
-
/* @__PURE__ */
|
|
5260
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
|
|
5210
5261
|
/* @__PURE__ */ jsx13(
|
|
5211
5262
|
GalleryVertical,
|
|
5212
5263
|
{
|
|
@@ -5223,14 +5274,14 @@ function DestinationBreadcrumb({
|
|
|
5223
5274
|
|
|
5224
5275
|
// src/ui/link-modal/SectionTreeItem.tsx
|
|
5225
5276
|
import { GalleryVertical as GalleryVertical2 } from "lucide-react";
|
|
5226
|
-
import { jsx as jsx14, jsxs as
|
|
5277
|
+
import { jsx as jsx14, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
5227
5278
|
function SectionTreeItem({
|
|
5228
5279
|
section,
|
|
5229
5280
|
onSelect,
|
|
5230
5281
|
selected
|
|
5231
5282
|
}) {
|
|
5232
5283
|
const interactive = Boolean(onSelect);
|
|
5233
|
-
return /* @__PURE__ */
|
|
5284
|
+
return /* @__PURE__ */ jsxs8("div", { className: "flex h-9 w-full items-end pl-3", children: [
|
|
5234
5285
|
/* @__PURE__ */ jsx14(
|
|
5235
5286
|
"div",
|
|
5236
5287
|
{
|
|
@@ -5238,7 +5289,7 @@ function SectionTreeItem({
|
|
|
5238
5289
|
"aria-hidden": true
|
|
5239
5290
|
}
|
|
5240
5291
|
),
|
|
5241
|
-
/* @__PURE__ */
|
|
5292
|
+
/* @__PURE__ */ jsxs8(
|
|
5242
5293
|
"div",
|
|
5243
5294
|
{
|
|
5244
5295
|
role: interactive ? "button" : void 0,
|
|
@@ -5312,7 +5363,7 @@ function Label({ className, ...props }) {
|
|
|
5312
5363
|
|
|
5313
5364
|
// src/ui/link-modal/UrlOrPageInput.tsx
|
|
5314
5365
|
import { ChevronDown, File as File2, X as X2 } from "lucide-react";
|
|
5315
|
-
import { jsx as jsx17, jsxs as
|
|
5366
|
+
import { jsx as jsx17, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
5316
5367
|
function FieldChevron({
|
|
5317
5368
|
onClick
|
|
5318
5369
|
}) {
|
|
@@ -5385,10 +5436,10 @@ function UrlOrPageInput({
|
|
|
5385
5436
|
"data-ohw-link-field flex h-[36px] w-full items-center overflow-hidden rounded-md border bg-background pl-3 pr-3 py-2 outline-none transition-[border-color,box-shadow]",
|
|
5386
5437
|
urlError ? "border-destructive shadow-[0_0_0_1px_var(--ohw-destructive)]" : isFocused ? "border-primary shadow-[0_0_0_1px_var(--ohw-primary)]" : "border-input"
|
|
5387
5438
|
);
|
|
5388
|
-
return /* @__PURE__ */
|
|
5439
|
+
return /* @__PURE__ */ jsxs9("div", { className: "flex w-full flex-col gap-2 p-0", children: [
|
|
5389
5440
|
/* @__PURE__ */ jsx17(Label, { htmlFor: inputId, className: cn(urlError && "text-destructive"), children: "Destination" }),
|
|
5390
|
-
/* @__PURE__ */
|
|
5391
|
-
/* @__PURE__ */
|
|
5441
|
+
/* @__PURE__ */ jsxs9("div", { ref: rootRef, className: "relative w-full", children: [
|
|
5442
|
+
/* @__PURE__ */ jsxs9("div", { "data-ohw-link-field": true, className: fieldClassName, children: [
|
|
5392
5443
|
selectedPage ? /* @__PURE__ */ jsx17("div", { className: "flex shrink-0 items-center pr-2", children: /* @__PURE__ */ jsx17(
|
|
5393
5444
|
File2,
|
|
5394
5445
|
{
|
|
@@ -5442,7 +5493,7 @@ function UrlOrPageInput({
|
|
|
5442
5493
|
"data-ohw-link-page-dropdown": "",
|
|
5443
5494
|
className: "absolute left-0 right-0 top-[calc(100%+4px)] z-50 max-h-48 overflow-auto rounded-lg border border-border bg-popover py-1 shadow-lg",
|
|
5444
5495
|
onMouseDown: (e) => e.preventDefault(),
|
|
5445
|
-
children: filteredPages.map((page) => /* @__PURE__ */
|
|
5496
|
+
children: filteredPages.map((page) => /* @__PURE__ */ jsxs9(
|
|
5446
5497
|
"button",
|
|
5447
5498
|
{
|
|
5448
5499
|
type: "button",
|
|
@@ -5463,10 +5514,10 @@ function UrlOrPageInput({
|
|
|
5463
5514
|
}
|
|
5464
5515
|
|
|
5465
5516
|
// src/ui/link-modal/LinkEditorPanel.tsx
|
|
5466
|
-
import { Fragment as Fragment3, jsx as jsx18, jsxs as
|
|
5517
|
+
import { Fragment as Fragment3, jsx as jsx18, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
5467
5518
|
function LinkEditorPanel({ state, onClose }) {
|
|
5468
5519
|
const isCancel = state.secondaryLabel === "Cancel" || state.secondaryLabel === "Back to sections";
|
|
5469
|
-
return /* @__PURE__ */
|
|
5520
|
+
return /* @__PURE__ */ jsxs10(Fragment3, { children: [
|
|
5470
5521
|
/* @__PURE__ */ jsx18(DialogClose, { asChild: true, children: /* @__PURE__ */ jsx18(
|
|
5471
5522
|
"button",
|
|
5472
5523
|
{
|
|
@@ -5478,7 +5529,7 @@ function LinkEditorPanel({ state, onClose }) {
|
|
|
5478
5529
|
}
|
|
5479
5530
|
) }),
|
|
5480
5531
|
/* @__PURE__ */ jsx18(DialogHeader, { className: "w-full gap-1.5 p-6 pr-12", children: /* @__PURE__ */ jsx18(DialogTitle, { className: "m-0 w-full break-words", children: state.title }) }),
|
|
5481
|
-
/* @__PURE__ */
|
|
5532
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex w-full flex-col gap-3 px-6 pb-8 pt-1", children: [
|
|
5482
5533
|
state.showBreadcrumb && state.selectedPage && state.selectedSection ? /* @__PURE__ */ jsx18(
|
|
5483
5534
|
DestinationBreadcrumb,
|
|
5484
5535
|
{
|
|
@@ -5498,7 +5549,7 @@ function LinkEditorPanel({ state, onClose }) {
|
|
|
5498
5549
|
urlError: state.urlError
|
|
5499
5550
|
}
|
|
5500
5551
|
),
|
|
5501
|
-
state.showChooseSection ? /* @__PURE__ */
|
|
5552
|
+
state.showChooseSection ? /* @__PURE__ */ jsxs10("div", { className: "flex flex-col justify-center gap-2", children: [
|
|
5502
5553
|
/* @__PURE__ */ jsx18(
|
|
5503
5554
|
Button,
|
|
5504
5555
|
{
|
|
@@ -5510,14 +5561,14 @@ function LinkEditorPanel({ state, onClose }) {
|
|
|
5510
5561
|
children: "Choose a section"
|
|
5511
5562
|
}
|
|
5512
5563
|
),
|
|
5513
|
-
/* @__PURE__ */
|
|
5564
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-1 text-sm text-muted-foreground", children: [
|
|
5514
5565
|
/* @__PURE__ */ jsx18(Info, { size: 16, className: "shrink-0", "aria-hidden": true }),
|
|
5515
5566
|
/* @__PURE__ */ jsx18("span", { children: "Pick a section this link should scroll to." })
|
|
5516
5567
|
] })
|
|
5517
5568
|
] }) : null,
|
|
5518
5569
|
state.showSectionRow && state.selectedSection ? /* @__PURE__ */ jsx18(SectionTreeItem, { section: state.selectedSection, selected: true }) : null
|
|
5519
5570
|
] }),
|
|
5520
|
-
/* @__PURE__ */
|
|
5571
|
+
/* @__PURE__ */ jsxs10(DialogFooter, { className: "w-full px-6 pb-6", children: [
|
|
5521
5572
|
/* @__PURE__ */ jsx18(
|
|
5522
5573
|
Button,
|
|
5523
5574
|
{
|
|
@@ -5556,7 +5607,7 @@ import { useCallback, useEffect as useEffect4, useMemo as useMemo2, useRef as us
|
|
|
5556
5607
|
import { createPortal } from "react-dom";
|
|
5557
5608
|
import { ArrowLeft, Check } from "lucide-react";
|
|
5558
5609
|
import { usePathname, useRouter } from "next/navigation";
|
|
5559
|
-
import { jsx as jsx19, jsxs as
|
|
5610
|
+
import { jsx as jsx19, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
5560
5611
|
var DIM_OVERLAY = "rgba(0, 0, 0, 0.45)";
|
|
5561
5612
|
function rectsEqual(a, b) {
|
|
5562
5613
|
if (a.size !== b.size) return false;
|
|
@@ -5785,7 +5836,7 @@ function SectionPickerOverlay({
|
|
|
5785
5836
|
const portalRoot = typeof document !== "undefined" ? document.querySelector("[data-ohw-bridge-root]") ?? document.body : null;
|
|
5786
5837
|
if (!portalRoot) return null;
|
|
5787
5838
|
return createPortal(
|
|
5788
|
-
/* @__PURE__ */
|
|
5839
|
+
/* @__PURE__ */ jsxs11(
|
|
5789
5840
|
"div",
|
|
5790
5841
|
{
|
|
5791
5842
|
"data-ohw-section-picker": "",
|
|
@@ -5800,7 +5851,7 @@ function SectionPickerOverlay({
|
|
|
5800
5851
|
{
|
|
5801
5852
|
className: "pointer-events-auto fixed left-5 z-[2]",
|
|
5802
5853
|
style: { top: chromeClip.top + 20 },
|
|
5803
|
-
children: /* @__PURE__ */
|
|
5854
|
+
children: /* @__PURE__ */ jsxs11(
|
|
5804
5855
|
Button,
|
|
5805
5856
|
{
|
|
5806
5857
|
type: "button",
|
|
@@ -5844,7 +5895,7 @@ function SectionPickerOverlay({
|
|
|
5844
5895
|
const isSelected = selectedId === section.id;
|
|
5845
5896
|
const isHovered = hoveredId === section.id;
|
|
5846
5897
|
const isLit = isSelected || isHovered;
|
|
5847
|
-
return /* @__PURE__ */
|
|
5898
|
+
return /* @__PURE__ */ jsxs11(
|
|
5848
5899
|
"button",
|
|
5849
5900
|
{
|
|
5850
5901
|
type: "button",
|
|
@@ -6058,7 +6109,7 @@ function useLinkModalState({
|
|
|
6058
6109
|
}
|
|
6059
6110
|
|
|
6060
6111
|
// src/ui/link-modal/LinkPopover.tsx
|
|
6061
|
-
import { Fragment as Fragment4, jsx as jsx20, jsxs as
|
|
6112
|
+
import { Fragment as Fragment4, jsx as jsx20, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
6062
6113
|
function postToParent(data) {
|
|
6063
6114
|
window.parent?.postMessage(data, "*");
|
|
6064
6115
|
}
|
|
@@ -6154,7 +6205,7 @@ function LinkPopover({
|
|
|
6154
6205
|
);
|
|
6155
6206
|
};
|
|
6156
6207
|
}, [open, sectionPickerActive]);
|
|
6157
|
-
return /* @__PURE__ */
|
|
6208
|
+
return /* @__PURE__ */ jsxs12(Fragment4, { children: [
|
|
6158
6209
|
/* @__PURE__ */ jsx20(
|
|
6159
6210
|
Dialog2,
|
|
6160
6211
|
{
|
|
@@ -6258,9 +6309,155 @@ function shouldUseDevFixtures() {
|
|
|
6258
6309
|
return new URLSearchParams(q).get("ohw-fixtures") === "1";
|
|
6259
6310
|
}
|
|
6260
6311
|
|
|
6312
|
+
// src/lib/nav-tree.ts
|
|
6313
|
+
var MAX_LEVEL = { nav: 1 };
|
|
6314
|
+
var ROOT = null;
|
|
6315
|
+
function cloneForest(nodes) {
|
|
6316
|
+
return nodes.map((n) => ({ id: n.id, children: cloneForest(n.children) }));
|
|
6317
|
+
}
|
|
6318
|
+
function findNode(nodes, id, parentId = ROOT) {
|
|
6319
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
6320
|
+
const node = nodes[i];
|
|
6321
|
+
if (node.id === id) return { node, parentId, index: i, siblings: nodes };
|
|
6322
|
+
const nested = findNode(node.children, id, node.id);
|
|
6323
|
+
if (nested) return nested;
|
|
6324
|
+
}
|
|
6325
|
+
return null;
|
|
6326
|
+
}
|
|
6327
|
+
function getChildrenOf(nodes, parentId) {
|
|
6328
|
+
if (parentId === ROOT) return nodes;
|
|
6329
|
+
const found = findNode(nodes, parentId);
|
|
6330
|
+
return found ? found.node.children : null;
|
|
6331
|
+
}
|
|
6332
|
+
function isDescendant(nodes, ancestorId, maybeDescendantId) {
|
|
6333
|
+
const found = findNode(nodes, ancestorId);
|
|
6334
|
+
if (!found) return false;
|
|
6335
|
+
return findNode(found.node.children, maybeDescendantId) !== null;
|
|
6336
|
+
}
|
|
6337
|
+
function levelOf(nodes, id) {
|
|
6338
|
+
const loc = findNode(nodes, id);
|
|
6339
|
+
if (!loc) return -1;
|
|
6340
|
+
if (loc.parentId === ROOT) return 0;
|
|
6341
|
+
return 1 + Math.max(0, levelOf(nodes, loc.parentId));
|
|
6342
|
+
}
|
|
6343
|
+
function insertedLevel(nodes, parentId) {
|
|
6344
|
+
if (parentId === ROOT) return 0;
|
|
6345
|
+
const parentLevel = levelOf(nodes, parentId);
|
|
6346
|
+
if (parentLevel < 0) return -1;
|
|
6347
|
+
return parentLevel + 1;
|
|
6348
|
+
}
|
|
6349
|
+
function takeNode(nodes, id) {
|
|
6350
|
+
const forest = cloneForest(nodes);
|
|
6351
|
+
const loc = findNode(forest, id);
|
|
6352
|
+
if (!loc) return null;
|
|
6353
|
+
const [taken] = loc.siblings.splice(loc.index, 1);
|
|
6354
|
+
if (!taken) return null;
|
|
6355
|
+
return { forest, taken };
|
|
6356
|
+
}
|
|
6357
|
+
function insertInto(forest, node, parentId, index) {
|
|
6358
|
+
const siblings = getChildrenOf(forest, parentId);
|
|
6359
|
+
if (!siblings) return false;
|
|
6360
|
+
const clamped = Math.max(0, Math.min(index, siblings.length));
|
|
6361
|
+
siblings.splice(clamped, 0, node);
|
|
6362
|
+
return true;
|
|
6363
|
+
}
|
|
6364
|
+
function normalize(nodes) {
|
|
6365
|
+
const walk = (list) => list.map((n) => {
|
|
6366
|
+
const children = walk(n.children);
|
|
6367
|
+
return { id: n.id, children };
|
|
6368
|
+
});
|
|
6369
|
+
return walk(nodes);
|
|
6370
|
+
}
|
|
6371
|
+
function moveNode(model, draggedId, target) {
|
|
6372
|
+
const { parentId, index: targetIndex } = target;
|
|
6373
|
+
if (parentId === draggedId) return null;
|
|
6374
|
+
if (parentId !== ROOT && isDescendant(model, draggedId, parentId)) return null;
|
|
6375
|
+
const nextLevel = insertedLevel(model, parentId);
|
|
6376
|
+
if (nextLevel < 0 || nextLevel > MAX_LEVEL.nav) return null;
|
|
6377
|
+
const draggedLoc = findNode(model, draggedId);
|
|
6378
|
+
if (!draggedLoc) return null;
|
|
6379
|
+
if (parentId !== ROOT && draggedLoc.node.children.length > 0) return null;
|
|
6380
|
+
const taken = takeNode(model, draggedId);
|
|
6381
|
+
if (!taken) return null;
|
|
6382
|
+
let insertIndex = targetIndex;
|
|
6383
|
+
if (draggedLoc.parentId === parentId && draggedLoc.index < targetIndex) {
|
|
6384
|
+
insertIndex -= 1;
|
|
6385
|
+
}
|
|
6386
|
+
if (!insertInto(taken.forest, taken.taken, parentId, insertIndex)) return null;
|
|
6387
|
+
const next = normalize(taken.forest);
|
|
6388
|
+
if (forestsEqual(model, next)) return null;
|
|
6389
|
+
return next;
|
|
6390
|
+
}
|
|
6391
|
+
function forestsEqual(a, b) {
|
|
6392
|
+
if (a.length !== b.length) return false;
|
|
6393
|
+
for (let i = 0; i < a.length; i++) {
|
|
6394
|
+
const left = a[i];
|
|
6395
|
+
const right = b[i];
|
|
6396
|
+
if (left.id !== right.id) return false;
|
|
6397
|
+
if (!forestsEqual(left.children, right.children)) return false;
|
|
6398
|
+
}
|
|
6399
|
+
return true;
|
|
6400
|
+
}
|
|
6401
|
+
function forestFromFlatOrder(order) {
|
|
6402
|
+
return order.map((id) => ({ id, children: [] }));
|
|
6403
|
+
}
|
|
6404
|
+
function serializeNavOrder(nodes) {
|
|
6405
|
+
const hasNesting = nodes.some((n) => n.children.length > 0);
|
|
6406
|
+
if (!hasNesting) {
|
|
6407
|
+
return JSON.stringify(nodes.map((n) => n.id));
|
|
6408
|
+
}
|
|
6409
|
+
return JSON.stringify(nodes);
|
|
6410
|
+
}
|
|
6411
|
+
function parseNavOrderJson(raw) {
|
|
6412
|
+
if (!raw) return null;
|
|
6413
|
+
try {
|
|
6414
|
+
const parsed = JSON.parse(raw);
|
|
6415
|
+
if (!Array.isArray(parsed)) return null;
|
|
6416
|
+
if (parsed.every((x) => typeof x === "string")) {
|
|
6417
|
+
return forestFromFlatOrder(parsed.filter((x) => typeof x === "string" && x.length > 0));
|
|
6418
|
+
}
|
|
6419
|
+
return parseNavNodeList(parsed);
|
|
6420
|
+
} catch {
|
|
6421
|
+
return null;
|
|
6422
|
+
}
|
|
6423
|
+
}
|
|
6424
|
+
function parseNavNodeList(raw) {
|
|
6425
|
+
const out = [];
|
|
6426
|
+
for (const item of raw) {
|
|
6427
|
+
if (typeof item === "string" && item.length > 0) {
|
|
6428
|
+
out.push({ id: item, children: [] });
|
|
6429
|
+
continue;
|
|
6430
|
+
}
|
|
6431
|
+
if (!item || typeof item !== "object") return null;
|
|
6432
|
+
const rec = item;
|
|
6433
|
+
if (typeof rec.id !== "string" || !rec.id) return null;
|
|
6434
|
+
const children = Array.isArray(rec.children) ? parseNavNodeList(rec.children) : [];
|
|
6435
|
+
if (!children) return null;
|
|
6436
|
+
out.push({ id: rec.id, children });
|
|
6437
|
+
}
|
|
6438
|
+
return out;
|
|
6439
|
+
}
|
|
6440
|
+
function flattenNavOrder(nodes) {
|
|
6441
|
+
const out = [];
|
|
6442
|
+
const walk = (list) => {
|
|
6443
|
+
for (const n of list) {
|
|
6444
|
+
out.push(n.id);
|
|
6445
|
+
walk(n.children);
|
|
6446
|
+
}
|
|
6447
|
+
};
|
|
6448
|
+
walk(nodes);
|
|
6449
|
+
return out;
|
|
6450
|
+
}
|
|
6451
|
+
|
|
6261
6452
|
// src/lib/nav-items.ts
|
|
6262
6453
|
var NAV_COUNT_KEY = "__ohw_nav_count";
|
|
6263
6454
|
var NAV_ORDER_KEY = "__ohw_nav_order";
|
|
6455
|
+
var NAV_HREF_RE = /^nav-(\d+)-href$/;
|
|
6456
|
+
function isNavbarHrefKey(key) {
|
|
6457
|
+
if (!key) return false;
|
|
6458
|
+
if (key === "nav-book-href") return false;
|
|
6459
|
+
return NAV_HREF_RE.test(key);
|
|
6460
|
+
}
|
|
6264
6461
|
function getLinkHref(el) {
|
|
6265
6462
|
const key = el.getAttribute("data-ohw-href-key");
|
|
6266
6463
|
if (key) {
|
|
@@ -6297,7 +6494,7 @@ function listNavbarItems() {
|
|
|
6297
6494
|
}
|
|
6298
6495
|
function parseNavIndexFromKey(key) {
|
|
6299
6496
|
if (!key) return null;
|
|
6300
|
-
const match = key.match(
|
|
6497
|
+
const match = key.match(NAV_HREF_RE);
|
|
6301
6498
|
if (!match) return null;
|
|
6302
6499
|
return parseInt(match[1], 10);
|
|
6303
6500
|
}
|
|
@@ -6320,17 +6517,6 @@ function getNavbarExistingTargets() {
|
|
|
6320
6517
|
function getNavOrderFromDom() {
|
|
6321
6518
|
return listNavbarItems().map((el) => el.getAttribute("data-ohw-href-key")).filter((key) => Boolean(key));
|
|
6322
6519
|
}
|
|
6323
|
-
function parseNavOrder(content) {
|
|
6324
|
-
const raw = content[NAV_ORDER_KEY];
|
|
6325
|
-
if (!raw) return null;
|
|
6326
|
-
try {
|
|
6327
|
-
const parsed = JSON.parse(raw);
|
|
6328
|
-
if (!Array.isArray(parsed)) return null;
|
|
6329
|
-
return parsed.filter((key) => typeof key === "string" && key.length > 0);
|
|
6330
|
-
} catch {
|
|
6331
|
-
return null;
|
|
6332
|
-
}
|
|
6333
|
-
}
|
|
6334
6520
|
function findCounterpartByHrefKey(hrefKey, root) {
|
|
6335
6521
|
return root.querySelector(`[data-ohw-href-key="${CSS.escape(hrefKey)}"]`);
|
|
6336
6522
|
}
|
|
@@ -6394,6 +6580,13 @@ function insertNavbarItemDom(index, href, label, afterAnchor) {
|
|
|
6394
6580
|
}
|
|
6395
6581
|
return primary;
|
|
6396
6582
|
}
|
|
6583
|
+
function navOrderKeysEqual(a, b) {
|
|
6584
|
+
if (a.length !== b.length) return false;
|
|
6585
|
+
for (let i = 0; i < a.length; i++) {
|
|
6586
|
+
if (a[i] !== b[i]) return false;
|
|
6587
|
+
}
|
|
6588
|
+
return true;
|
|
6589
|
+
}
|
|
6397
6590
|
function getNavbarLinkKeysInContainer(container) {
|
|
6398
6591
|
return Array.from(container.querySelectorAll("[data-ohw-href-key]")).filter(isNavbarLinkItem).map((el) => el.getAttribute("data-ohw-href-key")).filter((key) => Boolean(key));
|
|
6399
6592
|
}
|
|
@@ -6402,6 +6595,8 @@ function applyNavOrderToContainer(container, order) {
|
|
|
6402
6595
|
const current = getNavbarLinkKeysInContainer(container);
|
|
6403
6596
|
const extras = current.filter((key) => !desired.includes(key));
|
|
6404
6597
|
const expected = [...desired.filter((key) => current.includes(key)), ...extras];
|
|
6598
|
+
const orderedEls = [];
|
|
6599
|
+
if (navOrderKeysEqual(current, expected)) return;
|
|
6405
6600
|
if (current.length === expected.length && current.every((key, i) => key === expected[i])) {
|
|
6406
6601
|
return;
|
|
6407
6602
|
}
|
|
@@ -6410,13 +6605,18 @@ function applyNavOrderToContainer(container, order) {
|
|
|
6410
6605
|
if (seen.has(hrefKey)) continue;
|
|
6411
6606
|
seen.add(hrefKey);
|
|
6412
6607
|
const el = findCounterpartByHrefKey(hrefKey, container);
|
|
6413
|
-
if (el)
|
|
6608
|
+
if (el && isNavbarLinkItem(el)) orderedEls.push(el);
|
|
6414
6609
|
}
|
|
6415
6610
|
for (const el of container.querySelectorAll("[data-ohw-href-key]")) {
|
|
6416
6611
|
if (!isNavbarLinkItem(el)) continue;
|
|
6417
6612
|
const key = el.getAttribute("data-ohw-href-key");
|
|
6418
6613
|
if (!key || seen.has(key)) continue;
|
|
6419
|
-
|
|
6614
|
+
orderedEls.push(el);
|
|
6615
|
+
}
|
|
6616
|
+
for (const el of orderedEls) {
|
|
6617
|
+
if (container.lastElementChild !== el) {
|
|
6618
|
+
container.appendChild(el);
|
|
6619
|
+
}
|
|
6420
6620
|
}
|
|
6421
6621
|
}
|
|
6422
6622
|
function applyNavOrder(order) {
|
|
@@ -6425,6 +6625,75 @@ function applyNavOrder(order) {
|
|
|
6425
6625
|
const drawer = getNavbarDrawerContainer();
|
|
6426
6626
|
if (drawer) applyNavOrderToContainer(drawer, order);
|
|
6427
6627
|
}
|
|
6628
|
+
function applyChildrenOrder(parentHrefKey, childKeys, root) {
|
|
6629
|
+
const parent = findCounterpartByHrefKey(parentHrefKey, root);
|
|
6630
|
+
if (!parent) return;
|
|
6631
|
+
const group = parent.closest("[data-ohw-nav-group]");
|
|
6632
|
+
const childrenRoot = group?.querySelector(":scope > [data-ohw-nav-children]");
|
|
6633
|
+
if (!childrenRoot) return;
|
|
6634
|
+
const current = Array.from(childrenRoot.querySelectorAll(":scope > [data-ohw-href-key]")).map((el) => el.getAttribute("data-ohw-href-key")).filter((key) => Boolean(key));
|
|
6635
|
+
if (navOrderKeysEqual(current, childKeys)) return;
|
|
6636
|
+
for (const key of childKeys) {
|
|
6637
|
+
const el = findCounterpartByHrefKey(key, root);
|
|
6638
|
+
if (!el) continue;
|
|
6639
|
+
if (childrenRoot.lastElementChild !== el) {
|
|
6640
|
+
childrenRoot.appendChild(el);
|
|
6641
|
+
}
|
|
6642
|
+
}
|
|
6643
|
+
}
|
|
6644
|
+
function applyNavForest(forest) {
|
|
6645
|
+
if (forestsEqual(forest, getNavForestFromDom())) return;
|
|
6646
|
+
const rootKeys = forest.map((n) => n.id);
|
|
6647
|
+
applyNavOrder(rootKeys);
|
|
6648
|
+
const desktop = getNavbarDesktopContainer();
|
|
6649
|
+
const drawer = getNavbarDrawerContainer();
|
|
6650
|
+
for (const node of forest) {
|
|
6651
|
+
if (node.children.length === 0) continue;
|
|
6652
|
+
const childKeys = node.children.map((c) => c.id);
|
|
6653
|
+
if (desktop) applyChildrenOrder(node.id, childKeys, desktop);
|
|
6654
|
+
if (drawer) applyChildrenOrder(node.id, childKeys, drawer);
|
|
6655
|
+
}
|
|
6656
|
+
}
|
|
6657
|
+
function getNavForestFromDom() {
|
|
6658
|
+
const items = listNavbarItems();
|
|
6659
|
+
const nestedChildKeys = /* @__PURE__ */ new Set();
|
|
6660
|
+
const roots = [];
|
|
6661
|
+
for (const item of items) {
|
|
6662
|
+
const key = item.getAttribute("data-ohw-href-key");
|
|
6663
|
+
if (!key || !isNavbarHrefKey(key)) continue;
|
|
6664
|
+
if (item.closest("[data-ohw-nav-children]")) continue;
|
|
6665
|
+
const group = item.closest("[data-ohw-nav-group]");
|
|
6666
|
+
const childrenRoot = group?.querySelector(":scope > [data-ohw-nav-children]");
|
|
6667
|
+
const children = [];
|
|
6668
|
+
if (childrenRoot) {
|
|
6669
|
+
for (const child of childrenRoot.querySelectorAll(":scope > [data-ohw-href-key]")) {
|
|
6670
|
+
if (!isNavbarLinkItem(child)) continue;
|
|
6671
|
+
const childKey = child.getAttribute("data-ohw-href-key");
|
|
6672
|
+
if (!childKey || !isNavbarHrefKey(childKey)) continue;
|
|
6673
|
+
nestedChildKeys.add(childKey);
|
|
6674
|
+
children.push({ id: childKey, children: [] });
|
|
6675
|
+
}
|
|
6676
|
+
}
|
|
6677
|
+
roots.push({ id: key, children });
|
|
6678
|
+
}
|
|
6679
|
+
if (roots.length === 0) {
|
|
6680
|
+
return forestFromFlatOrder(
|
|
6681
|
+
getNavOrderFromDom().filter((k) => isNavbarHrefKey(k) && !nestedChildKeys.has(k))
|
|
6682
|
+
);
|
|
6683
|
+
}
|
|
6684
|
+
return roots;
|
|
6685
|
+
}
|
|
6686
|
+
function planNavItemMove(hrefKey, parentId, insertIndex) {
|
|
6687
|
+
const model = getNavForestFromDom();
|
|
6688
|
+
const next = moveNode(model, hrefKey, { parentId, index: insertIndex });
|
|
6689
|
+
if (!next) return null;
|
|
6690
|
+
if (forestsEqual(model, next)) return null;
|
|
6691
|
+
return {
|
|
6692
|
+
forest: next,
|
|
6693
|
+
orderJson: serializeNavOrder(next),
|
|
6694
|
+
flatOrder: flattenNavOrder(next)
|
|
6695
|
+
};
|
|
6696
|
+
}
|
|
6428
6697
|
function collectNavbarIndicesFromContent(content) {
|
|
6429
6698
|
const indices = /* @__PURE__ */ new Set();
|
|
6430
6699
|
for (const key of Object.keys(content)) {
|
|
@@ -6452,8 +6721,10 @@ function reconcileNavbarItemsFromContent(content) {
|
|
|
6452
6721
|
if (!href && !label) continue;
|
|
6453
6722
|
insertNavbarItemDom(index, href ?? "/", label ?? "Untitled", null);
|
|
6454
6723
|
}
|
|
6455
|
-
const
|
|
6456
|
-
if (
|
|
6724
|
+
const orderForest = parseNavOrderJson(content[NAV_ORDER_KEY]);
|
|
6725
|
+
if (orderForest?.length) {
|
|
6726
|
+
applyNavForest(orderForest);
|
|
6727
|
+
}
|
|
6457
6728
|
}
|
|
6458
6729
|
function buildNavOrderAfterInsert(afterAnchor, newHrefKey) {
|
|
6459
6730
|
const order = getNavOrderFromDom();
|
|
@@ -6493,161 +6764,1051 @@ function insertNavbarItem(href, label, afterAnchor = null) {
|
|
|
6493
6764
|
};
|
|
6494
6765
|
}
|
|
6495
6766
|
|
|
6496
|
-
// src/
|
|
6497
|
-
|
|
6498
|
-
|
|
6499
|
-
function
|
|
6500
|
-
|
|
6501
|
-
|
|
6502
|
-
|
|
6503
|
-
|
|
6504
|
-
return /* @__PURE__ */ jsx21(
|
|
6505
|
-
"div",
|
|
6506
|
-
{
|
|
6507
|
-
"data-ohw-navbar-container-chrome": "",
|
|
6508
|
-
"data-ohw-bridge": "",
|
|
6509
|
-
className: "pointer-events-none fixed z-[2147483647]",
|
|
6510
|
-
style: {
|
|
6511
|
-
top: rect.top - chromeGap,
|
|
6512
|
-
left: rect.left - chromeGap,
|
|
6513
|
-
width: rect.width + chromeGap * 2,
|
|
6514
|
-
height: rect.height + chromeGap * 2
|
|
6515
|
-
},
|
|
6516
|
-
children: /* @__PURE__ */ jsx21(
|
|
6517
|
-
"button",
|
|
6518
|
-
{
|
|
6519
|
-
type: "button",
|
|
6520
|
-
"data-ohw-navbar-add-button": "",
|
|
6521
|
-
className: "pointer-events-auto absolute left-1/2 flex p-0.5 rounded-[10px] size-7 -translate-x-1/2 translate-y-1/2 items-center justify-center border border-border bg-background shadow-sm transition-colors hover:bg-muted/80",
|
|
6522
|
-
style: { top: "70%" },
|
|
6523
|
-
"aria-label": "Add item",
|
|
6524
|
-
onMouseDown: (e) => {
|
|
6525
|
-
e.preventDefault();
|
|
6526
|
-
e.stopPropagation();
|
|
6527
|
-
},
|
|
6528
|
-
onClick: (e) => {
|
|
6529
|
-
e.preventDefault();
|
|
6530
|
-
e.stopPropagation();
|
|
6531
|
-
onAdd();
|
|
6532
|
-
},
|
|
6533
|
-
children: /* @__PURE__ */ jsx21(Plus2, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
|
|
6534
|
-
}
|
|
6535
|
-
)
|
|
6536
|
-
}
|
|
6537
|
-
);
|
|
6767
|
+
// src/lib/footer-items.ts
|
|
6768
|
+
var FOOTER_ORDER_KEY = "__ohw_footer_order";
|
|
6769
|
+
var FOOTER_HREF_RE = /^footer-(\d+)-(\d+)-href$/;
|
|
6770
|
+
function parseFooterHrefKey(key) {
|
|
6771
|
+
if (!key) return null;
|
|
6772
|
+
const match = key.match(FOOTER_HREF_RE);
|
|
6773
|
+
if (!match) return null;
|
|
6774
|
+
return { col: parseInt(match[1], 10), item: parseInt(match[2], 10) };
|
|
6538
6775
|
}
|
|
6539
|
-
|
|
6540
|
-
|
|
6541
|
-
import { jsx as jsx22 } from "react/jsx-runtime";
|
|
6542
|
-
var badgeVariants = cva(
|
|
6543
|
-
"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",
|
|
6544
|
-
{
|
|
6545
|
-
variants: {
|
|
6546
|
-
variant: {
|
|
6547
|
-
default: "border-transparent bg-primary text-primary-foreground",
|
|
6548
|
-
secondary: "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
6549
|
-
destructive: "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",
|
|
6550
|
-
outline: "text-foreground"
|
|
6551
|
-
}
|
|
6552
|
-
},
|
|
6553
|
-
defaultVariants: {
|
|
6554
|
-
variant: "default"
|
|
6555
|
-
}
|
|
6556
|
-
}
|
|
6557
|
-
);
|
|
6558
|
-
function Badge({ className, variant, ...props }) {
|
|
6559
|
-
return /* @__PURE__ */ jsx22("div", { className: cn(badgeVariants({ variant }), className), ...props });
|
|
6776
|
+
function isFooterHrefKey(key) {
|
|
6777
|
+
return parseFooterHrefKey(key) !== null;
|
|
6560
6778
|
}
|
|
6561
|
-
|
|
6562
|
-
|
|
6563
|
-
import { Link as Link2 } from "lucide-react";
|
|
6564
|
-
import { Fragment as Fragment5, jsx as jsx23, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
6565
|
-
var PRIMARY2 = "#0885FE";
|
|
6566
|
-
var IMAGE_FADE_MS = 300;
|
|
6567
|
-
function runOpacityFade(el, onDone) {
|
|
6568
|
-
const anim = el.animate([{ opacity: 0 }, { opacity: 1 }], {
|
|
6569
|
-
duration: IMAGE_FADE_MS,
|
|
6570
|
-
easing: "ease",
|
|
6571
|
-
fill: "forwards"
|
|
6572
|
-
});
|
|
6573
|
-
let finished = false;
|
|
6574
|
-
const finish = () => {
|
|
6575
|
-
if (finished) return;
|
|
6576
|
-
finished = true;
|
|
6577
|
-
anim.cancel();
|
|
6578
|
-
el.style.opacity = "";
|
|
6579
|
-
onDone();
|
|
6580
|
-
};
|
|
6581
|
-
anim.finished.then(finish).catch(finish);
|
|
6582
|
-
window.setTimeout(finish, IMAGE_FADE_MS + 100);
|
|
6779
|
+
function getFooterRoot() {
|
|
6780
|
+
return document.querySelector('footer[data-ohw-section="footer"], footer');
|
|
6583
6781
|
}
|
|
6584
|
-
function
|
|
6585
|
-
|
|
6586
|
-
|
|
6587
|
-
|
|
6588
|
-
|
|
6782
|
+
function getFooterLinksContainer() {
|
|
6783
|
+
return document.querySelector("[data-ohw-footer-links]") ?? document.querySelector(".rb-footer-links");
|
|
6784
|
+
}
|
|
6785
|
+
function isFooterLinkAnchor(el) {
|
|
6786
|
+
if (!el.matches("[data-ohw-href-key]")) return false;
|
|
6787
|
+
if (!isFooterHrefKey(el.getAttribute("data-ohw-href-key"))) return false;
|
|
6788
|
+
return Boolean(el.querySelector('[data-ohw-editable="text"]'));
|
|
6789
|
+
}
|
|
6790
|
+
function listFooterColumns() {
|
|
6791
|
+
const root = getFooterLinksContainer() ?? getFooterRoot()?.querySelector(".rb-footer-links") ?? null;
|
|
6792
|
+
if (!root) return [];
|
|
6793
|
+
const explicit = Array.from(root.querySelectorAll(":scope > [data-ohw-footer-col]"));
|
|
6794
|
+
if (explicit.length > 0) return explicit;
|
|
6795
|
+
return Array.from(root.children).filter((el) => {
|
|
6796
|
+
if (!(el instanceof HTMLElement)) return false;
|
|
6797
|
+
return Array.from(el.querySelectorAll(":scope > [data-ohw-href-key]")).some(
|
|
6798
|
+
isFooterLinkAnchor
|
|
6799
|
+
);
|
|
6589
6800
|
});
|
|
6590
6801
|
}
|
|
6591
|
-
function
|
|
6592
|
-
|
|
6593
|
-
|
|
6594
|
-
|
|
6802
|
+
function listFooterLinksInColumn(column) {
|
|
6803
|
+
return Array.from(column.querySelectorAll(":scope > [data-ohw-href-key]")).filter(
|
|
6804
|
+
isFooterLinkAnchor
|
|
6805
|
+
);
|
|
6595
6806
|
}
|
|
6596
|
-
function
|
|
6597
|
-
const
|
|
6598
|
-
|
|
6599
|
-
|
|
6600
|
-
|
|
6601
|
-
|
|
6602
|
-
|
|
6603
|
-
|
|
6604
|
-
|
|
6605
|
-
|
|
6606
|
-
|
|
6607
|
-
|
|
6608
|
-
|
|
6609
|
-
|
|
6610
|
-
|
|
6611
|
-
|
|
6612
|
-
|
|
6613
|
-
|
|
6614
|
-
|
|
6615
|
-
|
|
6616
|
-
layer.remove();
|
|
6617
|
-
if (!prevPos || prevPos === "static") el.style.position = prevPos;
|
|
6807
|
+
function findFooterColumnForLink(anchor) {
|
|
6808
|
+
const columns = listFooterColumns();
|
|
6809
|
+
return columns.find((col) => col.contains(anchor)) ?? null;
|
|
6810
|
+
}
|
|
6811
|
+
function getFooterOrderFromDom() {
|
|
6812
|
+
return listFooterColumns().map(
|
|
6813
|
+
(col) => listFooterLinksInColumn(col).map((el) => el.getAttribute("data-ohw-href-key")).filter((key) => Boolean(key))
|
|
6814
|
+
);
|
|
6815
|
+
}
|
|
6816
|
+
function findFooterLinkByKey(hrefKey) {
|
|
6817
|
+
return document.querySelector(
|
|
6818
|
+
`footer [data-ohw-href-key="${CSS.escape(hrefKey)}"]`
|
|
6819
|
+
);
|
|
6820
|
+
}
|
|
6821
|
+
function syncFooterColumnIndices(columns) {
|
|
6822
|
+
columns.forEach((col, index) => {
|
|
6823
|
+
const next = String(index);
|
|
6824
|
+
if (col.getAttribute("data-ohw-footer-col") !== next) {
|
|
6825
|
+
col.setAttribute("data-ohw-footer-col", next);
|
|
6826
|
+
}
|
|
6618
6827
|
});
|
|
6619
6828
|
}
|
|
6620
|
-
function
|
|
6621
|
-
|
|
6622
|
-
|
|
6623
|
-
el = document.createElement("div");
|
|
6624
|
-
el.setAttribute("data-ohw-sections-tracker", "");
|
|
6625
|
-
el.style.display = "none";
|
|
6626
|
-
document.body.appendChild(el);
|
|
6829
|
+
function appendChildIfNeeded(parent, child) {
|
|
6830
|
+
if (parent.lastElementChild !== child) {
|
|
6831
|
+
parent.appendChild(child);
|
|
6627
6832
|
}
|
|
6628
|
-
return el;
|
|
6629
6833
|
}
|
|
6630
|
-
function
|
|
6631
|
-
const
|
|
6632
|
-
|
|
6633
|
-
|
|
6634
|
-
|
|
6635
|
-
|
|
6834
|
+
function applyFooterOrder(order) {
|
|
6835
|
+
const container = getFooterLinksContainer();
|
|
6836
|
+
if (!container) return;
|
|
6837
|
+
const columns = listFooterColumns();
|
|
6838
|
+
if (columns.length === 0) return;
|
|
6839
|
+
const currentOrder = getFooterOrderFromDom();
|
|
6840
|
+
if (ordersEqual(order, currentOrder)) {
|
|
6841
|
+
syncFooterColumnIndices(columns);
|
|
6842
|
+
return;
|
|
6843
|
+
}
|
|
6844
|
+
const used = /* @__PURE__ */ new Set();
|
|
6845
|
+
const orderedCols = [];
|
|
6846
|
+
for (const colOrder of order) {
|
|
6847
|
+
let matched = null;
|
|
6848
|
+
for (const hrefKey of colOrder) {
|
|
6849
|
+
const link = findFooterLinkByKey(hrefKey);
|
|
6850
|
+
if (!link) continue;
|
|
6851
|
+
const owner = findFooterColumnForLink(link);
|
|
6852
|
+
if (owner && !used.has(owner)) {
|
|
6853
|
+
matched = owner;
|
|
6854
|
+
break;
|
|
6855
|
+
}
|
|
6856
|
+
}
|
|
6857
|
+
if (!matched) {
|
|
6858
|
+
matched = columns.find((col) => !used.has(col)) ?? null;
|
|
6859
|
+
}
|
|
6860
|
+
if (matched) {
|
|
6861
|
+
used.add(matched);
|
|
6862
|
+
orderedCols.push(matched);
|
|
6863
|
+
}
|
|
6864
|
+
}
|
|
6865
|
+
for (const col of columns) {
|
|
6866
|
+
if (!used.has(col)) orderedCols.push(col);
|
|
6867
|
+
}
|
|
6868
|
+
for (const col of orderedCols) {
|
|
6869
|
+
appendChildIfNeeded(container, col);
|
|
6870
|
+
}
|
|
6871
|
+
const freshColumns = listFooterColumns();
|
|
6872
|
+
syncFooterColumnIndices(freshColumns);
|
|
6873
|
+
for (let c = 0; c < order.length; c++) {
|
|
6874
|
+
const col = freshColumns[c];
|
|
6875
|
+
if (!col) continue;
|
|
6876
|
+
const colOrder = order[c];
|
|
6877
|
+
for (const hrefKey of colOrder) {
|
|
6878
|
+
const el = findFooterLinkByKey(hrefKey);
|
|
6879
|
+
if (!el) continue;
|
|
6880
|
+
if (el.parentElement !== col || col.lastElementChild !== el) {
|
|
6881
|
+
col.appendChild(el);
|
|
6882
|
+
}
|
|
6883
|
+
}
|
|
6636
6884
|
}
|
|
6637
|
-
const currentPath = window.location.pathname;
|
|
6638
|
-
const updated = sections.map((s) => {
|
|
6639
|
-
if (s.type !== "scheduling" || s.insertAfter !== insertAfter) return s;
|
|
6640
|
-
if (s.pagePath && s.pagePath !== currentPath) return s;
|
|
6641
|
-
return { ...s, scheduleId };
|
|
6642
|
-
});
|
|
6643
|
-
tracker.textContent = JSON.stringify(updated);
|
|
6644
|
-
return tracker.textContent ?? "[]";
|
|
6645
6885
|
}
|
|
6646
|
-
function
|
|
6647
|
-
return
|
|
6886
|
+
function ordersEqual(a, b) {
|
|
6887
|
+
if (a.length !== b.length) return false;
|
|
6888
|
+
for (let i = 0; i < a.length; i++) {
|
|
6889
|
+
const left = a[i];
|
|
6890
|
+
const right = b[i];
|
|
6891
|
+
if (left.length !== right.length) return false;
|
|
6892
|
+
for (let j = 0; j < left.length; j++) {
|
|
6893
|
+
if (left[j] !== right[j]) return false;
|
|
6894
|
+
}
|
|
6895
|
+
}
|
|
6896
|
+
return true;
|
|
6648
6897
|
}
|
|
6649
|
-
|
|
6650
|
-
|
|
6898
|
+
function planFooterLinkMove(hrefKey, targetColIndex, insertIndex) {
|
|
6899
|
+
const order = getFooterOrderFromDom();
|
|
6900
|
+
if (targetColIndex < 0 || targetColIndex >= order.length) return null;
|
|
6901
|
+
let fromCol = -1;
|
|
6902
|
+
let fromIdx = -1;
|
|
6903
|
+
for (let c = 0; c < order.length; c++) {
|
|
6904
|
+
const idx = order[c].indexOf(hrefKey);
|
|
6905
|
+
if (idx >= 0) {
|
|
6906
|
+
fromCol = c;
|
|
6907
|
+
fromIdx = idx;
|
|
6908
|
+
break;
|
|
6909
|
+
}
|
|
6910
|
+
}
|
|
6911
|
+
if (fromCol < 0) return null;
|
|
6912
|
+
const next = order.map((col) => [...col]);
|
|
6913
|
+
next[fromCol].splice(fromIdx, 1);
|
|
6914
|
+
let adjusted = insertIndex;
|
|
6915
|
+
if (fromCol === targetColIndex && fromIdx < insertIndex) adjusted -= 1;
|
|
6916
|
+
adjusted = Math.max(0, Math.min(adjusted, next[targetColIndex].length));
|
|
6917
|
+
next[targetColIndex].splice(adjusted, 0, hrefKey);
|
|
6918
|
+
if (ordersEqual(next, order)) return null;
|
|
6919
|
+
return next;
|
|
6920
|
+
}
|
|
6921
|
+
function planFooterColumnMove(fromIndex, toIndex) {
|
|
6922
|
+
const order = getFooterOrderFromDom();
|
|
6923
|
+
const columns = listFooterColumns();
|
|
6924
|
+
if (fromIndex < 0 || fromIndex >= columns.length || toIndex < 0 || toIndex > columns.length) {
|
|
6925
|
+
return null;
|
|
6926
|
+
}
|
|
6927
|
+
if (toIndex === fromIndex || toIndex === fromIndex + 1) return null;
|
|
6928
|
+
const nextOrder = order.map((col) => [...col]);
|
|
6929
|
+
const [movedOrder] = nextOrder.splice(fromIndex, 1);
|
|
6930
|
+
if (!movedOrder) return null;
|
|
6931
|
+
let adjusted = toIndex;
|
|
6932
|
+
if (fromIndex < toIndex) adjusted -= 1;
|
|
6933
|
+
adjusted = Math.max(0, Math.min(adjusted, nextOrder.length));
|
|
6934
|
+
nextOrder.splice(adjusted, 0, movedOrder);
|
|
6935
|
+
if (ordersEqual(nextOrder, order)) return null;
|
|
6936
|
+
return nextOrder;
|
|
6937
|
+
}
|
|
6938
|
+
function parseFooterOrder(content) {
|
|
6939
|
+
const raw = content[FOOTER_ORDER_KEY];
|
|
6940
|
+
if (!raw) return null;
|
|
6941
|
+
try {
|
|
6942
|
+
const parsed = JSON.parse(raw);
|
|
6943
|
+
if (!Array.isArray(parsed)) return null;
|
|
6944
|
+
return parsed.filter((col) => Array.isArray(col)).map((col) => col.filter((key) => typeof key === "string" && key.length > 0));
|
|
6945
|
+
} catch {
|
|
6946
|
+
return null;
|
|
6947
|
+
}
|
|
6948
|
+
}
|
|
6949
|
+
function reconcileFooterOrderFromContent(content) {
|
|
6950
|
+
const order = parseFooterOrder(content);
|
|
6951
|
+
if (!order?.length) return;
|
|
6952
|
+
const current = getFooterOrderFromDom();
|
|
6953
|
+
if (ordersEqual(order, current)) {
|
|
6954
|
+
syncFooterColumnIndices(listFooterColumns());
|
|
6955
|
+
return;
|
|
6956
|
+
}
|
|
6957
|
+
applyFooterOrder(order);
|
|
6958
|
+
}
|
|
6959
|
+
function buildLinkDropSlots(column, columnIndex) {
|
|
6960
|
+
const links = listFooterLinksInColumn(column);
|
|
6961
|
+
const colRect = column.getBoundingClientRect();
|
|
6962
|
+
const slots = [];
|
|
6963
|
+
const barThickness = 3;
|
|
6964
|
+
if (links.length === 0) {
|
|
6965
|
+
slots.push({
|
|
6966
|
+
insertIndex: 0,
|
|
6967
|
+
columnIndex,
|
|
6968
|
+
left: colRect.left,
|
|
6969
|
+
top: colRect.top + colRect.height / 2 - barThickness / 2,
|
|
6970
|
+
width: colRect.width,
|
|
6971
|
+
height: barThickness,
|
|
6972
|
+
direction: "horizontal"
|
|
6973
|
+
});
|
|
6974
|
+
return slots;
|
|
6975
|
+
}
|
|
6976
|
+
for (let i = 0; i <= links.length; i++) {
|
|
6977
|
+
let top;
|
|
6978
|
+
if (i === 0) {
|
|
6979
|
+
top = links[0].getBoundingClientRect().top - barThickness / 2;
|
|
6980
|
+
} else if (i === links.length) {
|
|
6981
|
+
const last = links[links.length - 1].getBoundingClientRect();
|
|
6982
|
+
top = last.bottom - barThickness / 2;
|
|
6983
|
+
} else {
|
|
6984
|
+
const prev = links[i - 1].getBoundingClientRect();
|
|
6985
|
+
const next = links[i].getBoundingClientRect();
|
|
6986
|
+
top = (prev.bottom + next.top) / 2 - barThickness / 2;
|
|
6987
|
+
}
|
|
6988
|
+
const widthRef = i === 0 ? links[0].getBoundingClientRect() : i === links.length ? links[links.length - 1].getBoundingClientRect() : links[i].getBoundingClientRect();
|
|
6989
|
+
slots.push({
|
|
6990
|
+
insertIndex: i,
|
|
6991
|
+
columnIndex,
|
|
6992
|
+
left: widthRef.left,
|
|
6993
|
+
top,
|
|
6994
|
+
width: Math.max(widthRef.width, colRect.width * 0.8),
|
|
6995
|
+
height: barThickness,
|
|
6996
|
+
direction: "horizontal"
|
|
6997
|
+
});
|
|
6998
|
+
}
|
|
6999
|
+
return slots;
|
|
7000
|
+
}
|
|
7001
|
+
function buildColumnDropSlots() {
|
|
7002
|
+
const columns = listFooterColumns();
|
|
7003
|
+
const slots = [];
|
|
7004
|
+
const barThickness = 3;
|
|
7005
|
+
if (columns.length === 0) return slots;
|
|
7006
|
+
for (let i = 0; i <= columns.length; i++) {
|
|
7007
|
+
let left;
|
|
7008
|
+
let height;
|
|
7009
|
+
let top;
|
|
7010
|
+
if (i === 0) {
|
|
7011
|
+
const first = columns[0].getBoundingClientRect();
|
|
7012
|
+
left = first.left - barThickness / 2;
|
|
7013
|
+
top = first.top;
|
|
7014
|
+
height = first.height;
|
|
7015
|
+
} else if (i === columns.length) {
|
|
7016
|
+
const last = columns[columns.length - 1].getBoundingClientRect();
|
|
7017
|
+
left = last.right - barThickness / 2;
|
|
7018
|
+
top = last.top;
|
|
7019
|
+
height = last.height;
|
|
7020
|
+
} else {
|
|
7021
|
+
const prev = columns[i - 1].getBoundingClientRect();
|
|
7022
|
+
const next = columns[i].getBoundingClientRect();
|
|
7023
|
+
left = (prev.right + next.left) / 2 - barThickness / 2;
|
|
7024
|
+
top = Math.min(prev.top, next.top);
|
|
7025
|
+
height = Math.max(prev.bottom, next.bottom) - top;
|
|
7026
|
+
}
|
|
7027
|
+
slots.push({
|
|
7028
|
+
insertIndex: i,
|
|
7029
|
+
columnIndex: i,
|
|
7030
|
+
left,
|
|
7031
|
+
top,
|
|
7032
|
+
width: barThickness,
|
|
7033
|
+
height: Math.max(height, 24),
|
|
7034
|
+
direction: "vertical"
|
|
7035
|
+
});
|
|
7036
|
+
}
|
|
7037
|
+
return slots;
|
|
7038
|
+
}
|
|
7039
|
+
function hitTestLinkDropSlot(clientX, clientY, draggedHrefKey) {
|
|
7040
|
+
const columns = listFooterColumns();
|
|
7041
|
+
let best = null;
|
|
7042
|
+
for (let c = 0; c < columns.length; c++) {
|
|
7043
|
+
const col = columns[c];
|
|
7044
|
+
const colRect = col.getBoundingClientRect();
|
|
7045
|
+
const inColX = clientX >= colRect.left - 24 && clientX <= colRect.right + 24;
|
|
7046
|
+
if (!inColX) continue;
|
|
7047
|
+
const slots = buildLinkDropSlots(col, c).filter((slot) => {
|
|
7048
|
+
const links = listFooterLinksInColumn(col);
|
|
7049
|
+
const fromIdx = links.findIndex(
|
|
7050
|
+
(el) => el.getAttribute("data-ohw-href-key") === draggedHrefKey
|
|
7051
|
+
);
|
|
7052
|
+
if (fromIdx < 0) return true;
|
|
7053
|
+
if (c === findColumnIndexForKey(draggedHrefKey) && (slot.insertIndex === fromIdx || slot.insertIndex === fromIdx + 1)) {
|
|
7054
|
+
return true;
|
|
7055
|
+
}
|
|
7056
|
+
return true;
|
|
7057
|
+
});
|
|
7058
|
+
for (const slot of slots) {
|
|
7059
|
+
const cy = slot.top + slot.height / 2;
|
|
7060
|
+
const dist = Math.abs(clientY - cy) + (inColX ? 0 : 1e3);
|
|
7061
|
+
if (!best || dist < best.dist) best = { slot, dist };
|
|
7062
|
+
}
|
|
7063
|
+
}
|
|
7064
|
+
return best?.slot ?? null;
|
|
7065
|
+
}
|
|
7066
|
+
function findColumnIndexForKey(hrefKey) {
|
|
7067
|
+
const order = getFooterOrderFromDom();
|
|
7068
|
+
for (let c = 0; c < order.length; c++) {
|
|
7069
|
+
if (order[c].includes(hrefKey)) return c;
|
|
7070
|
+
}
|
|
7071
|
+
return -1;
|
|
7072
|
+
}
|
|
7073
|
+
function hitTestColumnDropSlot(clientX, _clientY) {
|
|
7074
|
+
const slots = buildColumnDropSlots();
|
|
7075
|
+
let best = null;
|
|
7076
|
+
for (const slot of slots) {
|
|
7077
|
+
const cx2 = slot.left + slot.width / 2;
|
|
7078
|
+
const dist = Math.abs(clientX - cx2);
|
|
7079
|
+
if (!best || dist < best.dist) best = { slot, dist };
|
|
7080
|
+
}
|
|
7081
|
+
return best?.slot ?? null;
|
|
7082
|
+
}
|
|
7083
|
+
|
|
7084
|
+
// src/lib/item-drag-interaction.ts
|
|
7085
|
+
function disableNativeHrefDrag(el) {
|
|
7086
|
+
if (el.draggable) el.draggable = false;
|
|
7087
|
+
if (el.getAttribute("draggable") !== "false") {
|
|
7088
|
+
el.setAttribute("draggable", "false");
|
|
7089
|
+
}
|
|
7090
|
+
}
|
|
7091
|
+
function clearTextSelection() {
|
|
7092
|
+
const sel = window.getSelection();
|
|
7093
|
+
if (sel && !sel.isCollapsed) sel.removeAllRanges();
|
|
7094
|
+
}
|
|
7095
|
+
function armItemPressDrag() {
|
|
7096
|
+
document.documentElement.setAttribute("data-ohw-footer-press-drag", "");
|
|
7097
|
+
}
|
|
7098
|
+
function lockItemDuringDrag() {
|
|
7099
|
+
document.documentElement.removeAttribute("data-ohw-footer-press-drag");
|
|
7100
|
+
document.documentElement.setAttribute("data-ohw-item-dragging", "");
|
|
7101
|
+
clearTextSelection();
|
|
7102
|
+
}
|
|
7103
|
+
function unlockItemDragInteraction() {
|
|
7104
|
+
document.documentElement.removeAttribute("data-ohw-footer-press-drag");
|
|
7105
|
+
document.documentElement.removeAttribute("data-ohw-item-dragging");
|
|
7106
|
+
clearTextSelection();
|
|
7107
|
+
}
|
|
7108
|
+
var armFooterPressDrag = armItemPressDrag;
|
|
7109
|
+
var lockFooterDuringDrag = lockItemDuringDrag;
|
|
7110
|
+
var unlockFooterDragInteraction = unlockItemDragInteraction;
|
|
7111
|
+
|
|
7112
|
+
// src/lib/nav-dnd.ts
|
|
7113
|
+
function listReorderableNavItems() {
|
|
7114
|
+
return listNavbarItems().filter((el) => {
|
|
7115
|
+
const key = el.getAttribute("data-ohw-href-key");
|
|
7116
|
+
return isNavbarHrefKey(key) && !el.closest("[data-ohw-nav-children]");
|
|
7117
|
+
});
|
|
7118
|
+
}
|
|
7119
|
+
function listNavChildren(parentHrefKey) {
|
|
7120
|
+
const items = listNavbarItems();
|
|
7121
|
+
const parent = items.find((el) => el.getAttribute("data-ohw-href-key") === parentHrefKey);
|
|
7122
|
+
if (!parent) return [];
|
|
7123
|
+
const group = parent.closest("[data-ohw-nav-group]");
|
|
7124
|
+
const childrenRoot = group?.querySelector(":scope > [data-ohw-nav-children]");
|
|
7125
|
+
if (!childrenRoot) return [];
|
|
7126
|
+
return Array.from(childrenRoot.querySelectorAll(":scope > [data-ohw-href-key]")).filter(
|
|
7127
|
+
(el) => isNavbarHrefKey(el.getAttribute("data-ohw-href-key"))
|
|
7128
|
+
);
|
|
7129
|
+
}
|
|
7130
|
+
function activeNavListContainer() {
|
|
7131
|
+
const desktop = getNavbarDesktopContainer();
|
|
7132
|
+
if (desktop && desktop.getClientRects().length > 0) {
|
|
7133
|
+
const style = window.getComputedStyle(desktop);
|
|
7134
|
+
if (style.display !== "none" && style.visibility !== "hidden") return desktop;
|
|
7135
|
+
}
|
|
7136
|
+
return getNavbarDrawerContainer();
|
|
7137
|
+
}
|
|
7138
|
+
function buildRootNavDropSlots() {
|
|
7139
|
+
const items = listReorderableNavItems();
|
|
7140
|
+
const slots = [];
|
|
7141
|
+
const barThickness = 3;
|
|
7142
|
+
if (items.length === 0) {
|
|
7143
|
+
const container = activeNavListContainer();
|
|
7144
|
+
if (!container) return slots;
|
|
7145
|
+
const rect = container.getBoundingClientRect();
|
|
7146
|
+
slots.push({
|
|
7147
|
+
insertIndex: 0,
|
|
7148
|
+
parentId: null,
|
|
7149
|
+
left: rect.left + rect.width / 2 - barThickness / 2,
|
|
7150
|
+
top: rect.top,
|
|
7151
|
+
width: barThickness,
|
|
7152
|
+
height: Math.max(rect.height, 24),
|
|
7153
|
+
direction: "vertical"
|
|
7154
|
+
});
|
|
7155
|
+
return slots;
|
|
7156
|
+
}
|
|
7157
|
+
const edgeGap = (() => {
|
|
7158
|
+
if (items.length < 2) return 32;
|
|
7159
|
+
const a = items[0].getBoundingClientRect();
|
|
7160
|
+
const b = items[1].getBoundingClientRect();
|
|
7161
|
+
return Math.max(0, b.left - a.right);
|
|
7162
|
+
})();
|
|
7163
|
+
for (let i = 0; i <= items.length; i++) {
|
|
7164
|
+
let left;
|
|
7165
|
+
let top;
|
|
7166
|
+
let height;
|
|
7167
|
+
if (i === 0) {
|
|
7168
|
+
const first = items[0].getBoundingClientRect();
|
|
7169
|
+
left = first.left - edgeGap / 2 - barThickness / 2;
|
|
7170
|
+
top = first.top;
|
|
7171
|
+
height = first.height;
|
|
7172
|
+
} else if (i === items.length) {
|
|
7173
|
+
const last = items[items.length - 1].getBoundingClientRect();
|
|
7174
|
+
const lastGap = items.length >= 2 ? Math.max(
|
|
7175
|
+
0,
|
|
7176
|
+
last.left - items[items.length - 2].getBoundingClientRect().right
|
|
7177
|
+
) : edgeGap;
|
|
7178
|
+
left = last.right + lastGap / 2 - barThickness / 2;
|
|
7179
|
+
top = last.top;
|
|
7180
|
+
height = last.height;
|
|
7181
|
+
} else {
|
|
7182
|
+
const prev = items[i - 1].getBoundingClientRect();
|
|
7183
|
+
const next = items[i].getBoundingClientRect();
|
|
7184
|
+
left = (prev.right + next.left) / 2 - barThickness / 2;
|
|
7185
|
+
top = Math.min(prev.top, next.top);
|
|
7186
|
+
height = Math.max(prev.bottom, next.bottom) - top;
|
|
7187
|
+
}
|
|
7188
|
+
slots.push({
|
|
7189
|
+
insertIndex: i,
|
|
7190
|
+
parentId: null,
|
|
7191
|
+
left,
|
|
7192
|
+
top,
|
|
7193
|
+
width: barThickness,
|
|
7194
|
+
height: Math.max(height, 24),
|
|
7195
|
+
direction: "vertical"
|
|
7196
|
+
});
|
|
7197
|
+
}
|
|
7198
|
+
return slots;
|
|
7199
|
+
}
|
|
7200
|
+
function buildChildNavDropSlots(parentHrefKey) {
|
|
7201
|
+
const children = listNavChildren(parentHrefKey);
|
|
7202
|
+
const slots = [];
|
|
7203
|
+
const barThickness = 3;
|
|
7204
|
+
if (children.length === 0) return slots;
|
|
7205
|
+
const edgeGap = (() => {
|
|
7206
|
+
if (children.length < 2) return 16;
|
|
7207
|
+
const a = children[0].getBoundingClientRect();
|
|
7208
|
+
const b = children[1].getBoundingClientRect();
|
|
7209
|
+
return Math.max(0, b.top - a.bottom);
|
|
7210
|
+
})();
|
|
7211
|
+
for (let i = 0; i <= children.length; i++) {
|
|
7212
|
+
let top;
|
|
7213
|
+
let width;
|
|
7214
|
+
let left;
|
|
7215
|
+
if (i === 0) {
|
|
7216
|
+
const first = children[0].getBoundingClientRect();
|
|
7217
|
+
top = first.top - edgeGap / 2 - barThickness / 2;
|
|
7218
|
+
left = first.left;
|
|
7219
|
+
width = first.width;
|
|
7220
|
+
} else if (i === children.length) {
|
|
7221
|
+
const last = children[children.length - 1].getBoundingClientRect();
|
|
7222
|
+
const lastGap = children.length >= 2 ? Math.max(
|
|
7223
|
+
0,
|
|
7224
|
+
last.top - children[children.length - 2].getBoundingClientRect().bottom
|
|
7225
|
+
) : edgeGap;
|
|
7226
|
+
top = last.bottom + lastGap / 2 - barThickness / 2;
|
|
7227
|
+
left = last.left;
|
|
7228
|
+
width = last.width;
|
|
7229
|
+
} else {
|
|
7230
|
+
const prev = children[i - 1].getBoundingClientRect();
|
|
7231
|
+
const next = children[i].getBoundingClientRect();
|
|
7232
|
+
top = (prev.bottom + next.top) / 2 - barThickness / 2;
|
|
7233
|
+
left = Math.min(prev.left, next.left);
|
|
7234
|
+
width = Math.max(prev.right, next.right) - left;
|
|
7235
|
+
}
|
|
7236
|
+
slots.push({
|
|
7237
|
+
insertIndex: i,
|
|
7238
|
+
parentId: parentHrefKey,
|
|
7239
|
+
left,
|
|
7240
|
+
top,
|
|
7241
|
+
width: Math.max(width, 40),
|
|
7242
|
+
height: barThickness,
|
|
7243
|
+
direction: "horizontal"
|
|
7244
|
+
});
|
|
7245
|
+
}
|
|
7246
|
+
return slots;
|
|
7247
|
+
}
|
|
7248
|
+
function buildAllNavDropSlots(draggedHrefKey) {
|
|
7249
|
+
const slots = [...buildRootNavDropSlots()];
|
|
7250
|
+
for (const item of listReorderableNavItems()) {
|
|
7251
|
+
const key = item.getAttribute("data-ohw-href-key");
|
|
7252
|
+
if (!key || key === draggedHrefKey) continue;
|
|
7253
|
+
const group = item.closest("[data-ohw-nav-group]");
|
|
7254
|
+
if (!group?.querySelector(":scope > [data-ohw-nav-children]")) continue;
|
|
7255
|
+
slots.push(...buildChildNavDropSlots(key));
|
|
7256
|
+
}
|
|
7257
|
+
const dragged = listNavbarItems().find((el) => el.getAttribute("data-ohw-href-key") === draggedHrefKey);
|
|
7258
|
+
const parentGroup = dragged?.closest("[data-ohw-nav-children]")?.closest("[data-ohw-nav-group]");
|
|
7259
|
+
const parentTrigger = parentGroup?.querySelector(":scope > [data-ohw-href-key]");
|
|
7260
|
+
const parentKey = parentTrigger?.getAttribute("data-ohw-href-key");
|
|
7261
|
+
if (parentKey && isNavbarHrefKey(parentKey)) {
|
|
7262
|
+
const existing = slots.some((s) => s.parentId === parentKey);
|
|
7263
|
+
if (!existing) slots.push(...buildChildNavDropSlots(parentKey));
|
|
7264
|
+
}
|
|
7265
|
+
return slots;
|
|
7266
|
+
}
|
|
7267
|
+
function hitTestNavDropSlot(clientX, clientY, draggedHrefKey) {
|
|
7268
|
+
const slots = buildAllNavDropSlots(draggedHrefKey);
|
|
7269
|
+
let best = null;
|
|
7270
|
+
for (const slot of slots) {
|
|
7271
|
+
const cx2 = slot.left + slot.width / 2;
|
|
7272
|
+
const cy = slot.top + slot.height / 2;
|
|
7273
|
+
const dist = slot.direction === "vertical" ? Math.abs(clientX - cx2) + Math.abs(clientY - cy) * 0.25 : Math.abs(clientY - cy) + Math.abs(clientX - cx2) * 0.25;
|
|
7274
|
+
if (!best || dist < best.dist) best = { slot, dist };
|
|
7275
|
+
}
|
|
7276
|
+
return best?.slot ?? null;
|
|
7277
|
+
}
|
|
7278
|
+
|
|
7279
|
+
// src/useNavItemDrag.ts
|
|
7280
|
+
import { useCallback as useCallback3, useEffect as useEffect7, useRef as useRef6, useState as useState6 } from "react";
|
|
7281
|
+
function useNavItemDrag({
|
|
7282
|
+
isEditMode,
|
|
7283
|
+
editContentRef,
|
|
7284
|
+
selectedElRef,
|
|
7285
|
+
activeElRef,
|
|
7286
|
+
footerDragRef,
|
|
7287
|
+
suppressNextClickRef,
|
|
7288
|
+
suppressClickUntilRef,
|
|
7289
|
+
siblingHintElRef,
|
|
7290
|
+
postToParentRef,
|
|
7291
|
+
deselectRef,
|
|
7292
|
+
selectRef,
|
|
7293
|
+
deactivateRef,
|
|
7294
|
+
setLinkPopover,
|
|
7295
|
+
linkPopoverOpenRef,
|
|
7296
|
+
setIsItemDragging,
|
|
7297
|
+
setDraggedItemRect,
|
|
7298
|
+
setSiblingHintRect,
|
|
7299
|
+
setSiblingHintRects,
|
|
7300
|
+
setToolbarRect,
|
|
7301
|
+
getNavigationItemAnchor: getNavigationItemAnchor2,
|
|
7302
|
+
isDragHandleDisabled: isDragHandleDisabled2,
|
|
7303
|
+
isNavbarButton: isNavbarButton3
|
|
7304
|
+
}) {
|
|
7305
|
+
const navDragRef = useRef6(null);
|
|
7306
|
+
const [navDropSlots, setNavDropSlots] = useState6([]);
|
|
7307
|
+
const [activeNavDropIndex, setActiveNavDropIndex] = useState6(null);
|
|
7308
|
+
const navPointerDragRef = useRef6(null);
|
|
7309
|
+
const clearNavDragVisuals = useCallback3(() => {
|
|
7310
|
+
navDragRef.current = null;
|
|
7311
|
+
setNavDropSlots([]);
|
|
7312
|
+
setActiveNavDropIndex(null);
|
|
7313
|
+
setDraggedItemRect(null);
|
|
7314
|
+
setSiblingHintRects([]);
|
|
7315
|
+
setIsItemDragging(false);
|
|
7316
|
+
unlockItemDragInteraction();
|
|
7317
|
+
}, [setDraggedItemRect, setIsItemDragging, setSiblingHintRects]);
|
|
7318
|
+
const refreshNavDragVisuals = useCallback3(
|
|
7319
|
+
(session, activeSlot, clientX, clientY) => {
|
|
7320
|
+
setDraggedItemRect(session.draggedEl.getBoundingClientRect());
|
|
7321
|
+
if (typeof clientX === "number" && typeof clientY === "number") {
|
|
7322
|
+
session.lastClientX = clientX;
|
|
7323
|
+
session.lastClientY = clientY;
|
|
7324
|
+
}
|
|
7325
|
+
session.activeSlot = activeSlot;
|
|
7326
|
+
setSiblingHintRects([]);
|
|
7327
|
+
const slots = buildAllNavDropSlots(session.hrefKey);
|
|
7328
|
+
setNavDropSlots(slots);
|
|
7329
|
+
const activeIdx = activeSlot ? slots.findIndex(
|
|
7330
|
+
(s) => s.parentId === activeSlot.parentId && s.insertIndex === activeSlot.insertIndex
|
|
7331
|
+
) : -1;
|
|
7332
|
+
setActiveNavDropIndex(activeIdx >= 0 ? activeIdx : null);
|
|
7333
|
+
},
|
|
7334
|
+
[setDraggedItemRect, setSiblingHintRects]
|
|
7335
|
+
);
|
|
7336
|
+
const refreshNavDragVisualsRef = useRef6(refreshNavDragVisuals);
|
|
7337
|
+
refreshNavDragVisualsRef.current = refreshNavDragVisuals;
|
|
7338
|
+
const commitNavDragRef = useRef6(() => {
|
|
7339
|
+
});
|
|
7340
|
+
const beginNavDragRef = useRef6(() => {
|
|
7341
|
+
});
|
|
7342
|
+
const beginNavDrag = useCallback3(
|
|
7343
|
+
(session) => {
|
|
7344
|
+
const rect = session.draggedEl.getBoundingClientRect();
|
|
7345
|
+
session.lastClientX = session.lastClientX || rect.left + rect.width / 2;
|
|
7346
|
+
session.lastClientY = session.lastClientY || rect.top + rect.height / 2;
|
|
7347
|
+
session.activeSlot = session.activeSlot ?? null;
|
|
7348
|
+
navDragRef.current = session;
|
|
7349
|
+
setIsItemDragging(true);
|
|
7350
|
+
lockItemDuringDrag();
|
|
7351
|
+
siblingHintElRef.current = null;
|
|
7352
|
+
setSiblingHintRect(null);
|
|
7353
|
+
if (session.wasSelected && selectedElRef.current === session.draggedEl) {
|
|
7354
|
+
setToolbarRect(rect);
|
|
7355
|
+
}
|
|
7356
|
+
const initialSlot = hitTestNavDropSlot(session.lastClientX, session.lastClientY, session.hrefKey);
|
|
7357
|
+
refreshNavDragVisuals(session, initialSlot, session.lastClientX, session.lastClientY);
|
|
7358
|
+
},
|
|
7359
|
+
[
|
|
7360
|
+
refreshNavDragVisuals,
|
|
7361
|
+
selectedElRef,
|
|
7362
|
+
setIsItemDragging,
|
|
7363
|
+
setSiblingHintRect,
|
|
7364
|
+
setToolbarRect,
|
|
7365
|
+
siblingHintElRef
|
|
7366
|
+
]
|
|
7367
|
+
);
|
|
7368
|
+
beginNavDragRef.current = beginNavDrag;
|
|
7369
|
+
const commitNavDrag = useCallback3(
|
|
7370
|
+
(clientX, clientY) => {
|
|
7371
|
+
const session = navDragRef.current;
|
|
7372
|
+
if (!session) {
|
|
7373
|
+
clearNavDragVisuals();
|
|
7374
|
+
return;
|
|
7375
|
+
}
|
|
7376
|
+
const x = typeof clientX === "number" && (clientX !== 0 || clientY !== 0) ? clientX : session.lastClientX;
|
|
7377
|
+
const y = typeof clientY === "number" && (clientX !== 0 || clientY !== 0) ? clientY : session.lastClientY;
|
|
7378
|
+
const slot = session.activeSlot ?? hitTestNavDropSlot(x, y, session.hrefKey);
|
|
7379
|
+
const planned = slot != null ? planNavItemMove(session.hrefKey, slot.parentId, slot.insertIndex) : null;
|
|
7380
|
+
const wasSelected = session.wasSelected;
|
|
7381
|
+
const hrefKey = session.hrefKey;
|
|
7382
|
+
const applySelectionAfterDrop = () => {
|
|
7383
|
+
if (!wasSelected) {
|
|
7384
|
+
deselectRef.current();
|
|
7385
|
+
return;
|
|
7386
|
+
}
|
|
7387
|
+
const desktop = document.querySelector("[data-ohw-nav-container]");
|
|
7388
|
+
const drawer = document.querySelector("[data-ohw-nav-drawer]");
|
|
7389
|
+
const link = desktop?.querySelector(`[data-ohw-href-key="${CSS.escape(hrefKey)}"]`) ?? drawer?.querySelector(`[data-ohw-href-key="${CSS.escape(hrefKey)}"]`) ?? document.querySelector(`[data-ohw-href-key="${CSS.escape(hrefKey)}"]`);
|
|
7390
|
+
if (link) {
|
|
7391
|
+
selectRef.current(link);
|
|
7392
|
+
return;
|
|
7393
|
+
}
|
|
7394
|
+
deselectRef.current();
|
|
7395
|
+
};
|
|
7396
|
+
if (planned) {
|
|
7397
|
+
editContentRef.current = {
|
|
7398
|
+
...editContentRef.current,
|
|
7399
|
+
[NAV_ORDER_KEY]: planned.orderJson
|
|
7400
|
+
};
|
|
7401
|
+
applyNavForest(planned.forest);
|
|
7402
|
+
document.querySelectorAll(
|
|
7403
|
+
"nav [data-ohw-href-key], [data-ohw-nav-container] [data-ohw-href-key], [data-ohw-nav-drawer] [data-ohw-href-key]"
|
|
7404
|
+
).forEach((el) => {
|
|
7405
|
+
if (isNavbarHrefKey(el.getAttribute("data-ohw-href-key"))) {
|
|
7406
|
+
disableNativeHrefDrag(el);
|
|
7407
|
+
}
|
|
7408
|
+
});
|
|
7409
|
+
postToParentRef.current({
|
|
7410
|
+
type: "ow:change",
|
|
7411
|
+
nodes: [{ key: NAV_ORDER_KEY, text: planned.orderJson }]
|
|
7412
|
+
});
|
|
7413
|
+
applySelectionAfterDrop();
|
|
7414
|
+
clearNavDragVisuals();
|
|
7415
|
+
requestAnimationFrame(() => {
|
|
7416
|
+
if (editContentRef.current[NAV_ORDER_KEY] === planned.orderJson) {
|
|
7417
|
+
applyNavForest(planned.forest);
|
|
7418
|
+
}
|
|
7419
|
+
applySelectionAfterDrop();
|
|
7420
|
+
requestAnimationFrame(applySelectionAfterDrop);
|
|
7421
|
+
});
|
|
7422
|
+
return;
|
|
7423
|
+
}
|
|
7424
|
+
applySelectionAfterDrop();
|
|
7425
|
+
clearNavDragVisuals();
|
|
7426
|
+
},
|
|
7427
|
+
[clearNavDragVisuals, deselectRef, editContentRef, postToParentRef, selectRef]
|
|
7428
|
+
);
|
|
7429
|
+
commitNavDragRef.current = commitNavDrag;
|
|
7430
|
+
const startNavLinkDrag = useCallback3(
|
|
7431
|
+
(anchor, clientX, clientY, wasSelected) => {
|
|
7432
|
+
if (footerDragRef.current) return false;
|
|
7433
|
+
const hrefKey = anchor.getAttribute("data-ohw-href-key");
|
|
7434
|
+
if (!hrefKey || !isNavbarHrefKey(hrefKey)) return false;
|
|
7435
|
+
if (isNavbarButton3(anchor) || isDragHandleDisabled2(anchor)) return false;
|
|
7436
|
+
beginNavDrag({
|
|
7437
|
+
hrefKey,
|
|
7438
|
+
wasSelected,
|
|
7439
|
+
draggedEl: anchor,
|
|
7440
|
+
lastClientX: clientX,
|
|
7441
|
+
lastClientY: clientY,
|
|
7442
|
+
activeSlot: null
|
|
7443
|
+
});
|
|
7444
|
+
return true;
|
|
7445
|
+
},
|
|
7446
|
+
[beginNavDrag, footerDragRef, isDragHandleDisabled2, isNavbarButton3]
|
|
7447
|
+
);
|
|
7448
|
+
const onNavDragOver = useCallback3(
|
|
7449
|
+
(e) => {
|
|
7450
|
+
const session = navDragRef.current;
|
|
7451
|
+
if (!session) return false;
|
|
7452
|
+
e.preventDefault();
|
|
7453
|
+
if (e.dataTransfer) e.dataTransfer.dropEffect = "move";
|
|
7454
|
+
const slot = hitTestNavDropSlot(e.clientX, e.clientY, session.hrefKey);
|
|
7455
|
+
refreshNavDragVisualsRef.current(session, slot, e.clientX, e.clientY);
|
|
7456
|
+
return true;
|
|
7457
|
+
},
|
|
7458
|
+
[]
|
|
7459
|
+
);
|
|
7460
|
+
useEffect7(() => {
|
|
7461
|
+
if (!isEditMode) return;
|
|
7462
|
+
const THRESHOLD = 10;
|
|
7463
|
+
const resolveWasSelected = (el) => {
|
|
7464
|
+
if (selectedElRef.current === el) return true;
|
|
7465
|
+
const activeAnchor = activeElRef.current ? getNavigationItemAnchor2(activeElRef.current) : null;
|
|
7466
|
+
return activeAnchor === el;
|
|
7467
|
+
};
|
|
7468
|
+
const onPointerDown = (e) => {
|
|
7469
|
+
if (e.button !== 0) return;
|
|
7470
|
+
if (navDragRef.current || footerDragRef.current) return;
|
|
7471
|
+
const target = e.target;
|
|
7472
|
+
if (!target) return;
|
|
7473
|
+
if (target.closest(
|
|
7474
|
+
'[data-ohw-drag-handle-container], [data-slot="drag-handle"], [data-ohw-toolbar], [data-ohw-item-toolbar-anchor], [data-ohw-link-popover-root]'
|
|
7475
|
+
)) {
|
|
7476
|
+
return;
|
|
7477
|
+
}
|
|
7478
|
+
if (target.closest("[data-ohw-item-drag-surface]")) return;
|
|
7479
|
+
const anchor = getNavigationItemAnchor2(target);
|
|
7480
|
+
const hrefKey = anchor?.getAttribute("data-ohw-href-key") ?? null;
|
|
7481
|
+
if (!anchor || !isNavbarHrefKey(hrefKey)) return;
|
|
7482
|
+
if (isNavbarButton3(anchor) || isDragHandleDisabled2(anchor)) return;
|
|
7483
|
+
armItemPressDrag();
|
|
7484
|
+
navPointerDragRef.current = {
|
|
7485
|
+
el: anchor,
|
|
7486
|
+
startX: e.clientX,
|
|
7487
|
+
startY: e.clientY,
|
|
7488
|
+
pointerId: e.pointerId,
|
|
7489
|
+
wasSelected: resolveWasSelected(anchor),
|
|
7490
|
+
started: false
|
|
7491
|
+
};
|
|
7492
|
+
};
|
|
7493
|
+
const onPointerMove = (e) => {
|
|
7494
|
+
const pending = navPointerDragRef.current;
|
|
7495
|
+
if (!pending) return;
|
|
7496
|
+
if (pending.started) {
|
|
7497
|
+
e.preventDefault();
|
|
7498
|
+
clearTextSelection();
|
|
7499
|
+
const session = navDragRef.current;
|
|
7500
|
+
if (!session) return;
|
|
7501
|
+
const slot = hitTestNavDropSlot(e.clientX, e.clientY, session.hrefKey);
|
|
7502
|
+
refreshNavDragVisualsRef.current(session, slot, e.clientX, e.clientY);
|
|
7503
|
+
return;
|
|
7504
|
+
}
|
|
7505
|
+
const dx = e.clientX - pending.startX;
|
|
7506
|
+
const dy = e.clientY - pending.startY;
|
|
7507
|
+
if (dx * dx + dy * dy < THRESHOLD * THRESHOLD) return;
|
|
7508
|
+
e.preventDefault();
|
|
7509
|
+
pending.started = true;
|
|
7510
|
+
clearTextSelection();
|
|
7511
|
+
try {
|
|
7512
|
+
document.body.setPointerCapture(pending.pointerId);
|
|
7513
|
+
} catch {
|
|
7514
|
+
}
|
|
7515
|
+
if (linkPopoverOpenRef.current) setLinkPopover(null);
|
|
7516
|
+
if (activeElRef.current) deactivateRef.current();
|
|
7517
|
+
const key = pending.el.getAttribute("data-ohw-href-key");
|
|
7518
|
+
if (!key) return;
|
|
7519
|
+
beginNavDragRef.current({
|
|
7520
|
+
hrefKey: key,
|
|
7521
|
+
wasSelected: pending.wasSelected,
|
|
7522
|
+
draggedEl: pending.el,
|
|
7523
|
+
lastClientX: e.clientX,
|
|
7524
|
+
lastClientY: e.clientY,
|
|
7525
|
+
activeSlot: null
|
|
7526
|
+
});
|
|
7527
|
+
};
|
|
7528
|
+
const endPointerDrag = (e) => {
|
|
7529
|
+
const pending = navPointerDragRef.current;
|
|
7530
|
+
navPointerDragRef.current = null;
|
|
7531
|
+
try {
|
|
7532
|
+
if (document.body.hasPointerCapture(e.pointerId)) {
|
|
7533
|
+
document.body.releasePointerCapture(e.pointerId);
|
|
7534
|
+
}
|
|
7535
|
+
} catch {
|
|
7536
|
+
}
|
|
7537
|
+
if (!pending?.started) {
|
|
7538
|
+
unlockItemDragInteraction();
|
|
7539
|
+
return;
|
|
7540
|
+
}
|
|
7541
|
+
suppressNextClickRef.current = true;
|
|
7542
|
+
suppressClickUntilRef.current = Date.now() + 500;
|
|
7543
|
+
commitNavDragRef.current(e.clientX, e.clientY);
|
|
7544
|
+
};
|
|
7545
|
+
const blockSelectStart = (e) => {
|
|
7546
|
+
if (navDragRef.current || navPointerDragRef.current?.started || document.documentElement.hasAttribute("data-ohw-footer-press-drag")) {
|
|
7547
|
+
e.preventDefault();
|
|
7548
|
+
}
|
|
7549
|
+
};
|
|
7550
|
+
const onDragEnd = () => {
|
|
7551
|
+
if (!navDragRef.current) return;
|
|
7552
|
+
suppressNextClickRef.current = true;
|
|
7553
|
+
suppressClickUntilRef.current = Date.now() + 500;
|
|
7554
|
+
commitNavDragRef.current();
|
|
7555
|
+
};
|
|
7556
|
+
document.addEventListener("pointerdown", onPointerDown, true);
|
|
7557
|
+
document.addEventListener("pointermove", onPointerMove, true);
|
|
7558
|
+
document.addEventListener("pointerup", endPointerDrag, true);
|
|
7559
|
+
document.addEventListener("pointercancel", endPointerDrag, true);
|
|
7560
|
+
document.addEventListener("selectstart", blockSelectStart, true);
|
|
7561
|
+
document.addEventListener("dragend", onDragEnd, true);
|
|
7562
|
+
return () => {
|
|
7563
|
+
document.removeEventListener("pointerdown", onPointerDown, true);
|
|
7564
|
+
document.removeEventListener("pointermove", onPointerMove, true);
|
|
7565
|
+
document.removeEventListener("pointerup", endPointerDrag, true);
|
|
7566
|
+
document.removeEventListener("pointercancel", endPointerDrag, true);
|
|
7567
|
+
document.removeEventListener("selectstart", blockSelectStart, true);
|
|
7568
|
+
document.removeEventListener("dragend", onDragEnd, true);
|
|
7569
|
+
unlockItemDragInteraction();
|
|
7570
|
+
};
|
|
7571
|
+
}, [
|
|
7572
|
+
activeElRef,
|
|
7573
|
+
deactivateRef,
|
|
7574
|
+
footerDragRef,
|
|
7575
|
+
getNavigationItemAnchor2,
|
|
7576
|
+
isDragHandleDisabled2,
|
|
7577
|
+
isEditMode,
|
|
7578
|
+
isNavbarButton3,
|
|
7579
|
+
linkPopoverOpenRef,
|
|
7580
|
+
selectedElRef,
|
|
7581
|
+
setLinkPopover,
|
|
7582
|
+
suppressNextClickRef
|
|
7583
|
+
]);
|
|
7584
|
+
const armNavPressFromChrome = useCallback3(
|
|
7585
|
+
(selected, clientX, clientY, pointerId) => {
|
|
7586
|
+
const hrefKey = selected.getAttribute("data-ohw-href-key");
|
|
7587
|
+
if (!hrefKey || !isNavbarHrefKey(hrefKey)) return false;
|
|
7588
|
+
if (isNavbarButton3(selected) || isDragHandleDisabled2(selected)) return false;
|
|
7589
|
+
armItemPressDrag();
|
|
7590
|
+
navPointerDragRef.current = {
|
|
7591
|
+
el: selected,
|
|
7592
|
+
startX: clientX,
|
|
7593
|
+
startY: clientY,
|
|
7594
|
+
pointerId,
|
|
7595
|
+
wasSelected: true,
|
|
7596
|
+
started: false
|
|
7597
|
+
};
|
|
7598
|
+
return true;
|
|
7599
|
+
},
|
|
7600
|
+
[isDragHandleDisabled2, isNavbarButton3]
|
|
7601
|
+
);
|
|
7602
|
+
return {
|
|
7603
|
+
navDragRef,
|
|
7604
|
+
navDropSlots,
|
|
7605
|
+
activeNavDropIndex,
|
|
7606
|
+
startNavLinkDrag,
|
|
7607
|
+
commitNavDrag,
|
|
7608
|
+
onNavDragOver,
|
|
7609
|
+
armNavPressFromChrome,
|
|
7610
|
+
clearNavDragVisuals,
|
|
7611
|
+
refreshNavDragVisualsRef
|
|
7612
|
+
};
|
|
7613
|
+
}
|
|
7614
|
+
|
|
7615
|
+
// src/ui/navbar-container-chrome.tsx
|
|
7616
|
+
import { Plus as Plus2 } from "lucide-react";
|
|
7617
|
+
import { jsx as jsx21 } from "react/jsx-runtime";
|
|
7618
|
+
function NavbarContainerChrome({
|
|
7619
|
+
rect,
|
|
7620
|
+
onAdd
|
|
7621
|
+
}) {
|
|
7622
|
+
const chromeGap = 6;
|
|
7623
|
+
return /* @__PURE__ */ jsx21(
|
|
7624
|
+
"div",
|
|
7625
|
+
{
|
|
7626
|
+
"data-ohw-navbar-container-chrome": "",
|
|
7627
|
+
"data-ohw-bridge": "",
|
|
7628
|
+
className: "pointer-events-none fixed z-[2147483647]",
|
|
7629
|
+
style: {
|
|
7630
|
+
top: rect.top - chromeGap,
|
|
7631
|
+
left: rect.left - chromeGap,
|
|
7632
|
+
width: rect.width + chromeGap * 2,
|
|
7633
|
+
height: rect.height + chromeGap * 2
|
|
7634
|
+
},
|
|
7635
|
+
children: /* @__PURE__ */ jsx21(
|
|
7636
|
+
"button",
|
|
7637
|
+
{
|
|
7638
|
+
type: "button",
|
|
7639
|
+
"data-ohw-navbar-add-button": "",
|
|
7640
|
+
className: "pointer-events-auto absolute left-1/2 flex p-0.5 rounded-[10px] size-7 -translate-x-1/2 translate-y-1/2 items-center justify-center border border-border bg-background shadow-sm transition-colors hover:bg-muted/80",
|
|
7641
|
+
style: { top: "70%" },
|
|
7642
|
+
"aria-label": "Add item",
|
|
7643
|
+
onMouseDown: (e) => {
|
|
7644
|
+
e.preventDefault();
|
|
7645
|
+
e.stopPropagation();
|
|
7646
|
+
},
|
|
7647
|
+
onClick: (e) => {
|
|
7648
|
+
e.preventDefault();
|
|
7649
|
+
e.stopPropagation();
|
|
7650
|
+
onAdd();
|
|
7651
|
+
},
|
|
7652
|
+
children: /* @__PURE__ */ jsx21(Plus2, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
|
|
7653
|
+
}
|
|
7654
|
+
)
|
|
7655
|
+
}
|
|
7656
|
+
);
|
|
7657
|
+
}
|
|
7658
|
+
|
|
7659
|
+
// src/ui/drop-indicator.tsx
|
|
7660
|
+
import * as React10 from "react";
|
|
7661
|
+
import { jsx as jsx22 } from "react/jsx-runtime";
|
|
7662
|
+
var dropIndicatorVariants = cva(
|
|
7663
|
+
"ov-gap-line pointer-events-none shrink-0 transition-opacity duration-150",
|
|
7664
|
+
{
|
|
7665
|
+
variants: {
|
|
7666
|
+
direction: {
|
|
7667
|
+
vertical: "h-6 w-[3px]",
|
|
7668
|
+
horizontal: "h-[3px] w-[200px]"
|
|
7669
|
+
},
|
|
7670
|
+
state: {
|
|
7671
|
+
default: "opacity-0",
|
|
7672
|
+
hover: "opacity-100",
|
|
7673
|
+
dragIdle: "opacity-40",
|
|
7674
|
+
dragActive: "opacity-100"
|
|
7675
|
+
}
|
|
7676
|
+
},
|
|
7677
|
+
defaultVariants: {
|
|
7678
|
+
direction: "vertical",
|
|
7679
|
+
state: "default"
|
|
7680
|
+
}
|
|
7681
|
+
}
|
|
7682
|
+
);
|
|
7683
|
+
var DropIndicator = React10.forwardRef(
|
|
7684
|
+
({ className, direction, state, ...props }, ref) => {
|
|
7685
|
+
return /* @__PURE__ */ jsx22(
|
|
7686
|
+
"div",
|
|
7687
|
+
{
|
|
7688
|
+
ref,
|
|
7689
|
+
"data-slot": "drop-indicator",
|
|
7690
|
+
"data-direction": direction ?? "vertical",
|
|
7691
|
+
"data-state": state ?? "default",
|
|
7692
|
+
"aria-hidden": "true",
|
|
7693
|
+
className: cn(dropIndicatorVariants({ direction, state }), className),
|
|
7694
|
+
...props
|
|
7695
|
+
}
|
|
7696
|
+
);
|
|
7697
|
+
}
|
|
7698
|
+
);
|
|
7699
|
+
DropIndicator.displayName = "DropIndicator";
|
|
7700
|
+
|
|
7701
|
+
// src/ui/badge.tsx
|
|
7702
|
+
import { jsx as jsx23 } from "react/jsx-runtime";
|
|
7703
|
+
var badgeVariants = cva(
|
|
7704
|
+
"inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
|
|
7705
|
+
{
|
|
7706
|
+
variants: {
|
|
7707
|
+
variant: {
|
|
7708
|
+
default: "border-transparent bg-primary text-primary-foreground",
|
|
7709
|
+
secondary: "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
7710
|
+
destructive: "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",
|
|
7711
|
+
outline: "text-foreground"
|
|
7712
|
+
}
|
|
7713
|
+
},
|
|
7714
|
+
defaultVariants: {
|
|
7715
|
+
variant: "default"
|
|
7716
|
+
}
|
|
7717
|
+
}
|
|
7718
|
+
);
|
|
7719
|
+
function Badge({ className, variant, ...props }) {
|
|
7720
|
+
return /* @__PURE__ */ jsx23("div", { className: cn(badgeVariants({ variant }), className), ...props });
|
|
7721
|
+
}
|
|
7722
|
+
|
|
7723
|
+
// src/OhhwellsBridge.tsx
|
|
7724
|
+
import { Link as Link2 } from "lucide-react";
|
|
7725
|
+
import { Fragment as Fragment5, jsx as jsx24, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
7726
|
+
var PRIMARY2 = "#0885FE";
|
|
7727
|
+
var IMAGE_FADE_MS = 300;
|
|
7728
|
+
function runOpacityFade(el, onDone) {
|
|
7729
|
+
const anim = el.animate([{ opacity: 0 }, { opacity: 1 }], {
|
|
7730
|
+
duration: IMAGE_FADE_MS,
|
|
7731
|
+
easing: "ease",
|
|
7732
|
+
fill: "forwards"
|
|
7733
|
+
});
|
|
7734
|
+
let finished = false;
|
|
7735
|
+
const finish = () => {
|
|
7736
|
+
if (finished) return;
|
|
7737
|
+
finished = true;
|
|
7738
|
+
anim.cancel();
|
|
7739
|
+
el.style.opacity = "";
|
|
7740
|
+
onDone();
|
|
7741
|
+
};
|
|
7742
|
+
anim.finished.then(finish).catch(finish);
|
|
7743
|
+
window.setTimeout(finish, IMAGE_FADE_MS + 100);
|
|
7744
|
+
}
|
|
7745
|
+
function fadeInImageElement(img, onReady) {
|
|
7746
|
+
onReady();
|
|
7747
|
+
img.style.opacity = "0";
|
|
7748
|
+
runOpacityFade(img, () => {
|
|
7749
|
+
img.style.opacity = "";
|
|
7750
|
+
});
|
|
7751
|
+
}
|
|
7752
|
+
function applyEditableImageSrc(img, url) {
|
|
7753
|
+
img.removeAttribute("srcset");
|
|
7754
|
+
img.removeAttribute("sizes");
|
|
7755
|
+
img.src = url;
|
|
7756
|
+
}
|
|
7757
|
+
function fadeInBgImage(el, url, onReady) {
|
|
7758
|
+
const prevPos = el.style.position;
|
|
7759
|
+
if (!prevPos || prevPos === "static") el.style.position = "relative";
|
|
7760
|
+
const layer = document.createElement("div");
|
|
7761
|
+
layer.setAttribute("data-ohw-bg-fade-layer", "");
|
|
7762
|
+
Object.assign(layer.style, {
|
|
7763
|
+
position: "absolute",
|
|
7764
|
+
inset: "0",
|
|
7765
|
+
zIndex: "0",
|
|
7766
|
+
backgroundImage: `url('${url}')`,
|
|
7767
|
+
backgroundSize: "cover",
|
|
7768
|
+
backgroundPosition: "center",
|
|
7769
|
+
backgroundRepeat: "no-repeat",
|
|
7770
|
+
opacity: "0",
|
|
7771
|
+
pointerEvents: "none"
|
|
7772
|
+
});
|
|
7773
|
+
el.prepend(layer);
|
|
7774
|
+
onReady();
|
|
7775
|
+
runOpacityFade(layer, () => {
|
|
7776
|
+
el.style.backgroundImage = `url('${url}')`;
|
|
7777
|
+
layer.remove();
|
|
7778
|
+
if (!prevPos || prevPos === "static") el.style.position = prevPos;
|
|
7779
|
+
});
|
|
7780
|
+
}
|
|
7781
|
+
function getSectionsTracker() {
|
|
7782
|
+
let el = document.querySelector("[data-ohw-sections-tracker]");
|
|
7783
|
+
if (!el) {
|
|
7784
|
+
el = document.createElement("div");
|
|
7785
|
+
el.setAttribute("data-ohw-sections-tracker", "");
|
|
7786
|
+
el.style.display = "none";
|
|
7787
|
+
document.body.appendChild(el);
|
|
7788
|
+
}
|
|
7789
|
+
return el;
|
|
7790
|
+
}
|
|
7791
|
+
function updateSectionScheduleId(insertAfter, scheduleId) {
|
|
7792
|
+
const tracker = getSectionsTracker();
|
|
7793
|
+
let sections = [];
|
|
7794
|
+
try {
|
|
7795
|
+
sections = JSON.parse(tracker.textContent || "[]");
|
|
7796
|
+
} catch {
|
|
7797
|
+
}
|
|
7798
|
+
const currentPath = window.location.pathname;
|
|
7799
|
+
const updated = sections.map((s) => {
|
|
7800
|
+
if (s.type !== "scheduling" || s.insertAfter !== insertAfter) return s;
|
|
7801
|
+
if (s.pagePath && s.pagePath !== currentPath) return s;
|
|
7802
|
+
return { ...s, scheduleId };
|
|
7803
|
+
});
|
|
7804
|
+
tracker.textContent = JSON.stringify(updated);
|
|
7805
|
+
return tracker.textContent ?? "[]";
|
|
7806
|
+
}
|
|
7807
|
+
function schedulingSectionId(insertAfter) {
|
|
7808
|
+
return `scheduling-${insertAfter}`;
|
|
7809
|
+
}
|
|
7810
|
+
var INSERT_BEFORE_MARKER = ":before:";
|
|
7811
|
+
function parseSchedulingInsertAfter(insertAfter) {
|
|
6651
7812
|
const idx = insertAfter.indexOf(INSERT_BEFORE_MARKER);
|
|
6652
7813
|
if (idx < 0) return { anchor: insertAfter, insertBefore: null };
|
|
6653
7814
|
return {
|
|
@@ -6740,7 +7901,7 @@ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId,
|
|
|
6740
7901
|
const root = createRoot(container);
|
|
6741
7902
|
flushSync(() => {
|
|
6742
7903
|
root.render(
|
|
6743
|
-
/* @__PURE__ */
|
|
7904
|
+
/* @__PURE__ */ jsx24(
|
|
6744
7905
|
SchedulingWidget,
|
|
6745
7906
|
{
|
|
6746
7907
|
notifyOnConnect,
|
|
@@ -6815,7 +7976,7 @@ function syncNavigationDragCursorAttrs() {
|
|
|
6815
7976
|
el.setAttribute("data-ohw-can-drag", "");
|
|
6816
7977
|
});
|
|
6817
7978
|
}
|
|
6818
|
-
function collectEditableNodes() {
|
|
7979
|
+
function collectEditableNodes(extraContent) {
|
|
6819
7980
|
const nodes = Array.from(document.querySelectorAll("[data-ohw-editable]")).map((el) => {
|
|
6820
7981
|
if (el.dataset.ohwEditable === "image") {
|
|
6821
7982
|
const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
|
|
@@ -6843,6 +8004,14 @@ function collectEditableNodes() {
|
|
|
6843
8004
|
if (!key) return;
|
|
6844
8005
|
nodes.push({ key, type: "link", text: getLinkHref2(el) });
|
|
6845
8006
|
});
|
|
8007
|
+
if (extraContent) {
|
|
8008
|
+
for (const key of [NAV_ORDER_KEY, FOOTER_ORDER_KEY, NAV_COUNT_KEY]) {
|
|
8009
|
+
const text = extraContent[key];
|
|
8010
|
+
if (typeof text === "string" && text.length > 0) {
|
|
8011
|
+
nodes.push({ key, type: "meta", text });
|
|
8012
|
+
}
|
|
8013
|
+
}
|
|
8014
|
+
}
|
|
6846
8015
|
document.querySelectorAll('[data-ohw-editable="video"]').forEach((el) => {
|
|
6847
8016
|
const key = el.dataset.ohwKey ?? "";
|
|
6848
8017
|
const video = getVideoEl(el);
|
|
@@ -6956,6 +8125,11 @@ function getNavigationItemAnchor(el) {
|
|
|
6956
8125
|
function isNavigationItem(el) {
|
|
6957
8126
|
return getNavigationItemAnchor(el) !== null;
|
|
6958
8127
|
}
|
|
8128
|
+
function listNavigationItems() {
|
|
8129
|
+
return Array.from(
|
|
8130
|
+
document.querySelectorAll("nav [data-ohw-href-key], footer [data-ohw-href-key]")
|
|
8131
|
+
).filter((el) => isNavigationItem(el));
|
|
8132
|
+
}
|
|
6959
8133
|
function getNavigationItemReorderState(anchor) {
|
|
6960
8134
|
if (isNavbarButton2(anchor)) return { key: null, disabled: false };
|
|
6961
8135
|
return getReorderHandleStateFromAnchor(anchor);
|
|
@@ -6988,7 +8162,7 @@ function countFooterNavItems(el) {
|
|
|
6988
8162
|
return Array.from(el.querySelectorAll("[data-ohw-href-key]")).filter(isNavigationItem).length;
|
|
6989
8163
|
}
|
|
6990
8164
|
function findFooterItemGroup(item) {
|
|
6991
|
-
const explicit = item.closest("[data-ohw-footer-column]");
|
|
8165
|
+
const explicit = item.closest("[data-ohw-footer-col], [data-ohw-footer-column]");
|
|
6992
8166
|
if (explicit) return explicit;
|
|
6993
8167
|
const footer = item.closest("footer");
|
|
6994
8168
|
if (!footer) return null;
|
|
@@ -7005,17 +8179,17 @@ function isNavigationRoot(el) {
|
|
|
7005
8179
|
function isInferredFooterGroup(el) {
|
|
7006
8180
|
const footer = el.closest("footer");
|
|
7007
8181
|
if (!footer || el === footer) return false;
|
|
7008
|
-
if (el.hasAttribute("data-ohw-footer-column")) return true;
|
|
8182
|
+
if (el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column")) return true;
|
|
7009
8183
|
return countFooterNavItems(el) >= 2;
|
|
7010
8184
|
}
|
|
7011
8185
|
function isNavigationContainer(el) {
|
|
7012
|
-
return el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-footer-column") || isNavigationRoot(el) || isInferredFooterGroup(el);
|
|
8186
|
+
return el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isNavigationRoot(el) || isInferredFooterGroup(el);
|
|
7013
8187
|
}
|
|
7014
8188
|
function isNavbarLinksContainer(el) {
|
|
7015
8189
|
return el.hasAttribute("data-ohw-nav-container");
|
|
7016
8190
|
}
|
|
7017
8191
|
function getFooterColumn(el) {
|
|
7018
|
-
return el.closest("[data-ohw-footer-column]");
|
|
8192
|
+
return el.closest("[data-ohw-footer-col], [data-ohw-footer-column]");
|
|
7019
8193
|
}
|
|
7020
8194
|
function resolveFooterColumnSelectionTarget(target, clientX, clientY) {
|
|
7021
8195
|
if (getNavigationItemAnchor(target)) return null;
|
|
@@ -7039,7 +8213,7 @@ function isPointOverNavigation(x, y) {
|
|
|
7039
8213
|
function findHoveredNavOrFooterContainer(x, y) {
|
|
7040
8214
|
const candidates = [
|
|
7041
8215
|
...document.querySelectorAll("[data-ohw-nav-container]"),
|
|
7042
|
-
...
|
|
8216
|
+
...listFooterColumns()
|
|
7043
8217
|
];
|
|
7044
8218
|
for (const container of candidates) {
|
|
7045
8219
|
const r2 = container.getBoundingClientRect();
|
|
@@ -7086,32 +8260,57 @@ function getNavigationSelectionParent(el) {
|
|
|
7086
8260
|
if (footerGroup) return footerGroup;
|
|
7087
8261
|
return getNavigationRoot(el);
|
|
7088
8262
|
}
|
|
7089
|
-
if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-footer-column") || isInferredFooterGroup(el)) {
|
|
8263
|
+
if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isInferredFooterGroup(el)) {
|
|
7090
8264
|
return getNavigationRoot(el);
|
|
7091
8265
|
}
|
|
7092
8266
|
return null;
|
|
7093
8267
|
}
|
|
8268
|
+
function collectNavigationItemSiblingHintRects(selected) {
|
|
8269
|
+
if (!isNavigationItem(selected)) return [];
|
|
8270
|
+
const footerColumn = getFooterColumn(selected);
|
|
8271
|
+
if (footerColumn) {
|
|
8272
|
+
return listFooterLinksInColumn(footerColumn).filter((link) => link !== selected).map((link) => link.getBoundingClientRect());
|
|
8273
|
+
}
|
|
8274
|
+
const navContainer = selected.closest("[data-ohw-nav-container], [data-ohw-nav-drawer]");
|
|
8275
|
+
if (navContainer) {
|
|
8276
|
+
return Array.from(navContainer.querySelectorAll("[data-ohw-href-key]")).filter((el) => isNavigationItem(el) && el !== selected).map((el) => el.getBoundingClientRect());
|
|
8277
|
+
}
|
|
8278
|
+
return listNavigationItems().filter((el) => el !== selected).map((el) => el.getBoundingClientRect());
|
|
8279
|
+
}
|
|
7094
8280
|
function placeCaretAtPoint(el, x, y) {
|
|
7095
8281
|
const selection = window.getSelection();
|
|
7096
8282
|
if (!selection) return;
|
|
7097
|
-
|
|
7098
|
-
|
|
7099
|
-
|
|
7100
|
-
|
|
7101
|
-
|
|
7102
|
-
|
|
8283
|
+
const overlays = Array.from(
|
|
8284
|
+
document.querySelectorAll(
|
|
8285
|
+
"[data-ohw-item-drag-surface], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-ohw-item-toolbar-anchor]"
|
|
8286
|
+
)
|
|
8287
|
+
);
|
|
8288
|
+
const prevPointerEvents = overlays.map((node) => node.style.pointerEvents);
|
|
8289
|
+
for (const node of overlays) node.style.pointerEvents = "none";
|
|
8290
|
+
try {
|
|
8291
|
+
if (typeof document.caretRangeFromPoint === "function") {
|
|
8292
|
+
const range = document.caretRangeFromPoint(x, y);
|
|
8293
|
+
if (range && el.contains(range.startContainer)) {
|
|
8294
|
+
selection.removeAllRanges();
|
|
8295
|
+
selection.addRange(range);
|
|
8296
|
+
return;
|
|
8297
|
+
}
|
|
7103
8298
|
}
|
|
7104
|
-
|
|
7105
|
-
|
|
7106
|
-
|
|
7107
|
-
|
|
7108
|
-
|
|
7109
|
-
|
|
7110
|
-
|
|
7111
|
-
|
|
7112
|
-
|
|
7113
|
-
|
|
8299
|
+
const caretPositionFromPoint = document.caretPositionFromPoint;
|
|
8300
|
+
if (typeof caretPositionFromPoint === "function") {
|
|
8301
|
+
const position = caretPositionFromPoint(x, y);
|
|
8302
|
+
if (position && el.contains(position.offsetNode)) {
|
|
8303
|
+
const range = document.createRange();
|
|
8304
|
+
range.setStart(position.offsetNode, position.offset);
|
|
8305
|
+
range.collapse(true);
|
|
8306
|
+
selection.removeAllRanges();
|
|
8307
|
+
selection.addRange(range);
|
|
8308
|
+
}
|
|
7114
8309
|
}
|
|
8310
|
+
} finally {
|
|
8311
|
+
overlays.forEach((node, i) => {
|
|
8312
|
+
node.style.pointerEvents = prevPointerEvents[i] ?? "";
|
|
8313
|
+
});
|
|
7115
8314
|
}
|
|
7116
8315
|
}
|
|
7117
8316
|
function selectAllTextInEditable(el) {
|
|
@@ -7277,10 +8476,11 @@ function EditGlowChrome({
|
|
|
7277
8476
|
rect,
|
|
7278
8477
|
elRef,
|
|
7279
8478
|
reorderHrefKey,
|
|
7280
|
-
dragDisabled = false
|
|
8479
|
+
dragDisabled = false,
|
|
8480
|
+
hideHandle = false
|
|
7281
8481
|
}) {
|
|
7282
8482
|
const GAP = SELECTION_CHROME_GAP2;
|
|
7283
|
-
return /* @__PURE__ */
|
|
8483
|
+
return /* @__PURE__ */ jsxs13(
|
|
7284
8484
|
"div",
|
|
7285
8485
|
{
|
|
7286
8486
|
ref: elRef,
|
|
@@ -7295,7 +8495,7 @@ function EditGlowChrome({
|
|
|
7295
8495
|
zIndex: 2147483646
|
|
7296
8496
|
},
|
|
7297
8497
|
children: [
|
|
7298
|
-
/* @__PURE__ */
|
|
8498
|
+
/* @__PURE__ */ jsx24(
|
|
7299
8499
|
"div",
|
|
7300
8500
|
{
|
|
7301
8501
|
style: {
|
|
@@ -7308,7 +8508,7 @@ function EditGlowChrome({
|
|
|
7308
8508
|
}
|
|
7309
8509
|
}
|
|
7310
8510
|
),
|
|
7311
|
-
reorderHrefKey && /* @__PURE__ */
|
|
8511
|
+
reorderHrefKey && !hideHandle && /* @__PURE__ */ jsx24(
|
|
7312
8512
|
"div",
|
|
7313
8513
|
{
|
|
7314
8514
|
"data-ohw-drag-handle-container": "",
|
|
@@ -7320,7 +8520,7 @@ function EditGlowChrome({
|
|
|
7320
8520
|
transform: "translate(calc(-100% - 7px), -50%)",
|
|
7321
8521
|
pointerEvents: dragDisabled ? "none" : "auto"
|
|
7322
8522
|
},
|
|
7323
|
-
children: /* @__PURE__ */
|
|
8523
|
+
children: /* @__PURE__ */ jsx24(
|
|
7324
8524
|
DragHandle,
|
|
7325
8525
|
{
|
|
7326
8526
|
"aria-label": `Reorder ${reorderHrefKey}`,
|
|
@@ -7430,9 +8630,9 @@ function FloatingToolbar({
|
|
|
7430
8630
|
showEditLink,
|
|
7431
8631
|
onEditLink
|
|
7432
8632
|
}) {
|
|
7433
|
-
const localRef =
|
|
7434
|
-
const [measuredW, setMeasuredW] =
|
|
7435
|
-
const setRefs =
|
|
8633
|
+
const localRef = React11.useRef(null);
|
|
8634
|
+
const [measuredW, setMeasuredW] = React11.useState(330);
|
|
8635
|
+
const setRefs = React11.useCallback(
|
|
7436
8636
|
(node) => {
|
|
7437
8637
|
localRef.current = node;
|
|
7438
8638
|
if (typeof elRef === "function") elRef(node);
|
|
@@ -7444,7 +8644,7 @@ function FloatingToolbar({
|
|
|
7444
8644
|
},
|
|
7445
8645
|
[elRef]
|
|
7446
8646
|
);
|
|
7447
|
-
|
|
8647
|
+
React11.useLayoutEffect(() => {
|
|
7448
8648
|
const node = localRef.current;
|
|
7449
8649
|
if (!node) return;
|
|
7450
8650
|
const update = () => {
|
|
@@ -7457,7 +8657,7 @@ function FloatingToolbar({
|
|
|
7457
8657
|
return () => ro.disconnect();
|
|
7458
8658
|
}, [showEditLink, activeCommands]);
|
|
7459
8659
|
const { top, left, transform } = calcToolbarPos(rect, parentScroll, measuredW);
|
|
7460
|
-
return /* @__PURE__ */
|
|
8660
|
+
return /* @__PURE__ */ jsx24(
|
|
7461
8661
|
"div",
|
|
7462
8662
|
{
|
|
7463
8663
|
ref: setRefs,
|
|
@@ -7469,12 +8669,12 @@ function FloatingToolbar({
|
|
|
7469
8669
|
zIndex: 2147483647,
|
|
7470
8670
|
pointerEvents: "auto"
|
|
7471
8671
|
},
|
|
7472
|
-
children: /* @__PURE__ */
|
|
7473
|
-
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */
|
|
7474
|
-
gi > 0 && /* @__PURE__ */
|
|
8672
|
+
children: /* @__PURE__ */ jsxs13(CustomToolbar, { children: [
|
|
8673
|
+
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ jsxs13(React11.Fragment, { children: [
|
|
8674
|
+
gi > 0 && /* @__PURE__ */ jsx24(CustomToolbarDivider, {}),
|
|
7475
8675
|
btns.map((btn) => {
|
|
7476
8676
|
const isActive = activeCommands.has(btn.cmd);
|
|
7477
|
-
return /* @__PURE__ */
|
|
8677
|
+
return /* @__PURE__ */ jsx24(
|
|
7478
8678
|
CustomToolbarButton,
|
|
7479
8679
|
{
|
|
7480
8680
|
title: btn.title,
|
|
@@ -7483,7 +8683,7 @@ function FloatingToolbar({
|
|
|
7483
8683
|
e.preventDefault();
|
|
7484
8684
|
onCommand(btn.cmd);
|
|
7485
8685
|
},
|
|
7486
|
-
children: /* @__PURE__ */
|
|
8686
|
+
children: /* @__PURE__ */ jsx24(
|
|
7487
8687
|
"svg",
|
|
7488
8688
|
{
|
|
7489
8689
|
width: "16",
|
|
@@ -7504,7 +8704,7 @@ function FloatingToolbar({
|
|
|
7504
8704
|
);
|
|
7505
8705
|
})
|
|
7506
8706
|
] }, gi)),
|
|
7507
|
-
showEditLink ? /* @__PURE__ */
|
|
8707
|
+
showEditLink ? /* @__PURE__ */ jsx24(
|
|
7508
8708
|
CustomToolbarButton,
|
|
7509
8709
|
{
|
|
7510
8710
|
type: "button",
|
|
@@ -7518,7 +8718,7 @@ function FloatingToolbar({
|
|
|
7518
8718
|
e.preventDefault();
|
|
7519
8719
|
e.stopPropagation();
|
|
7520
8720
|
},
|
|
7521
|
-
children: /* @__PURE__ */
|
|
8721
|
+
children: /* @__PURE__ */ jsx24(Link2, { className: "size-4 shrink-0", "aria-hidden": true })
|
|
7522
8722
|
}
|
|
7523
8723
|
) : null
|
|
7524
8724
|
] })
|
|
@@ -7535,7 +8735,7 @@ function StateToggle({
|
|
|
7535
8735
|
states,
|
|
7536
8736
|
onStateChange
|
|
7537
8737
|
}) {
|
|
7538
|
-
return /* @__PURE__ */
|
|
8738
|
+
return /* @__PURE__ */ jsx24(
|
|
7539
8739
|
ToggleGroup,
|
|
7540
8740
|
{
|
|
7541
8741
|
"data-ohw-state-toggle": "",
|
|
@@ -7549,7 +8749,7 @@ function StateToggle({
|
|
|
7549
8749
|
left: rect.right - 8,
|
|
7550
8750
|
transform: "translateX(-100%)"
|
|
7551
8751
|
},
|
|
7552
|
-
children: states.map((state) => /* @__PURE__ */
|
|
8752
|
+
children: states.map((state) => /* @__PURE__ */ jsx24(ToggleGroupItem, { value: state, size: "sm", children: state }, state))
|
|
7553
8753
|
}
|
|
7554
8754
|
);
|
|
7555
8755
|
}
|
|
@@ -7576,8 +8776,8 @@ function OhhwellsBridge() {
|
|
|
7576
8776
|
const router = useRouter2();
|
|
7577
8777
|
const searchParams = useSearchParams();
|
|
7578
8778
|
const isEditMode = isEditSessionActive();
|
|
7579
|
-
const [bridgeRoot, setBridgeRoot] =
|
|
7580
|
-
|
|
8779
|
+
const [bridgeRoot, setBridgeRoot] = useState7(null);
|
|
8780
|
+
useEffect8(() => {
|
|
7581
8781
|
const figtreeFontId = "ohw-figtree-font";
|
|
7582
8782
|
if (!document.getElementById(figtreeFontId)) {
|
|
7583
8783
|
const preconnect1 = Object.assign(document.createElement("link"), { rel: "preconnect", href: "https://fonts.googleapis.com" });
|
|
@@ -7605,92 +8805,136 @@ function OhhwellsBridge() {
|
|
|
7605
8805
|
const subdomainFromQuery = searchParams.get("subdomain");
|
|
7606
8806
|
const subdomain = resolveSubdomain(subdomainFromQuery);
|
|
7607
8807
|
useLinkHrefGuardian(pathname, subdomain, isEditMode);
|
|
7608
|
-
const postToParent2 =
|
|
8808
|
+
const postToParent2 = useCallback4((data) => {
|
|
7609
8809
|
if (typeof window !== "undefined" && window.parent !== window) {
|
|
7610
8810
|
window.parent.postMessage(data, "*");
|
|
7611
8811
|
}
|
|
7612
8812
|
}, []);
|
|
7613
|
-
const [fetchState, setFetchState] =
|
|
7614
|
-
const autoSaveTimers =
|
|
7615
|
-
const activeElRef =
|
|
7616
|
-
const selectedElRef =
|
|
7617
|
-
const
|
|
7618
|
-
const
|
|
7619
|
-
const
|
|
7620
|
-
const
|
|
7621
|
-
const
|
|
7622
|
-
const
|
|
8813
|
+
const [fetchState, setFetchState] = useState7("idle");
|
|
8814
|
+
const autoSaveTimers = useRef7(/* @__PURE__ */ new Map());
|
|
8815
|
+
const activeElRef = useRef7(null);
|
|
8816
|
+
const selectedElRef = useRef7(null);
|
|
8817
|
+
const selectedHrefKeyRef = useRef7(null);
|
|
8818
|
+
const selectedFooterColAttrRef = useRef7(null);
|
|
8819
|
+
const originalContentRef = useRef7(null);
|
|
8820
|
+
const activeStateElRef = useRef7(null);
|
|
8821
|
+
const parentScrollRef = useRef7(null);
|
|
8822
|
+
const visibleViewportRef = useRef7(null);
|
|
8823
|
+
const [dialogPortalContainer, setDialogPortalContainer] = useState7(null);
|
|
8824
|
+
const attachVisibleViewport = useCallback4((node) => {
|
|
7623
8825
|
visibleViewportRef.current = node;
|
|
7624
8826
|
setDialogPortalContainer(node);
|
|
7625
8827
|
if (node) applyVisibleViewport(node, parentScrollRef.current);
|
|
7626
8828
|
}, []);
|
|
7627
|
-
const toolbarElRef =
|
|
7628
|
-
const glowElRef =
|
|
7629
|
-
const hoveredImageRef =
|
|
7630
|
-
const hoveredImageHasTextOverlapRef =
|
|
7631
|
-
const dragOverElRef =
|
|
7632
|
-
const [mediaHover, setMediaHover] =
|
|
7633
|
-
const [uploadingRects, setUploadingRects] =
|
|
7634
|
-
const hoveredGapRef =
|
|
7635
|
-
const imageUnhoverTimerRef =
|
|
7636
|
-
const imageShowTimerRef =
|
|
7637
|
-
const editStylesRef =
|
|
7638
|
-
const activateRef =
|
|
8829
|
+
const toolbarElRef = useRef7(null);
|
|
8830
|
+
const glowElRef = useRef7(null);
|
|
8831
|
+
const hoveredImageRef = useRef7(null);
|
|
8832
|
+
const hoveredImageHasTextOverlapRef = useRef7(false);
|
|
8833
|
+
const dragOverElRef = useRef7(null);
|
|
8834
|
+
const [mediaHover, setMediaHover] = useState7(null);
|
|
8835
|
+
const [uploadingRects, setUploadingRects] = useState7({});
|
|
8836
|
+
const hoveredGapRef = useRef7(null);
|
|
8837
|
+
const imageUnhoverTimerRef = useRef7(null);
|
|
8838
|
+
const imageShowTimerRef = useRef7(null);
|
|
8839
|
+
const editStylesRef = useRef7(null);
|
|
8840
|
+
const activateRef = useRef7(() => {
|
|
7639
8841
|
});
|
|
7640
|
-
const deactivateRef =
|
|
8842
|
+
const deactivateRef = useRef7(() => {
|
|
7641
8843
|
});
|
|
7642
|
-
const selectRef =
|
|
8844
|
+
const selectRef = useRef7(() => {
|
|
7643
8845
|
});
|
|
7644
|
-
const selectFrameRef =
|
|
8846
|
+
const selectFrameRef = useRef7(() => {
|
|
7645
8847
|
});
|
|
7646
|
-
const deselectRef =
|
|
8848
|
+
const deselectRef = useRef7(() => {
|
|
7647
8849
|
});
|
|
7648
|
-
const reselectNavigationItemRef =
|
|
8850
|
+
const reselectNavigationItemRef = useRef7(() => {
|
|
7649
8851
|
});
|
|
7650
|
-
const commitNavigationTextEditRef =
|
|
8852
|
+
const commitNavigationTextEditRef = useRef7(() => {
|
|
7651
8853
|
});
|
|
7652
|
-
const refreshActiveCommandsRef =
|
|
8854
|
+
const refreshActiveCommandsRef = useRef7(() => {
|
|
7653
8855
|
});
|
|
7654
|
-
const postToParentRef =
|
|
8856
|
+
const postToParentRef = useRef7(postToParent2);
|
|
7655
8857
|
postToParentRef.current = postToParent2;
|
|
7656
|
-
const sectionsLoadedRef =
|
|
7657
|
-
const pendingScheduleConfigRequests =
|
|
7658
|
-
const [toolbarRect, setToolbarRect] =
|
|
7659
|
-
const [toolbarVariant, setToolbarVariant] =
|
|
7660
|
-
const toolbarVariantRef =
|
|
8858
|
+
const sectionsLoadedRef = useRef7(false);
|
|
8859
|
+
const pendingScheduleConfigRequests = useRef7([]);
|
|
8860
|
+
const [toolbarRect, setToolbarRect] = useState7(null);
|
|
8861
|
+
const [toolbarVariant, setToolbarVariant] = useState7("none");
|
|
8862
|
+
const toolbarVariantRef = useRef7("none");
|
|
7661
8863
|
toolbarVariantRef.current = toolbarVariant;
|
|
7662
|
-
const [selectedIsCta, setSelectedIsCta] =
|
|
7663
|
-
const [reorderHrefKey, setReorderHrefKey] =
|
|
7664
|
-
const [reorderDragDisabled, setReorderDragDisabled] =
|
|
7665
|
-
const [toggleState, setToggleState] =
|
|
7666
|
-
const [maxBadge, setMaxBadge] =
|
|
7667
|
-
const [activeCommands, setActiveCommands] =
|
|
7668
|
-
const [sectionGap, setSectionGap] =
|
|
7669
|
-
const [toolbarShowEditLink, setToolbarShowEditLink] =
|
|
7670
|
-
const hoveredNavContainerRef =
|
|
7671
|
-
const [hoveredNavContainerRect, setHoveredNavContainerRect] =
|
|
7672
|
-
const hoveredItemElRef =
|
|
7673
|
-
const [hoveredItemRect, setHoveredItemRect] =
|
|
7674
|
-
const siblingHintElRef =
|
|
7675
|
-
const [siblingHintRect, setSiblingHintRect] =
|
|
7676
|
-
const [
|
|
7677
|
-
const [
|
|
7678
|
-
const
|
|
7679
|
-
const
|
|
7680
|
-
const
|
|
7681
|
-
const [
|
|
7682
|
-
const [
|
|
7683
|
-
const
|
|
7684
|
-
const
|
|
7685
|
-
const
|
|
7686
|
-
const
|
|
7687
|
-
const
|
|
8864
|
+
const [selectedIsCta, setSelectedIsCta] = useState7(false);
|
|
8865
|
+
const [reorderHrefKey, setReorderHrefKey] = useState7(null);
|
|
8866
|
+
const [reorderDragDisabled, setReorderDragDisabled] = useState7(false);
|
|
8867
|
+
const [toggleState, setToggleState] = useState7(null);
|
|
8868
|
+
const [maxBadge, setMaxBadge] = useState7(null);
|
|
8869
|
+
const [activeCommands, setActiveCommands] = useState7(/* @__PURE__ */ new Set());
|
|
8870
|
+
const [sectionGap, setSectionGap] = useState7(null);
|
|
8871
|
+
const [toolbarShowEditLink, setToolbarShowEditLink] = useState7(false);
|
|
8872
|
+
const hoveredNavContainerRef = useRef7(null);
|
|
8873
|
+
const [hoveredNavContainerRect, setHoveredNavContainerRect] = useState7(null);
|
|
8874
|
+
const hoveredItemElRef = useRef7(null);
|
|
8875
|
+
const [hoveredItemRect, setHoveredItemRect] = useState7(null);
|
|
8876
|
+
const siblingHintElRef = useRef7(null);
|
|
8877
|
+
const [siblingHintRect, setSiblingHintRect] = useState7(null);
|
|
8878
|
+
const [siblingHintRects, setSiblingHintRects] = useState7([]);
|
|
8879
|
+
const [isItemDragging, setIsItemDragging] = useState7(false);
|
|
8880
|
+
const [isFooterFrameSelection, setIsFooterFrameSelection] = useState7(false);
|
|
8881
|
+
const footerDragRef = useRef7(null);
|
|
8882
|
+
const [footerDropSlots, setFooterDropSlots] = useState7([]);
|
|
8883
|
+
const [activeFooterDropIndex, setActiveFooterDropIndex] = useState7(null);
|
|
8884
|
+
const [draggedItemRect, setDraggedItemRect] = useState7(null);
|
|
8885
|
+
const footerPointerDragRef = useRef7(null);
|
|
8886
|
+
const suppressNextClickRef = useRef7(false);
|
|
8887
|
+
const suppressClickUntilRef = useRef7(0);
|
|
8888
|
+
const [linkPopover, setLinkPopover] = useState7(null);
|
|
8889
|
+
const linkPopoverSessionRef = useRef7(null);
|
|
8890
|
+
const addNavAfterAnchorRef = useRef7(null);
|
|
8891
|
+
const editContentRef = useRef7({});
|
|
8892
|
+
const [sitePages, setSitePages] = useState7([]);
|
|
8893
|
+
const [sectionsByPath, setSectionsByPath] = useState7({});
|
|
8894
|
+
const sectionsPrefetchGenRef = useRef7(0);
|
|
8895
|
+
const setLinkPopoverRef = useRef7(setLinkPopover);
|
|
8896
|
+
const linkPopoverPanelRef = useRef7(null);
|
|
8897
|
+
const linkPopoverOpenRef = useRef7(false);
|
|
8898
|
+
const linkPopoverGraceUntilRef = useRef7(0);
|
|
7688
8899
|
setLinkPopoverRef.current = setLinkPopover;
|
|
7689
8900
|
linkPopoverSessionRef.current = linkPopover;
|
|
8901
|
+
const {
|
|
8902
|
+
navDragRef,
|
|
8903
|
+
navDropSlots,
|
|
8904
|
+
activeNavDropIndex,
|
|
8905
|
+
startNavLinkDrag,
|
|
8906
|
+
commitNavDrag,
|
|
8907
|
+
onNavDragOver,
|
|
8908
|
+
armNavPressFromChrome,
|
|
8909
|
+
refreshNavDragVisualsRef
|
|
8910
|
+
} = useNavItemDrag({
|
|
8911
|
+
isEditMode,
|
|
8912
|
+
editContentRef,
|
|
8913
|
+
selectedElRef,
|
|
8914
|
+
activeElRef,
|
|
8915
|
+
footerDragRef,
|
|
8916
|
+
suppressNextClickRef,
|
|
8917
|
+
suppressClickUntilRef,
|
|
8918
|
+
siblingHintElRef,
|
|
8919
|
+
postToParentRef,
|
|
8920
|
+
deselectRef,
|
|
8921
|
+
selectRef,
|
|
8922
|
+
deactivateRef,
|
|
8923
|
+
setLinkPopover: () => setLinkPopover(null),
|
|
8924
|
+
linkPopoverOpenRef,
|
|
8925
|
+
setIsItemDragging,
|
|
8926
|
+
setDraggedItemRect,
|
|
8927
|
+
setSiblingHintRect,
|
|
8928
|
+
setSiblingHintRects,
|
|
8929
|
+
setToolbarRect,
|
|
8930
|
+
getNavigationItemAnchor,
|
|
8931
|
+
isDragHandleDisabled,
|
|
8932
|
+
isNavbarButton: isNavbarButton2
|
|
8933
|
+
});
|
|
7690
8934
|
const bumpLinkPopoverGrace = () => {
|
|
7691
8935
|
linkPopoverGraceUntilRef.current = Date.now() + 350;
|
|
7692
8936
|
};
|
|
7693
|
-
const runSectionsPrefetch =
|
|
8937
|
+
const runSectionsPrefetch = useCallback4((pages) => {
|
|
7694
8938
|
if (!isEditMode || shouldUseDevFixtures() || pages.length === 0) return;
|
|
7695
8939
|
const gen = ++sectionsPrefetchGenRef.current;
|
|
7696
8940
|
const paths = pages.map((p) => p.path);
|
|
@@ -7709,10 +8953,24 @@ function OhhwellsBridge() {
|
|
|
7709
8953
|
);
|
|
7710
8954
|
});
|
|
7711
8955
|
}, [isEditMode, pathname]);
|
|
7712
|
-
const runSectionsPrefetchRef =
|
|
8956
|
+
const runSectionsPrefetchRef = useRef7(runSectionsPrefetch);
|
|
7713
8957
|
runSectionsPrefetchRef.current = runSectionsPrefetch;
|
|
7714
|
-
|
|
7715
|
-
if (!linkPopover)
|
|
8958
|
+
useEffect8(() => {
|
|
8959
|
+
if (!linkPopover) {
|
|
8960
|
+
document.documentElement.removeAttribute("data-ohw-link-popover-open");
|
|
8961
|
+
return;
|
|
8962
|
+
}
|
|
8963
|
+
document.documentElement.setAttribute("data-ohw-link-popover-open", "");
|
|
8964
|
+
hoveredItemElRef.current = null;
|
|
8965
|
+
setHoveredItemRect(null);
|
|
8966
|
+
hoveredNavContainerRef.current = null;
|
|
8967
|
+
setHoveredNavContainerRect(null);
|
|
8968
|
+
siblingHintElRef.current = null;
|
|
8969
|
+
setSiblingHintRect(null);
|
|
8970
|
+
setSiblingHintRects([]);
|
|
8971
|
+
if (selectedElRef.current || toolbarVariantRef.current !== "none") {
|
|
8972
|
+
deselectRef.current();
|
|
8973
|
+
}
|
|
7716
8974
|
if (hoveredImageRef.current) {
|
|
7717
8975
|
hoveredImageRef.current = null;
|
|
7718
8976
|
hoveredImageHasTextOverlapRef.current = false;
|
|
@@ -7746,7 +9004,7 @@ function OhhwellsBridge() {
|
|
|
7746
9004
|
document.removeEventListener("touchmove", preventBackgroundScroll, scrollOpts);
|
|
7747
9005
|
};
|
|
7748
9006
|
}, [linkPopover, postToParent2]);
|
|
7749
|
-
|
|
9007
|
+
useEffect8(() => {
|
|
7750
9008
|
if (!isEditMode) return;
|
|
7751
9009
|
const useFixtures = shouldUseDevFixtures();
|
|
7752
9010
|
if (useFixtures) {
|
|
@@ -7770,14 +9028,14 @@ function OhhwellsBridge() {
|
|
|
7770
9028
|
if (!useFixtures) postToParent2({ type: "ow:request-site-pages" });
|
|
7771
9029
|
return () => window.removeEventListener("message", onSitePages);
|
|
7772
9030
|
}, [isEditMode, postToParent2]);
|
|
7773
|
-
|
|
9031
|
+
useEffect8(() => {
|
|
7774
9032
|
if (!isEditMode || shouldUseDevFixtures()) return;
|
|
7775
9033
|
void loadAllSectionsManifest().then((manifest) => {
|
|
7776
9034
|
if (Object.keys(manifest).length === 0) return;
|
|
7777
9035
|
setSectionsByPath((prev) => ({ ...manifest, ...prev }));
|
|
7778
9036
|
});
|
|
7779
9037
|
}, [isEditMode]);
|
|
7780
|
-
|
|
9038
|
+
useEffect8(() => {
|
|
7781
9039
|
const update = () => {
|
|
7782
9040
|
const el = activeElRef.current ?? selectedElRef.current;
|
|
7783
9041
|
if (el) setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
|
|
@@ -7801,10 +9059,10 @@ function OhhwellsBridge() {
|
|
|
7801
9059
|
vvp.removeEventListener("resize", update);
|
|
7802
9060
|
};
|
|
7803
9061
|
}, []);
|
|
7804
|
-
const refreshStateRules =
|
|
9062
|
+
const refreshStateRules = useCallback4(() => {
|
|
7805
9063
|
editStylesRef.current?.forceHover && (editStylesRef.current.forceHover.textContent = collectStateRules());
|
|
7806
9064
|
}, []);
|
|
7807
|
-
const processConfigRequest =
|
|
9065
|
+
const processConfigRequest = useCallback4((insertAfterVal) => {
|
|
7808
9066
|
const tracker = getSectionsTracker();
|
|
7809
9067
|
let entries = [];
|
|
7810
9068
|
try {
|
|
@@ -7827,7 +9085,7 @@ function OhhwellsBridge() {
|
|
|
7827
9085
|
}
|
|
7828
9086
|
window.postMessage({ type: "ow:schedule-config", insertAfter: insertAfterVal, scheduleId: null }, "*");
|
|
7829
9087
|
}, [isEditMode]);
|
|
7830
|
-
const deactivate =
|
|
9088
|
+
const deactivate = useCallback4(() => {
|
|
7831
9089
|
const el = activeElRef.current;
|
|
7832
9090
|
if (!el) return;
|
|
7833
9091
|
const key = el.dataset.ohwKey;
|
|
@@ -7859,19 +9117,23 @@ function OhhwellsBridge() {
|
|
|
7859
9117
|
setToolbarShowEditLink(false);
|
|
7860
9118
|
postToParent2({ type: "ow:exit-edit" });
|
|
7861
9119
|
}, [postToParent2]);
|
|
7862
|
-
const clearSelectedAttr =
|
|
9120
|
+
const clearSelectedAttr = useCallback4(() => {
|
|
7863
9121
|
document.querySelectorAll("[data-ohw-selected]").forEach((el) => {
|
|
7864
9122
|
el.removeAttribute("data-ohw-selected");
|
|
7865
9123
|
});
|
|
7866
9124
|
}, []);
|
|
7867
|
-
const deselect =
|
|
9125
|
+
const deselect = useCallback4(() => {
|
|
7868
9126
|
clearSelectedAttr();
|
|
7869
9127
|
selectedElRef.current = null;
|
|
9128
|
+
selectedHrefKeyRef.current = null;
|
|
9129
|
+
selectedFooterColAttrRef.current = null;
|
|
7870
9130
|
setSelectedIsCta(false);
|
|
7871
9131
|
setReorderHrefKey(null);
|
|
7872
9132
|
setReorderDragDisabled(false);
|
|
9133
|
+
setIsFooterFrameSelection(false);
|
|
7873
9134
|
siblingHintElRef.current = null;
|
|
7874
9135
|
setSiblingHintRect(null);
|
|
9136
|
+
setSiblingHintRects([]);
|
|
7875
9137
|
setIsItemDragging(false);
|
|
7876
9138
|
hoveredNavContainerRef.current = null;
|
|
7877
9139
|
setHoveredNavContainerRect(null);
|
|
@@ -7880,12 +9142,57 @@ function OhhwellsBridge() {
|
|
|
7880
9142
|
setToolbarVariant("none");
|
|
7881
9143
|
}
|
|
7882
9144
|
}, [clearSelectedAttr]);
|
|
7883
|
-
const markSelected =
|
|
9145
|
+
const markSelected = useCallback4((el) => {
|
|
7884
9146
|
clearSelectedAttr();
|
|
7885
9147
|
el.setAttribute("data-ohw-selected", "");
|
|
7886
9148
|
}, [clearSelectedAttr]);
|
|
7887
|
-
const
|
|
9149
|
+
const resolveHrefKeyElement = useCallback4((hrefKey) => {
|
|
9150
|
+
if (isFooterHrefKey(hrefKey)) {
|
|
9151
|
+
return document.querySelector(
|
|
9152
|
+
`footer [data-ohw-href-key="${CSS.escape(hrefKey)}"]`
|
|
9153
|
+
);
|
|
9154
|
+
}
|
|
9155
|
+
if (isNavbarHrefKey(hrefKey)) {
|
|
9156
|
+
const desktop = document.querySelector("[data-ohw-nav-container]");
|
|
9157
|
+
const drawer = document.querySelector("[data-ohw-nav-drawer]");
|
|
9158
|
+
return desktop?.querySelector(`[data-ohw-href-key="${CSS.escape(hrefKey)}"]`) ?? drawer?.querySelector(`[data-ohw-href-key="${CSS.escape(hrefKey)}"]`) ?? document.querySelector(`[data-ohw-href-key="${CSS.escape(hrefKey)}"]`);
|
|
9159
|
+
}
|
|
9160
|
+
return document.querySelector(
|
|
9161
|
+
`[data-ohw-href-key="${CSS.escape(hrefKey)}"]`
|
|
9162
|
+
);
|
|
9163
|
+
}, []);
|
|
9164
|
+
const resyncSelectedNavigationItem = useCallback4(() => {
|
|
9165
|
+
const hrefKey = selectedHrefKeyRef.current;
|
|
9166
|
+
if (hrefKey) {
|
|
9167
|
+
const link = resolveHrefKeyElement(hrefKey);
|
|
9168
|
+
if (!link || !isNavigationItem(link)) return;
|
|
9169
|
+
selectedElRef.current = link;
|
|
9170
|
+
const { key, disabled } = getNavigationItemReorderState(link);
|
|
9171
|
+
setReorderHrefKey(key);
|
|
9172
|
+
setReorderDragDisabled(disabled);
|
|
9173
|
+
setIsFooterFrameSelection(false);
|
|
9174
|
+
setToolbarVariant("link-action");
|
|
9175
|
+
setToolbarRect(link.getBoundingClientRect());
|
|
9176
|
+
setSiblingHintRects(collectNavigationItemSiblingHintRects(link));
|
|
9177
|
+
return;
|
|
9178
|
+
}
|
|
9179
|
+
const colAttr = selectedFooterColAttrRef.current;
|
|
9180
|
+
if (colAttr != null) {
|
|
9181
|
+
const column = document.querySelector(`[data-ohw-footer-col="${CSS.escape(colAttr)}"]`) ?? listFooterColumns()[Number(colAttr)] ?? null;
|
|
9182
|
+
if (!column || !isNavigationContainer(column)) return;
|
|
9183
|
+
selectedElRef.current = column;
|
|
9184
|
+
setIsFooterFrameSelection(true);
|
|
9185
|
+
setToolbarVariant("select-frame");
|
|
9186
|
+
setToolbarRect(column.getBoundingClientRect());
|
|
9187
|
+
setSiblingHintRects(
|
|
9188
|
+
listFooterColumns().filter((c) => c !== column).map((c) => c.getBoundingClientRect())
|
|
9189
|
+
);
|
|
9190
|
+
}
|
|
9191
|
+
}, [resolveHrefKeyElement]);
|
|
9192
|
+
const reselectNavigationItem = useCallback4((navAnchor) => {
|
|
7888
9193
|
selectedElRef.current = navAnchor;
|
|
9194
|
+
selectedHrefKeyRef.current = navAnchor.getAttribute("data-ohw-href-key");
|
|
9195
|
+
selectedFooterColAttrRef.current = null;
|
|
7889
9196
|
markSelected(navAnchor);
|
|
7890
9197
|
setSelectedIsCta(isNavbarButton2(navAnchor));
|
|
7891
9198
|
const { key, disabled } = getNavigationItemReorderState(navAnchor);
|
|
@@ -7893,10 +9200,11 @@ function OhhwellsBridge() {
|
|
|
7893
9200
|
setReorderDragDisabled(disabled);
|
|
7894
9201
|
setToolbarVariant("link-action");
|
|
7895
9202
|
setToolbarRect(navAnchor.getBoundingClientRect());
|
|
9203
|
+
setSiblingHintRects(collectNavigationItemSiblingHintRects(navAnchor));
|
|
7896
9204
|
setToolbarShowEditLink(false);
|
|
7897
9205
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
7898
9206
|
}, [markSelected]);
|
|
7899
|
-
const commitNavigationTextEdit =
|
|
9207
|
+
const commitNavigationTextEdit = useCallback4((navAnchor) => {
|
|
7900
9208
|
const el = activeElRef.current;
|
|
7901
9209
|
if (!el) return;
|
|
7902
9210
|
const key = el.dataset.ohwKey;
|
|
@@ -7906,49 +9214,337 @@ function OhhwellsBridge() {
|
|
|
7906
9214
|
clearTimeout(timer);
|
|
7907
9215
|
autoSaveTimers.current.delete(key);
|
|
7908
9216
|
}
|
|
7909
|
-
const html = sanitizeHtml(el.innerHTML);
|
|
7910
|
-
const original = originalContentRef.current ?? "";
|
|
7911
|
-
if (html !== sanitizeHtml(original)) {
|
|
7912
|
-
postToParent2({ type: "ow:change", nodes: [{ key, text: html }] });
|
|
7913
|
-
const h = document.documentElement.scrollHeight;
|
|
7914
|
-
if (h > 50) postToParent2({ type: "ow:height", height: h });
|
|
9217
|
+
const html = sanitizeHtml(el.innerHTML);
|
|
9218
|
+
const original = originalContentRef.current ?? "";
|
|
9219
|
+
if (html !== sanitizeHtml(original)) {
|
|
9220
|
+
postToParent2({ type: "ow:change", nodes: [{ key, text: html }] });
|
|
9221
|
+
const h = document.documentElement.scrollHeight;
|
|
9222
|
+
if (h > 50) postToParent2({ type: "ow:height", height: h });
|
|
9223
|
+
}
|
|
9224
|
+
}
|
|
9225
|
+
el.removeAttribute("contenteditable");
|
|
9226
|
+
el.removeAttribute("data-ohw-editing");
|
|
9227
|
+
activeElRef.current = null;
|
|
9228
|
+
setMaxBadge(null);
|
|
9229
|
+
setActiveCommands(/* @__PURE__ */ new Set());
|
|
9230
|
+
setToolbarShowEditLink(false);
|
|
9231
|
+
postToParent2({ type: "ow:exit-edit" });
|
|
9232
|
+
reselectNavigationItem(navAnchor);
|
|
9233
|
+
}, [postToParent2, reselectNavigationItem]);
|
|
9234
|
+
const handleAddTopLevelNavItem = useCallback4(() => {
|
|
9235
|
+
const items = listNavbarItems();
|
|
9236
|
+
addNavAfterAnchorRef.current = items[items.length - 1] ?? null;
|
|
9237
|
+
deselectRef.current();
|
|
9238
|
+
deactivateRef.current();
|
|
9239
|
+
bumpLinkPopoverGrace();
|
|
9240
|
+
setLinkPopover({
|
|
9241
|
+
key: "__add-nav__",
|
|
9242
|
+
mode: "create",
|
|
9243
|
+
intent: "add-nav"
|
|
9244
|
+
});
|
|
9245
|
+
}, []);
|
|
9246
|
+
const clearFooterDragVisuals = useCallback4(() => {
|
|
9247
|
+
footerDragRef.current = null;
|
|
9248
|
+
setSiblingHintRects([]);
|
|
9249
|
+
setFooterDropSlots([]);
|
|
9250
|
+
setActiveFooterDropIndex(null);
|
|
9251
|
+
setDraggedItemRect(null);
|
|
9252
|
+
setIsItemDragging(false);
|
|
9253
|
+
unlockFooterDragInteraction();
|
|
9254
|
+
}, []);
|
|
9255
|
+
const refreshFooterDragVisuals = useCallback4((session, activeSlot, clientX, clientY) => {
|
|
9256
|
+
const dragged = session.draggedEl;
|
|
9257
|
+
setDraggedItemRect(dragged.getBoundingClientRect());
|
|
9258
|
+
if (typeof clientX === "number" && typeof clientY === "number") {
|
|
9259
|
+
session.lastClientX = clientX;
|
|
9260
|
+
session.lastClientY = clientY;
|
|
9261
|
+
}
|
|
9262
|
+
session.activeSlot = activeSlot;
|
|
9263
|
+
setSiblingHintRects([]);
|
|
9264
|
+
if (session.kind === "link") {
|
|
9265
|
+
const columns = listFooterColumns();
|
|
9266
|
+
const slots2 = [];
|
|
9267
|
+
columns.forEach((col, i) => {
|
|
9268
|
+
slots2.push(...buildLinkDropSlots(col, i));
|
|
9269
|
+
});
|
|
9270
|
+
setFooterDropSlots(slots2);
|
|
9271
|
+
const activeIdx2 = activeSlot ? slots2.findIndex((s) => s.columnIndex === activeSlot.columnIndex && s.insertIndex === activeSlot.insertIndex) : -1;
|
|
9272
|
+
setActiveFooterDropIndex(activeIdx2 >= 0 ? activeIdx2 : null);
|
|
9273
|
+
return;
|
|
9274
|
+
}
|
|
9275
|
+
const slots = buildColumnDropSlots();
|
|
9276
|
+
setFooterDropSlots(slots);
|
|
9277
|
+
const activeIdx = activeSlot ? slots.findIndex((s) => s.insertIndex === activeSlot.insertIndex) : -1;
|
|
9278
|
+
setActiveFooterDropIndex(activeIdx >= 0 ? activeIdx : null);
|
|
9279
|
+
}, []);
|
|
9280
|
+
const refreshFooterDragVisualsRef = useRef7(refreshFooterDragVisuals);
|
|
9281
|
+
refreshFooterDragVisualsRef.current = refreshFooterDragVisuals;
|
|
9282
|
+
const commitFooterDragRef = useRef7(() => {
|
|
9283
|
+
});
|
|
9284
|
+
const beginFooterDragRef = useRef7(() => {
|
|
9285
|
+
});
|
|
9286
|
+
const beginFooterDrag = useCallback4(
|
|
9287
|
+
(session) => {
|
|
9288
|
+
const rect = session.draggedEl.getBoundingClientRect();
|
|
9289
|
+
session.lastClientX = session.lastClientX || rect.left + rect.width / 2;
|
|
9290
|
+
session.lastClientY = session.lastClientY || rect.top + rect.height / 2;
|
|
9291
|
+
session.activeSlot = session.activeSlot ?? null;
|
|
9292
|
+
footerDragRef.current = session;
|
|
9293
|
+
setIsItemDragging(true);
|
|
9294
|
+
lockFooterDuringDrag();
|
|
9295
|
+
siblingHintElRef.current = null;
|
|
9296
|
+
setSiblingHintRect(null);
|
|
9297
|
+
if (session.wasSelected && selectedElRef.current === session.draggedEl) {
|
|
9298
|
+
setToolbarRect(rect);
|
|
9299
|
+
}
|
|
9300
|
+
const initialSlot = session.kind === "link" && session.hrefKey ? hitTestLinkDropSlot(session.lastClientX, session.lastClientY, session.hrefKey) : hitTestColumnDropSlot(session.lastClientX, session.lastClientY);
|
|
9301
|
+
refreshFooterDragVisuals(session, initialSlot, session.lastClientX, session.lastClientY);
|
|
9302
|
+
},
|
|
9303
|
+
[refreshFooterDragVisuals]
|
|
9304
|
+
);
|
|
9305
|
+
beginFooterDragRef.current = beginFooterDrag;
|
|
9306
|
+
const commitFooterDrag = useCallback4(
|
|
9307
|
+
(clientX, clientY) => {
|
|
9308
|
+
const session = footerDragRef.current;
|
|
9309
|
+
if (!session) {
|
|
9310
|
+
clearFooterDragVisuals();
|
|
9311
|
+
return;
|
|
9312
|
+
}
|
|
9313
|
+
const x = typeof clientX === "number" && (clientX !== 0 || clientY !== 0) ? clientX : session.lastClientX;
|
|
9314
|
+
const y = typeof clientY === "number" && (clientX !== 0 || clientY !== 0) ? clientY : session.lastClientY;
|
|
9315
|
+
let nextOrder = null;
|
|
9316
|
+
const slot = session.activeSlot ?? (session.kind === "link" && session.hrefKey ? hitTestLinkDropSlot(x, y, session.hrefKey) : session.kind === "column" ? hitTestColumnDropSlot(x, y) : null);
|
|
9317
|
+
if (session.kind === "link" && session.hrefKey && slot) {
|
|
9318
|
+
nextOrder = planFooterLinkMove(session.hrefKey, slot.columnIndex, slot.insertIndex);
|
|
9319
|
+
} else if (session.kind === "column" && slot) {
|
|
9320
|
+
nextOrder = planFooterColumnMove(session.sourceColumnIndex, slot.insertIndex);
|
|
9321
|
+
}
|
|
9322
|
+
const wasSelected = session.wasSelected;
|
|
9323
|
+
const draggedEl = session.draggedEl;
|
|
9324
|
+
const hrefKey = session.hrefKey;
|
|
9325
|
+
let movedColumnIndex = null;
|
|
9326
|
+
if (session.kind === "column" && slot && nextOrder) {
|
|
9327
|
+
let adjusted = slot.insertIndex;
|
|
9328
|
+
if (session.sourceColumnIndex < slot.insertIndex) adjusted -= 1;
|
|
9329
|
+
movedColumnIndex = Math.max(0, Math.min(adjusted, nextOrder.length - 1));
|
|
9330
|
+
}
|
|
9331
|
+
const applySelectionAfterDrop = () => {
|
|
9332
|
+
if (!wasSelected) {
|
|
9333
|
+
deselectRef.current();
|
|
9334
|
+
return;
|
|
9335
|
+
}
|
|
9336
|
+
if (hrefKey) {
|
|
9337
|
+
selectedHrefKeyRef.current = hrefKey;
|
|
9338
|
+
selectedFooterColAttrRef.current = null;
|
|
9339
|
+
const link = resolveHrefKeyElement(hrefKey);
|
|
9340
|
+
if (link && isNavigationItem(link)) {
|
|
9341
|
+
selectRef.current(link);
|
|
9342
|
+
return;
|
|
9343
|
+
}
|
|
9344
|
+
}
|
|
9345
|
+
if (movedColumnIndex !== null && nextOrder) {
|
|
9346
|
+
const colKeys = nextOrder[movedColumnIndex] ?? [];
|
|
9347
|
+
let column = null;
|
|
9348
|
+
for (const key of colKeys) {
|
|
9349
|
+
const link = document.querySelector(
|
|
9350
|
+
`footer [data-ohw-href-key="${CSS.escape(key)}"]`
|
|
9351
|
+
);
|
|
9352
|
+
if (link) {
|
|
9353
|
+
column = findFooterColumnForLink(link);
|
|
9354
|
+
if (column) break;
|
|
9355
|
+
}
|
|
9356
|
+
}
|
|
9357
|
+
if (!column) column = listFooterColumns()[movedColumnIndex] ?? null;
|
|
9358
|
+
if (column && isNavigationContainer(column)) {
|
|
9359
|
+
selectFrameRef.current(column);
|
|
9360
|
+
return;
|
|
9361
|
+
}
|
|
9362
|
+
}
|
|
9363
|
+
if (document.body.contains(draggedEl)) {
|
|
9364
|
+
if (isNavigationItem(draggedEl)) {
|
|
9365
|
+
selectRef.current(draggedEl);
|
|
9366
|
+
return;
|
|
9367
|
+
}
|
|
9368
|
+
if (isNavigationContainer(draggedEl)) {
|
|
9369
|
+
selectFrameRef.current(draggedEl);
|
|
9370
|
+
return;
|
|
9371
|
+
}
|
|
9372
|
+
}
|
|
9373
|
+
deselectRef.current();
|
|
9374
|
+
};
|
|
9375
|
+
if (nextOrder) {
|
|
9376
|
+
const orderJson = JSON.stringify(nextOrder);
|
|
9377
|
+
editContentRef.current = {
|
|
9378
|
+
...editContentRef.current,
|
|
9379
|
+
[FOOTER_ORDER_KEY]: orderJson
|
|
9380
|
+
};
|
|
9381
|
+
applyFooterOrder(nextOrder);
|
|
9382
|
+
document.querySelectorAll("footer [data-ohw-href-key]").forEach(disableNativeHrefDrag);
|
|
9383
|
+
postToParentRef.current({
|
|
9384
|
+
type: "ow:change",
|
|
9385
|
+
nodes: [{ key: FOOTER_ORDER_KEY, text: orderJson }]
|
|
9386
|
+
});
|
|
9387
|
+
applySelectionAfterDrop();
|
|
9388
|
+
clearFooterDragVisuals();
|
|
9389
|
+
requestAnimationFrame(() => {
|
|
9390
|
+
if (editContentRef.current[FOOTER_ORDER_KEY] === orderJson) {
|
|
9391
|
+
applyFooterOrder(nextOrder);
|
|
9392
|
+
document.querySelectorAll("footer [data-ohw-href-key]").forEach(disableNativeHrefDrag);
|
|
9393
|
+
}
|
|
9394
|
+
applySelectionAfterDrop();
|
|
9395
|
+
requestAnimationFrame(() => {
|
|
9396
|
+
if (editContentRef.current[FOOTER_ORDER_KEY] === orderJson) {
|
|
9397
|
+
applyFooterOrder(nextOrder);
|
|
9398
|
+
}
|
|
9399
|
+
resyncSelectedNavigationItem();
|
|
9400
|
+
});
|
|
9401
|
+
});
|
|
9402
|
+
return;
|
|
9403
|
+
}
|
|
9404
|
+
applySelectionAfterDrop();
|
|
9405
|
+
clearFooterDragVisuals();
|
|
9406
|
+
},
|
|
9407
|
+
[clearFooterDragVisuals, resolveHrefKeyElement, resyncSelectedNavigationItem]
|
|
9408
|
+
);
|
|
9409
|
+
commitFooterDragRef.current = commitFooterDrag;
|
|
9410
|
+
const startFooterLinkDrag = useCallback4(
|
|
9411
|
+
(anchor, clientX, clientY, wasSelected) => {
|
|
9412
|
+
const hrefKey = anchor.getAttribute("data-ohw-href-key");
|
|
9413
|
+
if (!hrefKey || !isFooterHrefKey(hrefKey)) return false;
|
|
9414
|
+
const column = findFooterColumnForLink(anchor);
|
|
9415
|
+
const columns = listFooterColumns();
|
|
9416
|
+
beginFooterDrag({
|
|
9417
|
+
kind: "link",
|
|
9418
|
+
hrefKey,
|
|
9419
|
+
columnEl: column,
|
|
9420
|
+
sourceColumnIndex: column ? columns.indexOf(column) : 0,
|
|
9421
|
+
wasSelected,
|
|
9422
|
+
draggedEl: anchor,
|
|
9423
|
+
lastClientX: clientX,
|
|
9424
|
+
lastClientY: clientY,
|
|
9425
|
+
activeSlot: null
|
|
9426
|
+
});
|
|
9427
|
+
return true;
|
|
9428
|
+
},
|
|
9429
|
+
[beginFooterDrag]
|
|
9430
|
+
);
|
|
9431
|
+
const startFooterColumnDrag = useCallback4(
|
|
9432
|
+
(columnEl, clientX, clientY, wasSelected) => {
|
|
9433
|
+
const columns = listFooterColumns();
|
|
9434
|
+
const idx = columns.indexOf(columnEl);
|
|
9435
|
+
if (idx < 0) return false;
|
|
9436
|
+
beginFooterDrag({
|
|
9437
|
+
kind: "column",
|
|
9438
|
+
hrefKey: null,
|
|
9439
|
+
columnEl,
|
|
9440
|
+
sourceColumnIndex: idx,
|
|
9441
|
+
wasSelected,
|
|
9442
|
+
draggedEl: columnEl,
|
|
9443
|
+
lastClientX: clientX,
|
|
9444
|
+
lastClientY: clientY,
|
|
9445
|
+
activeSlot: null
|
|
9446
|
+
});
|
|
9447
|
+
return true;
|
|
9448
|
+
},
|
|
9449
|
+
[beginFooterDrag]
|
|
9450
|
+
);
|
|
9451
|
+
const handleItemDragStart = useCallback4(
|
|
9452
|
+
(e) => {
|
|
9453
|
+
const selected = selectedElRef.current;
|
|
9454
|
+
if (!selected) {
|
|
9455
|
+
setIsItemDragging(true);
|
|
9456
|
+
return;
|
|
9457
|
+
}
|
|
9458
|
+
const clientX = e?.clientX ?? selected.getBoundingClientRect().left + 8;
|
|
9459
|
+
const clientY = e?.clientY ?? selected.getBoundingClientRect().top + 8;
|
|
9460
|
+
if (startFooterLinkDrag(selected, clientX, clientY, true)) return;
|
|
9461
|
+
if (selected.hasAttribute("data-ohw-footer-col") || isInferredFooterGroup(selected) && selected.closest("footer")) {
|
|
9462
|
+
if (startFooterColumnDrag(selected, clientX, clientY, true)) return;
|
|
9463
|
+
}
|
|
9464
|
+
if (startNavLinkDrag(selected, clientX, clientY, true)) return;
|
|
9465
|
+
siblingHintElRef.current = null;
|
|
9466
|
+
setSiblingHintRect(null);
|
|
9467
|
+
setIsItemDragging(true);
|
|
9468
|
+
},
|
|
9469
|
+
[startFooterColumnDrag, startFooterLinkDrag, startNavLinkDrag]
|
|
9470
|
+
);
|
|
9471
|
+
const handleItemDragEnd = useCallback4(
|
|
9472
|
+
(e) => {
|
|
9473
|
+
if (footerDragRef.current) {
|
|
9474
|
+
const x = e?.clientX;
|
|
9475
|
+
const y = e?.clientY;
|
|
9476
|
+
if (typeof x === "number" && typeof y === "number" && (x !== 0 || y !== 0)) {
|
|
9477
|
+
commitFooterDrag(x, y);
|
|
9478
|
+
} else {
|
|
9479
|
+
commitFooterDrag();
|
|
9480
|
+
}
|
|
9481
|
+
return;
|
|
9482
|
+
}
|
|
9483
|
+
if (navDragRef.current) {
|
|
9484
|
+
const x = e?.clientX;
|
|
9485
|
+
const y = e?.clientY;
|
|
9486
|
+
if (typeof x === "number" && typeof y === "number" && (x !== 0 || y !== 0)) {
|
|
9487
|
+
commitNavDrag(x, y);
|
|
9488
|
+
} else {
|
|
9489
|
+
commitNavDrag();
|
|
9490
|
+
}
|
|
9491
|
+
return;
|
|
7915
9492
|
}
|
|
9493
|
+
setIsItemDragging(false);
|
|
9494
|
+
},
|
|
9495
|
+
[commitFooterDrag, commitNavDrag, navDragRef]
|
|
9496
|
+
);
|
|
9497
|
+
const handleItemChromePointerDown = useCallback4((e) => {
|
|
9498
|
+
if (e.button !== 0) return;
|
|
9499
|
+
const selected = selectedElRef.current;
|
|
9500
|
+
if (!selected) return;
|
|
9501
|
+
armFooterPressDrag();
|
|
9502
|
+
const hrefKey = selected.getAttribute("data-ohw-href-key");
|
|
9503
|
+
if (hrefKey && isFooterHrefKey(hrefKey)) {
|
|
9504
|
+
footerPointerDragRef.current = {
|
|
9505
|
+
el: selected,
|
|
9506
|
+
kind: "link",
|
|
9507
|
+
startX: e.clientX,
|
|
9508
|
+
startY: e.clientY,
|
|
9509
|
+
pointerId: e.pointerId,
|
|
9510
|
+
wasSelected: true,
|
|
9511
|
+
started: false
|
|
9512
|
+
};
|
|
9513
|
+
return;
|
|
7916
9514
|
}
|
|
7917
|
-
|
|
7918
|
-
|
|
7919
|
-
|
|
7920
|
-
|
|
7921
|
-
|
|
7922
|
-
|
|
7923
|
-
|
|
7924
|
-
|
|
7925
|
-
|
|
7926
|
-
|
|
7927
|
-
|
|
7928
|
-
|
|
7929
|
-
|
|
7930
|
-
|
|
7931
|
-
|
|
7932
|
-
|
|
7933
|
-
|
|
7934
|
-
|
|
7935
|
-
|
|
7936
|
-
|
|
7937
|
-
|
|
7938
|
-
|
|
7939
|
-
|
|
7940
|
-
|
|
7941
|
-
setIsItemDragging(true);
|
|
7942
|
-
}, []);
|
|
7943
|
-
const handleItemDragEnd = useCallback3(() => {
|
|
7944
|
-
setIsItemDragging(false);
|
|
9515
|
+
if (selected.hasAttribute("data-ohw-footer-col") || isInferredFooterGroup(selected) && selected.closest("footer")) {
|
|
9516
|
+
footerPointerDragRef.current = {
|
|
9517
|
+
el: selected,
|
|
9518
|
+
kind: "column",
|
|
9519
|
+
startX: e.clientX,
|
|
9520
|
+
startY: e.clientY,
|
|
9521
|
+
pointerId: e.pointerId,
|
|
9522
|
+
wasSelected: true,
|
|
9523
|
+
started: false
|
|
9524
|
+
};
|
|
9525
|
+
return;
|
|
9526
|
+
}
|
|
9527
|
+
if (armNavPressFromChrome(selected, e.clientX, e.clientY, e.pointerId)) return;
|
|
9528
|
+
}, [armNavPressFromChrome]);
|
|
9529
|
+
const handleItemChromeClick = useCallback4((clientX, clientY) => {
|
|
9530
|
+
if (suppressNextClickRef.current || Date.now() < suppressClickUntilRef.current) {
|
|
9531
|
+
suppressNextClickRef.current = false;
|
|
9532
|
+
return;
|
|
9533
|
+
}
|
|
9534
|
+
const selected = selectedElRef.current;
|
|
9535
|
+
if (!selected || !isNavigationItem(selected)) return;
|
|
9536
|
+
const editable = selected.querySelector('[data-ohw-editable="text"]') ?? selected.querySelector("[data-ohw-editable]");
|
|
9537
|
+
if (!editable) return;
|
|
9538
|
+
activateRef.current(editable, { caretX: clientX, caretY: clientY });
|
|
7945
9539
|
}, []);
|
|
7946
9540
|
reselectNavigationItemRef.current = reselectNavigationItem;
|
|
7947
9541
|
commitNavigationTextEditRef.current = commitNavigationTextEdit;
|
|
7948
|
-
const select =
|
|
9542
|
+
const select = useCallback4((anchor) => {
|
|
7949
9543
|
if (!isNavigationItem(anchor)) return;
|
|
7950
9544
|
if (activeElRef.current) deactivate();
|
|
7951
9545
|
selectedElRef.current = anchor;
|
|
9546
|
+
selectedHrefKeyRef.current = anchor.getAttribute("data-ohw-href-key");
|
|
9547
|
+
selectedFooterColAttrRef.current = null;
|
|
7952
9548
|
markSelected(anchor);
|
|
7953
9549
|
setSelectedIsCta(isNavbarButton2(anchor));
|
|
7954
9550
|
clearHrefKeyHover(anchor);
|
|
@@ -7958,19 +9554,24 @@ function OhhwellsBridge() {
|
|
|
7958
9554
|
hoveredItemElRef.current = null;
|
|
7959
9555
|
siblingHintElRef.current = null;
|
|
7960
9556
|
setSiblingHintRect(null);
|
|
9557
|
+
setSiblingHintRects(collectNavigationItemSiblingHintRects(anchor));
|
|
7961
9558
|
setIsItemDragging(false);
|
|
7962
9559
|
const { key, disabled } = getNavigationItemReorderState(anchor);
|
|
7963
9560
|
setReorderHrefKey(key);
|
|
7964
9561
|
setReorderDragDisabled(disabled);
|
|
9562
|
+
setIsFooterFrameSelection(false);
|
|
7965
9563
|
setToolbarVariant("link-action");
|
|
7966
9564
|
setToolbarRect(anchor.getBoundingClientRect());
|
|
7967
9565
|
setToolbarShowEditLink(false);
|
|
7968
9566
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
7969
9567
|
}, [deactivate, markSelected]);
|
|
7970
|
-
const selectFrame =
|
|
9568
|
+
const selectFrame = useCallback4((el) => {
|
|
7971
9569
|
if (!isNavigationContainer(el)) return;
|
|
7972
9570
|
if (activeElRef.current) deactivate();
|
|
9571
|
+
const isFooterColumn = el.hasAttribute("data-ohw-footer-col") || Boolean(el.closest("footer") && isInferredFooterGroup(el));
|
|
7973
9572
|
selectedElRef.current = el;
|
|
9573
|
+
selectedHrefKeyRef.current = null;
|
|
9574
|
+
selectedFooterColAttrRef.current = isFooterColumn ? el.getAttribute("data-ohw-footer-col") ?? String(listFooterColumns().indexOf(el)) : null;
|
|
7974
9575
|
markSelected(el);
|
|
7975
9576
|
setSelectedIsCta(false);
|
|
7976
9577
|
clearHrefKeyHover(el);
|
|
@@ -7980,18 +9581,24 @@ function OhhwellsBridge() {
|
|
|
7980
9581
|
hoveredItemElRef.current = null;
|
|
7981
9582
|
siblingHintElRef.current = null;
|
|
7982
9583
|
setSiblingHintRect(null);
|
|
9584
|
+
setSiblingHintRects(
|
|
9585
|
+
isFooterColumn ? listFooterColumns().filter((column) => column !== el).map((column) => column.getBoundingClientRect()) : []
|
|
9586
|
+
);
|
|
7983
9587
|
setIsItemDragging(false);
|
|
7984
9588
|
setReorderHrefKey(null);
|
|
7985
9589
|
setReorderDragDisabled(false);
|
|
9590
|
+
setIsFooterFrameSelection(isFooterColumn);
|
|
7986
9591
|
setToolbarVariant("select-frame");
|
|
7987
9592
|
setToolbarRect(el.getBoundingClientRect());
|
|
7988
9593
|
setToolbarShowEditLink(false);
|
|
7989
9594
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
7990
9595
|
}, [deactivate, markSelected]);
|
|
7991
|
-
const activate =
|
|
9596
|
+
const activate = useCallback4((el, options) => {
|
|
7992
9597
|
if (activeElRef.current === el) return;
|
|
7993
9598
|
clearSelectedAttr();
|
|
7994
9599
|
selectedElRef.current = null;
|
|
9600
|
+
selectedHrefKeyRef.current = null;
|
|
9601
|
+
selectedFooterColAttrRef.current = null;
|
|
7995
9602
|
setSelectedIsCta(false);
|
|
7996
9603
|
deactivate();
|
|
7997
9604
|
if (hoveredImageRef.current) {
|
|
@@ -8010,7 +9617,11 @@ function OhhwellsBridge() {
|
|
|
8010
9617
|
originalContentRef.current = el.innerHTML;
|
|
8011
9618
|
el.focus({ preventScroll: true });
|
|
8012
9619
|
if (options?.caretX !== void 0 && options?.caretY !== void 0) {
|
|
8013
|
-
|
|
9620
|
+
const { caretX, caretY } = options;
|
|
9621
|
+
placeCaretAtPoint(el, caretX, caretY);
|
|
9622
|
+
requestAnimationFrame(() => {
|
|
9623
|
+
if (activeElRef.current === el) placeCaretAtPoint(el, caretX, caretY);
|
|
9624
|
+
});
|
|
8014
9625
|
} else {
|
|
8015
9626
|
const selection = window.getSelection();
|
|
8016
9627
|
if (selection && selection.rangeCount === 0) {
|
|
@@ -8081,6 +9692,7 @@ function OhhwellsBridge() {
|
|
|
8081
9692
|
applyLinkByKey(key, val);
|
|
8082
9693
|
}
|
|
8083
9694
|
reconcileNavbarItemsFromContent(content);
|
|
9695
|
+
reconcileFooterOrderFromContent(content);
|
|
8084
9696
|
enforceLinkHrefs();
|
|
8085
9697
|
initSectionsFromContent(content, true);
|
|
8086
9698
|
sectionsLoadedRef.current = true;
|
|
@@ -8109,7 +9721,7 @@ function OhhwellsBridge() {
|
|
|
8109
9721
|
cancelled = true;
|
|
8110
9722
|
};
|
|
8111
9723
|
}, [subdomain, isEditMode]);
|
|
8112
|
-
|
|
9724
|
+
useEffect8(() => {
|
|
8113
9725
|
if (!subdomain || isEditMode) return;
|
|
8114
9726
|
let debounceTimer = null;
|
|
8115
9727
|
let observer = null;
|
|
@@ -8141,6 +9753,7 @@ function OhhwellsBridge() {
|
|
|
8141
9753
|
applyLinkByKey(key, val);
|
|
8142
9754
|
}
|
|
8143
9755
|
reconcileNavbarItemsFromContent(content);
|
|
9756
|
+
reconcileFooterOrderFromContent(content);
|
|
8144
9757
|
} finally {
|
|
8145
9758
|
observer?.observe(document.body, { childList: true, subtree: true });
|
|
8146
9759
|
}
|
|
@@ -8164,10 +9777,10 @@ function OhhwellsBridge() {
|
|
|
8164
9777
|
const visible = Boolean(subdomain) && fetchState !== "done";
|
|
8165
9778
|
el.style.display = visible ? "flex" : "none";
|
|
8166
9779
|
}, [subdomain, fetchState]);
|
|
8167
|
-
|
|
9780
|
+
useEffect8(() => {
|
|
8168
9781
|
postToParent2({ type: "ow:navigation", path: pathname });
|
|
8169
9782
|
}, [pathname, postToParent2]);
|
|
8170
|
-
|
|
9783
|
+
useEffect8(() => {
|
|
8171
9784
|
if (!isEditMode) return;
|
|
8172
9785
|
if (linkPopoverSessionRef.current?.intent === "add-nav") return;
|
|
8173
9786
|
if (document.querySelector("[data-ohw-section-picker]")) return;
|
|
@@ -8175,7 +9788,7 @@ function OhhwellsBridge() {
|
|
|
8175
9788
|
deselectRef.current();
|
|
8176
9789
|
deactivateRef.current();
|
|
8177
9790
|
}, [pathname, isEditMode]);
|
|
8178
|
-
|
|
9791
|
+
useEffect8(() => {
|
|
8179
9792
|
const contentForNav = () => {
|
|
8180
9793
|
if (isEditMode) return editContentRef.current;
|
|
8181
9794
|
if (!subdomain) return {};
|
|
@@ -8187,6 +9800,7 @@ function OhhwellsBridge() {
|
|
|
8187
9800
|
const roots = observeRoots();
|
|
8188
9801
|
if (roots.length === 0) {
|
|
8189
9802
|
reconcileNavbarItemsFromContent(contentForNav());
|
|
9803
|
+
reconcileFooterOrderFromContent(contentForNav());
|
|
8190
9804
|
if (isEditMode) syncNavigationDragCursorAttrs();
|
|
8191
9805
|
return;
|
|
8192
9806
|
}
|
|
@@ -8199,11 +9813,26 @@ function OhhwellsBridge() {
|
|
|
8199
9813
|
}
|
|
8200
9814
|
};
|
|
8201
9815
|
const run = () => {
|
|
8202
|
-
if (applying) return;
|
|
9816
|
+
if (footerDragRef.current || navDragRef.current || applying) return;
|
|
8203
9817
|
applying = true;
|
|
8204
9818
|
observer?.disconnect();
|
|
8205
9819
|
try {
|
|
8206
|
-
|
|
9820
|
+
const content = contentForNav();
|
|
9821
|
+
reconcileNavbarItemsFromContent(content);
|
|
9822
|
+
reconcileFooterOrderFromContent(content);
|
|
9823
|
+
document.querySelectorAll("footer [data-ohw-href-key]").forEach((el) => {
|
|
9824
|
+
if (isFooterHrefKey(el.getAttribute("data-ohw-href-key"))) {
|
|
9825
|
+
disableNativeHrefDrag(el);
|
|
9826
|
+
}
|
|
9827
|
+
});
|
|
9828
|
+
document.querySelectorAll(
|
|
9829
|
+
"nav [data-ohw-href-key], [data-ohw-nav-container] [data-ohw-href-key], [data-ohw-nav-drawer] [data-ohw-href-key]"
|
|
9830
|
+
).forEach((el) => {
|
|
9831
|
+
if (isNavbarHrefKey(el.getAttribute("data-ohw-href-key"))) {
|
|
9832
|
+
disableNativeHrefDrag(el);
|
|
9833
|
+
}
|
|
9834
|
+
});
|
|
9835
|
+
resyncSelectedNavigationItem();
|
|
8207
9836
|
if (isEditMode) syncNavigationDragCursorAttrs();
|
|
8208
9837
|
} finally {
|
|
8209
9838
|
applying = false;
|
|
@@ -8223,8 +9852,8 @@ function OhhwellsBridge() {
|
|
|
8223
9852
|
if (rafId != null) cancelAnimationFrame(rafId);
|
|
8224
9853
|
observer?.disconnect();
|
|
8225
9854
|
};
|
|
8226
|
-
}, [isEditMode, pathname, subdomain, fetchState]);
|
|
8227
|
-
|
|
9855
|
+
}, [isEditMode, pathname, subdomain, fetchState, resyncSelectedNavigationItem]);
|
|
9856
|
+
useEffect8(() => {
|
|
8228
9857
|
if (!isEditMode) return;
|
|
8229
9858
|
const measure = () => {
|
|
8230
9859
|
const h = document.body.scrollHeight;
|
|
@@ -8248,7 +9877,7 @@ function OhhwellsBridge() {
|
|
|
8248
9877
|
window.removeEventListener("resize", handleResize);
|
|
8249
9878
|
};
|
|
8250
9879
|
}, [pathname, isEditMode, postToParent2]);
|
|
8251
|
-
|
|
9880
|
+
useEffect8(() => {
|
|
8252
9881
|
if (!subdomainFromQuery || isEditMode) return;
|
|
8253
9882
|
const handleClick = (e) => {
|
|
8254
9883
|
const anchor = e.target.closest("a");
|
|
@@ -8264,7 +9893,7 @@ function OhhwellsBridge() {
|
|
|
8264
9893
|
document.addEventListener("click", handleClick, true);
|
|
8265
9894
|
return () => document.removeEventListener("click", handleClick, true);
|
|
8266
9895
|
}, [subdomainFromQuery, isEditMode, router]);
|
|
8267
|
-
|
|
9896
|
+
useEffect8(() => {
|
|
8268
9897
|
if (!isEditMode) {
|
|
8269
9898
|
editStylesRef.current?.base.remove();
|
|
8270
9899
|
editStylesRef.current?.forceHover.remove();
|
|
@@ -8326,6 +9955,21 @@ function OhhwellsBridge() {
|
|
|
8326
9955
|
outline: none !important;
|
|
8327
9956
|
outline-offset: 0 !important;
|
|
8328
9957
|
}
|
|
9958
|
+
/* Editor chrome owns selection \u2014 suppress native focus rings on nav/footer items. */
|
|
9959
|
+
nav [data-ohw-href-key]:focus,
|
|
9960
|
+
nav [data-ohw-href-key]:focus-visible,
|
|
9961
|
+
nav [data-ohw-href-key]:focus-within,
|
|
9962
|
+
footer [data-ohw-href-key]:focus,
|
|
9963
|
+
footer [data-ohw-href-key]:focus-visible,
|
|
9964
|
+
footer [data-ohw-href-key]:focus-within,
|
|
9965
|
+
nav [data-ohw-href-key] [data-ohw-editable]:focus,
|
|
9966
|
+
nav [data-ohw-href-key] [data-ohw-editable]:focus-visible,
|
|
9967
|
+
footer [data-ohw-href-key] [data-ohw-editable]:focus,
|
|
9968
|
+
footer [data-ohw-href-key] [data-ohw-editable]:focus-visible {
|
|
9969
|
+
outline: none !important;
|
|
9970
|
+
outline-offset: 0 !important;
|
|
9971
|
+
box-shadow: none !important;
|
|
9972
|
+
}
|
|
8329
9973
|
/* Text edit wins over grab/default (must beat [data-ohw-can-drag] *). */
|
|
8330
9974
|
[data-ohw-editing],
|
|
8331
9975
|
[data-ohw-editing] *,
|
|
@@ -8367,12 +10011,39 @@ function OhhwellsBridge() {
|
|
|
8367
10011
|
syncNavigationDragCursorAttrs();
|
|
8368
10012
|
refreshStateRules();
|
|
8369
10013
|
const handleClick = (e) => {
|
|
10014
|
+
if (suppressNextClickRef.current || Date.now() < suppressClickUntilRef.current) {
|
|
10015
|
+
suppressNextClickRef.current = false;
|
|
10016
|
+
e.preventDefault();
|
|
10017
|
+
e.stopPropagation();
|
|
10018
|
+
return;
|
|
10019
|
+
}
|
|
8370
10020
|
const target = e.target;
|
|
8371
10021
|
if (target.closest("[data-ohw-toolbar]")) return;
|
|
8372
10022
|
if (target.closest("[data-ohw-state-toggle]")) return;
|
|
8373
10023
|
if (target.closest("[data-ohw-max-badge]")) return;
|
|
8374
10024
|
if (isInsideLinkEditor(target)) return;
|
|
8375
10025
|
if (target.closest('[data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
|
|
10026
|
+
if (target.closest("[data-ohw-item-drag-surface]")) {
|
|
10027
|
+
e.preventDefault();
|
|
10028
|
+
e.stopPropagation();
|
|
10029
|
+
const selected = selectedElRef.current;
|
|
10030
|
+
if (selected && isNavigationItem(selected)) {
|
|
10031
|
+
const editable2 = selected.querySelector('[data-ohw-editable="text"]') ?? selected.querySelector("[data-ohw-editable]");
|
|
10032
|
+
if (editable2) {
|
|
10033
|
+
activateRef.current(editable2, {
|
|
10034
|
+
caretX: e.clientX,
|
|
10035
|
+
caretY: e.clientY
|
|
10036
|
+
});
|
|
10037
|
+
}
|
|
10038
|
+
} else if (selected?.hasAttribute("data-ohw-footer-col")) {
|
|
10039
|
+
const link = listFooterLinksInColumn(selected).find((el) => {
|
|
10040
|
+
const r2 = el.getBoundingClientRect();
|
|
10041
|
+
return e.clientX >= r2.left && e.clientX <= r2.right && e.clientY >= r2.top && e.clientY <= r2.bottom;
|
|
10042
|
+
});
|
|
10043
|
+
if (link) selectRef.current(link);
|
|
10044
|
+
}
|
|
10045
|
+
return;
|
|
10046
|
+
}
|
|
8376
10047
|
const navFromChrome = resolveNavContainerSelectionTarget(target, e.clientX, e.clientY);
|
|
8377
10048
|
if (navFromChrome) {
|
|
8378
10049
|
e.preventDefault();
|
|
@@ -8451,10 +10122,26 @@ function OhhwellsBridge() {
|
|
|
8451
10122
|
if (hrefAnchor) {
|
|
8452
10123
|
e.preventDefault();
|
|
8453
10124
|
e.stopPropagation();
|
|
8454
|
-
if (selectedElRef.current === hrefAnchor)
|
|
10125
|
+
if (selectedElRef.current === hrefAnchor) {
|
|
10126
|
+
const textEditable = hrefAnchor.querySelector('[data-ohw-editable="text"]') ?? hrefAnchor.querySelector("[data-ohw-editable]");
|
|
10127
|
+
if (textEditable) {
|
|
10128
|
+
activateRef.current(textEditable, {
|
|
10129
|
+
caretX: e.clientX,
|
|
10130
|
+
caretY: e.clientY
|
|
10131
|
+
});
|
|
10132
|
+
}
|
|
10133
|
+
return;
|
|
10134
|
+
}
|
|
8455
10135
|
selectRef.current(hrefAnchor);
|
|
8456
10136
|
return;
|
|
8457
10137
|
}
|
|
10138
|
+
const footerColClick = target.closest("[data-ohw-footer-col]");
|
|
10139
|
+
if (footerColClick) {
|
|
10140
|
+
e.preventDefault();
|
|
10141
|
+
e.stopPropagation();
|
|
10142
|
+
selectFrameRef.current(footerColClick);
|
|
10143
|
+
return;
|
|
10144
|
+
}
|
|
8458
10145
|
const navContainerToSelect = resolveNavContainerSelectionTarget(target, e.clientX, e.clientY);
|
|
8459
10146
|
if (navContainerToSelect) {
|
|
8460
10147
|
e.preventDefault();
|
|
@@ -8528,16 +10215,23 @@ function OhhwellsBridge() {
|
|
|
8528
10215
|
const handleMouseOver = (e) => {
|
|
8529
10216
|
if (document.documentElement.hasAttribute("data-ohw-section-picking")) return;
|
|
8530
10217
|
const target = e.target;
|
|
10218
|
+
if (linkPopoverOpenRef.current) {
|
|
10219
|
+
hoveredItemElRef.current = null;
|
|
10220
|
+
setHoveredItemRect(null);
|
|
10221
|
+
hoveredNavContainerRef.current = null;
|
|
10222
|
+
setHoveredNavContainerRect(null);
|
|
10223
|
+
return;
|
|
10224
|
+
}
|
|
8531
10225
|
if (toolbarVariantRef.current !== "select-frame") {
|
|
8532
|
-
const
|
|
8533
|
-
if (
|
|
8534
|
-
hoveredNavContainerRef.current =
|
|
8535
|
-
setHoveredNavContainerRect(
|
|
10226
|
+
const navContainer = target.closest("[data-ohw-nav-container]");
|
|
10227
|
+
if (navContainer && !getNavigationItemAnchor(target)) {
|
|
10228
|
+
hoveredNavContainerRef.current = navContainer;
|
|
10229
|
+
setHoveredNavContainerRect(navContainer.getBoundingClientRect());
|
|
8536
10230
|
hoveredItemElRef.current = null;
|
|
8537
10231
|
setHoveredItemRect(null);
|
|
8538
10232
|
return;
|
|
8539
10233
|
}
|
|
8540
|
-
if (!target.closest("[data-ohw-nav-container]
|
|
10234
|
+
if (!target.closest("[data-ohw-nav-container]")) {
|
|
8541
10235
|
hoveredNavContainerRef.current = null;
|
|
8542
10236
|
setHoveredNavContainerRect(null);
|
|
8543
10237
|
}
|
|
@@ -8547,12 +10241,21 @@ function OhhwellsBridge() {
|
|
|
8547
10241
|
hoveredNavContainerRef.current = null;
|
|
8548
10242
|
setHoveredNavContainerRect(null);
|
|
8549
10243
|
const selected2 = selectedElRef.current;
|
|
8550
|
-
if (selected2 === navAnchor
|
|
10244
|
+
if (selected2 === navAnchor) return;
|
|
8551
10245
|
clearHrefKeyHover(navAnchor);
|
|
8552
10246
|
hoveredItemElRef.current = navAnchor;
|
|
8553
10247
|
setHoveredItemRect(navAnchor.getBoundingClientRect());
|
|
8554
10248
|
return;
|
|
8555
10249
|
}
|
|
10250
|
+
const footerCol = target.closest("[data-ohw-footer-col]") ?? target.closest("[data-ohw-footer-column]");
|
|
10251
|
+
if (footerCol) {
|
|
10252
|
+
hoveredNavContainerRef.current = null;
|
|
10253
|
+
setHoveredNavContainerRect(null);
|
|
10254
|
+
if (selectedElRef.current === footerCol) return;
|
|
10255
|
+
hoveredItemElRef.current = footerCol;
|
|
10256
|
+
setHoveredItemRect(footerCol.getBoundingClientRect());
|
|
10257
|
+
return;
|
|
10258
|
+
}
|
|
8556
10259
|
const editable = target.closest("[data-ohw-editable]");
|
|
8557
10260
|
if (!editable) return;
|
|
8558
10261
|
const selected = selectedElRef.current;
|
|
@@ -8570,14 +10273,25 @@ function OhhwellsBridge() {
|
|
|
8570
10273
|
};
|
|
8571
10274
|
const handleMouseOut = (e) => {
|
|
8572
10275
|
const target = e.target;
|
|
8573
|
-
if (target.closest("[data-ohw-nav-container], [data-ohw-footer-column]")) {
|
|
10276
|
+
if (target.closest("[data-ohw-nav-container], [data-ohw-footer-col], [data-ohw-footer-column]")) {
|
|
8574
10277
|
const related2 = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
8575
|
-
if (related2?.closest("[data-ohw-nav-container], [data-ohw-footer-column], [data-ohw-navbar-container-chrome], [data-ohw-navbar-add-button]")) {
|
|
10278
|
+
if (related2?.closest("[data-ohw-nav-container], [data-ohw-footer-col], [data-ohw-footer-column], [data-ohw-navbar-container-chrome], [data-ohw-navbar-add-button]")) {
|
|
8576
10279
|
return;
|
|
8577
10280
|
}
|
|
8578
10281
|
hoveredNavContainerRef.current = null;
|
|
8579
10282
|
setHoveredNavContainerRect(null);
|
|
8580
10283
|
}
|
|
10284
|
+
const footerCol = target.closest("[data-ohw-footer-col]") ?? target.closest("[data-ohw-footer-column]");
|
|
10285
|
+
if (footerCol && hoveredItemElRef.current === footerCol) {
|
|
10286
|
+
const related2 = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
10287
|
+
if (related2?.closest("[data-ohw-drag-handle-container], [data-ohw-item-interaction]")) return;
|
|
10288
|
+
if (related2?.closest("[data-ohw-footer-col], [data-ohw-footer-column]") === footerCol) {
|
|
10289
|
+
return;
|
|
10290
|
+
}
|
|
10291
|
+
hoveredItemElRef.current = null;
|
|
10292
|
+
setHoveredItemRect(null);
|
|
10293
|
+
return;
|
|
10294
|
+
}
|
|
8581
10295
|
const navAnchor = getNavigationItemAnchor(target);
|
|
8582
10296
|
if (navAnchor) {
|
|
8583
10297
|
const related2 = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
@@ -8711,14 +10425,12 @@ function OhhwellsBridge() {
|
|
|
8711
10425
|
if (toolbarVariantRef.current === "select-frame") {
|
|
8712
10426
|
hoveredNavContainerRef.current = null;
|
|
8713
10427
|
setHoveredNavContainerRect(null);
|
|
8714
|
-
return;
|
|
8715
10428
|
}
|
|
8716
|
-
const
|
|
8717
|
-
|
|
8718
|
-
|
|
8719
|
-
|
|
8720
|
-
|
|
8721
|
-
for (const container of frameContainers) {
|
|
10429
|
+
const navContainers = Array.from(
|
|
10430
|
+
document.querySelectorAll("[data-ohw-nav-container]")
|
|
10431
|
+
);
|
|
10432
|
+
const footerColumns = listFooterColumns();
|
|
10433
|
+
for (const container of [...navContainers, ...footerColumns]) {
|
|
8722
10434
|
const containerRect = container.getBoundingClientRect();
|
|
8723
10435
|
const overContainer = x >= containerRect.left && x <= containerRect.right && y >= containerRect.top && y <= containerRect.bottom;
|
|
8724
10436
|
if (!overContainer) continue;
|
|
@@ -8733,25 +10445,55 @@ function OhhwellsBridge() {
|
|
|
8733
10445
|
hoveredNavContainerRef.current = null;
|
|
8734
10446
|
setHoveredNavContainerRect(null);
|
|
8735
10447
|
const selected = selectedElRef.current;
|
|
8736
|
-
if (selected !== navItemHit
|
|
10448
|
+
if (selected !== navItemHit) {
|
|
8737
10449
|
clearHrefKeyHover(navItemHit);
|
|
8738
10450
|
hoveredItemElRef.current = navItemHit;
|
|
8739
10451
|
setHoveredItemRect(navItemHit.getBoundingClientRect());
|
|
10452
|
+
} else if (hoveredItemElRef.current === navItemHit) {
|
|
10453
|
+
hoveredItemElRef.current = null;
|
|
10454
|
+
setHoveredItemRect(null);
|
|
8740
10455
|
}
|
|
8741
10456
|
return;
|
|
8742
10457
|
}
|
|
8743
|
-
overFrame = container;
|
|
8744
|
-
break;
|
|
8745
10458
|
}
|
|
8746
|
-
if (
|
|
10459
|
+
if (toolbarVariantRef.current !== "select-frame") {
|
|
10460
|
+
for (const container of navContainers) {
|
|
10461
|
+
const containerRect = container.getBoundingClientRect();
|
|
10462
|
+
const overContainer = x >= containerRect.left && x <= containerRect.right && y >= containerRect.top && y <= containerRect.bottom;
|
|
10463
|
+
if (!overContainer) continue;
|
|
10464
|
+
if (isPointOverNavItem(container, x, y)) continue;
|
|
10465
|
+
hoveredNavContainerRef.current = container;
|
|
10466
|
+
setHoveredNavContainerRect(container.getBoundingClientRect());
|
|
10467
|
+
hoveredItemElRef.current = null;
|
|
10468
|
+
setHoveredItemRect(null);
|
|
10469
|
+
return;
|
|
10470
|
+
}
|
|
10471
|
+
hoveredNavContainerRef.current = null;
|
|
10472
|
+
setHoveredNavContainerRect(null);
|
|
10473
|
+
} else {
|
|
8747
10474
|
hoveredNavContainerRef.current = null;
|
|
8748
10475
|
setHoveredNavContainerRect(null);
|
|
10476
|
+
}
|
|
10477
|
+
for (const column of footerColumns) {
|
|
10478
|
+
const containerRect = column.getBoundingClientRect();
|
|
10479
|
+
const overContainer = x >= containerRect.left && x <= containerRect.right && y >= containerRect.top && y <= containerRect.bottom;
|
|
10480
|
+
if (!overContainer) continue;
|
|
10481
|
+
if (isPointOverNavItem(column, x, y)) continue;
|
|
10482
|
+
if (selectedElRef.current === column) {
|
|
10483
|
+
if (hoveredItemElRef.current === column) {
|
|
10484
|
+
hoveredItemElRef.current = null;
|
|
10485
|
+
setHoveredItemRect(null);
|
|
10486
|
+
}
|
|
10487
|
+
return;
|
|
10488
|
+
}
|
|
10489
|
+
hoveredItemElRef.current = column;
|
|
10490
|
+
setHoveredItemRect(column.getBoundingClientRect());
|
|
8749
10491
|
return;
|
|
8750
10492
|
}
|
|
8751
|
-
|
|
8752
|
-
|
|
8753
|
-
|
|
8754
|
-
|
|
10493
|
+
if (hoveredItemElRef.current?.hasAttribute("data-ohw-footer-col") || hoveredItemElRef.current?.hasAttribute("data-ohw-footer-column")) {
|
|
10494
|
+
hoveredItemElRef.current = null;
|
|
10495
|
+
setHoveredItemRect(null);
|
|
10496
|
+
}
|
|
8755
10497
|
};
|
|
8756
10498
|
const probeImageAt = (clientX, clientY, isDragOver = false, fromParentViewport = false) => {
|
|
8757
10499
|
if (linkPopoverOpenRef.current) {
|
|
@@ -8772,6 +10514,10 @@ function OhhwellsBridge() {
|
|
|
8772
10514
|
}
|
|
8773
10515
|
hoveredNavContainerRef.current = null;
|
|
8774
10516
|
setHoveredNavContainerRect(null);
|
|
10517
|
+
if (hoveredItemElRef.current?.hasAttribute("data-ohw-footer-col") || hoveredItemElRef.current?.hasAttribute("data-ohw-footer-column")) {
|
|
10518
|
+
hoveredItemElRef.current = null;
|
|
10519
|
+
setHoveredItemRect(null);
|
|
10520
|
+
}
|
|
8775
10521
|
const toggleEl = document.querySelector("[data-ohw-state-toggle]");
|
|
8776
10522
|
if (toggleEl) {
|
|
8777
10523
|
const tr = toggleEl.getBoundingClientRect();
|
|
@@ -9019,6 +10765,15 @@ function OhhwellsBridge() {
|
|
|
9019
10765
|
probeHoverCardsAt(clientX, clientY);
|
|
9020
10766
|
};
|
|
9021
10767
|
const handleDragOver = (e) => {
|
|
10768
|
+
const footerSession = footerDragRef.current;
|
|
10769
|
+
if (footerSession) {
|
|
10770
|
+
e.preventDefault();
|
|
10771
|
+
if (e.dataTransfer) e.dataTransfer.dropEffect = "move";
|
|
10772
|
+
const slot = footerSession.kind === "link" && footerSession.hrefKey ? hitTestLinkDropSlot(e.clientX, e.clientY, footerSession.hrefKey) : hitTestColumnDropSlot(e.clientX, e.clientY);
|
|
10773
|
+
refreshFooterDragVisualsRef.current(footerSession, slot, e.clientX, e.clientY);
|
|
10774
|
+
return;
|
|
10775
|
+
}
|
|
10776
|
+
if (onNavDragOver(e)) return;
|
|
9022
10777
|
e.preventDefault();
|
|
9023
10778
|
const el = findImageAtPoint(e.clientX, e.clientY, false);
|
|
9024
10779
|
if (!el) {
|
|
@@ -9382,6 +11137,26 @@ function OhhwellsBridge() {
|
|
|
9382
11137
|
if (siblingHintElRef.current) {
|
|
9383
11138
|
setSiblingHintRect(siblingHintElRef.current.getBoundingClientRect());
|
|
9384
11139
|
}
|
|
11140
|
+
const selected = selectedElRef.current;
|
|
11141
|
+
if (selected && !footerDragRef.current && !navDragRef.current) {
|
|
11142
|
+
if (selected.hasAttribute("data-ohw-footer-col") || Boolean(selected.closest("footer") && isInferredFooterGroup(selected))) {
|
|
11143
|
+
setSiblingHintRects(
|
|
11144
|
+
listFooterColumns().filter((column) => column !== selected).map((column) => column.getBoundingClientRect())
|
|
11145
|
+
);
|
|
11146
|
+
} else if (isNavigationItem(selected)) {
|
|
11147
|
+
setSiblingHintRects(collectNavigationItemSiblingHintRects(selected));
|
|
11148
|
+
}
|
|
11149
|
+
}
|
|
11150
|
+
if (footerDragRef.current) {
|
|
11151
|
+
const session = footerDragRef.current;
|
|
11152
|
+
const slot = session.kind === "link" && session.hrefKey ? hitTestLinkDropSlot(session.lastClientX, session.lastClientY, session.hrefKey) : hitTestColumnDropSlot(session.lastClientX, session.lastClientY);
|
|
11153
|
+
refreshFooterDragVisualsRef.current(session, slot, session.lastClientX, session.lastClientY);
|
|
11154
|
+
}
|
|
11155
|
+
if (navDragRef.current) {
|
|
11156
|
+
const session = navDragRef.current;
|
|
11157
|
+
const slot = hitTestNavDropSlot(session.lastClientX, session.lastClientY, session.hrefKey);
|
|
11158
|
+
refreshNavDragVisualsRef.current(session, slot, session.lastClientX, session.lastClientY);
|
|
11159
|
+
}
|
|
9385
11160
|
if (hoveredImageRef.current) {
|
|
9386
11161
|
const el = hoveredImageRef.current;
|
|
9387
11162
|
const r2 = el.getBoundingClientRect();
|
|
@@ -9392,7 +11167,7 @@ function OhhwellsBridge() {
|
|
|
9392
11167
|
};
|
|
9393
11168
|
const handleSave = (e) => {
|
|
9394
11169
|
if (e.data?.type !== "ow:save") return;
|
|
9395
|
-
const nodes = collectEditableNodes();
|
|
11170
|
+
const nodes = collectEditableNodes(editContentRef.current);
|
|
9396
11171
|
const tracker = document.querySelector("[data-ohw-sections-tracker]");
|
|
9397
11172
|
if (tracker?.textContent) nodes.push({ key: "__ohw_sections", type: "sections", text: tracker.textContent });
|
|
9398
11173
|
postToParentRef.current({ type: "ow:save-result", nodes });
|
|
@@ -9615,7 +11390,7 @@ function OhhwellsBridge() {
|
|
|
9615
11390
|
}
|
|
9616
11391
|
}
|
|
9617
11392
|
const footerColumn = findHoveredNavOrFooterContainer(clientX, clientY);
|
|
9618
|
-
if (footerColumn?.hasAttribute("data-ohw-footer-column")) {
|
|
11393
|
+
if (footerColumn?.hasAttribute("data-ohw-footer-col") || footerColumn?.hasAttribute("data-ohw-footer-column")) {
|
|
9619
11394
|
selectFrameRef.current(footerColumn);
|
|
9620
11395
|
return;
|
|
9621
11396
|
}
|
|
@@ -9690,7 +11465,161 @@ function OhhwellsBridge() {
|
|
|
9690
11465
|
if (imageShowTimerRef.current) clearTimeout(imageShowTimerRef.current);
|
|
9691
11466
|
};
|
|
9692
11467
|
}, [isEditMode, refreshStateRules]);
|
|
9693
|
-
|
|
11468
|
+
useEffect8(() => {
|
|
11469
|
+
if (!isEditMode) return;
|
|
11470
|
+
const THRESHOLD = 10;
|
|
11471
|
+
const resolveWasSelected = (el) => {
|
|
11472
|
+
if (selectedElRef.current === el) return true;
|
|
11473
|
+
const activeAnchor = activeElRef.current ? getNavigationItemAnchor(activeElRef.current) : null;
|
|
11474
|
+
return activeAnchor === el;
|
|
11475
|
+
};
|
|
11476
|
+
const onPointerDown = (e) => {
|
|
11477
|
+
if (e.button !== 0) return;
|
|
11478
|
+
if (suppressNextClickRef.current && Date.now() >= suppressClickUntilRef.current && !footerDragRef.current && !footerPointerDragRef.current?.started) {
|
|
11479
|
+
suppressNextClickRef.current = false;
|
|
11480
|
+
}
|
|
11481
|
+
if (footerDragRef.current) return;
|
|
11482
|
+
const target = e.target;
|
|
11483
|
+
if (!target) return;
|
|
11484
|
+
if (target.closest('[data-ohw-drag-handle-container], [data-slot="drag-handle"], [data-ohw-toolbar], [data-ohw-item-toolbar-anchor], [data-ohw-link-popover-root]')) {
|
|
11485
|
+
return;
|
|
11486
|
+
}
|
|
11487
|
+
if (target.closest("[data-ohw-item-drag-surface]")) return;
|
|
11488
|
+
const anchor = getNavigationItemAnchor(target);
|
|
11489
|
+
const hrefKey = anchor?.getAttribute("data-ohw-href-key") ?? null;
|
|
11490
|
+
if (anchor && isFooterHrefKey(hrefKey)) {
|
|
11491
|
+
armFooterPressDrag();
|
|
11492
|
+
footerPointerDragRef.current = {
|
|
11493
|
+
el: anchor,
|
|
11494
|
+
kind: "link",
|
|
11495
|
+
startX: e.clientX,
|
|
11496
|
+
startY: e.clientY,
|
|
11497
|
+
pointerId: e.pointerId,
|
|
11498
|
+
wasSelected: resolveWasSelected(anchor),
|
|
11499
|
+
started: false
|
|
11500
|
+
};
|
|
11501
|
+
return;
|
|
11502
|
+
}
|
|
11503
|
+
const col = target.closest("[data-ohw-footer-col]");
|
|
11504
|
+
if (col && !getNavigationItemAnchor(target)) {
|
|
11505
|
+
armFooterPressDrag();
|
|
11506
|
+
footerPointerDragRef.current = {
|
|
11507
|
+
el: col,
|
|
11508
|
+
kind: "column",
|
|
11509
|
+
startX: e.clientX,
|
|
11510
|
+
startY: e.clientY,
|
|
11511
|
+
pointerId: e.pointerId,
|
|
11512
|
+
wasSelected: resolveWasSelected(col),
|
|
11513
|
+
started: false
|
|
11514
|
+
};
|
|
11515
|
+
}
|
|
11516
|
+
};
|
|
11517
|
+
const onPointerMove = (e) => {
|
|
11518
|
+
const pending = footerPointerDragRef.current;
|
|
11519
|
+
if (!pending) return;
|
|
11520
|
+
if (pending.started) {
|
|
11521
|
+
e.preventDefault();
|
|
11522
|
+
clearTextSelection();
|
|
11523
|
+
const session = footerDragRef.current;
|
|
11524
|
+
if (!session) return;
|
|
11525
|
+
const slot = session.kind === "link" && session.hrefKey ? hitTestLinkDropSlot(e.clientX, e.clientY, session.hrefKey) : hitTestColumnDropSlot(e.clientX, e.clientY);
|
|
11526
|
+
refreshFooterDragVisualsRef.current(session, slot, e.clientX, e.clientY);
|
|
11527
|
+
return;
|
|
11528
|
+
}
|
|
11529
|
+
const dx = e.clientX - pending.startX;
|
|
11530
|
+
const dy = e.clientY - pending.startY;
|
|
11531
|
+
if (dx * dx + dy * dy < THRESHOLD * THRESHOLD) return;
|
|
11532
|
+
e.preventDefault();
|
|
11533
|
+
pending.started = true;
|
|
11534
|
+
clearTextSelection();
|
|
11535
|
+
try {
|
|
11536
|
+
document.body.setPointerCapture(pending.pointerId);
|
|
11537
|
+
} catch {
|
|
11538
|
+
}
|
|
11539
|
+
if (linkPopoverOpenRef.current) {
|
|
11540
|
+
setLinkPopoverRef.current(null);
|
|
11541
|
+
}
|
|
11542
|
+
if (activeElRef.current) {
|
|
11543
|
+
deactivateRef.current();
|
|
11544
|
+
}
|
|
11545
|
+
if (pending.kind === "link") {
|
|
11546
|
+
const key = pending.el.getAttribute("data-ohw-href-key");
|
|
11547
|
+
if (!key) return;
|
|
11548
|
+
const column = findFooterColumnForLink(pending.el);
|
|
11549
|
+
const columns2 = listFooterColumns();
|
|
11550
|
+
beginFooterDragRef.current({
|
|
11551
|
+
kind: "link",
|
|
11552
|
+
hrefKey: key,
|
|
11553
|
+
columnEl: column,
|
|
11554
|
+
sourceColumnIndex: column ? columns2.indexOf(column) : 0,
|
|
11555
|
+
wasSelected: pending.wasSelected,
|
|
11556
|
+
draggedEl: pending.el,
|
|
11557
|
+
lastClientX: e.clientX,
|
|
11558
|
+
lastClientY: e.clientY,
|
|
11559
|
+
activeSlot: null
|
|
11560
|
+
});
|
|
11561
|
+
return;
|
|
11562
|
+
}
|
|
11563
|
+
const columns = listFooterColumns();
|
|
11564
|
+
const idx = columns.indexOf(pending.el);
|
|
11565
|
+
if (idx < 0) return;
|
|
11566
|
+
beginFooterDragRef.current({
|
|
11567
|
+
kind: "column",
|
|
11568
|
+
hrefKey: null,
|
|
11569
|
+
columnEl: pending.el,
|
|
11570
|
+
sourceColumnIndex: idx,
|
|
11571
|
+
wasSelected: pending.wasSelected,
|
|
11572
|
+
draggedEl: pending.el,
|
|
11573
|
+
lastClientX: e.clientX,
|
|
11574
|
+
lastClientY: e.clientY,
|
|
11575
|
+
activeSlot: null
|
|
11576
|
+
});
|
|
11577
|
+
};
|
|
11578
|
+
const endPointerDrag = (e) => {
|
|
11579
|
+
const pending = footerPointerDragRef.current;
|
|
11580
|
+
footerPointerDragRef.current = null;
|
|
11581
|
+
try {
|
|
11582
|
+
if (document.body.hasPointerCapture(e.pointerId)) {
|
|
11583
|
+
document.body.releasePointerCapture(e.pointerId);
|
|
11584
|
+
}
|
|
11585
|
+
} catch {
|
|
11586
|
+
}
|
|
11587
|
+
if (!pending?.started) {
|
|
11588
|
+
unlockFooterDragInteraction();
|
|
11589
|
+
return;
|
|
11590
|
+
}
|
|
11591
|
+
suppressNextClickRef.current = true;
|
|
11592
|
+
suppressClickUntilRef.current = Date.now() + 500;
|
|
11593
|
+
commitFooterDragRef.current(e.clientX, e.clientY);
|
|
11594
|
+
};
|
|
11595
|
+
const blockSelectStart = (e) => {
|
|
11596
|
+
if (footerDragRef.current || footerPointerDragRef.current?.started || document.documentElement.hasAttribute("data-ohw-footer-press-drag")) {
|
|
11597
|
+
e.preventDefault();
|
|
11598
|
+
}
|
|
11599
|
+
};
|
|
11600
|
+
const onDragEnd = (_e) => {
|
|
11601
|
+
if (!footerDragRef.current) return;
|
|
11602
|
+
suppressNextClickRef.current = true;
|
|
11603
|
+
suppressClickUntilRef.current = Date.now() + 500;
|
|
11604
|
+
commitFooterDragRef.current();
|
|
11605
|
+
};
|
|
11606
|
+
document.addEventListener("pointerdown", onPointerDown, true);
|
|
11607
|
+
document.addEventListener("pointermove", onPointerMove, true);
|
|
11608
|
+
document.addEventListener("pointerup", endPointerDrag, true);
|
|
11609
|
+
document.addEventListener("pointercancel", endPointerDrag, true);
|
|
11610
|
+
document.addEventListener("selectstart", blockSelectStart, true);
|
|
11611
|
+
document.addEventListener("dragend", onDragEnd, true);
|
|
11612
|
+
return () => {
|
|
11613
|
+
document.removeEventListener("pointerdown", onPointerDown, true);
|
|
11614
|
+
document.removeEventListener("pointermove", onPointerMove, true);
|
|
11615
|
+
document.removeEventListener("pointerup", endPointerDrag, true);
|
|
11616
|
+
document.removeEventListener("pointercancel", endPointerDrag, true);
|
|
11617
|
+
document.removeEventListener("selectstart", blockSelectStart, true);
|
|
11618
|
+
document.removeEventListener("dragend", onDragEnd, true);
|
|
11619
|
+
unlockFooterDragInteraction();
|
|
11620
|
+
};
|
|
11621
|
+
}, [isEditMode]);
|
|
11622
|
+
useEffect8(() => {
|
|
9694
11623
|
const handler = (e) => {
|
|
9695
11624
|
if (e.data?.type !== "ow:request-schedule-config") return;
|
|
9696
11625
|
const insertAfterVal = e.data.insertAfter;
|
|
@@ -9706,7 +11635,7 @@ function OhhwellsBridge() {
|
|
|
9706
11635
|
window.addEventListener("message", handler);
|
|
9707
11636
|
return () => window.removeEventListener("message", handler);
|
|
9708
11637
|
}, [processConfigRequest]);
|
|
9709
|
-
|
|
11638
|
+
useEffect8(() => {
|
|
9710
11639
|
if (!isEditMode) return;
|
|
9711
11640
|
document.querySelectorAll("[data-ohw-active-state]").forEach((el) => {
|
|
9712
11641
|
el.removeAttribute("data-ohw-active-state");
|
|
@@ -9727,7 +11656,13 @@ function OhhwellsBridge() {
|
|
|
9727
11656
|
const next = { ...prev, [pathKey]: sections };
|
|
9728
11657
|
return shouldUseDevFixtures() ? { ...DEV_SECTIONS_BY_PATH, ...next } : next;
|
|
9729
11658
|
});
|
|
9730
|
-
postToParent2({
|
|
11659
|
+
postToParent2({
|
|
11660
|
+
type: "ow:ready",
|
|
11661
|
+
version: "1",
|
|
11662
|
+
path: pathname,
|
|
11663
|
+
nodes: collectEditableNodes(editContentRef.current),
|
|
11664
|
+
sections
|
|
11665
|
+
});
|
|
9731
11666
|
postToParent2({ type: "ow:request-site-pages" });
|
|
9732
11667
|
}, 150);
|
|
9733
11668
|
return () => {
|
|
@@ -9735,19 +11670,19 @@ function OhhwellsBridge() {
|
|
|
9735
11670
|
clearTimeout(timer);
|
|
9736
11671
|
};
|
|
9737
11672
|
}, [pathname, isEditMode, refreshStateRules, postToParent2]);
|
|
9738
|
-
|
|
11673
|
+
useEffect8(() => {
|
|
9739
11674
|
scrollToHashSectionWhenReady();
|
|
9740
11675
|
const onHashChange = () => scrollToHashSectionWhenReady();
|
|
9741
11676
|
window.addEventListener("hashchange", onHashChange);
|
|
9742
11677
|
return () => window.removeEventListener("hashchange", onHashChange);
|
|
9743
11678
|
}, [pathname]);
|
|
9744
|
-
const handleCommand =
|
|
11679
|
+
const handleCommand = useCallback4((cmd) => {
|
|
9745
11680
|
document.execCommand(cmd, false);
|
|
9746
11681
|
activeElRef.current?.focus();
|
|
9747
11682
|
if (activeElRef.current) setToolbarRect(getEditMeasureEl(activeElRef.current).getBoundingClientRect());
|
|
9748
11683
|
refreshActiveCommandsRef.current();
|
|
9749
11684
|
}, []);
|
|
9750
|
-
const handleStateChange =
|
|
11685
|
+
const handleStateChange = useCallback4((state) => {
|
|
9751
11686
|
if (!activeStateElRef.current) return;
|
|
9752
11687
|
const el = activeStateElRef.current;
|
|
9753
11688
|
if (state === "Default") {
|
|
@@ -9760,11 +11695,11 @@ function OhhwellsBridge() {
|
|
|
9760
11695
|
}
|
|
9761
11696
|
setToggleState((prev) => prev ? { ...prev, activeState: state } : null);
|
|
9762
11697
|
}, [deactivate]);
|
|
9763
|
-
const closeLinkPopover =
|
|
11698
|
+
const closeLinkPopover = useCallback4(() => {
|
|
9764
11699
|
addNavAfterAnchorRef.current = null;
|
|
9765
11700
|
setLinkPopover(null);
|
|
9766
11701
|
}, []);
|
|
9767
|
-
const openLinkPopoverForActive =
|
|
11702
|
+
const openLinkPopoverForActive = useCallback4(() => {
|
|
9768
11703
|
const hrefCtx = getHrefKeyFromElement(activeElRef.current);
|
|
9769
11704
|
if (!hrefCtx) return;
|
|
9770
11705
|
bumpLinkPopoverGrace();
|
|
@@ -9775,7 +11710,7 @@ function OhhwellsBridge() {
|
|
|
9775
11710
|
});
|
|
9776
11711
|
deactivate();
|
|
9777
11712
|
}, [deactivate]);
|
|
9778
|
-
const openLinkPopoverForSelected =
|
|
11713
|
+
const openLinkPopoverForSelected = useCallback4(() => {
|
|
9779
11714
|
const anchor = selectedElRef.current;
|
|
9780
11715
|
if (!anchor) return;
|
|
9781
11716
|
const key = anchor.getAttribute("data-ohw-href-key");
|
|
@@ -9788,7 +11723,7 @@ function OhhwellsBridge() {
|
|
|
9788
11723
|
});
|
|
9789
11724
|
deselect();
|
|
9790
11725
|
}, [deselect]);
|
|
9791
|
-
const handleLinkPopoverSubmit =
|
|
11726
|
+
const handleLinkPopoverSubmit = useCallback4(
|
|
9792
11727
|
(target) => {
|
|
9793
11728
|
const session = linkPopoverSessionRef.current;
|
|
9794
11729
|
if (!session) return;
|
|
@@ -9847,13 +11782,13 @@ function OhhwellsBridge() {
|
|
|
9847
11782
|
const showEditLink = toolbarShowEditLink;
|
|
9848
11783
|
const currentSections = sectionsByPath[pathname] ?? [];
|
|
9849
11784
|
linkPopoverOpenRef.current = linkPopover !== null;
|
|
9850
|
-
const handleMediaReplace =
|
|
11785
|
+
const handleMediaReplace = useCallback4(
|
|
9851
11786
|
(key) => {
|
|
9852
11787
|
postToParent2({ type: "ow:image-pick", key, elementType: mediaHover?.elementType ?? "image" });
|
|
9853
11788
|
},
|
|
9854
11789
|
[postToParent2, mediaHover?.elementType]
|
|
9855
11790
|
);
|
|
9856
|
-
const handleMediaFadeOutComplete =
|
|
11791
|
+
const handleMediaFadeOutComplete = useCallback4((key) => {
|
|
9857
11792
|
setUploadingRects((prev) => {
|
|
9858
11793
|
if (!(key in prev)) return prev;
|
|
9859
11794
|
const next = { ...prev };
|
|
@@ -9861,7 +11796,7 @@ function OhhwellsBridge() {
|
|
|
9861
11796
|
return next;
|
|
9862
11797
|
});
|
|
9863
11798
|
}, []);
|
|
9864
|
-
const handleVideoSettingsChange =
|
|
11799
|
+
const handleVideoSettingsChange = useCallback4(
|
|
9865
11800
|
(key, settings) => {
|
|
9866
11801
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
9867
11802
|
const video = getVideoEl(el);
|
|
@@ -9884,9 +11819,9 @@ function OhhwellsBridge() {
|
|
|
9884
11819
|
[postToParent2]
|
|
9885
11820
|
);
|
|
9886
11821
|
return bridgeRoot ? createPortal2(
|
|
9887
|
-
/* @__PURE__ */
|
|
9888
|
-
/* @__PURE__ */
|
|
9889
|
-
Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */
|
|
11822
|
+
/* @__PURE__ */ jsxs13(Fragment5, { children: [
|
|
11823
|
+
/* @__PURE__ */ jsx24("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
|
|
11824
|
+
Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ jsx24(
|
|
9890
11825
|
MediaOverlay,
|
|
9891
11826
|
{
|
|
9892
11827
|
hover: { key, rect, elementType: "image", isDragOver: false, hasTextOverlap: false },
|
|
@@ -9897,7 +11832,7 @@ function OhhwellsBridge() {
|
|
|
9897
11832
|
},
|
|
9898
11833
|
`uploading-${key}`
|
|
9899
11834
|
)),
|
|
9900
|
-
mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */
|
|
11835
|
+
mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */ jsx24(
|
|
9901
11836
|
MediaOverlay,
|
|
9902
11837
|
{
|
|
9903
11838
|
hover: mediaHover,
|
|
@@ -9906,28 +11841,69 @@ function OhhwellsBridge() {
|
|
|
9906
11841
|
onVideoSettingsChange: handleVideoSettingsChange
|
|
9907
11842
|
}
|
|
9908
11843
|
),
|
|
9909
|
-
siblingHintRect && !isItemDragging && /* @__PURE__ */
|
|
9910
|
-
|
|
9911
|
-
|
|
9912
|
-
|
|
11844
|
+
siblingHintRect && !linkPopover && !isItemDragging && siblingHintRects.length === 0 && /* @__PURE__ */ jsx24(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
|
|
11845
|
+
siblingHintRects.length > 0 && !linkPopover && !isItemDragging && siblingHintRects.map((rect, i) => /* @__PURE__ */ jsx24(ItemInteractionLayer, { rect, state: "sibling-hint" }, `sibling-hint-${i}`)),
|
|
11846
|
+
isItemDragging && draggedItemRect && selectedElRef.current !== footerDragRef.current?.draggedEl && selectedElRef.current !== navDragRef.current?.draggedEl && /* @__PURE__ */ jsx24(ItemInteractionLayer, { rect: draggedItemRect, state: "dragging" }),
|
|
11847
|
+
isItemDragging && footerDropSlots.map((slot, i) => /* @__PURE__ */ jsx24(
|
|
11848
|
+
"div",
|
|
9913
11849
|
{
|
|
9914
|
-
|
|
9915
|
-
|
|
9916
|
-
|
|
9917
|
-
|
|
9918
|
-
|
|
9919
|
-
|
|
11850
|
+
className: "pointer-events-none fixed z-2147483646",
|
|
11851
|
+
style: {
|
|
11852
|
+
left: slot.left,
|
|
11853
|
+
top: slot.top,
|
|
11854
|
+
width: slot.width,
|
|
11855
|
+
height: slot.height
|
|
11856
|
+
},
|
|
11857
|
+
children: /* @__PURE__ */ jsx24(
|
|
11858
|
+
DropIndicator,
|
|
11859
|
+
{
|
|
11860
|
+
direction: slot.direction,
|
|
11861
|
+
state: activeFooterDropIndex === i ? "dragActive" : "dragIdle",
|
|
11862
|
+
className: "!h-full !w-full"
|
|
11863
|
+
}
|
|
11864
|
+
)
|
|
11865
|
+
},
|
|
11866
|
+
`footer-drop-${slot.direction}-${slot.columnIndex}-${slot.insertIndex}-${i}`
|
|
11867
|
+
)),
|
|
11868
|
+
isItemDragging && navDropSlots.map((slot, i) => /* @__PURE__ */ jsx24(
|
|
11869
|
+
"div",
|
|
11870
|
+
{
|
|
11871
|
+
className: "pointer-events-none fixed z-2147483646",
|
|
11872
|
+
style: {
|
|
11873
|
+
left: slot.left,
|
|
11874
|
+
top: slot.top,
|
|
11875
|
+
width: slot.width,
|
|
11876
|
+
height: slot.height
|
|
11877
|
+
},
|
|
11878
|
+
children: /* @__PURE__ */ jsx24(
|
|
11879
|
+
DropIndicator,
|
|
11880
|
+
{
|
|
11881
|
+
direction: slot.direction,
|
|
11882
|
+
state: activeNavDropIndex === i ? "dragActive" : "dragIdle",
|
|
11883
|
+
className: "!h-full !w-full"
|
|
11884
|
+
}
|
|
11885
|
+
)
|
|
11886
|
+
},
|
|
11887
|
+
`nav-drop-${slot.direction}-${slot.parentId ?? "root"}-${slot.insertIndex}-${i}`
|
|
11888
|
+
)),
|
|
11889
|
+
hoveredNavContainerRect && toolbarVariant !== "select-frame" && !linkPopover && !isItemDragging && /* @__PURE__ */ jsx24(ItemInteractionLayer, { rect: hoveredNavContainerRect, state: "hover" }),
|
|
11890
|
+
hoveredItemRect && !linkPopover && !hoveredNavContainerRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ jsx24(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
|
|
11891
|
+
toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isNavbarLinksContainer(selectedElRef.current) && /* @__PURE__ */ jsx24(NavbarContainerChrome, { rect: toolbarRect, onAdd: handleAddTopLevelNavItem }),
|
|
11892
|
+
toolbarRect && !linkPopover && (toolbarVariant === "link-action" || toolbarVariant === "select-frame") && /* @__PURE__ */ jsx24(
|
|
9920
11893
|
ItemInteractionLayer,
|
|
9921
11894
|
{
|
|
9922
|
-
rect: toolbarRect,
|
|
11895
|
+
rect: isItemDragging && draggedItemRect && (footerDragRef.current?.wasSelected || navDragRef.current?.wasSelected) ? draggedItemRect : toolbarRect,
|
|
9923
11896
|
elRef: glowElRef,
|
|
9924
11897
|
state: isItemDragging ? "dragging" : resolveItemInteractionState(toolbarRect, parentScrollRef.current),
|
|
9925
|
-
showHandle: toolbarVariant === "link-action" && Boolean(reorderHrefKey),
|
|
11898
|
+
showHandle: toolbarVariant === "link-action" && Boolean(reorderHrefKey) || toolbarVariant === "select-frame" && isFooterFrameSelection,
|
|
9926
11899
|
dragDisabled: reorderDragDisabled,
|
|
9927
11900
|
dragHandleLabel: reorderHrefKey ? `Reorder ${reorderHrefKey}` : "Reorder item",
|
|
9928
11901
|
onDragHandleDragStart: handleItemDragStart,
|
|
9929
11902
|
onDragHandleDragEnd: handleItemDragEnd,
|
|
9930
|
-
|
|
11903
|
+
onItemPointerDown: handleItemChromePointerDown,
|
|
11904
|
+
onItemClick: handleItemChromeClick,
|
|
11905
|
+
itemDragSurface: !isFooterFrameSelection,
|
|
11906
|
+
toolbar: toolbarVariant === "link-action" && !isItemDragging ? /* @__PURE__ */ jsx24(
|
|
9931
11907
|
ItemActionToolbar,
|
|
9932
11908
|
{
|
|
9933
11909
|
onEditLink: openLinkPopoverForSelected,
|
|
@@ -9940,17 +11916,18 @@ function OhhwellsBridge() {
|
|
|
9940
11916
|
) : void 0
|
|
9941
11917
|
}
|
|
9942
11918
|
),
|
|
9943
|
-
toolbarRect && toolbarVariant === "rich-text" && /* @__PURE__ */
|
|
9944
|
-
/* @__PURE__ */
|
|
11919
|
+
toolbarRect && toolbarVariant === "rich-text" && !linkPopover && /* @__PURE__ */ jsxs13(Fragment5, { children: [
|
|
11920
|
+
/* @__PURE__ */ jsx24(
|
|
9945
11921
|
EditGlowChrome,
|
|
9946
11922
|
{
|
|
9947
11923
|
rect: toolbarRect,
|
|
9948
11924
|
elRef: glowElRef,
|
|
9949
11925
|
reorderHrefKey,
|
|
9950
|
-
dragDisabled: reorderDragDisabled
|
|
11926
|
+
dragDisabled: reorderDragDisabled,
|
|
11927
|
+
hideHandle: isItemDragging
|
|
9951
11928
|
}
|
|
9952
11929
|
),
|
|
9953
|
-
/* @__PURE__ */
|
|
11930
|
+
/* @__PURE__ */ jsx24(
|
|
9954
11931
|
FloatingToolbar,
|
|
9955
11932
|
{
|
|
9956
11933
|
rect: toolbarRect,
|
|
@@ -9963,7 +11940,7 @@ function OhhwellsBridge() {
|
|
|
9963
11940
|
}
|
|
9964
11941
|
)
|
|
9965
11942
|
] }),
|
|
9966
|
-
maxBadge && /* @__PURE__ */
|
|
11943
|
+
maxBadge && /* @__PURE__ */ jsxs13(
|
|
9967
11944
|
"div",
|
|
9968
11945
|
{
|
|
9969
11946
|
"data-ohw-max-badge": "",
|
|
@@ -9989,7 +11966,7 @@ function OhhwellsBridge() {
|
|
|
9989
11966
|
]
|
|
9990
11967
|
}
|
|
9991
11968
|
),
|
|
9992
|
-
toggleState && !linkPopover && /* @__PURE__ */
|
|
11969
|
+
toggleState && !linkPopover && /* @__PURE__ */ jsx24(
|
|
9993
11970
|
StateToggle,
|
|
9994
11971
|
{
|
|
9995
11972
|
rect: toggleState.rect,
|
|
@@ -9998,32 +11975,36 @@ function OhhwellsBridge() {
|
|
|
9998
11975
|
onStateChange: handleStateChange
|
|
9999
11976
|
}
|
|
10000
11977
|
),
|
|
10001
|
-
sectionGap && !linkPopover && /* @__PURE__ */
|
|
11978
|
+
sectionGap && !linkPopover && /* @__PURE__ */ jsxs13(
|
|
10002
11979
|
"div",
|
|
10003
11980
|
{
|
|
10004
11981
|
"data-ohw-section-insert-line": "",
|
|
10005
11982
|
className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
|
|
10006
11983
|
style: { top: sectionGap.y, transform: "translateY(-50%)" },
|
|
10007
11984
|
children: [
|
|
10008
|
-
/* @__PURE__ */
|
|
10009
|
-
/* @__PURE__ */
|
|
11985
|
+
/* @__PURE__ */ jsx24("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
|
|
11986
|
+
/* @__PURE__ */ jsx24(
|
|
10010
11987
|
Badge,
|
|
10011
11988
|
{
|
|
10012
11989
|
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",
|
|
10013
11990
|
onClick: () => {
|
|
10014
11991
|
window.parent.postMessage(
|
|
10015
|
-
{
|
|
11992
|
+
{
|
|
11993
|
+
type: "ow:add-section",
|
|
11994
|
+
insertAfter: sectionGap.insertAfter,
|
|
11995
|
+
insertBefore: sectionGap.insertBefore
|
|
11996
|
+
},
|
|
10016
11997
|
"*"
|
|
10017
11998
|
);
|
|
10018
11999
|
},
|
|
10019
12000
|
children: "Add Section"
|
|
10020
12001
|
}
|
|
10021
12002
|
),
|
|
10022
|
-
/* @__PURE__ */
|
|
12003
|
+
/* @__PURE__ */ jsx24("div", { className: "flex-1 bg-primary", style: { height: 3 } })
|
|
10023
12004
|
]
|
|
10024
12005
|
}
|
|
10025
12006
|
),
|
|
10026
|
-
linkPopover && dialogPortalContainer ? /* @__PURE__ */
|
|
12007
|
+
linkPopover && dialogPortalContainer ? /* @__PURE__ */ jsx24(
|
|
10027
12008
|
LinkPopover,
|
|
10028
12009
|
{
|
|
10029
12010
|
panelRef: linkPopoverPanelRef,
|
|
@@ -10044,48 +12025,6 @@ function OhhwellsBridge() {
|
|
|
10044
12025
|
bridgeRoot
|
|
10045
12026
|
) : null;
|
|
10046
12027
|
}
|
|
10047
|
-
|
|
10048
|
-
// src/ui/drop-indicator.tsx
|
|
10049
|
-
import * as React11 from "react";
|
|
10050
|
-
import { jsx as jsx24 } from "react/jsx-runtime";
|
|
10051
|
-
var dropIndicatorVariants = cva(
|
|
10052
|
-
"ov-gap-line pointer-events-none shrink-0 transition-opacity duration-150",
|
|
10053
|
-
{
|
|
10054
|
-
variants: {
|
|
10055
|
-
direction: {
|
|
10056
|
-
vertical: "h-6 w-[3px]",
|
|
10057
|
-
horizontal: "h-[3px] w-[200px]"
|
|
10058
|
-
},
|
|
10059
|
-
state: {
|
|
10060
|
-
default: "opacity-0",
|
|
10061
|
-
hover: "opacity-100",
|
|
10062
|
-
dragIdle: "opacity-40",
|
|
10063
|
-
dragActive: "opacity-100"
|
|
10064
|
-
}
|
|
10065
|
-
},
|
|
10066
|
-
defaultVariants: {
|
|
10067
|
-
direction: "vertical",
|
|
10068
|
-
state: "default"
|
|
10069
|
-
}
|
|
10070
|
-
}
|
|
10071
|
-
);
|
|
10072
|
-
var DropIndicator = React11.forwardRef(
|
|
10073
|
-
({ className, direction, state, ...props }, ref) => {
|
|
10074
|
-
return /* @__PURE__ */ jsx24(
|
|
10075
|
-
"div",
|
|
10076
|
-
{
|
|
10077
|
-
ref,
|
|
10078
|
-
"data-slot": "drop-indicator",
|
|
10079
|
-
"data-direction": direction ?? "vertical",
|
|
10080
|
-
"data-state": state ?? "default",
|
|
10081
|
-
"aria-hidden": "true",
|
|
10082
|
-
className: cn(dropIndicatorVariants({ direction, state }), className),
|
|
10083
|
-
...props
|
|
10084
|
-
}
|
|
10085
|
-
);
|
|
10086
|
-
}
|
|
10087
|
-
);
|
|
10088
|
-
DropIndicator.displayName = "DropIndicator";
|
|
10089
12028
|
export {
|
|
10090
12029
|
CustomToolbar,
|
|
10091
12030
|
CustomToolbarButton,
|