@ohhwells/bridge 0.1.38-next.62 → 0.1.38-next.64
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 +1126 -292
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +1122 -288
- package/dist/index.js.map +1 -1
- package/dist/styles.css +14 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -573,7 +573,7 @@ function ScheduleView({ schedule, dates, selectedIdx, onSelectDate, onOpenModal
|
|
|
573
573
|
}
|
|
574
574
|
)
|
|
575
575
|
] }),
|
|
576
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "sm:hidden flex flex-col gap-px", children: isFull ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "font-body text-sm text-(--color-dark,#200C02) opacity-80", children: "Full" }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
576
|
+
cls.showAvailability !== false && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "sm:hidden flex flex-col gap-px", children: isFull ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "font-body text-sm text-(--color-dark,#200C02) opacity-80", children: "Full" }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
577
577
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "font-body text-sm text-(--color-dark,#200C02) opacity-80", children: [
|
|
578
578
|
available,
|
|
579
579
|
"/",
|
|
@@ -585,9 +585,10 @@ function ScheduleView({ schedule, dates, selectedIdx, onSelectDate, onOpenModal
|
|
|
585
585
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex flex-1 flex-col gap-2 min-w-0 sm:contents", children: [
|
|
586
586
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex-1 flex flex-col gap-2 min-w-0", children: [
|
|
587
587
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "font-body text-base font-bold text-(--color-dark,#200C02) block truncate", children: cls.name }),
|
|
588
|
-
cls.hostName && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "font-body text-base font-normal text-(--color-dark,#200C02) opacity-80 block truncate", children: cls.hostName })
|
|
588
|
+
cls.hostName && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "font-body text-base font-normal text-(--color-dark,#200C02) opacity-80 block truncate", children: cls.hostName }),
|
|
589
|
+
cls.description && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "font-body text-sm font-normal text-(--color-dark,#200C02) opacity-70 block truncate", children: cls.description })
|
|
589
590
|
] }),
|
|
590
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "hidden sm:flex w-14 shrink-0 flex-col gap-px", children: isFull ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "font-body text-sm text-(--color-dark,#200C02) opacity-80", children: "Full" }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
591
|
+
cls.showAvailability !== false && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "hidden sm:flex w-14 shrink-0 flex-col gap-px", children: isFull ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "font-body text-sm text-(--color-dark,#200C02) opacity-80", children: "Full" }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
591
592
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "font-body text-sm text-(--color-dark,#200C02) opacity-80", children: [
|
|
592
593
|
available,
|
|
593
594
|
"/",
|
|
@@ -4554,7 +4555,7 @@ function getChromeStyle(state) {
|
|
|
4554
4555
|
case "dragging":
|
|
4555
4556
|
return {
|
|
4556
4557
|
border: `2px solid ${PRIMARY}`,
|
|
4557
|
-
boxShadow: DRAG_SHADOW
|
|
4558
|
+
boxShadow: `${FOCUS_RING}, ${DRAG_SHADOW}`
|
|
4558
4559
|
};
|
|
4559
4560
|
default:
|
|
4560
4561
|
return {};
|
|
@@ -4570,6 +4571,8 @@ function ItemInteractionLayer({
|
|
|
4570
4571
|
dragHandleLabel = "Reorder item",
|
|
4571
4572
|
onDragHandleDragStart,
|
|
4572
4573
|
onDragHandleDragEnd,
|
|
4574
|
+
onItemPointerDown,
|
|
4575
|
+
onItemClick,
|
|
4573
4576
|
chromeGap = 6,
|
|
4574
4577
|
className
|
|
4575
4578
|
}) {
|
|
@@ -4577,7 +4580,8 @@ function ItemInteractionLayer({
|
|
|
4577
4580
|
const isActive = state === "active-top" || state === "active-bottom";
|
|
4578
4581
|
const isDragging = state === "dragging";
|
|
4579
4582
|
const showToolbar = isActive && toolbar;
|
|
4580
|
-
const showDragHandle = isActive
|
|
4583
|
+
const showDragHandle = (isActive || isDragging) && showHandle;
|
|
4584
|
+
const itemDragEnabled = isActive && showHandle && !isDragging && !dragDisabled;
|
|
4581
4585
|
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
4582
4586
|
"div",
|
|
4583
4587
|
{
|
|
@@ -4602,11 +4606,28 @@ function ItemInteractionLayer({
|
|
|
4602
4606
|
style: getChromeStyle(state)
|
|
4603
4607
|
}
|
|
4604
4608
|
),
|
|
4609
|
+
itemDragEnabled && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
4610
|
+
"div",
|
|
4611
|
+
{
|
|
4612
|
+
"data-ohw-item-drag-surface": "",
|
|
4613
|
+
className: "pointer-events-auto absolute inset-0 cursor-grab rounded-lg active:cursor-grabbing",
|
|
4614
|
+
onPointerDown: (e) => {
|
|
4615
|
+
if (e.button !== 0) return;
|
|
4616
|
+
onItemPointerDown?.(e);
|
|
4617
|
+
},
|
|
4618
|
+
onClick: (e) => {
|
|
4619
|
+
e.preventDefault();
|
|
4620
|
+
e.stopPropagation();
|
|
4621
|
+
onItemClick?.(e.clientX, e.clientY);
|
|
4622
|
+
}
|
|
4623
|
+
}
|
|
4624
|
+
),
|
|
4605
4625
|
showDragHandle && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
4606
4626
|
"div",
|
|
4607
4627
|
{
|
|
4608
4628
|
"data-ohw-drag-handle-container": "",
|
|
4609
|
-
className: "pointer-events-auto absolute left-0 top-1/2 -translate-x-[calc(100%+7px)] -translate-y-1/2",
|
|
4629
|
+
className: "pointer-events-auto absolute left-0 top-1/2 z-10 -translate-x-[calc(100%+7px)] -translate-y-1/2",
|
|
4630
|
+
style: isDragging ? { visibility: "hidden" } : void 0,
|
|
4610
4631
|
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
4611
4632
|
DragHandle,
|
|
4612
4633
|
{
|
|
@@ -6608,6 +6629,319 @@ function insertNavbarItem(href, label, afterAnchor = null) {
|
|
|
6608
6629
|
};
|
|
6609
6630
|
}
|
|
6610
6631
|
|
|
6632
|
+
// src/lib/footer-items.ts
|
|
6633
|
+
var FOOTER_ORDER_KEY = "__ohw_footer_order";
|
|
6634
|
+
var FOOTER_HREF_RE = /^footer-(\d+)-(\d+)-href$/;
|
|
6635
|
+
function parseFooterHrefKey(key) {
|
|
6636
|
+
if (!key) return null;
|
|
6637
|
+
const match = key.match(FOOTER_HREF_RE);
|
|
6638
|
+
if (!match) return null;
|
|
6639
|
+
return { col: parseInt(match[1], 10), item: parseInt(match[2], 10) };
|
|
6640
|
+
}
|
|
6641
|
+
function isFooterHrefKey(key) {
|
|
6642
|
+
return parseFooterHrefKey(key) !== null;
|
|
6643
|
+
}
|
|
6644
|
+
function getFooterRoot() {
|
|
6645
|
+
return document.querySelector('footer[data-ohw-section="footer"], footer');
|
|
6646
|
+
}
|
|
6647
|
+
function getFooterLinksContainer() {
|
|
6648
|
+
return document.querySelector("[data-ohw-footer-links]") ?? document.querySelector(".rb-footer-links");
|
|
6649
|
+
}
|
|
6650
|
+
function isFooterLinkAnchor(el) {
|
|
6651
|
+
if (!el.matches("[data-ohw-href-key]")) return false;
|
|
6652
|
+
if (!isFooterHrefKey(el.getAttribute("data-ohw-href-key"))) return false;
|
|
6653
|
+
return Boolean(el.querySelector('[data-ohw-editable="text"]'));
|
|
6654
|
+
}
|
|
6655
|
+
function listFooterColumns() {
|
|
6656
|
+
const root = getFooterLinksContainer() ?? getFooterRoot()?.querySelector(".rb-footer-links") ?? null;
|
|
6657
|
+
if (!root) return [];
|
|
6658
|
+
const explicit = Array.from(root.querySelectorAll(":scope > [data-ohw-footer-col]"));
|
|
6659
|
+
if (explicit.length > 0) return explicit;
|
|
6660
|
+
return Array.from(root.children).filter((el) => {
|
|
6661
|
+
if (!(el instanceof HTMLElement)) return false;
|
|
6662
|
+
return Array.from(el.querySelectorAll(":scope > [data-ohw-href-key]")).some(
|
|
6663
|
+
isFooterLinkAnchor
|
|
6664
|
+
);
|
|
6665
|
+
});
|
|
6666
|
+
}
|
|
6667
|
+
function listFooterLinksInColumn(column) {
|
|
6668
|
+
return Array.from(column.querySelectorAll(":scope > [data-ohw-href-key]")).filter(
|
|
6669
|
+
isFooterLinkAnchor
|
|
6670
|
+
);
|
|
6671
|
+
}
|
|
6672
|
+
function findFooterColumnForLink(anchor) {
|
|
6673
|
+
const columns = listFooterColumns();
|
|
6674
|
+
return columns.find((col) => col.contains(anchor)) ?? null;
|
|
6675
|
+
}
|
|
6676
|
+
function getFooterOrderFromDom() {
|
|
6677
|
+
return listFooterColumns().map(
|
|
6678
|
+
(col) => listFooterLinksInColumn(col).map((el) => el.getAttribute("data-ohw-href-key")).filter((key) => Boolean(key))
|
|
6679
|
+
);
|
|
6680
|
+
}
|
|
6681
|
+
function findFooterLinkByKey(hrefKey) {
|
|
6682
|
+
return document.querySelector(
|
|
6683
|
+
`footer [data-ohw-href-key="${CSS.escape(hrefKey)}"]`
|
|
6684
|
+
);
|
|
6685
|
+
}
|
|
6686
|
+
function syncFooterColumnIndices(columns) {
|
|
6687
|
+
columns.forEach((col, index) => {
|
|
6688
|
+
const next = String(index);
|
|
6689
|
+
if (col.getAttribute("data-ohw-footer-col") !== next) {
|
|
6690
|
+
col.setAttribute("data-ohw-footer-col", next);
|
|
6691
|
+
}
|
|
6692
|
+
});
|
|
6693
|
+
}
|
|
6694
|
+
function appendChildIfNeeded(parent, child) {
|
|
6695
|
+
if (parent.lastElementChild !== child) {
|
|
6696
|
+
parent.appendChild(child);
|
|
6697
|
+
}
|
|
6698
|
+
}
|
|
6699
|
+
function insertLinkBeforeNext(col, el, nextEl) {
|
|
6700
|
+
if (nextEl) {
|
|
6701
|
+
if (el.nextElementSibling !== nextEl) {
|
|
6702
|
+
col.insertBefore(el, nextEl);
|
|
6703
|
+
}
|
|
6704
|
+
return;
|
|
6705
|
+
}
|
|
6706
|
+
if (col.lastElementChild !== el) {
|
|
6707
|
+
col.appendChild(el);
|
|
6708
|
+
}
|
|
6709
|
+
}
|
|
6710
|
+
function applyFooterOrder(order) {
|
|
6711
|
+
const container = getFooterLinksContainer();
|
|
6712
|
+
if (!container) return;
|
|
6713
|
+
const columns = listFooterColumns();
|
|
6714
|
+
if (columns.length === 0) return;
|
|
6715
|
+
const currentOrder = getFooterOrderFromDom();
|
|
6716
|
+
if (ordersEqual(order, currentOrder)) {
|
|
6717
|
+
syncFooterColumnIndices(columns);
|
|
6718
|
+
return;
|
|
6719
|
+
}
|
|
6720
|
+
const colCount = Math.max(columns.length, order.length);
|
|
6721
|
+
const working = columns.slice(0, colCount);
|
|
6722
|
+
for (let i = 0; i < order.length && i < working.length; i++) {
|
|
6723
|
+
appendChildIfNeeded(container, working[i]);
|
|
6724
|
+
}
|
|
6725
|
+
for (let i = order.length; i < working.length; i++) {
|
|
6726
|
+
appendChildIfNeeded(container, working[i]);
|
|
6727
|
+
}
|
|
6728
|
+
const freshColumns = listFooterColumns();
|
|
6729
|
+
syncFooterColumnIndices(freshColumns);
|
|
6730
|
+
for (let c = 0; c < order.length; c++) {
|
|
6731
|
+
const col = freshColumns[c];
|
|
6732
|
+
if (!col) continue;
|
|
6733
|
+
const colOrder = order[c];
|
|
6734
|
+
for (let j = 0; j < colOrder.length; j++) {
|
|
6735
|
+
const hrefKey = colOrder[j];
|
|
6736
|
+
const el = findFooterLinkByKey(hrefKey);
|
|
6737
|
+
if (!el) continue;
|
|
6738
|
+
if (el.parentElement !== col) {
|
|
6739
|
+
col.appendChild(el);
|
|
6740
|
+
}
|
|
6741
|
+
const nextKey = colOrder[j + 1];
|
|
6742
|
+
const nextEl = nextKey ? findFooterLinkByKey(nextKey) : null;
|
|
6743
|
+
insertLinkBeforeNext(col, el, nextEl?.parentElement === col ? nextEl : null);
|
|
6744
|
+
}
|
|
6745
|
+
}
|
|
6746
|
+
}
|
|
6747
|
+
function ordersEqual(a, b) {
|
|
6748
|
+
if (a.length !== b.length) return false;
|
|
6749
|
+
for (let i = 0; i < a.length; i++) {
|
|
6750
|
+
const left = a[i];
|
|
6751
|
+
const right = b[i];
|
|
6752
|
+
if (left.length !== right.length) return false;
|
|
6753
|
+
for (let j = 0; j < left.length; j++) {
|
|
6754
|
+
if (left[j] !== right[j]) return false;
|
|
6755
|
+
}
|
|
6756
|
+
}
|
|
6757
|
+
return true;
|
|
6758
|
+
}
|
|
6759
|
+
function planFooterLinkMove(hrefKey, targetColIndex, insertIndex) {
|
|
6760
|
+
const order = getFooterOrderFromDom();
|
|
6761
|
+
if (targetColIndex < 0 || targetColIndex >= order.length) return null;
|
|
6762
|
+
let fromCol = -1;
|
|
6763
|
+
let fromIdx = -1;
|
|
6764
|
+
for (let c = 0; c < order.length; c++) {
|
|
6765
|
+
const idx = order[c].indexOf(hrefKey);
|
|
6766
|
+
if (idx >= 0) {
|
|
6767
|
+
fromCol = c;
|
|
6768
|
+
fromIdx = idx;
|
|
6769
|
+
break;
|
|
6770
|
+
}
|
|
6771
|
+
}
|
|
6772
|
+
if (fromCol < 0) return null;
|
|
6773
|
+
const next = order.map((col) => [...col]);
|
|
6774
|
+
next[fromCol].splice(fromIdx, 1);
|
|
6775
|
+
let adjusted = insertIndex;
|
|
6776
|
+
if (fromCol === targetColIndex && fromIdx < insertIndex) adjusted -= 1;
|
|
6777
|
+
adjusted = Math.max(0, Math.min(adjusted, next[targetColIndex].length));
|
|
6778
|
+
next[targetColIndex].splice(adjusted, 0, hrefKey);
|
|
6779
|
+
if (ordersEqual(next, order)) return null;
|
|
6780
|
+
return next;
|
|
6781
|
+
}
|
|
6782
|
+
function planFooterColumnMove(fromIndex, toIndex) {
|
|
6783
|
+
const order = getFooterOrderFromDom();
|
|
6784
|
+
const columns = listFooterColumns();
|
|
6785
|
+
if (fromIndex < 0 || fromIndex >= columns.length || toIndex < 0 || toIndex > columns.length) {
|
|
6786
|
+
return null;
|
|
6787
|
+
}
|
|
6788
|
+
if (toIndex === fromIndex || toIndex === fromIndex + 1) return null;
|
|
6789
|
+
const nextOrder = order.map((col) => [...col]);
|
|
6790
|
+
const [movedOrder] = nextOrder.splice(fromIndex, 1);
|
|
6791
|
+
if (!movedOrder) return null;
|
|
6792
|
+
let adjusted = toIndex;
|
|
6793
|
+
if (fromIndex < toIndex) adjusted -= 1;
|
|
6794
|
+
adjusted = Math.max(0, Math.min(adjusted, nextOrder.length));
|
|
6795
|
+
nextOrder.splice(adjusted, 0, movedOrder);
|
|
6796
|
+
if (ordersEqual(nextOrder, order)) return null;
|
|
6797
|
+
return nextOrder;
|
|
6798
|
+
}
|
|
6799
|
+
function parseFooterOrder(content) {
|
|
6800
|
+
const raw = content[FOOTER_ORDER_KEY];
|
|
6801
|
+
if (!raw) return null;
|
|
6802
|
+
try {
|
|
6803
|
+
const parsed = JSON.parse(raw);
|
|
6804
|
+
if (!Array.isArray(parsed)) return null;
|
|
6805
|
+
return parsed.filter((col) => Array.isArray(col)).map((col) => col.filter((key) => typeof key === "string" && key.length > 0));
|
|
6806
|
+
} catch {
|
|
6807
|
+
return null;
|
|
6808
|
+
}
|
|
6809
|
+
}
|
|
6810
|
+
function reconcileFooterOrderFromContent(content) {
|
|
6811
|
+
const order = parseFooterOrder(content);
|
|
6812
|
+
if (!order?.length) return;
|
|
6813
|
+
const current = getFooterOrderFromDom();
|
|
6814
|
+
if (ordersEqual(order, current)) {
|
|
6815
|
+
syncFooterColumnIndices(listFooterColumns());
|
|
6816
|
+
return;
|
|
6817
|
+
}
|
|
6818
|
+
applyFooterOrder(order);
|
|
6819
|
+
}
|
|
6820
|
+
function buildLinkDropSlots(column, columnIndex) {
|
|
6821
|
+
const links = listFooterLinksInColumn(column);
|
|
6822
|
+
const colRect = column.getBoundingClientRect();
|
|
6823
|
+
const slots = [];
|
|
6824
|
+
const barThickness = 3;
|
|
6825
|
+
if (links.length === 0) {
|
|
6826
|
+
slots.push({
|
|
6827
|
+
insertIndex: 0,
|
|
6828
|
+
columnIndex,
|
|
6829
|
+
left: colRect.left,
|
|
6830
|
+
top: colRect.top + colRect.height / 2 - barThickness / 2,
|
|
6831
|
+
width: colRect.width,
|
|
6832
|
+
height: barThickness,
|
|
6833
|
+
direction: "horizontal"
|
|
6834
|
+
});
|
|
6835
|
+
return slots;
|
|
6836
|
+
}
|
|
6837
|
+
for (let i = 0; i <= links.length; i++) {
|
|
6838
|
+
let top;
|
|
6839
|
+
if (i === 0) {
|
|
6840
|
+
top = links[0].getBoundingClientRect().top - barThickness / 2;
|
|
6841
|
+
} else if (i === links.length) {
|
|
6842
|
+
const last = links[links.length - 1].getBoundingClientRect();
|
|
6843
|
+
top = last.bottom - barThickness / 2;
|
|
6844
|
+
} else {
|
|
6845
|
+
const prev = links[i - 1].getBoundingClientRect();
|
|
6846
|
+
const next = links[i].getBoundingClientRect();
|
|
6847
|
+
top = (prev.bottom + next.top) / 2 - barThickness / 2;
|
|
6848
|
+
}
|
|
6849
|
+
const widthRef = i === 0 ? links[0].getBoundingClientRect() : i === links.length ? links[links.length - 1].getBoundingClientRect() : links[i].getBoundingClientRect();
|
|
6850
|
+
slots.push({
|
|
6851
|
+
insertIndex: i,
|
|
6852
|
+
columnIndex,
|
|
6853
|
+
left: widthRef.left,
|
|
6854
|
+
top,
|
|
6855
|
+
width: Math.max(widthRef.width, colRect.width * 0.8),
|
|
6856
|
+
height: barThickness,
|
|
6857
|
+
direction: "horizontal"
|
|
6858
|
+
});
|
|
6859
|
+
}
|
|
6860
|
+
return slots;
|
|
6861
|
+
}
|
|
6862
|
+
function buildColumnDropSlots() {
|
|
6863
|
+
const columns = listFooterColumns();
|
|
6864
|
+
const slots = [];
|
|
6865
|
+
const barThickness = 3;
|
|
6866
|
+
if (columns.length === 0) return slots;
|
|
6867
|
+
for (let i = 0; i <= columns.length; i++) {
|
|
6868
|
+
let left;
|
|
6869
|
+
let height;
|
|
6870
|
+
let top;
|
|
6871
|
+
if (i === 0) {
|
|
6872
|
+
const first = columns[0].getBoundingClientRect();
|
|
6873
|
+
left = first.left - barThickness / 2;
|
|
6874
|
+
top = first.top;
|
|
6875
|
+
height = first.height;
|
|
6876
|
+
} else if (i === columns.length) {
|
|
6877
|
+
const last = columns[columns.length - 1].getBoundingClientRect();
|
|
6878
|
+
left = last.right - barThickness / 2;
|
|
6879
|
+
top = last.top;
|
|
6880
|
+
height = last.height;
|
|
6881
|
+
} else {
|
|
6882
|
+
const prev = columns[i - 1].getBoundingClientRect();
|
|
6883
|
+
const next = columns[i].getBoundingClientRect();
|
|
6884
|
+
left = (prev.right + next.left) / 2 - barThickness / 2;
|
|
6885
|
+
top = Math.min(prev.top, next.top);
|
|
6886
|
+
height = Math.max(prev.bottom, next.bottom) - top;
|
|
6887
|
+
}
|
|
6888
|
+
slots.push({
|
|
6889
|
+
insertIndex: i,
|
|
6890
|
+
columnIndex: i,
|
|
6891
|
+
left,
|
|
6892
|
+
top,
|
|
6893
|
+
width: barThickness,
|
|
6894
|
+
height: Math.max(height, 24),
|
|
6895
|
+
direction: "vertical"
|
|
6896
|
+
});
|
|
6897
|
+
}
|
|
6898
|
+
return slots;
|
|
6899
|
+
}
|
|
6900
|
+
function hitTestLinkDropSlot(clientX, clientY, draggedHrefKey) {
|
|
6901
|
+
const columns = listFooterColumns();
|
|
6902
|
+
let best = null;
|
|
6903
|
+
for (let c = 0; c < columns.length; c++) {
|
|
6904
|
+
const col = columns[c];
|
|
6905
|
+
const colRect = col.getBoundingClientRect();
|
|
6906
|
+
const inColX = clientX >= colRect.left - 24 && clientX <= colRect.right + 24;
|
|
6907
|
+
if (!inColX) continue;
|
|
6908
|
+
const slots = buildLinkDropSlots(col, c).filter((slot) => {
|
|
6909
|
+
const links = listFooterLinksInColumn(col);
|
|
6910
|
+
const fromIdx = links.findIndex(
|
|
6911
|
+
(el) => el.getAttribute("data-ohw-href-key") === draggedHrefKey
|
|
6912
|
+
);
|
|
6913
|
+
if (fromIdx < 0) return true;
|
|
6914
|
+
if (c === findColumnIndexForKey(draggedHrefKey) && (slot.insertIndex === fromIdx || slot.insertIndex === fromIdx + 1)) {
|
|
6915
|
+
return true;
|
|
6916
|
+
}
|
|
6917
|
+
return true;
|
|
6918
|
+
});
|
|
6919
|
+
for (const slot of slots) {
|
|
6920
|
+
const cy = slot.top + slot.height / 2;
|
|
6921
|
+
const dist = Math.abs(clientY - cy) + (inColX ? 0 : 1e3);
|
|
6922
|
+
if (!best || dist < best.dist) best = { slot, dist };
|
|
6923
|
+
}
|
|
6924
|
+
}
|
|
6925
|
+
return best?.slot ?? null;
|
|
6926
|
+
}
|
|
6927
|
+
function findColumnIndexForKey(hrefKey) {
|
|
6928
|
+
const order = getFooterOrderFromDom();
|
|
6929
|
+
for (let c = 0; c < order.length; c++) {
|
|
6930
|
+
if (order[c].includes(hrefKey)) return c;
|
|
6931
|
+
}
|
|
6932
|
+
return -1;
|
|
6933
|
+
}
|
|
6934
|
+
function hitTestColumnDropSlot(clientX, _clientY) {
|
|
6935
|
+
const slots = buildColumnDropSlots();
|
|
6936
|
+
let best = null;
|
|
6937
|
+
for (const slot of slots) {
|
|
6938
|
+
const cx2 = slot.left + slot.width / 2;
|
|
6939
|
+
const dist = Math.abs(clientX - cx2);
|
|
6940
|
+
if (!best || dist < best.dist) best = { slot, dist };
|
|
6941
|
+
}
|
|
6942
|
+
return best?.slot ?? null;
|
|
6943
|
+
}
|
|
6944
|
+
|
|
6611
6945
|
// src/lib/carousel.ts
|
|
6612
6946
|
var import_react8 = require("react");
|
|
6613
6947
|
var CAROUSEL_ATTR = "data-ohw-carousel";
|
|
@@ -6736,8 +7070,50 @@ function NavbarContainerChrome({
|
|
|
6736
7070
|
);
|
|
6737
7071
|
}
|
|
6738
7072
|
|
|
6739
|
-
// src/ui/
|
|
7073
|
+
// src/ui/drop-indicator.tsx
|
|
7074
|
+
var React9 = __toESM(require("react"), 1);
|
|
6740
7075
|
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
7076
|
+
var dropIndicatorVariants = cva(
|
|
7077
|
+
"ov-gap-line pointer-events-none shrink-0 transition-opacity duration-150",
|
|
7078
|
+
{
|
|
7079
|
+
variants: {
|
|
7080
|
+
direction: {
|
|
7081
|
+
vertical: "h-6 w-[3px]",
|
|
7082
|
+
horizontal: "h-[3px] w-[200px]"
|
|
7083
|
+
},
|
|
7084
|
+
state: {
|
|
7085
|
+
default: "opacity-0",
|
|
7086
|
+
hover: "opacity-100",
|
|
7087
|
+
dragIdle: "opacity-40",
|
|
7088
|
+
dragActive: "opacity-100"
|
|
7089
|
+
}
|
|
7090
|
+
},
|
|
7091
|
+
defaultVariants: {
|
|
7092
|
+
direction: "vertical",
|
|
7093
|
+
state: "default"
|
|
7094
|
+
}
|
|
7095
|
+
}
|
|
7096
|
+
);
|
|
7097
|
+
var DropIndicator = React9.forwardRef(
|
|
7098
|
+
({ className, direction, state, ...props }, ref) => {
|
|
7099
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
7100
|
+
"div",
|
|
7101
|
+
{
|
|
7102
|
+
ref,
|
|
7103
|
+
"data-slot": "drop-indicator",
|
|
7104
|
+
"data-direction": direction ?? "vertical",
|
|
7105
|
+
"data-state": state ?? "default",
|
|
7106
|
+
"aria-hidden": "true",
|
|
7107
|
+
className: cn(dropIndicatorVariants({ direction, state }), className),
|
|
7108
|
+
...props
|
|
7109
|
+
}
|
|
7110
|
+
);
|
|
7111
|
+
}
|
|
7112
|
+
);
|
|
7113
|
+
DropIndicator.displayName = "DropIndicator";
|
|
7114
|
+
|
|
7115
|
+
// src/ui/badge.tsx
|
|
7116
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
6741
7117
|
var badgeVariants = cva(
|
|
6742
7118
|
"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",
|
|
6743
7119
|
{
|
|
@@ -6755,12 +7131,12 @@ var badgeVariants = cva(
|
|
|
6755
7131
|
}
|
|
6756
7132
|
);
|
|
6757
7133
|
function Badge({ className, variant, ...props }) {
|
|
6758
|
-
return /* @__PURE__ */ (0,
|
|
7134
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: cn(badgeVariants({ variant }), className), ...props });
|
|
6759
7135
|
}
|
|
6760
7136
|
|
|
6761
7137
|
// src/OhhwellsBridge.tsx
|
|
6762
7138
|
var import_lucide_react12 = require("lucide-react");
|
|
6763
|
-
var
|
|
7139
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
6764
7140
|
var PRIMARY2 = "#0885FE";
|
|
6765
7141
|
var IMAGE_FADE_MS = 300;
|
|
6766
7142
|
function runOpacityFade(el, onDone) {
|
|
@@ -6939,7 +7315,7 @@ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId,
|
|
|
6939
7315
|
const root = (0, import_client.createRoot)(container);
|
|
6940
7316
|
(0, import_react_dom2.flushSync)(() => {
|
|
6941
7317
|
root.render(
|
|
6942
|
-
/* @__PURE__ */ (0,
|
|
7318
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
6943
7319
|
SchedulingWidget,
|
|
6944
7320
|
{
|
|
6945
7321
|
notifyOnConnect,
|
|
@@ -7001,7 +7377,7 @@ function isDragHandleDisabled(el) {
|
|
|
7001
7377
|
return raw === "true" || raw === "";
|
|
7002
7378
|
});
|
|
7003
7379
|
}
|
|
7004
|
-
function collectEditableNodes() {
|
|
7380
|
+
function collectEditableNodes(extraContent) {
|
|
7005
7381
|
const nodes = Array.from(document.querySelectorAll("[data-ohw-editable]")).map((el) => {
|
|
7006
7382
|
if (el.dataset.ohwEditable === "image") {
|
|
7007
7383
|
const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
|
|
@@ -7029,6 +7405,14 @@ function collectEditableNodes() {
|
|
|
7029
7405
|
if (!key) return;
|
|
7030
7406
|
nodes.push({ key, type: "link", text: getLinkHref2(el) });
|
|
7031
7407
|
});
|
|
7408
|
+
if (extraContent) {
|
|
7409
|
+
for (const key of [NAV_ORDER_KEY, FOOTER_ORDER_KEY, NAV_COUNT_KEY]) {
|
|
7410
|
+
const text = extraContent[key];
|
|
7411
|
+
if (typeof text === "string" && text.length > 0) {
|
|
7412
|
+
nodes.push({ key, type: "meta", text });
|
|
7413
|
+
}
|
|
7414
|
+
}
|
|
7415
|
+
}
|
|
7032
7416
|
document.querySelectorAll('[data-ohw-editable="video"]').forEach((el) => {
|
|
7033
7417
|
const key = el.dataset.ohwKey ?? "";
|
|
7034
7418
|
const video = getVideoEl(el);
|
|
@@ -7127,6 +7511,29 @@ function getHrefKeyFromElement(el) {
|
|
|
7127
7511
|
if (!key) return null;
|
|
7128
7512
|
return { anchor, key };
|
|
7129
7513
|
}
|
|
7514
|
+
function disableNativeHrefDrag(el) {
|
|
7515
|
+
if (el.draggable) el.draggable = false;
|
|
7516
|
+
if (el.getAttribute("draggable") !== "false") {
|
|
7517
|
+
el.setAttribute("draggable", "false");
|
|
7518
|
+
}
|
|
7519
|
+
}
|
|
7520
|
+
function clearTextSelection() {
|
|
7521
|
+
const sel = window.getSelection();
|
|
7522
|
+
if (sel && !sel.isCollapsed) sel.removeAllRanges();
|
|
7523
|
+
}
|
|
7524
|
+
function armFooterPressDrag() {
|
|
7525
|
+
document.documentElement.setAttribute("data-ohw-footer-press-drag", "");
|
|
7526
|
+
}
|
|
7527
|
+
function lockFooterDuringDrag() {
|
|
7528
|
+
document.documentElement.removeAttribute("data-ohw-footer-press-drag");
|
|
7529
|
+
document.documentElement.setAttribute("data-ohw-item-dragging", "");
|
|
7530
|
+
clearTextSelection();
|
|
7531
|
+
}
|
|
7532
|
+
function unlockFooterDragInteraction() {
|
|
7533
|
+
document.documentElement.removeAttribute("data-ohw-footer-press-drag");
|
|
7534
|
+
document.documentElement.removeAttribute("data-ohw-item-dragging");
|
|
7535
|
+
clearTextSelection();
|
|
7536
|
+
}
|
|
7130
7537
|
function isNavbarButton2(el) {
|
|
7131
7538
|
return Boolean(el.closest('[data-ohw-role="navbar-button"]'));
|
|
7132
7539
|
}
|
|
@@ -7425,7 +7832,7 @@ function EditGlowChrome({
|
|
|
7425
7832
|
dragDisabled = false
|
|
7426
7833
|
}) {
|
|
7427
7834
|
const GAP = 6;
|
|
7428
|
-
return /* @__PURE__ */ (0,
|
|
7835
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
7429
7836
|
"div",
|
|
7430
7837
|
{
|
|
7431
7838
|
ref: elRef,
|
|
@@ -7440,7 +7847,7 @@ function EditGlowChrome({
|
|
|
7440
7847
|
zIndex: 2147483646
|
|
7441
7848
|
},
|
|
7442
7849
|
children: [
|
|
7443
|
-
/* @__PURE__ */ (0,
|
|
7850
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
7444
7851
|
"div",
|
|
7445
7852
|
{
|
|
7446
7853
|
style: {
|
|
@@ -7453,7 +7860,7 @@ function EditGlowChrome({
|
|
|
7453
7860
|
}
|
|
7454
7861
|
}
|
|
7455
7862
|
),
|
|
7456
|
-
reorderHrefKey && /* @__PURE__ */ (0,
|
|
7863
|
+
reorderHrefKey && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
7457
7864
|
"div",
|
|
7458
7865
|
{
|
|
7459
7866
|
"data-ohw-drag-handle-container": "",
|
|
@@ -7465,7 +7872,7 @@ function EditGlowChrome({
|
|
|
7465
7872
|
transform: "translate(calc(-100% - 7px), -50%)",
|
|
7466
7873
|
pointerEvents: dragDisabled ? "none" : "auto"
|
|
7467
7874
|
},
|
|
7468
|
-
children: /* @__PURE__ */ (0,
|
|
7875
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
7469
7876
|
DragHandle,
|
|
7470
7877
|
{
|
|
7471
7878
|
"aria-label": `Reorder ${reorderHrefKey}`,
|
|
@@ -7569,7 +7976,7 @@ function FloatingToolbar({
|
|
|
7569
7976
|
onEditLink
|
|
7570
7977
|
}) {
|
|
7571
7978
|
const { top, left, transform } = calcToolbarPos(rect, parentScroll, 330);
|
|
7572
|
-
return /* @__PURE__ */ (0,
|
|
7979
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
7573
7980
|
"div",
|
|
7574
7981
|
{
|
|
7575
7982
|
ref: elRef,
|
|
@@ -7590,12 +7997,12 @@ function FloatingToolbar({
|
|
|
7590
7997
|
fontFamily: "sans-serif",
|
|
7591
7998
|
pointerEvents: "auto"
|
|
7592
7999
|
},
|
|
7593
|
-
children: /* @__PURE__ */ (0,
|
|
7594
|
-
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ (0,
|
|
7595
|
-
gi > 0 && /* @__PURE__ */ (0,
|
|
8000
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(CustomToolbar, { children: [
|
|
8001
|
+
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_react9.default.Fragment, { children: [
|
|
8002
|
+
gi > 0 && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(CustomToolbarDivider, {}),
|
|
7596
8003
|
btns.map((btn) => {
|
|
7597
8004
|
const isActive = activeCommands.has(btn.cmd);
|
|
7598
|
-
return /* @__PURE__ */ (0,
|
|
8005
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
7599
8006
|
CustomToolbarButton,
|
|
7600
8007
|
{
|
|
7601
8008
|
title: btn.title,
|
|
@@ -7604,7 +8011,7 @@ function FloatingToolbar({
|
|
|
7604
8011
|
e.preventDefault();
|
|
7605
8012
|
onCommand(btn.cmd);
|
|
7606
8013
|
},
|
|
7607
|
-
children: /* @__PURE__ */ (0,
|
|
8014
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
7608
8015
|
"svg",
|
|
7609
8016
|
{
|
|
7610
8017
|
width: "16",
|
|
@@ -7625,7 +8032,7 @@ function FloatingToolbar({
|
|
|
7625
8032
|
);
|
|
7626
8033
|
})
|
|
7627
8034
|
] }, gi)),
|
|
7628
|
-
showEditLink ? /* @__PURE__ */ (0,
|
|
8035
|
+
showEditLink ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
7629
8036
|
CustomToolbarButton,
|
|
7630
8037
|
{
|
|
7631
8038
|
type: "button",
|
|
@@ -7639,7 +8046,7 @@ function FloatingToolbar({
|
|
|
7639
8046
|
e.preventDefault();
|
|
7640
8047
|
e.stopPropagation();
|
|
7641
8048
|
},
|
|
7642
|
-
children: /* @__PURE__ */ (0,
|
|
8049
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Link, { className: "size-4 shrink-0", "aria-hidden": true })
|
|
7643
8050
|
}
|
|
7644
8051
|
) : null
|
|
7645
8052
|
] })
|
|
@@ -7656,7 +8063,7 @@ function StateToggle({
|
|
|
7656
8063
|
states,
|
|
7657
8064
|
onStateChange
|
|
7658
8065
|
}) {
|
|
7659
|
-
return /* @__PURE__ */ (0,
|
|
8066
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
7660
8067
|
ToggleGroup,
|
|
7661
8068
|
{
|
|
7662
8069
|
"data-ohw-state-toggle": "",
|
|
@@ -7670,7 +8077,7 @@ function StateToggle({
|
|
|
7670
8077
|
left: rect.right - 8,
|
|
7671
8078
|
transform: "translateX(-100%)"
|
|
7672
8079
|
},
|
|
7673
|
-
children: states.map((state) => /* @__PURE__ */ (0,
|
|
8080
|
+
children: states.map((state) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ToggleGroupItem, { value: state, size: "sm", children: state }, state))
|
|
7674
8081
|
}
|
|
7675
8082
|
);
|
|
7676
8083
|
}
|
|
@@ -7794,7 +8201,15 @@ function OhhwellsBridge() {
|
|
|
7794
8201
|
const [hoveredItemRect, setHoveredItemRect] = (0, import_react9.useState)(null);
|
|
7795
8202
|
const siblingHintElRef = (0, import_react9.useRef)(null);
|
|
7796
8203
|
const [siblingHintRect, setSiblingHintRect] = (0, import_react9.useState)(null);
|
|
8204
|
+
const [siblingHintRects, setSiblingHintRects] = (0, import_react9.useState)([]);
|
|
7797
8205
|
const [isItemDragging, setIsItemDragging] = (0, import_react9.useState)(false);
|
|
8206
|
+
const [isFooterFrameSelection, setIsFooterFrameSelection] = (0, import_react9.useState)(false);
|
|
8207
|
+
const footerDragRef = (0, import_react9.useRef)(null);
|
|
8208
|
+
const [footerDropSlots, setFooterDropSlots] = (0, import_react9.useState)([]);
|
|
8209
|
+
const [activeFooterDropIndex, setActiveFooterDropIndex] = (0, import_react9.useState)(null);
|
|
8210
|
+
const [draggedItemRect, setDraggedItemRect] = (0, import_react9.useState)(null);
|
|
8211
|
+
const footerPointerDragRef = (0, import_react9.useRef)(null);
|
|
8212
|
+
const suppressNextClickRef = (0, import_react9.useRef)(false);
|
|
7798
8213
|
const [linkPopover, setLinkPopover] = (0, import_react9.useState)(null);
|
|
7799
8214
|
const linkPopoverSessionRef = (0, import_react9.useRef)(null);
|
|
7800
8215
|
const addNavAfterAnchorRef = (0, import_react9.useRef)(null);
|
|
@@ -7958,8 +8373,10 @@ function OhhwellsBridge() {
|
|
|
7958
8373
|
selectedElRef.current = null;
|
|
7959
8374
|
setReorderHrefKey(null);
|
|
7960
8375
|
setReorderDragDisabled(false);
|
|
8376
|
+
setIsFooterFrameSelection(false);
|
|
7961
8377
|
siblingHintElRef.current = null;
|
|
7962
8378
|
setSiblingHintRect(null);
|
|
8379
|
+
setSiblingHintRects([]);
|
|
7963
8380
|
setIsItemDragging(false);
|
|
7964
8381
|
hoveredNavContainerRef.current = null;
|
|
7965
8382
|
setHoveredNavContainerRect(null);
|
|
@@ -8016,90 +8433,345 @@ function OhhwellsBridge() {
|
|
|
8016
8433
|
intent: "add-nav"
|
|
8017
8434
|
});
|
|
8018
8435
|
}, []);
|
|
8019
|
-
const
|
|
8020
|
-
|
|
8021
|
-
|
|
8022
|
-
|
|
8023
|
-
|
|
8024
|
-
|
|
8436
|
+
const clearFooterDragVisuals = (0, import_react9.useCallback)(() => {
|
|
8437
|
+
footerDragRef.current = null;
|
|
8438
|
+
setSiblingHintRects([]);
|
|
8439
|
+
setFooterDropSlots([]);
|
|
8440
|
+
setActiveFooterDropIndex(null);
|
|
8441
|
+
setDraggedItemRect(null);
|
|
8025
8442
|
setIsItemDragging(false);
|
|
8443
|
+
unlockFooterDragInteraction();
|
|
8026
8444
|
}, []);
|
|
8027
|
-
|
|
8028
|
-
|
|
8029
|
-
|
|
8030
|
-
if (
|
|
8031
|
-
|
|
8032
|
-
|
|
8033
|
-
clearHrefKeyHover(anchor);
|
|
8034
|
-
hoveredNavContainerRef.current = null;
|
|
8035
|
-
setHoveredNavContainerRect(null);
|
|
8036
|
-
setHoveredItemRect(null);
|
|
8037
|
-
hoveredItemElRef.current = null;
|
|
8038
|
-
siblingHintElRef.current = null;
|
|
8039
|
-
setSiblingHintRect(null);
|
|
8040
|
-
setIsItemDragging(false);
|
|
8041
|
-
const { key, disabled } = getNavigationItemReorderState(anchor);
|
|
8042
|
-
setReorderHrefKey(key);
|
|
8043
|
-
setReorderDragDisabled(disabled);
|
|
8044
|
-
setToolbarVariant("link-action");
|
|
8045
|
-
setToolbarRect(anchor.getBoundingClientRect());
|
|
8046
|
-
setToolbarShowEditLink(false);
|
|
8047
|
-
setActiveCommands(/* @__PURE__ */ new Set());
|
|
8048
|
-
}, [deactivate]);
|
|
8049
|
-
const selectFrame = (0, import_react9.useCallback)((el) => {
|
|
8050
|
-
if (!isNavigationContainer(el)) return;
|
|
8051
|
-
if (activeElRef.current) deactivate();
|
|
8052
|
-
selectedElRef.current = el;
|
|
8053
|
-
clearHrefKeyHover(el);
|
|
8054
|
-
hoveredNavContainerRef.current = null;
|
|
8055
|
-
setHoveredNavContainerRect(null);
|
|
8056
|
-
setHoveredItemRect(null);
|
|
8057
|
-
hoveredItemElRef.current = null;
|
|
8058
|
-
siblingHintElRef.current = null;
|
|
8059
|
-
setSiblingHintRect(null);
|
|
8060
|
-
setIsItemDragging(false);
|
|
8061
|
-
setReorderHrefKey(null);
|
|
8062
|
-
setReorderDragDisabled(false);
|
|
8063
|
-
setToolbarVariant("select-frame");
|
|
8064
|
-
setToolbarRect(el.getBoundingClientRect());
|
|
8065
|
-
setToolbarShowEditLink(false);
|
|
8066
|
-
setActiveCommands(/* @__PURE__ */ new Set());
|
|
8067
|
-
}, [deactivate]);
|
|
8068
|
-
const activate = (0, import_react9.useCallback)((el, options) => {
|
|
8069
|
-
if (activeElRef.current === el) return;
|
|
8070
|
-
selectedElRef.current = null;
|
|
8071
|
-
deactivate();
|
|
8072
|
-
if (hoveredImageRef.current) {
|
|
8073
|
-
hoveredImageRef.current = null;
|
|
8074
|
-
setMediaHover(null);
|
|
8445
|
+
const refreshFooterDragVisuals = (0, import_react9.useCallback)((session, activeSlot, clientX, clientY) => {
|
|
8446
|
+
const dragged = session.draggedEl;
|
|
8447
|
+
setDraggedItemRect(dragged.getBoundingClientRect());
|
|
8448
|
+
if (typeof clientX === "number" && typeof clientY === "number") {
|
|
8449
|
+
session.lastClientX = clientX;
|
|
8450
|
+
session.lastClientY = clientY;
|
|
8075
8451
|
}
|
|
8076
|
-
|
|
8077
|
-
|
|
8078
|
-
|
|
8079
|
-
|
|
8080
|
-
|
|
8081
|
-
|
|
8082
|
-
|
|
8083
|
-
|
|
8084
|
-
|
|
8085
|
-
|
|
8086
|
-
|
|
8087
|
-
|
|
8452
|
+
session.activeSlot = activeSlot;
|
|
8453
|
+
if (session.kind === "link") {
|
|
8454
|
+
const columns2 = listFooterColumns();
|
|
8455
|
+
const focusCols = /* @__PURE__ */ new Set([session.sourceColumnIndex]);
|
|
8456
|
+
if (activeSlot) focusCols.add(activeSlot.columnIndex);
|
|
8457
|
+
const siblingRects = [];
|
|
8458
|
+
columns2.forEach((col, i) => {
|
|
8459
|
+
if (!focusCols.has(i)) return;
|
|
8460
|
+
for (const link of listFooterLinksInColumn(col)) {
|
|
8461
|
+
if (link === dragged) continue;
|
|
8462
|
+
siblingRects.push(link.getBoundingClientRect());
|
|
8463
|
+
}
|
|
8464
|
+
});
|
|
8465
|
+
setSiblingHintRects(siblingRects);
|
|
8466
|
+
const slots2 = [];
|
|
8467
|
+
columns2.forEach((col, i) => {
|
|
8468
|
+
slots2.push(...buildLinkDropSlots(col, i));
|
|
8469
|
+
});
|
|
8470
|
+
setFooterDropSlots(slots2);
|
|
8471
|
+
const activeIdx2 = activeSlot ? slots2.findIndex((s) => s.columnIndex === activeSlot.columnIndex && s.insertIndex === activeSlot.insertIndex) : -1;
|
|
8472
|
+
setActiveFooterDropIndex(activeIdx2 >= 0 ? activeIdx2 : null);
|
|
8473
|
+
return;
|
|
8088
8474
|
}
|
|
8089
|
-
|
|
8090
|
-
|
|
8091
|
-
|
|
8475
|
+
const columns = listFooterColumns();
|
|
8476
|
+
setSiblingHintRects(columns.filter((col) => col !== dragged).map((col) => col.getBoundingClientRect()));
|
|
8477
|
+
const slots = buildColumnDropSlots();
|
|
8478
|
+
setFooterDropSlots(slots);
|
|
8479
|
+
const activeIdx = activeSlot ? slots.findIndex((s) => s.insertIndex === activeSlot.insertIndex) : -1;
|
|
8480
|
+
setActiveFooterDropIndex(activeIdx >= 0 ? activeIdx : null);
|
|
8481
|
+
}, []);
|
|
8482
|
+
const refreshFooterDragVisualsRef = (0, import_react9.useRef)(refreshFooterDragVisuals);
|
|
8483
|
+
refreshFooterDragVisualsRef.current = refreshFooterDragVisuals;
|
|
8484
|
+
const commitFooterDragRef = (0, import_react9.useRef)(() => {
|
|
8485
|
+
});
|
|
8486
|
+
const beginFooterDragRef = (0, import_react9.useRef)(() => {
|
|
8487
|
+
});
|
|
8488
|
+
const beginFooterDrag = (0, import_react9.useCallback)(
|
|
8489
|
+
(session) => {
|
|
8490
|
+
const rect = session.draggedEl.getBoundingClientRect();
|
|
8491
|
+
session.lastClientX = session.lastClientX || rect.left + rect.width / 2;
|
|
8492
|
+
session.lastClientY = session.lastClientY || rect.top + rect.height / 2;
|
|
8493
|
+
session.activeSlot = session.activeSlot ?? null;
|
|
8494
|
+
footerDragRef.current = session;
|
|
8495
|
+
setIsItemDragging(true);
|
|
8496
|
+
lockFooterDuringDrag();
|
|
8497
|
+
siblingHintElRef.current = null;
|
|
8498
|
+
setSiblingHintRect(null);
|
|
8499
|
+
if (session.wasSelected && selectedElRef.current === session.draggedEl) {
|
|
8500
|
+
setToolbarRect(rect);
|
|
8501
|
+
}
|
|
8502
|
+
const initialSlot = session.kind === "link" && session.hrefKey ? hitTestLinkDropSlot(session.lastClientX, session.lastClientY, session.hrefKey) : hitTestColumnDropSlot(session.lastClientX, session.lastClientY);
|
|
8503
|
+
refreshFooterDragVisuals(session, initialSlot, session.lastClientX, session.lastClientY);
|
|
8504
|
+
},
|
|
8505
|
+
[refreshFooterDragVisuals]
|
|
8506
|
+
);
|
|
8507
|
+
beginFooterDragRef.current = beginFooterDrag;
|
|
8508
|
+
const commitFooterDrag = (0, import_react9.useCallback)(
|
|
8509
|
+
(clientX, clientY) => {
|
|
8510
|
+
const session = footerDragRef.current;
|
|
8511
|
+
if (!session) {
|
|
8512
|
+
clearFooterDragVisuals();
|
|
8513
|
+
return;
|
|
8514
|
+
}
|
|
8515
|
+
const x = typeof clientX === "number" && (clientX !== 0 || clientY !== 0) ? clientX : session.lastClientX;
|
|
8516
|
+
const y = typeof clientY === "number" && (clientX !== 0 || clientY !== 0) ? clientY : session.lastClientY;
|
|
8517
|
+
let nextOrder = null;
|
|
8518
|
+
const slot = session.activeSlot ?? (session.kind === "link" && session.hrefKey ? hitTestLinkDropSlot(x, y, session.hrefKey) : session.kind === "column" ? hitTestColumnDropSlot(x, y) : null);
|
|
8519
|
+
if (session.kind === "link" && session.hrefKey && slot) {
|
|
8520
|
+
nextOrder = planFooterLinkMove(session.hrefKey, slot.columnIndex, slot.insertIndex);
|
|
8521
|
+
} else if (session.kind === "column" && slot) {
|
|
8522
|
+
nextOrder = planFooterColumnMove(session.sourceColumnIndex, slot.insertIndex);
|
|
8523
|
+
}
|
|
8524
|
+
const wasSelected = session.wasSelected;
|
|
8525
|
+
const draggedEl = session.draggedEl;
|
|
8526
|
+
const hrefKey = session.hrefKey;
|
|
8527
|
+
let movedColumnIndex = null;
|
|
8528
|
+
if (session.kind === "column" && slot && nextOrder) {
|
|
8529
|
+
let adjusted = slot.insertIndex;
|
|
8530
|
+
if (session.sourceColumnIndex < slot.insertIndex) adjusted -= 1;
|
|
8531
|
+
movedColumnIndex = Math.max(0, Math.min(adjusted, nextOrder.length - 1));
|
|
8532
|
+
}
|
|
8533
|
+
clearFooterDragVisuals();
|
|
8534
|
+
if (nextOrder) {
|
|
8535
|
+
const orderJson = JSON.stringify(nextOrder);
|
|
8536
|
+
editContentRef.current = {
|
|
8537
|
+
...editContentRef.current,
|
|
8538
|
+
[FOOTER_ORDER_KEY]: orderJson
|
|
8539
|
+
};
|
|
8540
|
+
applyFooterOrder(nextOrder);
|
|
8541
|
+
document.querySelectorAll("footer [data-ohw-href-key]").forEach(disableNativeHrefDrag);
|
|
8542
|
+
requestAnimationFrame(() => {
|
|
8543
|
+
if (editContentRef.current[FOOTER_ORDER_KEY] === orderJson) {
|
|
8544
|
+
applyFooterOrder(nextOrder);
|
|
8545
|
+
document.querySelectorAll("footer [data-ohw-href-key]").forEach(disableNativeHrefDrag);
|
|
8546
|
+
}
|
|
8547
|
+
});
|
|
8548
|
+
postToParentRef.current({
|
|
8549
|
+
type: "ow:change",
|
|
8550
|
+
nodes: [{ key: FOOTER_ORDER_KEY, text: orderJson }]
|
|
8551
|
+
});
|
|
8552
|
+
}
|
|
8553
|
+
const still = (hrefKey ? document.querySelector(`footer [data-ohw-href-key="${CSS.escape(hrefKey)}"]`) : null) ?? (movedColumnIndex !== null ? listFooterColumns()[movedColumnIndex] ?? null : null) ?? (document.body.contains(draggedEl) ? draggedEl : null);
|
|
8554
|
+
if (still && isNavigationItem(still)) {
|
|
8555
|
+
selectRef.current(still);
|
|
8556
|
+
} else if (still && isNavigationContainer(still)) {
|
|
8557
|
+
selectFrameRef.current(still);
|
|
8558
|
+
} else if (wasSelected) {
|
|
8559
|
+
deselectRef.current();
|
|
8560
|
+
}
|
|
8561
|
+
},
|
|
8562
|
+
[clearFooterDragVisuals]
|
|
8563
|
+
);
|
|
8564
|
+
commitFooterDragRef.current = commitFooterDrag;
|
|
8565
|
+
const startFooterLinkDrag = (0, import_react9.useCallback)(
|
|
8566
|
+
(anchor, clientX, clientY, wasSelected) => {
|
|
8567
|
+
const hrefKey = anchor.getAttribute("data-ohw-href-key");
|
|
8568
|
+
if (!hrefKey || !isFooterHrefKey(hrefKey)) return false;
|
|
8569
|
+
const column = findFooterColumnForLink(anchor);
|
|
8570
|
+
const columns = listFooterColumns();
|
|
8571
|
+
beginFooterDrag({
|
|
8572
|
+
kind: "link",
|
|
8573
|
+
hrefKey,
|
|
8574
|
+
columnEl: column,
|
|
8575
|
+
sourceColumnIndex: column ? columns.indexOf(column) : 0,
|
|
8576
|
+
wasSelected,
|
|
8577
|
+
draggedEl: anchor,
|
|
8578
|
+
lastClientX: clientX,
|
|
8579
|
+
lastClientY: clientY,
|
|
8580
|
+
activeSlot: null
|
|
8581
|
+
});
|
|
8582
|
+
return true;
|
|
8583
|
+
},
|
|
8584
|
+
[beginFooterDrag]
|
|
8585
|
+
);
|
|
8586
|
+
const startFooterColumnDrag = (0, import_react9.useCallback)(
|
|
8587
|
+
(columnEl, clientX, clientY, wasSelected) => {
|
|
8588
|
+
const columns = listFooterColumns();
|
|
8589
|
+
const idx = columns.indexOf(columnEl);
|
|
8590
|
+
if (idx < 0) return false;
|
|
8591
|
+
beginFooterDrag({
|
|
8592
|
+
kind: "column",
|
|
8593
|
+
hrefKey: null,
|
|
8594
|
+
columnEl,
|
|
8595
|
+
sourceColumnIndex: idx,
|
|
8596
|
+
wasSelected,
|
|
8597
|
+
draggedEl: columnEl,
|
|
8598
|
+
lastClientX: clientX,
|
|
8599
|
+
lastClientY: clientY,
|
|
8600
|
+
activeSlot: null
|
|
8601
|
+
});
|
|
8602
|
+
return true;
|
|
8603
|
+
},
|
|
8604
|
+
[beginFooterDrag]
|
|
8605
|
+
);
|
|
8606
|
+
const handleItemDragStart = (0, import_react9.useCallback)(
|
|
8607
|
+
(e) => {
|
|
8608
|
+
const selected = selectedElRef.current;
|
|
8609
|
+
if (!selected) {
|
|
8610
|
+
setIsItemDragging(true);
|
|
8611
|
+
return;
|
|
8612
|
+
}
|
|
8613
|
+
const clientX = e?.clientX ?? selected.getBoundingClientRect().left + 8;
|
|
8614
|
+
const clientY = e?.clientY ?? selected.getBoundingClientRect().top + 8;
|
|
8615
|
+
if (startFooterLinkDrag(selected, clientX, clientY, true)) return;
|
|
8616
|
+
if (selected.hasAttribute("data-ohw-footer-col") || isInferredFooterGroup(selected) && selected.closest("footer")) {
|
|
8617
|
+
if (startFooterColumnDrag(selected, clientX, clientY, true)) return;
|
|
8618
|
+
}
|
|
8619
|
+
siblingHintElRef.current = null;
|
|
8620
|
+
setSiblingHintRect(null);
|
|
8621
|
+
setIsItemDragging(true);
|
|
8622
|
+
},
|
|
8623
|
+
[startFooterColumnDrag, startFooterLinkDrag]
|
|
8624
|
+
);
|
|
8625
|
+
const handleItemDragEnd = (0, import_react9.useCallback)(
|
|
8626
|
+
(e) => {
|
|
8627
|
+
if (footerDragRef.current) {
|
|
8628
|
+
const x = e?.clientX;
|
|
8629
|
+
const y = e?.clientY;
|
|
8630
|
+
if (typeof x === "number" && typeof y === "number" && (x !== 0 || y !== 0)) {
|
|
8631
|
+
commitFooterDrag(x, y);
|
|
8632
|
+
} else {
|
|
8633
|
+
commitFooterDrag();
|
|
8634
|
+
}
|
|
8635
|
+
return;
|
|
8636
|
+
}
|
|
8637
|
+
setIsItemDragging(false);
|
|
8638
|
+
},
|
|
8639
|
+
[commitFooterDrag]
|
|
8640
|
+
);
|
|
8641
|
+
const handleItemChromePointerDown = (0, import_react9.useCallback)((e) => {
|
|
8642
|
+
if (e.button !== 0) return;
|
|
8643
|
+
const selected = selectedElRef.current;
|
|
8644
|
+
if (!selected) return;
|
|
8645
|
+
armFooterPressDrag();
|
|
8646
|
+
const hrefKey = selected.getAttribute("data-ohw-href-key");
|
|
8647
|
+
if (hrefKey && isFooterHrefKey(hrefKey)) {
|
|
8648
|
+
footerPointerDragRef.current = {
|
|
8649
|
+
el: selected,
|
|
8650
|
+
kind: "link",
|
|
8651
|
+
startX: e.clientX,
|
|
8652
|
+
startY: e.clientY,
|
|
8653
|
+
pointerId: e.pointerId,
|
|
8654
|
+
wasSelected: true,
|
|
8655
|
+
started: false
|
|
8656
|
+
};
|
|
8657
|
+
return;
|
|
8658
|
+
}
|
|
8659
|
+
if (selected.hasAttribute("data-ohw-footer-col") || isInferredFooterGroup(selected) && selected.closest("footer")) {
|
|
8660
|
+
footerPointerDragRef.current = {
|
|
8661
|
+
el: selected,
|
|
8662
|
+
kind: "column",
|
|
8663
|
+
startX: e.clientX,
|
|
8664
|
+
startY: e.clientY,
|
|
8665
|
+
pointerId: e.pointerId,
|
|
8666
|
+
wasSelected: true,
|
|
8667
|
+
started: false
|
|
8668
|
+
};
|
|
8669
|
+
}
|
|
8670
|
+
}, []);
|
|
8671
|
+
const handleItemChromeClick = (0, import_react9.useCallback)((clientX, clientY) => {
|
|
8672
|
+
if (suppressNextClickRef.current) {
|
|
8673
|
+
suppressNextClickRef.current = false;
|
|
8674
|
+
return;
|
|
8675
|
+
}
|
|
8676
|
+
const selected = selectedElRef.current;
|
|
8677
|
+
if (!selected || !isNavigationItem(selected)) return;
|
|
8678
|
+
const editable = selected.querySelector('[data-ohw-editable="text"]') ?? selected.querySelector("[data-ohw-editable]");
|
|
8679
|
+
if (!editable) return;
|
|
8680
|
+
activateRef.current(editable, { caretX: clientX, caretY: clientY });
|
|
8681
|
+
}, []);
|
|
8682
|
+
reselectNavigationItemRef.current = reselectNavigationItem;
|
|
8683
|
+
commitNavigationTextEditRef.current = commitNavigationTextEdit;
|
|
8684
|
+
const select = (0, import_react9.useCallback)(
|
|
8685
|
+
(anchor) => {
|
|
8686
|
+
if (!isNavigationItem(anchor)) return;
|
|
8687
|
+
if (activeElRef.current) deactivate();
|
|
8688
|
+
selectedElRef.current = anchor;
|
|
8689
|
+
clearHrefKeyHover(anchor);
|
|
8690
|
+
hoveredNavContainerRef.current = null;
|
|
8691
|
+
setHoveredNavContainerRect(null);
|
|
8692
|
+
setHoveredItemRect(null);
|
|
8693
|
+
hoveredItemElRef.current = null;
|
|
8694
|
+
siblingHintElRef.current = null;
|
|
8695
|
+
setSiblingHintRect(null);
|
|
8696
|
+
setSiblingHintRects([]);
|
|
8697
|
+
setIsItemDragging(false);
|
|
8698
|
+
const { key, disabled } = getNavigationItemReorderState(anchor);
|
|
8699
|
+
setReorderHrefKey(key);
|
|
8700
|
+
setReorderDragDisabled(disabled);
|
|
8701
|
+
setIsFooterFrameSelection(false);
|
|
8702
|
+
setToolbarVariant("link-action");
|
|
8703
|
+
setToolbarRect(anchor.getBoundingClientRect());
|
|
8704
|
+
setToolbarShowEditLink(false);
|
|
8705
|
+
setActiveCommands(/* @__PURE__ */ new Set());
|
|
8706
|
+
},
|
|
8707
|
+
[deactivate]
|
|
8708
|
+
);
|
|
8709
|
+
const selectFrame = (0, import_react9.useCallback)(
|
|
8710
|
+
(el) => {
|
|
8711
|
+
if (!isNavigationContainer(el)) return;
|
|
8712
|
+
if (activeElRef.current) deactivate();
|
|
8713
|
+
const isFooterColumn = el.hasAttribute("data-ohw-footer-col") || Boolean(el.closest("footer") && isInferredFooterGroup(el));
|
|
8714
|
+
selectedElRef.current = el;
|
|
8715
|
+
clearHrefKeyHover(el);
|
|
8716
|
+
hoveredNavContainerRef.current = null;
|
|
8717
|
+
setHoveredNavContainerRect(null);
|
|
8718
|
+
setHoveredItemRect(null);
|
|
8719
|
+
hoveredItemElRef.current = null;
|
|
8720
|
+
siblingHintElRef.current = null;
|
|
8721
|
+
setSiblingHintRect(null);
|
|
8722
|
+
setSiblingHintRects(
|
|
8723
|
+
isFooterColumn ? listFooterColumns().filter((column) => column !== el).map((column) => column.getBoundingClientRect()) : []
|
|
8724
|
+
);
|
|
8725
|
+
setIsItemDragging(false);
|
|
8092
8726
|
setReorderHrefKey(null);
|
|
8093
8727
|
setReorderDragDisabled(false);
|
|
8094
|
-
|
|
8095
|
-
|
|
8096
|
-
|
|
8097
|
-
|
|
8098
|
-
|
|
8099
|
-
|
|
8100
|
-
|
|
8101
|
-
|
|
8102
|
-
|
|
8728
|
+
setIsFooterFrameSelection(isFooterColumn);
|
|
8729
|
+
setToolbarVariant("select-frame");
|
|
8730
|
+
setToolbarRect(el.getBoundingClientRect());
|
|
8731
|
+
setToolbarShowEditLink(false);
|
|
8732
|
+
setActiveCommands(/* @__PURE__ */ new Set());
|
|
8733
|
+
},
|
|
8734
|
+
[deactivate]
|
|
8735
|
+
);
|
|
8736
|
+
const activate = (0, import_react9.useCallback)(
|
|
8737
|
+
(el, options) => {
|
|
8738
|
+
if (activeElRef.current === el) return;
|
|
8739
|
+
selectedElRef.current = null;
|
|
8740
|
+
deactivate();
|
|
8741
|
+
if (hoveredImageRef.current) {
|
|
8742
|
+
hoveredImageRef.current = null;
|
|
8743
|
+
postToParentRef.current({ type: "ow:image-unhover" });
|
|
8744
|
+
}
|
|
8745
|
+
setToolbarVariant("rich-text");
|
|
8746
|
+
siblingHintElRef.current = null;
|
|
8747
|
+
setSiblingHintRect(null);
|
|
8748
|
+
setSiblingHintRects([]);
|
|
8749
|
+
setIsItemDragging(false);
|
|
8750
|
+
el.setAttribute("contenteditable", "true");
|
|
8751
|
+
el.removeAttribute("data-ohw-hovered");
|
|
8752
|
+
el.closest("[data-ohw-href-key]")?.removeAttribute("data-ohw-hovered");
|
|
8753
|
+
activeElRef.current = el;
|
|
8754
|
+
originalContentRef.current = el.innerHTML;
|
|
8755
|
+
el.focus();
|
|
8756
|
+
if (options?.caretX !== void 0 && options?.caretY !== void 0) {
|
|
8757
|
+
placeCaretAtPoint(el, options.caretX, options.caretY);
|
|
8758
|
+
}
|
|
8759
|
+
setToolbarShowEditLink(Boolean(getHrefKeyFromElement(el)));
|
|
8760
|
+
const navAnchor = getNavigationItemAnchor(el);
|
|
8761
|
+
if (navAnchor) {
|
|
8762
|
+
setReorderHrefKey(null);
|
|
8763
|
+
setReorderDragDisabled(false);
|
|
8764
|
+
} else {
|
|
8765
|
+
const { key: reorderKey, disabled: reorderDisabled } = getReorderHandleState(el);
|
|
8766
|
+
setReorderHrefKey(reorderKey);
|
|
8767
|
+
setReorderDragDisabled(reorderDisabled);
|
|
8768
|
+
}
|
|
8769
|
+
setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
|
|
8770
|
+
postToParent2({ type: "ow:enter-edit", key: el.dataset.ohwKey });
|
|
8771
|
+
requestAnimationFrame(() => refreshActiveCommandsRef.current());
|
|
8772
|
+
},
|
|
8773
|
+
[deactivate, postToParent2]
|
|
8774
|
+
);
|
|
8103
8775
|
activateRef.current = activate;
|
|
8104
8776
|
deactivateRef.current = deactivate;
|
|
8105
8777
|
selectRef.current = select;
|
|
@@ -8147,6 +8819,7 @@ function OhhwellsBridge() {
|
|
|
8147
8819
|
applyLinkByKey(key, val);
|
|
8148
8820
|
}
|
|
8149
8821
|
reconcileNavbarItemsFromContent(content);
|
|
8822
|
+
reconcileFooterOrderFromContent(content);
|
|
8150
8823
|
enforceLinkHrefs();
|
|
8151
8824
|
initSectionsFromContent(content, true);
|
|
8152
8825
|
sectionsLoadedRef.current = true;
|
|
@@ -8208,6 +8881,7 @@ function OhhwellsBridge() {
|
|
|
8208
8881
|
applyLinkByKey(key, val);
|
|
8209
8882
|
}
|
|
8210
8883
|
reconcileNavbarItemsFromContent(content);
|
|
8884
|
+
reconcileFooterOrderFromContent(content);
|
|
8211
8885
|
} finally {
|
|
8212
8886
|
observer?.observe(document.body, { childList: true, subtree: true });
|
|
8213
8887
|
}
|
|
@@ -8248,15 +8922,42 @@ function OhhwellsBridge() {
|
|
|
8248
8922
|
if (!subdomain) return {};
|
|
8249
8923
|
return contentCache.get(subdomain) ?? {};
|
|
8250
8924
|
};
|
|
8251
|
-
|
|
8925
|
+
let applying = false;
|
|
8926
|
+
let rafId = null;
|
|
8927
|
+
const run = () => {
|
|
8928
|
+
if (footerDragRef.current || applying) return;
|
|
8929
|
+
applying = true;
|
|
8930
|
+
try {
|
|
8931
|
+
const content = contentForNav();
|
|
8932
|
+
reconcileNavbarItemsFromContent(content);
|
|
8933
|
+
reconcileFooterOrderFromContent(content);
|
|
8934
|
+
document.querySelectorAll("footer [data-ohw-href-key]").forEach((el) => {
|
|
8935
|
+
if (isFooterHrefKey(el.getAttribute("data-ohw-href-key"))) {
|
|
8936
|
+
disableNativeHrefDrag(el);
|
|
8937
|
+
}
|
|
8938
|
+
});
|
|
8939
|
+
} finally {
|
|
8940
|
+
applying = false;
|
|
8941
|
+
}
|
|
8942
|
+
};
|
|
8943
|
+
const scheduleRun = () => {
|
|
8944
|
+
if (rafId !== null) cancelAnimationFrame(rafId);
|
|
8945
|
+
rafId = requestAnimationFrame(() => {
|
|
8946
|
+
rafId = null;
|
|
8947
|
+
run();
|
|
8948
|
+
});
|
|
8949
|
+
};
|
|
8252
8950
|
run();
|
|
8253
8951
|
const nav = document.querySelector("nav");
|
|
8254
|
-
|
|
8255
|
-
const observer = new MutationObserver(
|
|
8256
|
-
|
|
8257
|
-
});
|
|
8258
|
-
|
|
8259
|
-
return () =>
|
|
8952
|
+
const footer = document.querySelector("footer");
|
|
8953
|
+
const observer = new MutationObserver(scheduleRun);
|
|
8954
|
+
if (nav) observer.observe(nav, { childList: true, subtree: true });
|
|
8955
|
+
if (footer) observer.observe(footer, { childList: true, subtree: true });
|
|
8956
|
+
if (!nav && !footer) return;
|
|
8957
|
+
return () => {
|
|
8958
|
+
observer.disconnect();
|
|
8959
|
+
if (rafId !== null) cancelAnimationFrame(rafId);
|
|
8960
|
+
};
|
|
8260
8961
|
}, [isEditMode, pathname, subdomain, fetchState]);
|
|
8261
8962
|
(0, import_react9.useEffect)(() => {
|
|
8262
8963
|
if (!isEditMode) return;
|
|
@@ -8321,6 +9022,29 @@ function OhhwellsBridge() {
|
|
|
8321
9022
|
[data-ohw-editable] {
|
|
8322
9023
|
display: block;
|
|
8323
9024
|
}
|
|
9025
|
+
/* Native <a> drag steals clicks \u2014 disable for edit links; reorder via press-to-drag / handle. */
|
|
9026
|
+
footer [data-ohw-href-key] {
|
|
9027
|
+
-webkit-user-drag: none !important;
|
|
9028
|
+
}
|
|
9029
|
+
footer [data-ohw-footer-col]:hover {
|
|
9030
|
+
outline: 1.5px dashed ${PRIMARY2} !important;
|
|
9031
|
+
outline-offset: 6px;
|
|
9032
|
+
border-radius: 8px;
|
|
9033
|
+
}
|
|
9034
|
+
html[data-ohw-footer-press-drag] footer,
|
|
9035
|
+
html[data-ohw-footer-press-drag] footer * {
|
|
9036
|
+
user-select: none !important;
|
|
9037
|
+
-webkit-user-select: none !important;
|
|
9038
|
+
}
|
|
9039
|
+
html[data-ohw-item-dragging] footer,
|
|
9040
|
+
html[data-ohw-item-dragging] footer * {
|
|
9041
|
+
user-select: none !important;
|
|
9042
|
+
-webkit-user-select: none !important;
|
|
9043
|
+
pointer-events: none !important;
|
|
9044
|
+
}
|
|
9045
|
+
html[data-ohw-item-dragging] {
|
|
9046
|
+
cursor: grabbing !important;
|
|
9047
|
+
}
|
|
8324
9048
|
[data-ohw-editable]:not([contenteditable]):not([data-ohw-editable="image"]):not([data-ohw-editable="bg-image"]):not([data-ohw-editable="video"]) { cursor: text !important; }
|
|
8325
9049
|
[data-ohw-editable="image"], [data-ohw-editable="image"] *,
|
|
8326
9050
|
[data-ohw-editable="video"], [data-ohw-editable="video"] *,
|
|
@@ -8366,12 +9090,39 @@ function OhhwellsBridge() {
|
|
|
8366
9090
|
}
|
|
8367
9091
|
refreshStateRules();
|
|
8368
9092
|
const handleClick = (e) => {
|
|
9093
|
+
if (suppressNextClickRef.current) {
|
|
9094
|
+
suppressNextClickRef.current = false;
|
|
9095
|
+
e.preventDefault();
|
|
9096
|
+
e.stopPropagation();
|
|
9097
|
+
return;
|
|
9098
|
+
}
|
|
8369
9099
|
const target = e.target;
|
|
8370
9100
|
if (target.closest("[data-ohw-toolbar]")) return;
|
|
8371
9101
|
if (target.closest("[data-ohw-state-toggle]")) return;
|
|
8372
9102
|
if (target.closest("[data-ohw-max-badge]")) return;
|
|
8373
9103
|
if (isInsideLinkEditor(target)) return;
|
|
8374
9104
|
if (target.closest('[data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
|
|
9105
|
+
if (target.closest("[data-ohw-item-drag-surface]")) {
|
|
9106
|
+
e.preventDefault();
|
|
9107
|
+
e.stopPropagation();
|
|
9108
|
+
const selected = selectedElRef.current;
|
|
9109
|
+
if (selected && isNavigationItem(selected)) {
|
|
9110
|
+
const editable2 = selected.querySelector('[data-ohw-editable="text"]') ?? selected.querySelector("[data-ohw-editable]");
|
|
9111
|
+
if (editable2) {
|
|
9112
|
+
activateRef.current(editable2, {
|
|
9113
|
+
caretX: e.clientX,
|
|
9114
|
+
caretY: e.clientY
|
|
9115
|
+
});
|
|
9116
|
+
}
|
|
9117
|
+
} else if (selected?.hasAttribute("data-ohw-footer-col")) {
|
|
9118
|
+
const link = listFooterLinksInColumn(selected).find((el) => {
|
|
9119
|
+
const r2 = el.getBoundingClientRect();
|
|
9120
|
+
return e.clientX >= r2.left && e.clientX <= r2.right && e.clientY >= r2.top && e.clientY <= r2.bottom;
|
|
9121
|
+
});
|
|
9122
|
+
if (link) selectRef.current(link);
|
|
9123
|
+
}
|
|
9124
|
+
return;
|
|
9125
|
+
}
|
|
8375
9126
|
const navFromChrome = resolveNavContainerSelectionTarget(target, e.clientX, e.clientY);
|
|
8376
9127
|
if (navFromChrome) {
|
|
8377
9128
|
e.preventDefault();
|
|
@@ -8426,10 +9177,26 @@ function OhhwellsBridge() {
|
|
|
8426
9177
|
if (hrefAnchor) {
|
|
8427
9178
|
e.preventDefault();
|
|
8428
9179
|
e.stopPropagation();
|
|
8429
|
-
if (selectedElRef.current === hrefAnchor)
|
|
9180
|
+
if (selectedElRef.current === hrefAnchor) {
|
|
9181
|
+
const textEditable = hrefAnchor.querySelector('[data-ohw-editable="text"]') ?? hrefAnchor.querySelector("[data-ohw-editable]");
|
|
9182
|
+
if (textEditable) {
|
|
9183
|
+
activateRef.current(textEditable, {
|
|
9184
|
+
caretX: e.clientX,
|
|
9185
|
+
caretY: e.clientY
|
|
9186
|
+
});
|
|
9187
|
+
}
|
|
9188
|
+
return;
|
|
9189
|
+
}
|
|
8430
9190
|
selectRef.current(hrefAnchor);
|
|
8431
9191
|
return;
|
|
8432
9192
|
}
|
|
9193
|
+
const footerColClick = target.closest("[data-ohw-footer-col]");
|
|
9194
|
+
if (footerColClick) {
|
|
9195
|
+
e.preventDefault();
|
|
9196
|
+
e.stopPropagation();
|
|
9197
|
+
selectFrameRef.current(footerColClick);
|
|
9198
|
+
return;
|
|
9199
|
+
}
|
|
8433
9200
|
const navContainerToSelect = resolveNavContainerSelectionTarget(target, e.clientX, e.clientY);
|
|
8434
9201
|
if (navContainerToSelect) {
|
|
8435
9202
|
e.preventDefault();
|
|
@@ -8510,6 +9277,15 @@ function OhhwellsBridge() {
|
|
|
8510
9277
|
setHoveredNavContainerRect(null);
|
|
8511
9278
|
}
|
|
8512
9279
|
}
|
|
9280
|
+
const footerCol = target.closest("[data-ohw-footer-col]");
|
|
9281
|
+
if (footerCol) {
|
|
9282
|
+
hoveredNavContainerRef.current = null;
|
|
9283
|
+
setHoveredNavContainerRect(null);
|
|
9284
|
+
if (selectedElRef.current === footerCol) return;
|
|
9285
|
+
hoveredItemElRef.current = footerCol;
|
|
9286
|
+
setHoveredItemRect(footerCol.getBoundingClientRect());
|
|
9287
|
+
return;
|
|
9288
|
+
}
|
|
8513
9289
|
const navAnchor = getNavigationItemAnchor(target);
|
|
8514
9290
|
if (navAnchor) {
|
|
8515
9291
|
hoveredNavContainerRef.current = null;
|
|
@@ -8546,6 +9322,15 @@ function OhhwellsBridge() {
|
|
|
8546
9322
|
hoveredNavContainerRef.current = null;
|
|
8547
9323
|
setHoveredNavContainerRect(null);
|
|
8548
9324
|
}
|
|
9325
|
+
const footerCol = target.closest("[data-ohw-footer-col]");
|
|
9326
|
+
if (footerCol && hoveredItemElRef.current === footerCol) {
|
|
9327
|
+
const related2 = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
9328
|
+
if (related2?.closest("[data-ohw-drag-handle-container], [data-ohw-item-interaction]")) return;
|
|
9329
|
+
if (related2?.closest("[data-ohw-footer-col]") === footerCol) return;
|
|
9330
|
+
hoveredItemElRef.current = null;
|
|
9331
|
+
setHoveredItemRect(null);
|
|
9332
|
+
return;
|
|
9333
|
+
}
|
|
8549
9334
|
const navAnchor = getNavigationItemAnchor(target);
|
|
8550
9335
|
if (navAnchor) {
|
|
8551
9336
|
const related2 = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
@@ -8954,6 +9739,14 @@ function OhhwellsBridge() {
|
|
|
8954
9739
|
probeHoverCardsAt(clientX, clientY);
|
|
8955
9740
|
};
|
|
8956
9741
|
const handleDragOver = (e) => {
|
|
9742
|
+
const footerSession = footerDragRef.current;
|
|
9743
|
+
if (footerSession) {
|
|
9744
|
+
e.preventDefault();
|
|
9745
|
+
if (e.dataTransfer) e.dataTransfer.dropEffect = "move";
|
|
9746
|
+
const slot = footerSession.kind === "link" && footerSession.hrefKey ? hitTestLinkDropSlot(e.clientX, e.clientY, footerSession.hrefKey) : hitTestColumnDropSlot(e.clientX, e.clientY);
|
|
9747
|
+
refreshFooterDragVisualsRef.current(footerSession, slot, e.clientX, e.clientY);
|
|
9748
|
+
return;
|
|
9749
|
+
}
|
|
8957
9750
|
e.preventDefault();
|
|
8958
9751
|
const el = findImageAtPoint(e.clientX, e.clientY, false);
|
|
8959
9752
|
if (!el) {
|
|
@@ -9161,6 +9954,7 @@ function OhhwellsBridge() {
|
|
|
9161
9954
|
}
|
|
9162
9955
|
editContentRef.current = { ...editContentRef.current, ...content };
|
|
9163
9956
|
reconcileNavbarItemsFromContent(editContentRef.current);
|
|
9957
|
+
reconcileFooterOrderFromContent(editContentRef.current);
|
|
9164
9958
|
enforceLinkHrefs();
|
|
9165
9959
|
postToParentRef.current({ type: "ow:hydrate-done" });
|
|
9166
9960
|
};
|
|
@@ -9274,6 +10068,17 @@ function OhhwellsBridge() {
|
|
|
9274
10068
|
if (siblingHintElRef.current) {
|
|
9275
10069
|
setSiblingHintRect(siblingHintElRef.current.getBoundingClientRect());
|
|
9276
10070
|
}
|
|
10071
|
+
const selected = selectedElRef.current;
|
|
10072
|
+
if (selected && !footerDragRef.current && (selected.hasAttribute("data-ohw-footer-col") || Boolean(selected.closest("footer") && isInferredFooterGroup(selected)))) {
|
|
10073
|
+
setSiblingHintRects(
|
|
10074
|
+
listFooterColumns().filter((column) => column !== selected).map((column) => column.getBoundingClientRect())
|
|
10075
|
+
);
|
|
10076
|
+
}
|
|
10077
|
+
if (footerDragRef.current) {
|
|
10078
|
+
const session = footerDragRef.current;
|
|
10079
|
+
const slot = session.kind === "link" && session.hrefKey ? hitTestLinkDropSlot(session.lastClientX, session.lastClientY, session.hrefKey) : hitTestColumnDropSlot(session.lastClientX, session.lastClientY);
|
|
10080
|
+
refreshFooterDragVisualsRef.current(session, slot, session.lastClientX, session.lastClientY);
|
|
10081
|
+
}
|
|
9277
10082
|
if (hoveredImageRef.current) {
|
|
9278
10083
|
const el = hoveredImageRef.current;
|
|
9279
10084
|
const r2 = el.getBoundingClientRect();
|
|
@@ -9284,7 +10089,7 @@ function OhhwellsBridge() {
|
|
|
9284
10089
|
};
|
|
9285
10090
|
const handleSave = (e) => {
|
|
9286
10091
|
if (e.data?.type !== "ow:save") return;
|
|
9287
|
-
const nodes = collectEditableNodes();
|
|
10092
|
+
const nodes = collectEditableNodes(editContentRef.current);
|
|
9288
10093
|
const tracker = document.querySelector("[data-ohw-sections-tracker]");
|
|
9289
10094
|
if (tracker?.textContent) nodes.push({ key: "__ohw_sections", type: "sections", text: tracker.textContent });
|
|
9290
10095
|
postToParentRef.current({ type: "ow:save-result", nodes });
|
|
@@ -9624,6 +10429,154 @@ function OhhwellsBridge() {
|
|
|
9624
10429
|
if (imageShowTimerRef.current) clearTimeout(imageShowTimerRef.current);
|
|
9625
10430
|
};
|
|
9626
10431
|
}, [isEditMode, refreshStateRules]);
|
|
10432
|
+
(0, import_react9.useEffect)(() => {
|
|
10433
|
+
if (!isEditMode) return;
|
|
10434
|
+
const THRESHOLD = 10;
|
|
10435
|
+
const resolveWasSelected = (el) => {
|
|
10436
|
+
if (selectedElRef.current === el) return true;
|
|
10437
|
+
const activeAnchor = activeElRef.current ? getNavigationItemAnchor(activeElRef.current) : null;
|
|
10438
|
+
return activeAnchor === el;
|
|
10439
|
+
};
|
|
10440
|
+
const onPointerDown = (e) => {
|
|
10441
|
+
if (e.button !== 0) return;
|
|
10442
|
+
if (footerDragRef.current) return;
|
|
10443
|
+
const target = e.target;
|
|
10444
|
+
if (!target) return;
|
|
10445
|
+
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]')) {
|
|
10446
|
+
return;
|
|
10447
|
+
}
|
|
10448
|
+
if (target.closest("[data-ohw-item-drag-surface]")) return;
|
|
10449
|
+
const anchor = getNavigationItemAnchor(target);
|
|
10450
|
+
const hrefKey = anchor?.getAttribute("data-ohw-href-key") ?? null;
|
|
10451
|
+
if (anchor && isFooterHrefKey(hrefKey)) {
|
|
10452
|
+
armFooterPressDrag();
|
|
10453
|
+
footerPointerDragRef.current = {
|
|
10454
|
+
el: anchor,
|
|
10455
|
+
kind: "link",
|
|
10456
|
+
startX: e.clientX,
|
|
10457
|
+
startY: e.clientY,
|
|
10458
|
+
pointerId: e.pointerId,
|
|
10459
|
+
wasSelected: resolveWasSelected(anchor),
|
|
10460
|
+
started: false
|
|
10461
|
+
};
|
|
10462
|
+
return;
|
|
10463
|
+
}
|
|
10464
|
+
const col = target.closest("[data-ohw-footer-col]");
|
|
10465
|
+
if (col && !getNavigationItemAnchor(target)) {
|
|
10466
|
+
armFooterPressDrag();
|
|
10467
|
+
footerPointerDragRef.current = {
|
|
10468
|
+
el: col,
|
|
10469
|
+
kind: "column",
|
|
10470
|
+
startX: e.clientX,
|
|
10471
|
+
startY: e.clientY,
|
|
10472
|
+
pointerId: e.pointerId,
|
|
10473
|
+
wasSelected: resolveWasSelected(col),
|
|
10474
|
+
started: false
|
|
10475
|
+
};
|
|
10476
|
+
}
|
|
10477
|
+
};
|
|
10478
|
+
const onPointerMove = (e) => {
|
|
10479
|
+
const pending = footerPointerDragRef.current;
|
|
10480
|
+
if (!pending) return;
|
|
10481
|
+
if (pending.started) {
|
|
10482
|
+
e.preventDefault();
|
|
10483
|
+
clearTextSelection();
|
|
10484
|
+
const session = footerDragRef.current;
|
|
10485
|
+
if (!session) return;
|
|
10486
|
+
const slot = session.kind === "link" && session.hrefKey ? hitTestLinkDropSlot(e.clientX, e.clientY, session.hrefKey) : hitTestColumnDropSlot(e.clientX, e.clientY);
|
|
10487
|
+
refreshFooterDragVisualsRef.current(session, slot, e.clientX, e.clientY);
|
|
10488
|
+
return;
|
|
10489
|
+
}
|
|
10490
|
+
const dx = e.clientX - pending.startX;
|
|
10491
|
+
const dy = e.clientY - pending.startY;
|
|
10492
|
+
if (dx * dx + dy * dy < THRESHOLD * THRESHOLD) return;
|
|
10493
|
+
e.preventDefault();
|
|
10494
|
+
pending.started = true;
|
|
10495
|
+
clearTextSelection();
|
|
10496
|
+
try {
|
|
10497
|
+
document.body.setPointerCapture(pending.pointerId);
|
|
10498
|
+
} catch {
|
|
10499
|
+
}
|
|
10500
|
+
if (linkPopoverOpenRef.current) {
|
|
10501
|
+
setLinkPopoverRef.current(null);
|
|
10502
|
+
}
|
|
10503
|
+
if (activeElRef.current) {
|
|
10504
|
+
deactivateRef.current();
|
|
10505
|
+
}
|
|
10506
|
+
if (pending.kind === "link") {
|
|
10507
|
+
const key = pending.el.getAttribute("data-ohw-href-key");
|
|
10508
|
+
if (!key) return;
|
|
10509
|
+
const column = findFooterColumnForLink(pending.el);
|
|
10510
|
+
const columns2 = listFooterColumns();
|
|
10511
|
+
beginFooterDragRef.current({
|
|
10512
|
+
kind: "link",
|
|
10513
|
+
hrefKey: key,
|
|
10514
|
+
columnEl: column,
|
|
10515
|
+
sourceColumnIndex: column ? columns2.indexOf(column) : 0,
|
|
10516
|
+
wasSelected: pending.wasSelected,
|
|
10517
|
+
draggedEl: pending.el,
|
|
10518
|
+
lastClientX: e.clientX,
|
|
10519
|
+
lastClientY: e.clientY,
|
|
10520
|
+
activeSlot: null
|
|
10521
|
+
});
|
|
10522
|
+
return;
|
|
10523
|
+
}
|
|
10524
|
+
const columns = listFooterColumns();
|
|
10525
|
+
const idx = columns.indexOf(pending.el);
|
|
10526
|
+
if (idx < 0) return;
|
|
10527
|
+
beginFooterDragRef.current({
|
|
10528
|
+
kind: "column",
|
|
10529
|
+
hrefKey: null,
|
|
10530
|
+
columnEl: pending.el,
|
|
10531
|
+
sourceColumnIndex: idx,
|
|
10532
|
+
wasSelected: pending.wasSelected,
|
|
10533
|
+
draggedEl: pending.el,
|
|
10534
|
+
lastClientX: e.clientX,
|
|
10535
|
+
lastClientY: e.clientY,
|
|
10536
|
+
activeSlot: null
|
|
10537
|
+
});
|
|
10538
|
+
};
|
|
10539
|
+
const endPointerDrag = (e) => {
|
|
10540
|
+
const pending = footerPointerDragRef.current;
|
|
10541
|
+
footerPointerDragRef.current = null;
|
|
10542
|
+
try {
|
|
10543
|
+
if (document.body.hasPointerCapture(e.pointerId)) {
|
|
10544
|
+
document.body.releasePointerCapture(e.pointerId);
|
|
10545
|
+
}
|
|
10546
|
+
} catch {
|
|
10547
|
+
}
|
|
10548
|
+
if (!pending?.started) {
|
|
10549
|
+
unlockFooterDragInteraction();
|
|
10550
|
+
return;
|
|
10551
|
+
}
|
|
10552
|
+
suppressNextClickRef.current = true;
|
|
10553
|
+
commitFooterDragRef.current(e.clientX, e.clientY);
|
|
10554
|
+
};
|
|
10555
|
+
const blockSelectStart = (e) => {
|
|
10556
|
+
if (footerDragRef.current || footerPointerDragRef.current?.started || document.documentElement.hasAttribute("data-ohw-footer-press-drag")) {
|
|
10557
|
+
e.preventDefault();
|
|
10558
|
+
}
|
|
10559
|
+
};
|
|
10560
|
+
const onDragEnd = (_e) => {
|
|
10561
|
+
if (!footerDragRef.current) return;
|
|
10562
|
+
commitFooterDragRef.current();
|
|
10563
|
+
};
|
|
10564
|
+
document.addEventListener("pointerdown", onPointerDown, true);
|
|
10565
|
+
document.addEventListener("pointermove", onPointerMove, true);
|
|
10566
|
+
document.addEventListener("pointerup", endPointerDrag, true);
|
|
10567
|
+
document.addEventListener("pointercancel", endPointerDrag, true);
|
|
10568
|
+
document.addEventListener("selectstart", blockSelectStart, true);
|
|
10569
|
+
document.addEventListener("dragend", onDragEnd, true);
|
|
10570
|
+
return () => {
|
|
10571
|
+
document.removeEventListener("pointerdown", onPointerDown, true);
|
|
10572
|
+
document.removeEventListener("pointermove", onPointerMove, true);
|
|
10573
|
+
document.removeEventListener("pointerup", endPointerDrag, true);
|
|
10574
|
+
document.removeEventListener("pointercancel", endPointerDrag, true);
|
|
10575
|
+
document.removeEventListener("selectstart", blockSelectStart, true);
|
|
10576
|
+
document.removeEventListener("dragend", onDragEnd, true);
|
|
10577
|
+
unlockFooterDragInteraction();
|
|
10578
|
+
};
|
|
10579
|
+
}, [isEditMode]);
|
|
9627
10580
|
(0, import_react9.useEffect)(() => {
|
|
9628
10581
|
const handler = (e) => {
|
|
9629
10582
|
if (e.data?.type !== "ow:request-schedule-config") return;
|
|
@@ -9661,7 +10614,13 @@ function OhhwellsBridge() {
|
|
|
9661
10614
|
const next = { ...prev, [pathKey]: sections };
|
|
9662
10615
|
return shouldUseDevFixtures() ? { ...DEV_SECTIONS_BY_PATH, ...next } : next;
|
|
9663
10616
|
});
|
|
9664
|
-
postToParent2({
|
|
10617
|
+
postToParent2({
|
|
10618
|
+
type: "ow:ready",
|
|
10619
|
+
version: "1",
|
|
10620
|
+
path: pathname,
|
|
10621
|
+
nodes: collectEditableNodes(editContentRef.current),
|
|
10622
|
+
sections
|
|
10623
|
+
});
|
|
9665
10624
|
postToParent2({ type: "ow:request-site-pages" });
|
|
9666
10625
|
}, 150);
|
|
9667
10626
|
return () => {
|
|
@@ -9778,9 +10737,6 @@ function OhhwellsBridge() {
|
|
|
9778
10737
|
},
|
|
9779
10738
|
[postToParent2, sitePages, sectionsByPath]
|
|
9780
10739
|
);
|
|
9781
|
-
const showEditLink = toolbarShowEditLink;
|
|
9782
|
-
const currentSections = sectionsByPath[pathname] ?? [];
|
|
9783
|
-
linkPopoverOpenRef.current = linkPopover !== null;
|
|
9784
10740
|
const handleMediaReplace = (0, import_react9.useCallback)(
|
|
9785
10741
|
(key) => {
|
|
9786
10742
|
postToParent2({ type: "ow:image-pick", key, elementType: mediaHover?.elementType ?? "image" });
|
|
@@ -9823,10 +10779,13 @@ function OhhwellsBridge() {
|
|
|
9823
10779
|
},
|
|
9824
10780
|
[postToParent2]
|
|
9825
10781
|
);
|
|
10782
|
+
const showEditLink = toolbarShowEditLink;
|
|
10783
|
+
const currentSections = sectionsByPath[pathname] ?? [];
|
|
10784
|
+
linkPopoverOpenRef.current = linkPopover !== null;
|
|
9826
10785
|
return bridgeRoot ? (0, import_react_dom3.createPortal)(
|
|
9827
|
-
/* @__PURE__ */ (0,
|
|
9828
|
-
/* @__PURE__ */ (0,
|
|
9829
|
-
Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ (0,
|
|
10786
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_jsx_runtime25.Fragment, { children: [
|
|
10787
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
|
|
10788
|
+
Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
9830
10789
|
MediaOverlay,
|
|
9831
10790
|
{
|
|
9832
10791
|
hover: { key, rect, elementType: "image", isDragOver: false, hasTextOverlap: false },
|
|
@@ -9837,7 +10796,7 @@ function OhhwellsBridge() {
|
|
|
9837
10796
|
},
|
|
9838
10797
|
`uploading-${key}`
|
|
9839
10798
|
)),
|
|
9840
|
-
mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */ (0,
|
|
10799
|
+
mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
9841
10800
|
MediaOverlay,
|
|
9842
10801
|
{
|
|
9843
10802
|
hover: mediaHover,
|
|
@@ -9846,63 +10805,33 @@ function OhhwellsBridge() {
|
|
|
9846
10805
|
onVideoSettingsChange: handleVideoSettingsChange
|
|
9847
10806
|
}
|
|
9848
10807
|
),
|
|
9849
|
-
carouselHover && /* @__PURE__ */ (0,
|
|
9850
|
-
siblingHintRect && !isItemDragging && /* @__PURE__ */ (0,
|
|
9851
|
-
|
|
9852
|
-
|
|
9853
|
-
|
|
9854
|
-
|
|
9855
|
-
rect: toolbarRect,
|
|
9856
|
-
onAdd: handleAddTopLevelNavItem
|
|
9857
|
-
}
|
|
9858
|
-
),
|
|
9859
|
-
hoveredItemRect && !hoveredNavContainerRect && !siblingHintRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
|
|
9860
|
-
toolbarRect && (toolbarVariant === "link-action" || toolbarVariant === "select-frame") && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
9861
|
-
ItemInteractionLayer,
|
|
10808
|
+
carouselHover && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(CarouselOverlay, { hover: carouselHover, onEdit: handleEditCarousel }),
|
|
10809
|
+
siblingHintRect && !isItemDragging && siblingHintRects.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
|
|
10810
|
+
siblingHintRects.map((rect, i) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ItemInteractionLayer, { rect, state: "sibling-hint" }, `sibling-hint-${i}`)),
|
|
10811
|
+
isItemDragging && draggedItemRect && selectedElRef.current !== footerDragRef.current?.draggedEl && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ItemInteractionLayer, { rect: draggedItemRect, state: "dragging" }),
|
|
10812
|
+
isItemDragging && footerDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
10813
|
+
"div",
|
|
9862
10814
|
{
|
|
9863
|
-
|
|
9864
|
-
|
|
9865
|
-
|
|
9866
|
-
|
|
9867
|
-
|
|
9868
|
-
|
|
9869
|
-
|
|
9870
|
-
|
|
9871
|
-
|
|
9872
|
-
|
|
9873
|
-
|
|
9874
|
-
|
|
9875
|
-
|
|
9876
|
-
|
|
9877
|
-
|
|
9878
|
-
|
|
9879
|
-
|
|
9880
|
-
}
|
|
9881
|
-
),
|
|
9882
|
-
toolbarRect && toolbarVariant === "rich-text" && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_jsx_runtime24.Fragment, { children: [
|
|
9883
|
-
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
9884
|
-
EditGlowChrome,
|
|
9885
|
-
{
|
|
9886
|
-
rect: toolbarRect,
|
|
9887
|
-
elRef: glowElRef,
|
|
9888
|
-
reorderHrefKey,
|
|
9889
|
-
dragDisabled: reorderDragDisabled
|
|
9890
|
-
}
|
|
9891
|
-
),
|
|
9892
|
-
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
9893
|
-
FloatingToolbar,
|
|
9894
|
-
{
|
|
9895
|
-
rect: toolbarRect,
|
|
9896
|
-
parentScroll: parentScrollRef.current,
|
|
9897
|
-
elRef: toolbarElRef,
|
|
9898
|
-
onCommand: handleCommand,
|
|
9899
|
-
activeCommands,
|
|
9900
|
-
showEditLink,
|
|
9901
|
-
onEditLink: openLinkPopoverForActive
|
|
9902
|
-
}
|
|
9903
|
-
)
|
|
10815
|
+
className: "pointer-events-none fixed z-2147483646",
|
|
10816
|
+
style: {
|
|
10817
|
+
left: slot.left,
|
|
10818
|
+
top: slot.top,
|
|
10819
|
+
width: slot.width,
|
|
10820
|
+
height: slot.height
|
|
10821
|
+
},
|
|
10822
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(DropIndicator, { direction: slot.direction, state: activeFooterDropIndex === i ? "dragActive" : "dragIdle", className: slot.direction === "horizontal" ? "!h-full !w-full" : "!h-full !w-full" })
|
|
10823
|
+
},
|
|
10824
|
+
`footer-drop-${slot.direction}-${slot.columnIndex}-${slot.insertIndex}-${i}`
|
|
10825
|
+
)),
|
|
10826
|
+
hoveredNavContainerRect && toolbarVariant !== "select-frame" && !linkPopover && !isItemDragging && !siblingHintRect && siblingHintRects.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ItemInteractionLayer, { rect: hoveredNavContainerRect, state: "hover" }),
|
|
10827
|
+
toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(NavbarContainerChrome, { rect: toolbarRect, onAdd: handleAddTopLevelNavItem }),
|
|
10828
|
+
hoveredItemRect && !hoveredNavContainerRect && !siblingHintRect && siblingHintRects.length === 0 && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
|
|
10829
|
+
toolbarRect && (toolbarVariant === "link-action" || toolbarVariant === "select-frame") && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ItemInteractionLayer, { rect: isItemDragging && draggedItemRect && footerDragRef.current?.wasSelected ? draggedItemRect : toolbarRect, elRef: glowElRef, state: isItemDragging ? "dragging" : resolveItemInteractionState(toolbarRect, parentScrollRef.current), showHandle: toolbarVariant === "link-action" && Boolean(reorderHrefKey) || toolbarVariant === "select-frame" && isFooterFrameSelection, dragDisabled: reorderDragDisabled, dragHandleLabel: reorderHrefKey ? `Reorder ${reorderHrefKey}` : "Reorder item", onDragHandleDragStart: handleItemDragStart, onDragHandleDragEnd: handleItemDragEnd, onItemPointerDown: handleItemChromePointerDown, onItemClick: handleItemChromeClick, toolbar: toolbarVariant === "link-action" && !isItemDragging ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ItemActionToolbar, { onEditLink: openLinkPopoverForSelected, addItemDisabled: true, editLinkDisabled: false, moreDisabled: true }) : void 0 }),
|
|
10830
|
+
toolbarRect && toolbarVariant === "rich-text" && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_jsx_runtime25.Fragment, { children: [
|
|
10831
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(EditGlowChrome, { rect: toolbarRect, elRef: glowElRef, reorderHrefKey, dragDisabled: reorderDragDisabled }),
|
|
10832
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(FloatingToolbar, { rect: toolbarRect, parentScroll: parentScrollRef.current, elRef: toolbarElRef, onCommand: handleCommand, activeCommands, showEditLink, onEditLink: openLinkPopoverForActive })
|
|
9904
10833
|
] }),
|
|
9905
|
-
maxBadge && /* @__PURE__ */ (0,
|
|
10834
|
+
maxBadge && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
9906
10835
|
"div",
|
|
9907
10836
|
{
|
|
9908
10837
|
"data-ohw-max-badge": "",
|
|
@@ -9928,128 +10857,33 @@ function OhhwellsBridge() {
|
|
|
9928
10857
|
]
|
|
9929
10858
|
}
|
|
9930
10859
|
),
|
|
9931
|
-
toggleState && !linkPopover && /* @__PURE__ */ (0,
|
|
9932
|
-
|
|
9933
|
-
{
|
|
9934
|
-
|
|
9935
|
-
|
|
9936
|
-
|
|
9937
|
-
|
|
9938
|
-
|
|
9939
|
-
|
|
9940
|
-
|
|
9941
|
-
|
|
9942
|
-
|
|
9943
|
-
|
|
9944
|
-
className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
|
|
9945
|
-
style: { top: sectionGap.y, transform: "translateY(-50%)" },
|
|
9946
|
-
children: [
|
|
9947
|
-
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
|
|
9948
|
-
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
9949
|
-
Badge,
|
|
9950
|
-
{
|
|
9951
|
-
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",
|
|
9952
|
-
onClick: () => {
|
|
9953
|
-
window.parent.postMessage(
|
|
9954
|
-
{ type: "ow:add-section", insertAfter: sectionGap.insertAfter, insertBefore: sectionGap.insertBefore },
|
|
9955
|
-
"*"
|
|
9956
|
-
);
|
|
9957
|
-
},
|
|
9958
|
-
children: "Add Section"
|
|
9959
|
-
}
|
|
9960
|
-
),
|
|
9961
|
-
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } })
|
|
9962
|
-
]
|
|
9963
|
-
}
|
|
9964
|
-
),
|
|
9965
|
-
linkPopover && dialogPortalContainer ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
9966
|
-
LinkPopover,
|
|
9967
|
-
{
|
|
9968
|
-
panelRef: linkPopoverPanelRef,
|
|
9969
|
-
portalContainer: dialogPortalContainer,
|
|
9970
|
-
open: true,
|
|
9971
|
-
mode: linkPopover.mode ?? "edit",
|
|
9972
|
-
pages: sitePages,
|
|
9973
|
-
sections: currentSections,
|
|
9974
|
-
sectionsByPath,
|
|
9975
|
-
initialTarget: linkPopover.target,
|
|
9976
|
-
existingTargets: linkPopover.intent === "add-nav" ? getNavbarExistingTargets() : [],
|
|
9977
|
-
onClose: closeLinkPopover,
|
|
9978
|
-
onSubmit: handleLinkPopoverSubmit
|
|
9979
|
-
},
|
|
9980
|
-
linkPopover.key
|
|
9981
|
-
) : null,
|
|
9982
|
-
sectionGap && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
9983
|
-
"div",
|
|
9984
|
-
{
|
|
9985
|
-
"data-ohw-section-insert-line": "",
|
|
9986
|
-
className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
|
|
9987
|
-
style: { top: sectionGap.y, transform: "translateY(-50%)" },
|
|
9988
|
-
children: [
|
|
9989
|
-
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
|
|
9990
|
-
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
9991
|
-
Badge,
|
|
9992
|
-
{
|
|
9993
|
-
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",
|
|
9994
|
-
onClick: () => {
|
|
9995
|
-
window.parent.postMessage(
|
|
9996
|
-
{ type: "ow:add-section", insertAfter: sectionGap.insertAfter, insertBefore: sectionGap.insertBefore },
|
|
9997
|
-
"*"
|
|
9998
|
-
);
|
|
10860
|
+
toggleState && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(StateToggle, { rect: toggleState.rect, activeState: toggleState.activeState, states: toggleState.states, onStateChange: handleStateChange }),
|
|
10861
|
+
sectionGap && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { "data-ohw-section-insert-line": "", className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none", style: { top: sectionGap.y, transform: "translateY(-50%)" }, children: [
|
|
10862
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
|
|
10863
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
10864
|
+
Badge,
|
|
10865
|
+
{
|
|
10866
|
+
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",
|
|
10867
|
+
onClick: () => {
|
|
10868
|
+
window.parent.postMessage(
|
|
10869
|
+
{
|
|
10870
|
+
type: "ow:add-section",
|
|
10871
|
+
insertAfter: sectionGap.insertAfter,
|
|
10872
|
+
insertBefore: sectionGap.insertBefore
|
|
9999
10873
|
},
|
|
10000
|
-
|
|
10001
|
-
|
|
10002
|
-
|
|
10003
|
-
|
|
10004
|
-
|
|
10005
|
-
|
|
10006
|
-
|
|
10874
|
+
"*"
|
|
10875
|
+
);
|
|
10876
|
+
},
|
|
10877
|
+
children: "Add Section"
|
|
10878
|
+
}
|
|
10879
|
+
),
|
|
10880
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } })
|
|
10881
|
+
] }),
|
|
10882
|
+
linkPopover && dialogPortalContainer ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(LinkPopover, { panelRef: linkPopoverPanelRef, portalContainer: dialogPortalContainer, open: true, mode: linkPopover.mode ?? "edit", pages: sitePages, sections: currentSections, sectionsByPath, initialTarget: linkPopover.target, existingTargets: linkPopover.intent === "add-nav" ? getNavbarExistingTargets() : [], onClose: closeLinkPopover, onSubmit: handleLinkPopoverSubmit }, linkPopover.key) : null
|
|
10007
10883
|
] }),
|
|
10008
10884
|
bridgeRoot
|
|
10009
10885
|
) : null;
|
|
10010
10886
|
}
|
|
10011
|
-
|
|
10012
|
-
// src/ui/drop-indicator.tsx
|
|
10013
|
-
var React10 = __toESM(require("react"), 1);
|
|
10014
|
-
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
10015
|
-
var dropIndicatorVariants = cva(
|
|
10016
|
-
"ov-gap-line pointer-events-none shrink-0 transition-opacity duration-150",
|
|
10017
|
-
{
|
|
10018
|
-
variants: {
|
|
10019
|
-
direction: {
|
|
10020
|
-
vertical: "h-6 w-[3px]",
|
|
10021
|
-
horizontal: "h-[3px] w-[200px]"
|
|
10022
|
-
},
|
|
10023
|
-
state: {
|
|
10024
|
-
default: "opacity-0",
|
|
10025
|
-
hover: "opacity-100",
|
|
10026
|
-
dragIdle: "opacity-40",
|
|
10027
|
-
dragActive: "opacity-100"
|
|
10028
|
-
}
|
|
10029
|
-
},
|
|
10030
|
-
defaultVariants: {
|
|
10031
|
-
direction: "vertical",
|
|
10032
|
-
state: "default"
|
|
10033
|
-
}
|
|
10034
|
-
}
|
|
10035
|
-
);
|
|
10036
|
-
var DropIndicator = React10.forwardRef(
|
|
10037
|
-
({ className, direction, state, ...props }, ref) => {
|
|
10038
|
-
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
10039
|
-
"div",
|
|
10040
|
-
{
|
|
10041
|
-
ref,
|
|
10042
|
-
"data-slot": "drop-indicator",
|
|
10043
|
-
"data-direction": direction ?? "vertical",
|
|
10044
|
-
"data-state": state ?? "default",
|
|
10045
|
-
"aria-hidden": "true",
|
|
10046
|
-
className: cn(dropIndicatorVariants({ direction, state }), className),
|
|
10047
|
-
...props
|
|
10048
|
-
}
|
|
10049
|
-
);
|
|
10050
|
-
}
|
|
10051
|
-
);
|
|
10052
|
-
DropIndicator.displayName = "DropIndicator";
|
|
10053
10887
|
// Annotate the CommonJS export names for ESM import in node:
|
|
10054
10888
|
0 && (module.exports = {
|
|
10055
10889
|
CustomToolbar,
|