@ohhwells/bridge 0.1.157 → 0.1.158

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.d.cts CHANGED
@@ -877,6 +877,36 @@ declare const SITE_OG_IMAGE_KEY = "__ohw_og_image";
877
877
  */
878
878
  declare function applyBrandChrome(content: Record<string, string>): void;
879
879
 
880
+ /**
881
+ * Marks an <img> that the TEMPLATE ships as its own brand mark — Re:Bound's wordmark PNG, salon's
882
+ * "Luxe Locks" lockup — as opposed to one this site's owner uploaded.
883
+ *
884
+ * The two are indistinguishable from the DOM alone: both are an <img> with a real src inside the
885
+ * logo root. Reading a template's mark as the owner's is what left a coffee roaster's navbar
886
+ * saying "Re:Bound" after onboarding wrote its business name (OHH-876) — the name reached the
887
+ * title, the footer and the editor chrome, and the one place a visitor actually looks kept
888
+ * somebody else's brand.
889
+ *
890
+ * So a template's mark is a placeholder with a better picture: it stands while the site has no
891
+ * name of its own, and gives way the moment it has one. An upload clears the attribute, because
892
+ * from then on the image IS the owner's.
893
+ */
894
+ declare const TEMPLATE_LOGO_ATTR = "data-ohw-template-logo";
895
+ /**
896
+ * Hand a template's mark over to the owner, but only when the incoming picture is a different one.
897
+ *
898
+ * A save carries every node on the page, so a template's own default src comes back as a content
899
+ * value on the next hydrate without anybody having uploaded anything. Releasing the mark on that
900
+ * made Re:Bound's wordmark band show the PNG and the business name side by side, each squeezed into
901
+ * half the band (OHH-876): the band hides the picture with
902
+ * `:has(.rb-wordmark-text:not(:empty)) img[data-ohw-template-logo]`, and the attribute was gone by
903
+ * the time the name arrived.
904
+ *
905
+ * Comparing resolved URLs is what separates the two cases: a round-tripped default resolves to the
906
+ * src already on the element, an upload never does.
907
+ */
908
+ declare function releaseTemplateLogoIfReplaced(img: HTMLImageElement, url: string): void;
909
+
880
910
  /**
881
911
  * Telling a page's content mounting apart from incidental DOM churn, so the hydration pass can run
882
912
  * before the browser paints in the first case and stay debounced in the second.
@@ -1000,4 +1030,4 @@ declare function useOhwCarousel(key: string, initial: CarouselSlide[]): {
1000
1030
  bind: Record<string, string>;
1001
1031
  };
1002
1032
 
1003
- export { AI_DEFAULT_BRAND, AI_FOOTER_KEY, AI_TREE_SCHEMA_VERSIONS, AI_TREE_TOKENS, type AiBlockNode, type AiBrandKit, type AiFooterBottomBar, type AiFooterColumn, type AiFooterLayoutTree, AiFooterRenderer, type AiFooterRendererProps, type AiLayoutTree, AiTreeRenderer, type AiTreeRendererProps, BRAND_TITLE_KEY, type CarouselSlide, type CollectionItemHit, type CollectionItemIndex, CustomToolbar, CustomToolbarButton, CustomToolbarDivider, DragHandle, DropIndicator, type DropIndicatorProps, DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger, EmptySection, type EmptySectionProps, FOOTER_COLUMN_BLOCKS, FOOTER_COLUMN_SPANS, FOOTER_SOCIAL_PLATFORMS, ItemActionToolbar, type ItemActionToolbarProps, ItemInteractionLayer, type ItemInteractionLayerProps, type ItemInteractionState, LinkEditorPanel, type LinkModalMode, type LinkModalProps, type LinkPage, LinkPopover, type LinkSection, OHW_LOADER_PREHYDRATE_SCRIPT, OHW_LOADER_STYLE, OhhwellsBridge, OhwLoaderSpinner, OhwLoaderSurface, SITE_OG_IMAGE_KEY, SchedulingWidget, type SectionScaffold, type SiteLegalLinks, type SitePageEntry, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, addFooterLinkColumn, appendFooterSocial, applyBrandChrome, applyStickySearchParams, buildDefaultFooterTree, buildTarget, dropIndicatorVariants, ensureFooterTree, filterAvailablePages, foldAlignIntoTrees, getEditModeInitialState, hasMountedContentNodes, indexCollectionItems, insertFooterHours, isEditSessionActive, isPlainLeftClick, isRenderableFooterTree, isRenderableTree, isStickySearchParam, isValidUrl, matchCollectionItemClick, nextViableSlide, parseAiFooterState, parseAiSectionsState, parseTarget, recordOverriddenPaths, removeFooterBlock, resetOverriddenPathsCache, resolveFooterCopyright, resolveStickyNavigation, serializeAiFooterState, shouldFetchContentForPath, stepViableSlide, stripTextAlignCss, toggleVariants, useOhwCarousel, validateUrlInput, viableSlides };
1033
+ export { AI_DEFAULT_BRAND, AI_FOOTER_KEY, AI_TREE_SCHEMA_VERSIONS, AI_TREE_TOKENS, type AiBlockNode, type AiBrandKit, type AiFooterBottomBar, type AiFooterColumn, type AiFooterLayoutTree, AiFooterRenderer, type AiFooterRendererProps, type AiLayoutTree, AiTreeRenderer, type AiTreeRendererProps, BRAND_TITLE_KEY, type CarouselSlide, type CollectionItemHit, type CollectionItemIndex, CustomToolbar, CustomToolbarButton, CustomToolbarDivider, DragHandle, DropIndicator, type DropIndicatorProps, DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger, EmptySection, type EmptySectionProps, FOOTER_COLUMN_BLOCKS, FOOTER_COLUMN_SPANS, FOOTER_SOCIAL_PLATFORMS, ItemActionToolbar, type ItemActionToolbarProps, ItemInteractionLayer, type ItemInteractionLayerProps, type ItemInteractionState, LinkEditorPanel, type LinkModalMode, type LinkModalProps, type LinkPage, LinkPopover, type LinkSection, OHW_LOADER_PREHYDRATE_SCRIPT, OHW_LOADER_STYLE, OhhwellsBridge, OhwLoaderSpinner, OhwLoaderSurface, SITE_OG_IMAGE_KEY, SchedulingWidget, type SectionScaffold, type SiteLegalLinks, type SitePageEntry, TEMPLATE_LOGO_ATTR, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, addFooterLinkColumn, appendFooterSocial, applyBrandChrome, applyStickySearchParams, buildDefaultFooterTree, buildTarget, dropIndicatorVariants, ensureFooterTree, filterAvailablePages, foldAlignIntoTrees, getEditModeInitialState, hasMountedContentNodes, indexCollectionItems, insertFooterHours, isEditSessionActive, isPlainLeftClick, isRenderableFooterTree, isRenderableTree, isStickySearchParam, isValidUrl, matchCollectionItemClick, nextViableSlide, parseAiFooterState, parseAiSectionsState, parseTarget, recordOverriddenPaths, releaseTemplateLogoIfReplaced, removeFooterBlock, resetOverriddenPathsCache, resolveFooterCopyright, resolveStickyNavigation, serializeAiFooterState, shouldFetchContentForPath, stepViableSlide, stripTextAlignCss, toggleVariants, useOhwCarousel, validateUrlInput, viableSlides };
package/dist/index.d.ts CHANGED
@@ -877,6 +877,36 @@ declare const SITE_OG_IMAGE_KEY = "__ohw_og_image";
877
877
  */
878
878
  declare function applyBrandChrome(content: Record<string, string>): void;
879
879
 
880
+ /**
881
+ * Marks an <img> that the TEMPLATE ships as its own brand mark — Re:Bound's wordmark PNG, salon's
882
+ * "Luxe Locks" lockup — as opposed to one this site's owner uploaded.
883
+ *
884
+ * The two are indistinguishable from the DOM alone: both are an <img> with a real src inside the
885
+ * logo root. Reading a template's mark as the owner's is what left a coffee roaster's navbar
886
+ * saying "Re:Bound" after onboarding wrote its business name (OHH-876) — the name reached the
887
+ * title, the footer and the editor chrome, and the one place a visitor actually looks kept
888
+ * somebody else's brand.
889
+ *
890
+ * So a template's mark is a placeholder with a better picture: it stands while the site has no
891
+ * name of its own, and gives way the moment it has one. An upload clears the attribute, because
892
+ * from then on the image IS the owner's.
893
+ */
894
+ declare const TEMPLATE_LOGO_ATTR = "data-ohw-template-logo";
895
+ /**
896
+ * Hand a template's mark over to the owner, but only when the incoming picture is a different one.
897
+ *
898
+ * A save carries every node on the page, so a template's own default src comes back as a content
899
+ * value on the next hydrate without anybody having uploaded anything. Releasing the mark on that
900
+ * made Re:Bound's wordmark band show the PNG and the business name side by side, each squeezed into
901
+ * half the band (OHH-876): the band hides the picture with
902
+ * `:has(.rb-wordmark-text:not(:empty)) img[data-ohw-template-logo]`, and the attribute was gone by
903
+ * the time the name arrived.
904
+ *
905
+ * Comparing resolved URLs is what separates the two cases: a round-tripped default resolves to the
906
+ * src already on the element, an upload never does.
907
+ */
908
+ declare function releaseTemplateLogoIfReplaced(img: HTMLImageElement, url: string): void;
909
+
880
910
  /**
881
911
  * Telling a page's content mounting apart from incidental DOM churn, so the hydration pass can run
882
912
  * before the browser paints in the first case and stay debounced in the second.
@@ -1000,4 +1030,4 @@ declare function useOhwCarousel(key: string, initial: CarouselSlide[]): {
1000
1030
  bind: Record<string, string>;
1001
1031
  };
1002
1032
 
1003
- export { AI_DEFAULT_BRAND, AI_FOOTER_KEY, AI_TREE_SCHEMA_VERSIONS, AI_TREE_TOKENS, type AiBlockNode, type AiBrandKit, type AiFooterBottomBar, type AiFooterColumn, type AiFooterLayoutTree, AiFooterRenderer, type AiFooterRendererProps, type AiLayoutTree, AiTreeRenderer, type AiTreeRendererProps, BRAND_TITLE_KEY, type CarouselSlide, type CollectionItemHit, type CollectionItemIndex, CustomToolbar, CustomToolbarButton, CustomToolbarDivider, DragHandle, DropIndicator, type DropIndicatorProps, DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger, EmptySection, type EmptySectionProps, FOOTER_COLUMN_BLOCKS, FOOTER_COLUMN_SPANS, FOOTER_SOCIAL_PLATFORMS, ItemActionToolbar, type ItemActionToolbarProps, ItemInteractionLayer, type ItemInteractionLayerProps, type ItemInteractionState, LinkEditorPanel, type LinkModalMode, type LinkModalProps, type LinkPage, LinkPopover, type LinkSection, OHW_LOADER_PREHYDRATE_SCRIPT, OHW_LOADER_STYLE, OhhwellsBridge, OhwLoaderSpinner, OhwLoaderSurface, SITE_OG_IMAGE_KEY, SchedulingWidget, type SectionScaffold, type SiteLegalLinks, type SitePageEntry, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, addFooterLinkColumn, appendFooterSocial, applyBrandChrome, applyStickySearchParams, buildDefaultFooterTree, buildTarget, dropIndicatorVariants, ensureFooterTree, filterAvailablePages, foldAlignIntoTrees, getEditModeInitialState, hasMountedContentNodes, indexCollectionItems, insertFooterHours, isEditSessionActive, isPlainLeftClick, isRenderableFooterTree, isRenderableTree, isStickySearchParam, isValidUrl, matchCollectionItemClick, nextViableSlide, parseAiFooterState, parseAiSectionsState, parseTarget, recordOverriddenPaths, removeFooterBlock, resetOverriddenPathsCache, resolveFooterCopyright, resolveStickyNavigation, serializeAiFooterState, shouldFetchContentForPath, stepViableSlide, stripTextAlignCss, toggleVariants, useOhwCarousel, validateUrlInput, viableSlides };
1033
+ export { AI_DEFAULT_BRAND, AI_FOOTER_KEY, AI_TREE_SCHEMA_VERSIONS, AI_TREE_TOKENS, type AiBlockNode, type AiBrandKit, type AiFooterBottomBar, type AiFooterColumn, type AiFooterLayoutTree, AiFooterRenderer, type AiFooterRendererProps, type AiLayoutTree, AiTreeRenderer, type AiTreeRendererProps, BRAND_TITLE_KEY, type CarouselSlide, type CollectionItemHit, type CollectionItemIndex, CustomToolbar, CustomToolbarButton, CustomToolbarDivider, DragHandle, DropIndicator, type DropIndicatorProps, DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger, EmptySection, type EmptySectionProps, FOOTER_COLUMN_BLOCKS, FOOTER_COLUMN_SPANS, FOOTER_SOCIAL_PLATFORMS, ItemActionToolbar, type ItemActionToolbarProps, ItemInteractionLayer, type ItemInteractionLayerProps, type ItemInteractionState, LinkEditorPanel, type LinkModalMode, type LinkModalProps, type LinkPage, LinkPopover, type LinkSection, OHW_LOADER_PREHYDRATE_SCRIPT, OHW_LOADER_STYLE, OhhwellsBridge, OhwLoaderSpinner, OhwLoaderSurface, SITE_OG_IMAGE_KEY, SchedulingWidget, type SectionScaffold, type SiteLegalLinks, type SitePageEntry, TEMPLATE_LOGO_ATTR, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, addFooterLinkColumn, appendFooterSocial, applyBrandChrome, applyStickySearchParams, buildDefaultFooterTree, buildTarget, dropIndicatorVariants, ensureFooterTree, filterAvailablePages, foldAlignIntoTrees, getEditModeInitialState, hasMountedContentNodes, indexCollectionItems, insertFooterHours, isEditSessionActive, isPlainLeftClick, isRenderableFooterTree, isRenderableTree, isStickySearchParam, isValidUrl, matchCollectionItemClick, nextViableSlide, parseAiFooterState, parseAiSectionsState, parseTarget, recordOverriddenPaths, releaseTemplateLogoIfReplaced, removeFooterBlock, resetOverriddenPathsCache, resolveFooterCopyright, resolveStickyNavigation, serializeAiFooterState, shouldFetchContentForPath, stepViableSlide, stripTextAlignCss, toggleVariants, useOhwCarousel, validateUrlInput, viableSlides };
package/dist/index.js CHANGED
@@ -406,11 +406,37 @@ function logoTextElement(root) {
406
406
  );
407
407
  return hasOwnText ? root : null;
408
408
  }
409
+ var TEMPLATE_LOGO_ATTR = "data-ohw-template-logo";
410
+ function releaseTemplateLogoIfReplaced(img, url) {
411
+ if (!img.hasAttribute(TEMPLATE_LOGO_ATTR)) return;
412
+ let incoming = url;
413
+ try {
414
+ incoming = new URL(url, document.baseURI).href;
415
+ } catch {
416
+ }
417
+ if (incoming !== img.src) img.removeAttribute(TEMPLATE_LOGO_ATTR);
418
+ }
419
+ function logoImage(root, selector) {
420
+ if (root instanceof HTMLImageElement && root.matches(selector)) return root;
421
+ return root.querySelector(selector);
422
+ }
409
423
  function logoRootImage(root) {
410
- const img = root.querySelector("img");
424
+ const img = logoImage(root, `img:not([${TEMPLATE_LOGO_ATTR}])`);
411
425
  const src = img?.getAttribute("src")?.trim() ?? "";
412
426
  return img && src && img.style.display !== "none" ? img : null;
413
427
  }
428
+ function templateLogoImage(root) {
429
+ const img = logoImage(root, `img[${TEMPLATE_LOGO_ATTR}]`);
430
+ return img && img.style.display !== "none" ? img : null;
431
+ }
432
+ function createWordmark(root) {
433
+ const el = document.createElement("span");
434
+ el.setAttribute("data-ohw-editable", "plain");
435
+ el.setAttribute("data-ohw-key", textKeyForRoot(root));
436
+ if (root instanceof HTMLImageElement) root.parentNode?.insertBefore(el, root.nextSibling);
437
+ else root.appendChild(el);
438
+ return el;
439
+ }
414
440
  function applyLogoIdentity(text, isPlaceholder) {
415
441
  const display = resolveLogoDisplayText(text);
416
442
  const placeholder = isPlaceholder || !text.trim() || display === PLACEHOLDER_BUSINESS_NAME;
@@ -429,7 +455,9 @@ function applyLogoIdentity(text, isPlaceholder) {
429
455
  if (placeholder) el.setAttribute("data-ohw-placeholder", "");
430
456
  else el.removeAttribute("data-ohw-placeholder");
431
457
  if (logoRootImage(el)) return;
432
- const textEl = logoTextElement(el);
458
+ const templateMark = placeholder ? null : templateLogoImage(el);
459
+ if (templateMark) templateMark.style.display = "none";
460
+ const textEl = logoTextElement(el) ?? (templateMark ? createWordmark(el) : null);
433
461
  if (textEl && textEl.textContent !== display) textEl.textContent = display;
434
462
  });
435
463
  return display;
@@ -461,6 +489,7 @@ function applyLogoImage(url, alt, placement) {
461
489
  }
462
490
  img.removeAttribute("srcset");
463
491
  img.removeAttribute("sizes");
492
+ img.removeAttribute(TEMPLATE_LOGO_ATTR);
464
493
  img.src = url;
465
494
  img.alt = displayAlt;
466
495
  img.style.display = "block";
@@ -480,10 +509,7 @@ function applyLogoImage(url, alt, placement) {
480
509
  img.style.display = "none";
481
510
  }
482
511
  if (!textEl) {
483
- textEl = document.createElement("span");
484
- textEl.setAttribute("data-ohw-editable", "plain");
485
- textEl.setAttribute("data-ohw-key", textKey);
486
- root.appendChild(textEl);
512
+ textEl = createWordmark(root);
487
513
  }
488
514
  textEl.style.display = "";
489
515
  if (textEl.textContent !== displayAlt) textEl.textContent = displayAlt;
@@ -6737,6 +6763,7 @@ function applyBrandChrome(content) {
6737
6763
  if (el.textContent !== name) el.textContent = name;
6738
6764
  if (el.getAttribute("title") !== name) el.setAttribute("title", name);
6739
6765
  });
6766
+ applyLogoIdentity(name, false);
6740
6767
  }
6741
6768
  const title = content[BRAND_TITLE_KEY];
6742
6769
  if (typeof title === "string" && title.length > 0) {
@@ -17100,7 +17127,7 @@ function apiBase() {
17100
17127
  function bridgeVersion() {
17101
17128
  try {
17102
17129
  if (true) {
17103
- return "0.1.157";
17130
+ return "0.1.158";
17104
17131
  }
17105
17132
  } catch {
17106
17133
  }
@@ -17114,7 +17141,7 @@ function stampBridgeVersionOnDocument() {
17114
17141
  return;
17115
17142
  }
17116
17143
  try {
17117
- const v = true ? "0.1.157" : "";
17144
+ const v = true ? "0.1.158" : "";
17118
17145
  if (v) {
17119
17146
  document.documentElement.setAttribute("data-ohw-bridge-version", v);
17120
17147
  window.__OHW_BRIDGE_VERSION__ = v;
@@ -23925,6 +23952,7 @@ function applyEditableImageSrc(img, url) {
23925
23952
  img.removeAttribute("srcset");
23926
23953
  img.removeAttribute("sizes");
23927
23954
  if (img.loading === "lazy") img.loading = "eager";
23955
+ releaseTemplateLogoIfReplaced(img, url);
23928
23956
  img.src = url;
23929
23957
  }
23930
23958
  function fadeInBgImage(el, url, onReady) {
@@ -31938,7 +31966,7 @@ function OhhwellsBridge() {
31938
31966
  postToParent2({
31939
31967
  type: "ow:ready",
31940
31968
  version: "1",
31941
- bridgeVersion: "0.1.157",
31969
+ bridgeVersion: "0.1.158",
31942
31970
  path: pathname,
31943
31971
  nodes: collectEditableNodes(editContentRef.current),
31944
31972
  sections
@@ -33144,6 +33172,7 @@ export {
33144
33172
  OhwLoaderSurface,
33145
33173
  SITE_OG_IMAGE_KEY,
33146
33174
  SchedulingWidget,
33175
+ TEMPLATE_LOGO_ATTR,
33147
33176
  Toggle,
33148
33177
  ToggleGroup,
33149
33178
  ToggleGroupItem,
@@ -33177,6 +33206,7 @@ export {
33177
33206
  parseAiSectionsState,
33178
33207
  parseTarget,
33179
33208
  recordOverriddenPaths,
33209
+ releaseTemplateLogoIfReplaced,
33180
33210
  removeFooterBlock,
33181
33211
  resetOverriddenPathsCache,
33182
33212
  resolveFooterCopyright,