@ohhwells/bridge 0.1.71 → 0.1.72
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 +64 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +64 -12
- package/dist/index.js.map +1 -1
- package/dist/social-glyphs.cjs +61 -0
- package/dist/social-glyphs.cjs.map +1 -0
- package/dist/social-glyphs.js +31 -0
- package/dist/social-glyphs.js.map +1 -0
- package/package.json +7 -2
package/dist/index.cjs
CHANGED
|
@@ -13224,6 +13224,18 @@ function collectEditableNodes(extraContent, root = document) {
|
|
|
13224
13224
|
}
|
|
13225
13225
|
if (extraContent && !isScoped) {
|
|
13226
13226
|
applyNavFooterDeleteOverrides(byKey, extraContent);
|
|
13227
|
+
for (const key of LOGO_IMAGE_KEYS) {
|
|
13228
|
+
if (!(key in extraContent)) continue;
|
|
13229
|
+
byKey.set(key, { key, type: "image", text: extraContent[key] ?? "" });
|
|
13230
|
+
}
|
|
13231
|
+
for (const key of [LOGO_PLACEHOLDER_KEY, LOGO_ALT_KEY]) {
|
|
13232
|
+
if (!(key in extraContent)) continue;
|
|
13233
|
+
byKey.set(key, { key, type: "meta", text: extraContent[key] ?? "" });
|
|
13234
|
+
}
|
|
13235
|
+
for (const key of LOGO_SIZE_KEYS) {
|
|
13236
|
+
if (!(key in extraContent)) continue;
|
|
13237
|
+
byKey.set(key, { key, type: "meta", text: extraContent[key] ?? "" });
|
|
13238
|
+
}
|
|
13227
13239
|
}
|
|
13228
13240
|
return Array.from(byKey.values());
|
|
13229
13241
|
}
|
|
@@ -13821,9 +13833,21 @@ function getLinkHref4(el) {
|
|
|
13821
13833
|
const anchor = el instanceof HTMLAnchorElement ? el : el.querySelector("a");
|
|
13822
13834
|
return anchor?.getAttribute("href") ?? "";
|
|
13823
13835
|
}
|
|
13836
|
+
function normalizeLinkHref(value) {
|
|
13837
|
+
const href = value.trim();
|
|
13838
|
+
if (!href) return href;
|
|
13839
|
+
if (/^[a-z][a-z0-9+.-]*:/i.test(href)) return href;
|
|
13840
|
+
if (href.startsWith("/") || href.startsWith("#") || href.startsWith("?")) return href;
|
|
13841
|
+
if (!/^[^\s/]+\.[a-z]{2,}(?:[/:?#]|$)/i.test(href)) return href;
|
|
13842
|
+
return `https://${href}`;
|
|
13843
|
+
}
|
|
13844
|
+
function isPageFrameSection(el) {
|
|
13845
|
+
const id = el.dataset.ohwSection ?? "";
|
|
13846
|
+
return el.tagName === "FOOTER" || el.tagName === "HEADER" || Boolean(el.closest("footer")) || /(^|[-_])(footer|navbar)$/i.test(id);
|
|
13847
|
+
}
|
|
13824
13848
|
function applyLinkHref(el, val) {
|
|
13825
13849
|
const anchor = el instanceof HTMLAnchorElement ? el : el.querySelector("a");
|
|
13826
|
-
if (anchor) anchor.setAttribute("href", val);
|
|
13850
|
+
if (anchor) anchor.setAttribute("href", normalizeLinkHref(val));
|
|
13827
13851
|
}
|
|
13828
13852
|
function currentIconRef(el) {
|
|
13829
13853
|
const uploaded = el instanceof HTMLImageElement ? el : el.querySelector("img");
|
|
@@ -13953,7 +13977,7 @@ function applyLinkByKey(key, val) {
|
|
|
13953
13977
|
});
|
|
13954
13978
|
const hrefAnchors = document.querySelectorAll(`[data-ohw-href-key="${key}"]`);
|
|
13955
13979
|
if (hrefAnchors.length > 0) {
|
|
13956
|
-
setStoredLinkHref(key, val);
|
|
13980
|
+
setStoredLinkHref(key, normalizeLinkHref(val));
|
|
13957
13981
|
hrefAnchors.forEach((el) => applyLinkHref(el, val));
|
|
13958
13982
|
}
|
|
13959
13983
|
}
|
|
@@ -15138,7 +15162,8 @@ function OhhwellsBridge() {
|
|
|
15138
15162
|
const el = document.querySelector(
|
|
15139
15163
|
'[data-ohw-hovered]:not([contenteditable]):not([data-ohw-href-key]):not([data-ohw-editable="form"] *)'
|
|
15140
15164
|
);
|
|
15141
|
-
const
|
|
15165
|
+
const busy = el?.querySelector('[contenteditable="true"]') ?? null;
|
|
15166
|
+
const target = el && !el.closest("[data-ohw-href-key]") && !busy ? el : null;
|
|
15142
15167
|
if (!target) {
|
|
15143
15168
|
setHoveredTextRect(null);
|
|
15144
15169
|
return;
|
|
@@ -15149,7 +15174,10 @@ function OhhwellsBridge() {
|
|
|
15149
15174
|
const observer = new MutationObserver(sync);
|
|
15150
15175
|
observer.observe(document.documentElement, {
|
|
15151
15176
|
attributes: true,
|
|
15152
|
-
|
|
15177
|
+
// `contenteditable` too: the box is recomputed only when one of these changes, and a click
|
|
15178
|
+
// that opens an element for typing changes nothing else — so the frame measured a moment
|
|
15179
|
+
// earlier, while merely hovering, stayed on screen inside the solid one (OHH-762).
|
|
15180
|
+
attributeFilter: ["data-ohw-hovered", "contenteditable"],
|
|
15153
15181
|
subtree: true
|
|
15154
15182
|
});
|
|
15155
15183
|
return () => observer.disconnect();
|
|
@@ -15436,6 +15464,14 @@ function OhhwellsBridge() {
|
|
|
15436
15464
|
el.removeAttribute("data-ohw-hovered");
|
|
15437
15465
|
el.setAttribute("data-ohw-selected", "");
|
|
15438
15466
|
}, [clearSelectedAttr]);
|
|
15467
|
+
const isSelectedForHover = (0, import_react16.useCallback)((el) => {
|
|
15468
|
+
if (!el) return false;
|
|
15469
|
+
return [selectedElRef.current, activeElRef.current].some(
|
|
15470
|
+
(busy) => busy && (el === busy || busy.contains(el) || el.contains(busy))
|
|
15471
|
+
);
|
|
15472
|
+
}, []);
|
|
15473
|
+
const isSelectedForHoverRef = (0, import_react16.useRef)(isSelectedForHover);
|
|
15474
|
+
isSelectedForHoverRef.current = isSelectedForHover;
|
|
15439
15475
|
const resolveHrefKeyElement = (0, import_react16.useCallback)((hrefKey) => {
|
|
15440
15476
|
if (isFooterHrefKey(hrefKey)) {
|
|
15441
15477
|
return document.querySelector(
|
|
@@ -16353,6 +16389,12 @@ function OhhwellsBridge() {
|
|
|
16353
16389
|
);
|
|
16354
16390
|
const activate = (0, import_react16.useCallback)((el, options) => {
|
|
16355
16391
|
if (activeElRef.current === el) return;
|
|
16392
|
+
document.querySelectorAll("[data-ohw-hovered]").forEach((hovered) => {
|
|
16393
|
+
hovered.removeAttribute("data-ohw-hovered");
|
|
16394
|
+
});
|
|
16395
|
+
setHoveredTextRect(null);
|
|
16396
|
+
hoveredItemElRef.current = null;
|
|
16397
|
+
setHoveredItemRect(null);
|
|
16356
16398
|
if (isIconEditable(el)) {
|
|
16357
16399
|
const social = getSocialItem(el);
|
|
16358
16400
|
const words = social ? social.querySelector('[data-ohw-editable="text"], [data-ohw-editable="plain"]') : null;
|
|
@@ -17539,13 +17581,13 @@ function OhhwellsBridge() {
|
|
|
17539
17581
|
clearHrefKeyHover(hoverTarget);
|
|
17540
17582
|
hoveredItemElRef.current = hoverTarget;
|
|
17541
17583
|
setHoveredItemRect(hoverTarget.getBoundingClientRect());
|
|
17542
|
-
} else if (!isInsideNavigationItem(editable) &&
|
|
17584
|
+
} else if (!isInsideNavigationItem(editable) && !isSelectedForHoverRef.current(hoverTarget)) {
|
|
17543
17585
|
hoverTarget.setAttribute("data-ohw-hovered", "");
|
|
17544
17586
|
if (editable.closest("footer") || editable.closest('[data-ohw-section="footer"]')) {
|
|
17545
17587
|
hoveredNavContainerRef.current = null;
|
|
17546
17588
|
setHoveredNavContainerRect(null);
|
|
17547
17589
|
hoveredItemElRef.current = editable;
|
|
17548
|
-
setHoveredItemRect(editable.getBoundingClientRect());
|
|
17590
|
+
setHoveredItemRect(isSelectedForHoverRef.current(editable) ? null : editable.getBoundingClientRect());
|
|
17549
17591
|
}
|
|
17550
17592
|
}
|
|
17551
17593
|
}
|
|
@@ -18000,7 +18042,7 @@ function OhhwellsBridge() {
|
|
|
18000
18042
|
showImageHover(imgEl, isDragOver, true);
|
|
18001
18043
|
}
|
|
18002
18044
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
18003
|
-
if (textEditable && !textEditable.closest("[data-ohw-href-key]")) {
|
|
18045
|
+
if (textEditable && !textEditable.closest("[data-ohw-href-key]") && !isSelectedForHoverRef.current(textEditable)) {
|
|
18004
18046
|
textEditable.setAttribute("data-ohw-hovered", "");
|
|
18005
18047
|
}
|
|
18006
18048
|
return;
|
|
@@ -18012,7 +18054,7 @@ function OhhwellsBridge() {
|
|
|
18012
18054
|
clearImageHover();
|
|
18013
18055
|
}
|
|
18014
18056
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
18015
|
-
if (textEditable && !textEditable.closest("[data-ohw-href-key]")) {
|
|
18057
|
+
if (textEditable && !textEditable.closest("[data-ohw-href-key]") && !isSelectedForHoverRef.current(textEditable)) {
|
|
18016
18058
|
textEditable.setAttribute("data-ohw-hovered", "");
|
|
18017
18059
|
}
|
|
18018
18060
|
return;
|
|
@@ -18086,7 +18128,7 @@ function OhhwellsBridge() {
|
|
|
18086
18128
|
hoveredItemElRef.current = navAnchor;
|
|
18087
18129
|
setHoveredItemRect(navAnchor.getBoundingClientRect());
|
|
18088
18130
|
}
|
|
18089
|
-
} else if (!textEl.closest("[data-ohw-href-key]")) {
|
|
18131
|
+
} else if (!textEl.closest("[data-ohw-href-key]") && !isSelectedForHoverRef.current(textEl)) {
|
|
18090
18132
|
hoveredItemElRef.current = null;
|
|
18091
18133
|
setHoveredItemRect(null);
|
|
18092
18134
|
textEl.setAttribute("data-ohw-hovered", "");
|
|
@@ -18180,7 +18222,7 @@ function OhhwellsBridge() {
|
|
|
18180
18222
|
const ZONE = 20;
|
|
18181
18223
|
for (let i = 0; i < sections.length; i++) {
|
|
18182
18224
|
const a = sections[i];
|
|
18183
|
-
if (a
|
|
18225
|
+
if (isPageFrameSection(a)) continue;
|
|
18184
18226
|
const b = sections[i + 1] ?? null;
|
|
18185
18227
|
const boundaryY = a.getBoundingClientRect().bottom;
|
|
18186
18228
|
if (Math.abs(y - boundaryY) <= ZONE) {
|
|
@@ -18640,9 +18682,10 @@ function OhhwellsBridge() {
|
|
|
18640
18682
|
const handleAiDeleteSection = (e) => {
|
|
18641
18683
|
if (e.data?.type !== "ow:ai-delete-section") return;
|
|
18642
18684
|
const sectionId = typeof e.data.sectionId === "string" ? e.data.sectionId : "";
|
|
18643
|
-
if (!sectionId
|
|
18685
|
+
if (!sectionId) return;
|
|
18644
18686
|
const exists = document.querySelector(`[data-ohw-section="${CSS.escape(sectionId)}"]`);
|
|
18645
18687
|
if (!exists) return;
|
|
18688
|
+
if (isPageFrameSection(exists)) return;
|
|
18646
18689
|
const previous = aiSectionsRef.current;
|
|
18647
18690
|
const nextState = deleteSectionFromState(parseAiSectionsState(previous), sectionId);
|
|
18648
18691
|
const nextValue = serializeAiSectionsState(nextState);
|
|
@@ -19275,6 +19318,15 @@ function OhhwellsBridge() {
|
|
|
19275
19318
|
if (visibleViewportRef.current) {
|
|
19276
19319
|
applyVisibleViewport(visibleViewportRef.current, parentScrollRef.current);
|
|
19277
19320
|
}
|
|
19321
|
+
handleScroll();
|
|
19322
|
+
document.querySelectorAll("[data-ohw-hovered]").forEach((hovered) => {
|
|
19323
|
+
hovered.removeAttribute("data-ohw-hovered");
|
|
19324
|
+
});
|
|
19325
|
+
setHoveredTextRect(null);
|
|
19326
|
+
hoveredItemElRef.current = null;
|
|
19327
|
+
setHoveredItemRect(null);
|
|
19328
|
+
hoveredNavContainerRef.current = null;
|
|
19329
|
+
setHoveredNavContainerRect(null);
|
|
19278
19330
|
};
|
|
19279
19331
|
window.addEventListener("resize", handleViewportResize, { passive: true });
|
|
19280
19332
|
document.addEventListener("click", handleClick, true);
|
|
@@ -19540,7 +19592,7 @@ function OhhwellsBridge() {
|
|
|
19540
19592
|
postToParent2({
|
|
19541
19593
|
type: "ow:ready",
|
|
19542
19594
|
version: "1",
|
|
19543
|
-
bridgeVersion: "0.1.
|
|
19595
|
+
bridgeVersion: "0.1.72",
|
|
19544
19596
|
path: pathname,
|
|
19545
19597
|
nodes: collectEditableNodes(editContentRef.current),
|
|
19546
19598
|
sections
|