@ohhwells/bridge 0.1.42-next.95 → 0.1.42-next.98

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 CHANGED
@@ -6000,8 +6000,8 @@ function SectionPickerOverlay({
6000
6000
  !isOnTargetPage ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
6001
6001
  "div",
6002
6002
  {
6003
- className: "pointer-events-none fixed left-1/2 z-[1] -translate-x-1/2 rounded-md bg-background/90 px-3 py-2 text-sm text-muted-foreground shadow-sm",
6004
- style: { top: chromeClip.top + 64 },
6003
+ className: "pointer-events-none fixed left-1/2 z-[1] -translate-x-1/2 rounded-md px-3 py-2 text-sm text-muted-foreground shadow-sm",
6004
+ style: { top: chromeClip.top + 64, backgroundColor: "var(--ohw-background, #ffffff)" },
6005
6005
  children: "Loading page preview\u2026"
6006
6006
  }
6007
6007
  ) : null,
@@ -6717,8 +6717,6 @@ function applyNavOrderToContainer(container, order) {
6717
6717
  if (current.length === expected.length && current.every((key, i) => key === expected[i])) {
6718
6718
  return;
6719
6719
  }
6720
- const lastCurrentLinkEl = current.length > 0 ? findCounterpartByHrefKey(current[current.length - 1], container) : null;
6721
- const anchor = lastCurrentLinkEl?.parentElement === container ? lastCurrentLinkEl.nextElementSibling : null;
6722
6720
  const seen = /* @__PURE__ */ new Set();
6723
6721
  for (const hrefKey of desired) {
6724
6722
  if (seen.has(hrefKey)) continue;
@@ -6733,9 +6731,7 @@ function applyNavOrderToContainer(container, order) {
6733
6731
  orderedEls.push(el);
6734
6732
  }
6735
6733
  for (const el of orderedEls) {
6736
- if (anchor) {
6737
- if (el.nextSibling !== anchor) container.insertBefore(el, anchor);
6738
- } else if (container.lastElementChild !== el) {
6734
+ if (container.lastElementChild !== el) {
6739
6735
  container.appendChild(el);
6740
6736
  }
6741
6737
  }
@@ -7077,11 +7073,6 @@ function reconcileFooterOrderFromContent(content) {
7077
7073
  }
7078
7074
  applyFooterOrder(order);
7079
7075
  }
7080
- function isRowLayoutColumn(links) {
7081
- if (links.length < 2) return false;
7082
- const firstTop = links[0].getBoundingClientRect().top;
7083
- return links.every((link) => Math.abs(link.getBoundingClientRect().top - firstTop) < 4);
7084
- }
7085
7076
  function buildLinkDropSlots(column, columnIndex) {
7086
7077
  const links = listFooterLinksInColumn(column);
7087
7078
  const colRect = column.getBoundingClientRect();
@@ -7099,32 +7090,6 @@ function buildLinkDropSlots(column, columnIndex) {
7099
7090
  });
7100
7091
  return slots;
7101
7092
  }
7102
- if (isRowLayoutColumn(links)) {
7103
- for (let i = 0; i <= links.length; i++) {
7104
- let left;
7105
- if (i === 0) {
7106
- left = links[0].getBoundingClientRect().left - barThickness / 2;
7107
- } else if (i === links.length) {
7108
- const last = links[links.length - 1].getBoundingClientRect();
7109
- left = last.right - barThickness / 2;
7110
- } else {
7111
- const prev = links[i - 1].getBoundingClientRect();
7112
- const next = links[i].getBoundingClientRect();
7113
- left = (prev.right + next.left) / 2 - barThickness / 2;
7114
- }
7115
- const heightRef = i === 0 ? links[0].getBoundingClientRect() : i === links.length ? links[links.length - 1].getBoundingClientRect() : links[i].getBoundingClientRect();
7116
- slots.push({
7117
- insertIndex: i,
7118
- columnIndex,
7119
- left,
7120
- top: heightRef.top,
7121
- width: barThickness,
7122
- height: Math.max(heightRef.height, colRect.height * 0.8),
7123
- direction: "vertical"
7124
- });
7125
- }
7126
- return slots;
7127
- }
7128
7093
  for (let i = 0; i <= links.length; i++) {
7129
7094
  let top;
7130
7095
  if (i === 0) {
@@ -7208,7 +7173,8 @@ function hitTestLinkDropSlot(clientX, clientY, draggedHrefKey) {
7208
7173
  return true;
7209
7174
  });
7210
7175
  for (const slot of slots) {
7211
- const dist = slot.direction === "vertical" ? Math.abs(clientX - (slot.left + slot.width / 2)) : Math.abs(clientY - (slot.top + slot.height / 2));
7176
+ const cy = slot.top + slot.height / 2;
7177
+ const dist = Math.abs(clientY - cy) + (inColX ? 0 : 1e3);
7212
7178
  if (!best || dist < best.dist) best = { slot, dist };
7213
7179
  }
7214
7180
  }
@@ -7618,6 +7584,7 @@ function useNavItemDrag({
7618
7584
  const hrefKey = anchor?.getAttribute("data-ohw-href-key") ?? null;
7619
7585
  if (!anchor || !isNavbarHrefKey(hrefKey)) return;
7620
7586
  if (isNavbarButton3(anchor) || isDragHandleDisabled2(anchor)) return;
7587
+ armItemPressDrag();
7621
7588
  navPointerDragRef.current = {
7622
7589
  el: anchor,
7623
7590
  startX: e.clientX,
@@ -7644,7 +7611,6 @@ function useNavItemDrag({
7644
7611
  if (dx * dx + dy * dy < THRESHOLD * THRESHOLD) return;
7645
7612
  e.preventDefault();
7646
7613
  pending.started = true;
7647
- armItemPressDrag();
7648
7614
  clearTextSelection();
7649
7615
  try {
7650
7616
  document.body.setPointerCapture(pending.pointerId);
@@ -7672,8 +7638,7 @@ function useNavItemDrag({
7672
7638
  }
7673
7639
  } catch {
7674
7640
  }
7675
- if (!pending) return;
7676
- if (!pending.started) {
7641
+ if (!pending?.started) {
7677
7642
  unlockItemDragInteraction();
7678
7643
  return;
7679
7644
  }
@@ -7725,6 +7690,7 @@ function useNavItemDrag({
7725
7690
  const hrefKey = selected.getAttribute("data-ohw-href-key");
7726
7691
  if (!hrefKey || !isNavbarHrefKey(hrefKey)) return false;
7727
7692
  if (isNavbarButton3(selected) || isDragHandleDisabled2(selected)) return false;
7693
+ armItemPressDrag();
7728
7694
  navPointerDragRef.current = {
7729
7695
  el: selected,
7730
7696
  startX: clientX,
@@ -8951,7 +8917,6 @@ function OhhwellsBridge() {
8951
8917
  const [fetchState, setFetchState] = (0, import_react9.useState)("idle");
8952
8918
  const autoSaveTimers = (0, import_react9.useRef)(/* @__PURE__ */ new Map());
8953
8919
  const activeElRef = (0, import_react9.useRef)(null);
8954
- const pointerHeldRef = (0, import_react9.useRef)(false);
8955
8920
  const selectedElRef = (0, import_react9.useRef)(null);
8956
8921
  const selectedHrefKeyRef = (0, import_react9.useRef)(null);
8957
8922
  const selectedFooterColAttrRef = (0, import_react9.useRef)(null);
@@ -9649,6 +9614,7 @@ function OhhwellsBridge() {
9649
9614
  if (e.button !== 0) return;
9650
9615
  const selected = selectedElRef.current;
9651
9616
  if (!selected) return;
9617
+ armFooterPressDrag();
9652
9618
  const hrefKey = selected.getAttribute("data-ohw-href-key");
9653
9619
  if (hrefKey && isFooterHrefKey(hrefKey)) {
9654
9620
  footerPointerDragRef.current = {
@@ -9759,8 +9725,6 @@ function OhhwellsBridge() {
9759
9725
  siblingHintElRef.current = null;
9760
9726
  setSiblingHintRect(null);
9761
9727
  setIsItemDragging(false);
9762
- const preActivationSelection = window.getSelection();
9763
- const preservedRange = preActivationSelection && preActivationSelection.rangeCount > 0 && !preActivationSelection.isCollapsed && el.contains(preActivationSelection.getRangeAt(0).commonAncestorContainer) ? preActivationSelection.getRangeAt(0).cloneRange() : null;
9764
9728
  el.setAttribute("contenteditable", "true");
9765
9729
  el.setAttribute("data-ohw-editing", "");
9766
9730
  el.removeAttribute("data-ohw-hovered");
@@ -9768,11 +9732,7 @@ function OhhwellsBridge() {
9768
9732
  activeElRef.current = el;
9769
9733
  originalContentRef.current = el.innerHTML;
9770
9734
  el.focus({ preventScroll: true });
9771
- if (preservedRange) {
9772
- const selection = window.getSelection();
9773
- selection?.removeAllRanges();
9774
- selection?.addRange(preservedRange);
9775
- } else if (options?.caretX !== void 0 && options?.caretY !== void 0) {
9735
+ if (options?.caretX !== void 0 && options?.caretY !== void 0) {
9776
9736
  const { caretX, caretY } = options;
9777
9737
  placeCaretAtPoint(el, caretX, caretY);
9778
9738
  requestAnimationFrame(() => {
@@ -10228,18 +10188,7 @@ function OhhwellsBridge() {
10228
10188
  if (inActive || inActiveNav) {
10229
10189
  e.preventDefault();
10230
10190
  e.stopPropagation();
10231
- const selection = window.getSelection();
10232
- const hasRangeSelection = Boolean(selection && !selection.isCollapsed);
10233
- console.log(
10234
- "[OHW DEBUG handleClick] already-active branch",
10235
- "detail=",
10236
- e.detail,
10237
- "hasRangeSelection=",
10238
- hasRangeSelection,
10239
- "willPlaceCaret=",
10240
- e.detail < 2 && !hasRangeSelection
10241
- );
10242
- if (e.detail < 2 && !hasRangeSelection) {
10191
+ if (e.detail < 2) {
10243
10192
  placeCaretAtPoint(active, e.clientX, e.clientY);
10244
10193
  refreshActiveCommandsRef.current();
10245
10194
  }
@@ -10282,15 +10231,6 @@ function OhhwellsBridge() {
10282
10231
  }
10283
10232
  e.preventDefault();
10284
10233
  e.stopPropagation();
10285
- console.log(
10286
- "[OHW DEBUG handleClick] first-activation branch",
10287
- "detail=",
10288
- e.detail,
10289
- "selectionAtClick=",
10290
- JSON.stringify(window.getSelection()?.toString() ?? ""),
10291
- "collapsedAtClick=",
10292
- window.getSelection()?.isCollapsed
10293
- );
10294
10234
  activateRef.current(editable);
10295
10235
  return;
10296
10236
  }
@@ -11401,83 +11341,30 @@ function OhhwellsBridge() {
11401
11341
  const h = document.documentElement.scrollHeight;
11402
11342
  if (h > 50) postToParentRef.current({ type: "ow:height", height: h });
11403
11343
  };
11404
- let selectionChangeRaf = null;
11405
- const runSelectionChange = () => {
11406
- selectionChangeRaf = null;
11407
- const activeRoot = activeElRef.current;
11408
- if (!activeRoot) return;
11344
+ const handleSelectionChange = () => {
11345
+ if (!activeElRef.current) return;
11409
11346
  const next = /* @__PURE__ */ new Set();
11410
- const sel = window.getSelection();
11411
- let startNode = null;
11412
- if (sel && sel.rangeCount > 0) {
11413
- const range = sel.getRangeAt(0);
11414
- startNode = range.startContainer;
11415
- if (startNode.nodeType === Node.ELEMENT_NODE) {
11416
- const el = startNode;
11417
- startNode = el.childNodes[range.startOffset] ?? el.childNodes[range.startOffset - 1] ?? el;
11347
+ for (const cmd of ["bold", "italic", "underline", "strikeThrough", "insertUnorderedList", "insertOrderedList"]) {
11348
+ try {
11349
+ if (document.queryCommandState(cmd)) next.add(cmd);
11350
+ } catch {
11418
11351
  }
11419
11352
  }
11420
- const startEl = startNode ? startNode.nodeType === Node.TEXT_NODE ? startNode.parentElement : startNode : null;
11421
- if (startEl) {
11422
- const cs = getComputedStyle(startEl);
11423
- const weight = parseInt(cs.fontWeight, 10);
11424
- let hasBold = cs.fontWeight === "bold" || !Number.isNaN(weight) && weight >= 600;
11425
- let hasItalic = cs.fontStyle === "italic" || cs.fontStyle === "oblique";
11426
- let hasUnderline = false;
11427
- let hasStrike = false;
11428
- let hasUl = false;
11429
- let hasOl = false;
11430
- for (let el = startEl; el; el = el.parentElement) {
11431
- if (el.tagName === "B" || el.tagName === "STRONG") hasBold = true;
11432
- if (el.tagName === "I" || el.tagName === "EM") hasItalic = true;
11433
- const decoration = getComputedStyle(el).textDecorationLine;
11434
- if (decoration.includes("underline") || el.tagName === "U" || el.tagName === "INS") hasUnderline = true;
11435
- if (decoration.includes("line-through") || el.tagName === "S" || el.tagName === "STRIKE" || el.tagName === "DEL") hasStrike = true;
11436
- if (el.tagName === "UL") hasUl = true;
11437
- if (el.tagName === "OL") hasOl = true;
11438
- if (el === activeRoot) break;
11439
- }
11440
- if (hasBold) next.add("bold");
11441
- if (hasItalic) next.add("italic");
11442
- if (hasUnderline) next.add("underline");
11443
- if (hasStrike) next.add("strikeThrough");
11444
- if (hasUl) next.add("insertUnorderedList");
11445
- if (hasOl) next.add("insertOrderedList");
11446
- const block = startEl.closest("div, p, h1, h2, h3, h4, h5, h6, li, td, th") ?? startEl;
11447
- const align = getComputedStyle(block).textAlign;
11448
- if (align === "center") next.add("justifyCenter");
11449
- else if (align === "right" || align === "end") next.add("justifyRight");
11450
- else next.add("justifyLeft");
11451
- }
11452
- setActiveCommands((prev) => {
11453
- if (prev.size === next.size) {
11454
- let same = true;
11455
- for (const cmd of prev) {
11456
- if (!next.has(cmd)) {
11457
- same = false;
11458
- break;
11459
- }
11460
- }
11461
- if (same) return prev;
11353
+ const sel = window.getSelection();
11354
+ const anchor = sel?.anchorNode;
11355
+ if (anchor) {
11356
+ const el = anchor.nodeType === Node.TEXT_NODE ? anchor.parentElement : anchor;
11357
+ const block = el?.closest("div, p, h1, h2, h3, h4, h5, h6, li, td, th") ?? el;
11358
+ if (block) {
11359
+ const align = getComputedStyle(block).textAlign;
11360
+ if (align === "center") next.add("justifyCenter");
11361
+ else if (align === "right" || align === "end") next.add("justifyRight");
11362
+ else next.add("justifyLeft");
11462
11363
  }
11463
- return next;
11464
- });
11465
- };
11466
- const handleSelectionChange = () => {
11467
- if (pointerHeldRef.current) return;
11468
- if (selectionChangeRaf !== null) return;
11469
- selectionChangeRaf = requestAnimationFrame(runSelectionChange);
11470
- };
11471
- const markPointerHeld = (e) => {
11472
- if (e.button !== 0) return;
11473
- pointerHeldRef.current = true;
11474
- };
11475
- const markPointerReleased = () => {
11476
- if (!pointerHeldRef.current) return;
11477
- pointerHeldRef.current = false;
11478
- handleSelectionChange();
11364
+ }
11365
+ setActiveCommands(next);
11479
11366
  };
11480
- refreshActiveCommandsRef.current = runSelectionChange;
11367
+ refreshActiveCommandsRef.current = handleSelectionChange;
11481
11368
  const handleDocMouseLeave = () => {
11482
11369
  hoveredImageRef.current = null;
11483
11370
  setMediaHover(null);
@@ -11717,6 +11604,7 @@ function OhhwellsBridge() {
11717
11604
  const anchor = getNavigationItemAnchor(target);
11718
11605
  const hrefKey = anchor?.getAttribute("data-ohw-href-key") ?? null;
11719
11606
  if (anchor && isFooterHrefKey(hrefKey)) {
11607
+ armFooterPressDrag();
11720
11608
  footerPointerDragRef.current = {
11721
11609
  el: anchor,
11722
11610
  kind: "link",
@@ -11730,6 +11618,7 @@ function OhhwellsBridge() {
11730
11618
  }
11731
11619
  const col = target.closest("[data-ohw-footer-col]");
11732
11620
  if (col && !getNavigationItemAnchor(target)) {
11621
+ armFooterPressDrag();
11733
11622
  footerPointerDragRef.current = {
11734
11623
  el: col,
11735
11624
  kind: "column",
@@ -11758,7 +11647,6 @@ function OhhwellsBridge() {
11758
11647
  if (dx * dx + dy * dy < THRESHOLD * THRESHOLD) return;
11759
11648
  e.preventDefault();
11760
11649
  pending.started = true;
11761
- armFooterPressDrag();
11762
11650
  clearTextSelection();
11763
11651
  try {
11764
11652
  document.body.setPointerCapture(pending.pointerId);
@@ -11812,8 +11700,7 @@ function OhhwellsBridge() {
11812
11700
  }
11813
11701
  } catch {
11814
11702
  }
11815
- if (!pending) return;
11816
- if (!pending.started) {
11703
+ if (!pending?.started) {
11817
11704
  unlockFooterDragInteraction();
11818
11705
  return;
11819
11706
  }
@@ -11848,22 +11735,6 @@ function OhhwellsBridge() {
11848
11735
  unlockFooterDragInteraction();
11849
11736
  };
11850
11737
  }, [isEditMode]);
11851
- (0, import_react9.useEffect)(() => {
11852
- if (!isEditMode) return;
11853
- const debugSelectionChange = () => {
11854
- const sel = window.getSelection();
11855
- console.log(
11856
- "[OHW DEBUG selectionchange]",
11857
- JSON.stringify(sel?.toString() ?? ""),
11858
- "collapsed=",
11859
- sel?.isCollapsed,
11860
- "anchorNode=",
11861
- sel?.anchorNode,
11862
- "activeEl=",
11863
- activeElRef.current
11864
- );
11865
- };
11866
- }, [isEditMode]);
11867
11738
  (0, import_react9.useEffect)(() => {
11868
11739
  const handler = (e) => {
11869
11740
  if (e.data?.type !== "ow:request-schedule-config") return;
@@ -11922,7 +11793,6 @@ function OhhwellsBridge() {
11922
11793
  return () => window.removeEventListener("hashchange", onHashChange);
11923
11794
  }, [pathname]);
11924
11795
  const handleCommand = (0, import_react9.useCallback)((cmd) => {
11925
- document.execCommand("styleWithCSS", false, true);
11926
11796
  document.execCommand(cmd, false);
11927
11797
  activeElRef.current?.focus();
11928
11798
  if (activeElRef.current) setToolbarRect(getEditMeasureEl(activeElRef.current).getBoundingClientRect());