@ohhwells/bridge 0.1.52-next.131 → 0.1.52-next.133

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/README.md CHANGED
@@ -194,12 +194,23 @@ For links whose **destination URL** is edited in the canvas, use a plain `<a>` w
194
194
  </a>
195
195
  ```
196
196
 
197
+ Section / body CTAs use the same two-phase select + Edit-link toolbar with `data-ohw-role="button"` (preferred). `navbar-button` remains supported as an alias for nav header CTAs:
198
+
199
+ ```tsx
200
+ <a href="/contact" data-ohw-href-key="hero-cta-href" data-ohw-role="button" data-ohw-drag-disabled="true">
201
+ <span data-ohw-editable="text" data-ohw-key="hero-cta-label">
202
+ Get started
203
+ </span>
204
+ </a>
205
+ ```
206
+
197
207
  | Attribute | Purpose |
198
208
  |-----------|---------|
199
209
  | `data-ohw-href-key` | Storage key for the link destination |
200
210
  | `href` | Default URL for SSR / first paint |
201
211
  | `data-ohw-key` + `data-ohw-editable` on inner span | Editable label text |
202
- | `data-ohw-role="navbar-button"` | Navbar CTA — two-phase select + link-action toolbar |
212
+ | `data-ohw-role="button"` | Section CTA — two-phase select + link-action toolbar (no reorder/More) |
213
+ | `data-ohw-role="navbar-button"` | Alias of `button` for navbar / header CTAs |
203
214
 
204
215
  The bridge persists and restores `href` values (including after React re-renders). No template-side wrapper component is required.
205
216
 
package/dist/index.cjs CHANGED
@@ -84,6 +84,9 @@ function getStoredLinkHref(key) {
84
84
  function clearStoredLinkHref(key) {
85
85
  linkHrefStore.delete(key);
86
86
  }
87
+ function listStoredLinkHrefs() {
88
+ return Array.from(linkHrefStore.entries());
89
+ }
87
90
  function enforceLinkHrefs() {
88
91
  document.querySelectorAll("[data-ohw-href-key]").forEach((el) => {
89
92
  const key = el.getAttribute("data-ohw-href-key") ?? "";
@@ -5646,6 +5649,42 @@ function AiSectionOverlay({
5646
5649
  var import_react_dom3 = require("react-dom");
5647
5650
  var import_navigation2 = require("next/navigation");
5648
5651
 
5652
+ // src/lib/cta-button.ts
5653
+ function isCtaButton(el) {
5654
+ return Boolean(
5655
+ el.closest('[data-ohw-role="navbar-button"], [data-ohw-role="button"]')
5656
+ );
5657
+ }
5658
+ var CTA_BUTTON_SELECTOR = '[data-ohw-role="navbar-button"], [data-ohw-role="button"]';
5659
+
5660
+ // src/lib/media-overlay-guards.ts
5661
+ var BRIDGE_CHROME_SELECTOR = [
5662
+ "[data-ohw-toolbar]",
5663
+ "[data-ohw-item-toolbar-anchor]",
5664
+ "[data-ohw-drag-handle-container]",
5665
+ '[data-slot="drag-handle"]',
5666
+ "[data-ohw-more-menu]",
5667
+ '[data-slot="dropdown-menu-content"]'
5668
+ ].join(", ");
5669
+ function containsPoint(el, x, y) {
5670
+ const r2 = el.getBoundingClientRect();
5671
+ if (r2.width <= 0 || r2.height <= 0) return false;
5672
+ return x >= r2.left && x <= r2.right && y >= r2.top && y <= r2.bottom;
5673
+ }
5674
+ function isPointOverBridgeChrome(x, y) {
5675
+ for (const el of document.querySelectorAll(BRIDGE_CHROME_SELECTOR)) {
5676
+ if (containsPoint(el, x, y)) return true;
5677
+ }
5678
+ return false;
5679
+ }
5680
+ function findCtaButtonAtPoint(x, y, media) {
5681
+ const hits = Array.from(
5682
+ document.querySelectorAll(CTA_BUTTON_SELECTOR)
5683
+ ).filter((el) => containsPoint(el, x, y) && !(media && el.contains(media)));
5684
+ if (hits.length === 0) return null;
5685
+ return hits.reduce((best, el) => best.contains(el) ? el : best);
5686
+ }
5687
+
5649
5688
  // src/lib/session-search.ts
5650
5689
  var STORAGE_KEY = "ohw-preserved-search";
5651
5690
  function readPreservedSearch() {
@@ -7239,12 +7278,9 @@ function getLinkHref(el) {
7239
7278
  }
7240
7279
  return el.getAttribute("href") ?? "";
7241
7280
  }
7242
- function isNavbarButton(el) {
7243
- return el.hasAttribute("data-ohw-role") && el.getAttribute("data-ohw-role") === "navbar-button";
7244
- }
7245
7281
  function isNavbarLinkItem(el) {
7246
7282
  if (!el.matches("[data-ohw-href-key]")) return false;
7247
- if (isNavbarButton(el)) return false;
7283
+ if (isCtaButton(el)) return false;
7248
7284
  if (!el.querySelector('[data-ohw-editable="text"]')) return false;
7249
7285
  return Boolean(el.closest("nav, [data-ohw-nav-container], [data-ohw-nav-drawer]"));
7250
7286
  }
@@ -7325,7 +7361,7 @@ function buildNavLink(index, href, label, template) {
7325
7361
  }
7326
7362
  function insertNavLinkInContainer(container, anchor, afterHrefKey) {
7327
7363
  if (!afterHrefKey) {
7328
- const cta = container.querySelector('[data-ohw-role="navbar-button"]');
7364
+ const cta = container.querySelector(CTA_BUTTON_SELECTOR);
7329
7365
  if (cta && cta.parentElement === container) {
7330
7366
  container.insertBefore(anchor, cta);
7331
7367
  return;
@@ -8976,6 +9012,57 @@ function deleteFooterColumn(column) {
8976
9012
  };
8977
9013
  }
8978
9014
 
9015
+ // src/lib/logo-identity.ts
9016
+ var LOGO_TEXT_KEYS = ["nav-logo-text", "footer-logo-text", "logo-text"];
9017
+ var LOGO_IMAGE_KEYS = ["nav-logo-image", "footer-logo", "footer-logo-image"];
9018
+ var LOGO_PLACEHOLDER_KEY = "logo-is-placeholder";
9019
+ var PLACEHOLDER_BUSINESS_NAME = "Business name";
9020
+ function resolveLogoDisplayText(text) {
9021
+ const trimmed = (text ?? "").trim();
9022
+ return trimmed || PLACEHOLDER_BUSINESS_NAME;
9023
+ }
9024
+ function applyLogoIdentity(text, isPlaceholder) {
9025
+ const display = resolveLogoDisplayText(text);
9026
+ const placeholder = isPlaceholder || !text.trim() || display === PLACEHOLDER_BUSINESS_NAME;
9027
+ for (const key of LOGO_TEXT_KEYS) {
9028
+ document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
9029
+ if (el.textContent !== display) el.textContent = display;
9030
+ });
9031
+ }
9032
+ for (const key of LOGO_IMAGE_KEYS) {
9033
+ document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
9034
+ const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
9035
+ if (img) img.alt = display;
9036
+ });
9037
+ }
9038
+ document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]').forEach((el) => {
9039
+ if (placeholder) el.setAttribute("data-ohw-placeholder", "");
9040
+ else el.removeAttribute("data-ohw-placeholder");
9041
+ });
9042
+ return display;
9043
+ }
9044
+ function readLogoIdentityFromDom() {
9045
+ for (const key of LOGO_TEXT_KEYS) {
9046
+ const el = document.querySelector(`[data-ohw-key="${key}"]`);
9047
+ if (el?.textContent?.trim()) {
9048
+ const text = el.textContent.trim();
9049
+ const logoRoot = el.closest('[data-ohw-role="logo"], [data-ohw-logo]');
9050
+ const isPlaceholder = logoRoot?.hasAttribute("data-ohw-placeholder") === true || text === PLACEHOLDER_BUSINESS_NAME;
9051
+ return { text, isPlaceholder };
9052
+ }
9053
+ }
9054
+ const logoImg = document.querySelector(
9055
+ '[data-ohw-key="nav-logo-image"], [data-ohw-key="footer-logo"]'
9056
+ );
9057
+ if (logoImg?.alt?.trim()) {
9058
+ const text = logoImg.alt.trim();
9059
+ const logoRoot = logoImg.closest('[data-ohw-role="logo"], [data-ohw-logo]');
9060
+ const isPlaceholder = logoRoot?.hasAttribute("data-ohw-placeholder") === true || text === PLACEHOLDER_BUSINESS_NAME;
9061
+ return { text, isPlaceholder };
9062
+ }
9063
+ return { text: PLACEHOLDER_BUSINESS_NAME, isPlaceholder: true };
9064
+ }
9065
+
8979
9066
  // src/lib/site-wide-scope.ts
8980
9067
  function getLogoElement(el) {
8981
9068
  const marked = el.closest('[data-ohw-role="logo"], [data-ohw-logo]');
@@ -9265,8 +9352,7 @@ function useNavItemDrag({
9265
9352
  setSiblingHintRects,
9266
9353
  setToolbarRect,
9267
9354
  getNavigationItemAnchor: getNavigationItemAnchor2,
9268
- isDragHandleDisabled: isDragHandleDisabled2,
9269
- isNavbarButton: isNavbarButton3
9355
+ isDragHandleDisabled: isDragHandleDisabled2
9270
9356
  }) {
9271
9357
  const navDragRef = (0, import_react11.useRef)(null);
9272
9358
  const [navDropSlots, setNavDropSlots] = (0, import_react11.useState)([]);
@@ -9413,7 +9499,7 @@ function useNavItemDrag({
9413
9499
  if (footerDragRef.current) return false;
9414
9500
  const hrefKey = anchor.getAttribute("data-ohw-href-key");
9415
9501
  if (!hrefKey || !isNavbarHrefKey(hrefKey)) return false;
9416
- if (isNavbarButton3(anchor) || isDragHandleDisabled2(anchor)) return false;
9502
+ if (isCtaButton(anchor) || isDragHandleDisabled2(anchor)) return false;
9417
9503
  beginNavDrag({
9418
9504
  hrefKey,
9419
9505
  wasSelected,
@@ -9424,7 +9510,7 @@ function useNavItemDrag({
9424
9510
  });
9425
9511
  return true;
9426
9512
  },
9427
- [beginNavDrag, footerDragRef, isDragHandleDisabled2, isNavbarButton3]
9513
+ [beginNavDrag, footerDragRef, isDragHandleDisabled2, isCtaButton]
9428
9514
  );
9429
9515
  const onNavDragOver = (0, import_react11.useCallback)(
9430
9516
  (e) => {
@@ -9460,7 +9546,7 @@ function useNavItemDrag({
9460
9546
  const anchor = getNavigationItemAnchor2(target);
9461
9547
  const hrefKey = anchor?.getAttribute("data-ohw-href-key") ?? null;
9462
9548
  if (!anchor || !isNavbarHrefKey(hrefKey)) return;
9463
- if (isNavbarButton3(anchor) || isDragHandleDisabled2(anchor)) return;
9549
+ if (isCtaButton(anchor) || isDragHandleDisabled2(anchor)) return;
9464
9550
  navPointerDragRef.current = {
9465
9551
  el: anchor,
9466
9552
  startX: e.clientX,
@@ -9557,7 +9643,7 @@ function useNavItemDrag({
9557
9643
  getNavigationItemAnchor2,
9558
9644
  isDragHandleDisabled2,
9559
9645
  isEditMode,
9560
- isNavbarButton3,
9646
+ isCtaButton,
9561
9647
  linkPopoverOpenRef,
9562
9648
  selectedElRef,
9563
9649
  setLinkPopover,
@@ -9567,7 +9653,7 @@ function useNavItemDrag({
9567
9653
  (selected, clientX, clientY, pointerId) => {
9568
9654
  const hrefKey = selected.getAttribute("data-ohw-href-key");
9569
9655
  if (!hrefKey || !isNavbarHrefKey(hrefKey)) return false;
9570
- if (isNavbarButton3(selected) || isDragHandleDisabled2(selected)) return false;
9656
+ if (isCtaButton(selected) || isDragHandleDisabled2(selected)) return false;
9571
9657
  navPointerDragRef.current = {
9572
9658
  el: selected,
9573
9659
  startX: clientX,
@@ -9578,7 +9664,7 @@ function useNavItemDrag({
9578
9664
  };
9579
9665
  return true;
9580
9666
  },
9581
- [isDragHandleDisabled2, isNavbarButton3]
9667
+ [isDragHandleDisabled2, isCtaButton]
9582
9668
  );
9583
9669
  return {
9584
9670
  navDragRef,
@@ -9780,7 +9866,10 @@ function collectEditableNodes(extraContent, root = document) {
9780
9866
  if (!key) return;
9781
9867
  nodes.push({ key, type: "link", text: getLinkHref3(el) });
9782
9868
  });
9783
- if (extraContent && !isScoped) {
9869
+ for (const [key, href] of listStoredLinkHrefs()) {
9870
+ nodes.push({ key, type: "link", text: href });
9871
+ }
9872
+ if (extraContent) {
9784
9873
  for (const key of [NAV_ORDER_KEY, FOOTER_ORDER_KEY, NAV_COUNT_KEY]) {
9785
9874
  const text = extraContent[key];
9786
9875
  if (typeof text === "string" && text.length > 0) {
@@ -10514,9 +10603,6 @@ function getHrefKeyFromElement(el) {
10514
10603
  if (!key) return null;
10515
10604
  return { anchor, key };
10516
10605
  }
10517
- function isNavbarButton2(el) {
10518
- return Boolean(el.closest('[data-ohw-role="navbar-button"]'));
10519
- }
10520
10606
  function isNavDropdownPanelOpen(childrenRoot) {
10521
10607
  if (childrenRoot.closest("[data-ohw-nav-drawer]")) return true;
10522
10608
  const group = childrenRoot.closest("[data-ohw-nav-group]");
@@ -10569,7 +10655,7 @@ function listNavigationItems() {
10569
10655
  ).filter((el) => isNavigationItem2(el));
10570
10656
  }
10571
10657
  function getNavigationItemReorderState(anchor) {
10572
- if (isNavbarButton2(anchor)) return { key: null, disabled: false };
10658
+ if (isCtaButton(anchor)) return { key: null, disabled: false };
10573
10659
  return getReorderHandleStateFromAnchor(anchor);
10574
10660
  }
10575
10661
  function getReorderHandleState(el) {
@@ -10671,7 +10757,7 @@ function findHoveredNavOrFooterContainer(x, y) {
10671
10757
  }
10672
10758
  function isPointOverNavItem(container, x, y) {
10673
10759
  return Array.from(container.querySelectorAll("[data-ohw-href-key]")).some((el) => {
10674
- if (!isNavigationItem2(el) || isNavbarButton2(el)) return false;
10760
+ if (!isNavigationItem2(el) || isCtaButton(el)) return false;
10675
10761
  if (!isNavItemPointerTarget(el)) return false;
10676
10762
  const itemRect = el.getBoundingClientRect();
10677
10763
  return x >= itemRect.left && x <= itemRect.right && y >= itemRect.top && y <= itemRect.bottom;
@@ -10685,7 +10771,7 @@ function isPointOverFooterColumn(x, y) {
10685
10771
  }
10686
10772
  function resolveNavContainerSelectionTarget(target, clientX, clientY) {
10687
10773
  if (getNavigationItemAnchor(target)) return null;
10688
- if (target.closest('[data-ohw-role="navbar-button"]')) return null;
10774
+ if (target.closest(CTA_BUTTON_SELECTOR)) return null;
10689
10775
  const plainLink = target.closest("a");
10690
10776
  if (plainLink && !plainLink.hasAttribute("data-ohw-href-key") && !plainLink.closest("[data-ohw-nav-container]")) {
10691
10777
  return null;
@@ -11492,8 +11578,7 @@ function OhhwellsBridge() {
11492
11578
  setSiblingHintRects,
11493
11579
  setToolbarRect,
11494
11580
  getNavigationItemAnchor,
11495
- isDragHandleDisabled,
11496
- isNavbarButton: isNavbarButton2
11581
+ isDragHandleDisabled
11497
11582
  });
11498
11583
  const bumpLinkPopoverGrace = () => {
11499
11584
  linkPopoverGraceUntilRef.current = Date.now() + 350;
@@ -11753,7 +11838,7 @@ function OhhwellsBridge() {
11753
11838
  selectedHrefKeyRef.current = navAnchor.getAttribute("data-ohw-href-key");
11754
11839
  selectedFooterColAttrRef.current = null;
11755
11840
  markSelected(navAnchor);
11756
- setSelectedIsCta(isNavbarButton2(navAnchor));
11841
+ setSelectedIsCta(isCtaButton(navAnchor));
11757
11842
  const isDropdownTrigger = !isNestedNavChild(navAnchor) && (navItemHasDropdownChildren(navAnchor) || navItemOwnsDropdownPanel(navAnchor));
11758
11843
  if (isNestedNavChild(navAnchor)) {
11759
11844
  setNavGroupForceOpen(navAnchor, true);
@@ -12274,7 +12359,7 @@ function OhhwellsBridge() {
12274
12359
  selectedHrefKeyRef.current = anchor.getAttribute("data-ohw-href-key");
12275
12360
  selectedFooterColAttrRef.current = null;
12276
12361
  markSelected(anchor);
12277
- setSelectedIsCta(isNavbarButton2(anchor));
12362
+ setSelectedIsCta(isCtaButton(anchor));
12278
12363
  clearHrefKeyHover(anchor);
12279
12364
  const isDropdownTrigger = !isNestedNavChild(anchor) && (navItemHasDropdownChildren(anchor) || navItemOwnsDropdownPanel(anchor));
12280
12365
  if (isNestedNavChild(anchor)) {
@@ -12898,7 +12983,8 @@ function OhhwellsBridge() {
12898
12983
  e.stopPropagation();
12899
12984
  deselectRef.current();
12900
12985
  deactivateRef.current();
12901
- postToParentRef.current({ type: "ow:open-logo-settings" });
12986
+ const identity = readLogoIdentityFromDom();
12987
+ postToParentRef.current({ type: "ow:open-logo-settings", ...identity });
12902
12988
  return;
12903
12989
  }
12904
12990
  const editable = target.closest("[data-ohw-editable]");
@@ -13356,7 +13442,7 @@ function OhhwellsBridge() {
13356
13442
  const navItemHit = Array.from(
13357
13443
  container.querySelectorAll("[data-ohw-href-key]")
13358
13444
  ).filter((el) => {
13359
- if (!isNavigationItem2(el) || isNavbarButton2(el)) return false;
13445
+ if (!isNavigationItem2(el) || isCtaButton(el)) return false;
13360
13446
  if (!isNavItemPointerTarget(el)) return false;
13361
13447
  const itemRect = el.getBoundingClientRect();
13362
13448
  return x >= itemRect.left && x <= itemRect.right && y >= itemRect.top && y <= itemRect.bottom;
@@ -13498,6 +13584,22 @@ function OhhwellsBridge() {
13498
13584
  }
13499
13585
  return;
13500
13586
  }
13587
+ if (!isDragOver && isPointOverBridgeChrome(x2, y2)) {
13588
+ dismissImageHover();
13589
+ return;
13590
+ }
13591
+ const ctaHit = isDragOver ? null : findCtaButtonAtPoint(x2, y2, imgEl);
13592
+ if (ctaHit) {
13593
+ dismissImageHover();
13594
+ document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
13595
+ const selected = selectedElRef.current;
13596
+ if (selected !== ctaHit && !selected?.contains(ctaHit)) {
13597
+ clearHrefKeyHover(ctaHit);
13598
+ hoveredItemElRef.current = ctaHit;
13599
+ setHoveredItemRect(ctaHit.getBoundingClientRect());
13600
+ }
13601
+ return;
13602
+ }
13501
13603
  const topEl = document.elementFromPoint(x2, y2);
13502
13604
  if (topEl?.closest('[data-ohw-toolbar], [data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"], [data-ohw-more-menu], [data-slot="dropdown-menu-content"], [data-slot="dropdown-menu-item"]')) {
13503
13605
  if (hoveredImageRef.current) {
@@ -13621,7 +13723,7 @@ function OhhwellsBridge() {
13621
13723
  const navLinkHit = Array.from(
13622
13724
  document.querySelectorAll("nav [data-ohw-href-key], footer [data-ohw-href-key]")
13623
13725
  ).find((el) => {
13624
- if (!isNavigationItem2(el) || isNavbarButton2(el)) return false;
13726
+ if (!isNavigationItem2(el) || isCtaButton(el)) return false;
13625
13727
  if (!isNavItemPointerTarget(el)) return false;
13626
13728
  const er = el.getBoundingClientRect();
13627
13729
  return x2 >= er.left && x2 <= er.right && y2 >= er.top && y2 <= er.bottom;
@@ -13939,6 +14041,7 @@ function OhhwellsBridge() {
13939
14041
  sectionsJson = val;
13940
14042
  continue;
13941
14043
  }
14044
+ if (key === LOGO_PLACEHOLDER_KEY) continue;
13942
14045
  if (applyVideoSettingNode(key, val)) continue;
13943
14046
  if (applyCarouselNode(key, val)) continue;
13944
14047
  document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
@@ -13958,6 +14061,12 @@ function OhhwellsBridge() {
13958
14061
  });
13959
14062
  applyLinkByKey(key, val);
13960
14063
  }
14064
+ const hasLogoIdentity = LOGO_PLACEHOLDER_KEY in content || LOGO_TEXT_KEYS.some((key) => key in content);
14065
+ if (hasLogoIdentity) {
14066
+ const logoText = content[LOGO_TEXT_KEYS[0]] ?? content[LOGO_TEXT_KEYS[1]] ?? readLogoIdentityFromDom().text;
14067
+ const logoIsPlaceholder = LOGO_PLACEHOLDER_KEY in content ? content[LOGO_PLACEHOLDER_KEY] !== "false" : !logoText.trim() || logoText === PLACEHOLDER_BUSINESS_NAME;
14068
+ applyLogoIdentity(logoText, logoIsPlaceholder);
14069
+ }
13961
14070
  if (sectionsJson) {
13962
14071
  initSectionsFromContent({ __ohw_sections: sectionsJson }, true);
13963
14072
  sectionsLoadedRef.current = true;
@@ -13970,6 +14079,21 @@ function OhhwellsBridge() {
13970
14079
  enforceLinkHrefs();
13971
14080
  postToParentRef.current({ type: "ow:hydrate-done" });
13972
14081
  };
14082
+ const handleUpdateLogoIdentity = (e) => {
14083
+ if (e.data?.type !== "ow:update-logo-identity") return;
14084
+ const rawText = typeof e.data.text === "string" ? e.data.text : "";
14085
+ const isPlaceholder = e.data.isPlaceholder !== false;
14086
+ const display = applyLogoIdentity(rawText, isPlaceholder);
14087
+ const nodes = [
14088
+ ...LOGO_TEXT_KEYS.map((key) => ({ key, text: display })),
14089
+ { key: LOGO_PLACEHOLDER_KEY, text: isPlaceholder || !rawText.trim() ? "true" : "false" }
14090
+ ];
14091
+ editContentRef.current = {
14092
+ ...editContentRef.current,
14093
+ ...Object.fromEntries(nodes.map(({ key, text }) => [key, text]))
14094
+ };
14095
+ postToParentRef.current({ type: "ow:change", nodes });
14096
+ };
13973
14097
  window.addEventListener("message", handleHydrate);
13974
14098
  const handleDeactivate = (e) => {
13975
14099
  if (e.data?.type !== "ow:deactivate") return;
@@ -14435,7 +14559,8 @@ function OhhwellsBridge() {
14435
14559
  if (logoAtPoint) {
14436
14560
  deselectRef.current();
14437
14561
  deactivateRef.current();
14438
- postToParentRef.current({ type: "ow:open-logo-settings" });
14562
+ const identity = readLogoIdentityFromDom();
14563
+ postToParentRef.current({ type: "ow:open-logo-settings", ...identity });
14439
14564
  return;
14440
14565
  }
14441
14566
  const textEditable = Array.from(
@@ -14472,7 +14597,7 @@ function OhhwellsBridge() {
14472
14597
  if (navRoot && navContainer) {
14473
14598
  const rr = navRoot.getBoundingClientRect();
14474
14599
  if (clientX >= rr.left && clientX <= rr.right && clientY >= rr.top && clientY <= rr.bottom && !isPointOverNavItem(navContainer, clientX, clientY)) {
14475
- const book = navRoot.querySelector('[data-ohw-role="navbar-button"]');
14600
+ const book = navRoot.querySelector(CTA_BUTTON_SELECTOR);
14476
14601
  if (book) {
14477
14602
  const br = book.getBoundingClientRect();
14478
14603
  if (clientX >= br.left && clientX <= br.right && clientY >= br.top && clientY <= br.bottom) {
@@ -14506,6 +14631,7 @@ function OhhwellsBridge() {
14506
14631
  window.addEventListener("message", handleParentScroll);
14507
14632
  window.addEventListener("message", handlePointerSync);
14508
14633
  window.addEventListener("message", handleClickAt);
14634
+ window.addEventListener("message", handleUpdateLogoIdentity);
14509
14635
  const handleViewportResize = () => {
14510
14636
  if (visibleViewportRef.current) {
14511
14637
  applyVisibleViewport(visibleViewportRef.current, parentScrollRef.current);
@@ -14558,6 +14684,7 @@ function OhhwellsBridge() {
14558
14684
  window.removeEventListener("resize", handleViewportResize);
14559
14685
  window.removeEventListener("message", handlePointerSync);
14560
14686
  window.removeEventListener("message", handleClickAt);
14687
+ window.removeEventListener("message", handleUpdateLogoIdentity);
14561
14688
  window.removeEventListener("message", handleHydrate);
14562
14689
  window.removeEventListener("message", handleDeactivate);
14563
14690
  window.removeEventListener("message", handleToastAction);
@@ -15068,6 +15195,7 @@ function OhhwellsBridge() {
15068
15195
  return;
15069
15196
  }
15070
15197
  const { key } = session;
15198
+ setStoredLinkHref(key, target);
15071
15199
  applyLinkByKey(key, target);
15072
15200
  editContentRef.current = { ...editContentRef.current, [key]: target };
15073
15201
  postToParent2({ type: "ow:change", nodes: [{ key, text: target }] });