@ohhwells/bridge 0.1.66-next.192 → 0.1.67-next.193
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 +115 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +115 -11
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -7551,13 +7551,17 @@ function MediaOverlay({
|
|
|
7551
7551
|
hover,
|
|
7552
7552
|
isUploading,
|
|
7553
7553
|
fadingOut = false,
|
|
7554
|
+
selected = false,
|
|
7555
|
+
hovered = false,
|
|
7554
7556
|
onFadeOutComplete,
|
|
7555
7557
|
onReplace,
|
|
7558
|
+
onSelect,
|
|
7556
7559
|
onVideoSettingsChange
|
|
7557
7560
|
}) {
|
|
7558
7561
|
const { rect } = hover;
|
|
7559
7562
|
const skeletonRef = React7.useRef(null);
|
|
7560
7563
|
const isVideo = hover.elementType === "video";
|
|
7564
|
+
const showChrome = !selected || hovered;
|
|
7561
7565
|
const autoplay = hover.videoAutoplay ?? true;
|
|
7562
7566
|
const muted = hover.videoMuted ?? true;
|
|
7563
7567
|
const box = {
|
|
@@ -7592,7 +7596,7 @@ function MediaOverlay({
|
|
|
7592
7596
|
}
|
|
7593
7597
|
);
|
|
7594
7598
|
}
|
|
7595
|
-
const settingsBar = isVideo && !hover.isDragOver ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
7599
|
+
const settingsBar = isVideo && !hover.isDragOver && showChrome ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
7596
7600
|
"div",
|
|
7597
7601
|
{
|
|
7598
7602
|
"data-ohw-bridge": "",
|
|
@@ -7662,11 +7666,13 @@ function MediaOverlay({
|
|
|
7662
7666
|
// in-document, pointer-events does it natively. The button below opts back in, so
|
|
7663
7667
|
// Replace still works.
|
|
7664
7668
|
pointerEvents: hover.hasTextOverlap ? "none" : "auto",
|
|
7665
|
-
|
|
7666
|
-
|
|
7669
|
+
// Selected: a firm component ring with no wash, so the image reads as chosen rather
|
|
7670
|
+
// than hovered. Hover keeps the existing tinted preview.
|
|
7671
|
+
boxShadow: selected ? "inset 0 0 0 2px var(--color-primary)" : "inset 0 0 0 1.5px var(--color-primary)",
|
|
7672
|
+
background: selected ? "transparent" : "color-mix(in srgb, var(--color-primary) 20%, transparent)"
|
|
7667
7673
|
},
|
|
7668
|
-
onClick: () => onReplace(hover.key),
|
|
7669
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
7674
|
+
onClick: () => onSelect && !selected ? onSelect(hover.key) : onReplace(hover.key),
|
|
7675
|
+
children: showChrome && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
7670
7676
|
Button,
|
|
7671
7677
|
{
|
|
7672
7678
|
"data-ohw-media-overlay": "",
|
|
@@ -15587,6 +15593,70 @@ function OhhwellsBridge() {
|
|
|
15587
15593
|
const hoveredImageHasTextOverlapRef = (0, import_react17.useRef)(false);
|
|
15588
15594
|
const dragOverElRef = (0, import_react17.useRef)(null);
|
|
15589
15595
|
const [mediaHover, setMediaHover] = (0, import_react17.useState)(null);
|
|
15596
|
+
const [selectedMedia, setSelectedMedia] = (0, import_react17.useState)(null);
|
|
15597
|
+
const selectedMediaElRef = (0, import_react17.useRef)(null);
|
|
15598
|
+
const clearMediaSelection = (0, import_react17.useCallback)(() => {
|
|
15599
|
+
const prev = selectedMediaElRef.current;
|
|
15600
|
+
selectedMediaElRef.current = null;
|
|
15601
|
+
setSelectedMedia(null);
|
|
15602
|
+
const sectionEl = prev?.closest("[data-ohw-section]") ?? null;
|
|
15603
|
+
if (sectionEl) {
|
|
15604
|
+
postToParentRef.current({
|
|
15605
|
+
type: "ow:section-selected",
|
|
15606
|
+
sectionId: sectionEl.dataset.ohwSection ?? null,
|
|
15607
|
+
sectionLabel: sectionEl.dataset.ohwSectionLabel ?? titleCaseSectionId(sectionEl.dataset.ohwSection ?? ""),
|
|
15608
|
+
key: null
|
|
15609
|
+
});
|
|
15610
|
+
}
|
|
15611
|
+
}, []);
|
|
15612
|
+
const clearMediaSelectionRef = (0, import_react17.useRef)(clearMediaSelection);
|
|
15613
|
+
clearMediaSelectionRef.current = clearMediaSelection;
|
|
15614
|
+
const selectMediaElement = (0, import_react17.useCallback)((el) => {
|
|
15615
|
+
const r2 = el.getBoundingClientRect();
|
|
15616
|
+
const video = el.dataset.ohwEditable === "video" ? el.querySelector("video") : null;
|
|
15617
|
+
selectedMediaElRef.current = el;
|
|
15618
|
+
setSelectedMedia({
|
|
15619
|
+
key: el.dataset.ohwKey ?? "",
|
|
15620
|
+
rect: { top: r2.top, left: r2.left, width: r2.width, height: r2.height },
|
|
15621
|
+
elementType: el.dataset.ohwEditable ?? "image",
|
|
15622
|
+
hasTextOverlap: false,
|
|
15623
|
+
isDragOver: false,
|
|
15624
|
+
...video ? { videoAutoplay: video.autoplay, videoMuted: video.muted } : {}
|
|
15625
|
+
});
|
|
15626
|
+
const sectionEl = el.closest("[data-ohw-section]");
|
|
15627
|
+
aiSectionApiRef.current?.selectFromElement(el, { report: false });
|
|
15628
|
+
postToParentRef.current({
|
|
15629
|
+
type: "ow:section-selected",
|
|
15630
|
+
sectionId: sectionEl?.dataset.ohwSection ?? null,
|
|
15631
|
+
sectionLabel: sectionEl ? sectionEl.dataset.ohwSectionLabel ?? titleCaseSectionId(sectionEl.dataset.ohwSection ?? "") : null,
|
|
15632
|
+
key: el.dataset.ohwKey ?? null,
|
|
15633
|
+
// Display name for the pill — the raw key prettifies into fragments ("Img"); the
|
|
15634
|
+
// bridge knows what the node IS, so it names it.
|
|
15635
|
+
keyLabel: el.dataset.ohwEditable === "video" ? "Video" : "Image"
|
|
15636
|
+
});
|
|
15637
|
+
}, []);
|
|
15638
|
+
const selectMediaElementRef = (0, import_react17.useRef)(selectMediaElement);
|
|
15639
|
+
selectMediaElementRef.current = selectMediaElement;
|
|
15640
|
+
(0, import_react17.useEffect)(() => {
|
|
15641
|
+
if (!selectedMedia) return;
|
|
15642
|
+
const update = () => {
|
|
15643
|
+
const el = selectedMediaElRef.current;
|
|
15644
|
+
if (!el || !el.isConnected) {
|
|
15645
|
+
clearMediaSelection();
|
|
15646
|
+
return;
|
|
15647
|
+
}
|
|
15648
|
+
const r2 = el.getBoundingClientRect();
|
|
15649
|
+
setSelectedMedia(
|
|
15650
|
+
(prev) => prev ? { ...prev, rect: { top: r2.top, left: r2.left, width: r2.width, height: r2.height } } : prev
|
|
15651
|
+
);
|
|
15652
|
+
};
|
|
15653
|
+
window.addEventListener("scroll", update, true);
|
|
15654
|
+
window.addEventListener("resize", update);
|
|
15655
|
+
return () => {
|
|
15656
|
+
window.removeEventListener("scroll", update, true);
|
|
15657
|
+
window.removeEventListener("resize", update);
|
|
15658
|
+
};
|
|
15659
|
+
}, [selectedMedia !== null]);
|
|
15590
15660
|
const [carouselHover, setCarouselHover] = (0, import_react17.useState)(null);
|
|
15591
15661
|
const [uploadingRects, setUploadingRects] = (0, import_react17.useState)({});
|
|
15592
15662
|
const hoveredGapRef = (0, import_react17.useRef)(null);
|
|
@@ -17719,6 +17789,9 @@ function OhhwellsBridge() {
|
|
|
17719
17789
|
)) {
|
|
17720
17790
|
return;
|
|
17721
17791
|
}
|
|
17792
|
+
if (selectedMediaElRef.current && !selectedMediaElRef.current.contains(target) && !target.closest("[data-ohw-media-overlay], [data-ohw-edit-chrome], [data-ohw-item-interaction]")) {
|
|
17793
|
+
clearMediaSelectionRef.current();
|
|
17794
|
+
}
|
|
17722
17795
|
{
|
|
17723
17796
|
const formEl = getFormElement(target);
|
|
17724
17797
|
const onSuccessText = target.closest(`[${SUCCESS_TEXT_ATTR}]`);
|
|
@@ -17866,8 +17939,11 @@ function OhhwellsBridge() {
|
|
|
17866
17939
|
if (isMediaEditable(editable) && !buttonOnMedia) {
|
|
17867
17940
|
e.preventDefault();
|
|
17868
17941
|
e.stopPropagation();
|
|
17869
|
-
|
|
17870
|
-
|
|
17942
|
+
if (selectedMediaElRef.current === editable) {
|
|
17943
|
+
postToParentRef.current({ type: "ow:image-pick", key: editable.dataset.ohwKey ?? "", elementType: editable.dataset.ohwEditable ?? "image" });
|
|
17944
|
+
} else {
|
|
17945
|
+
selectMediaElementRef.current(editable);
|
|
17946
|
+
}
|
|
17871
17947
|
return;
|
|
17872
17948
|
}
|
|
17873
17949
|
const hrefLookupTarget = buttonOnMedia ? clickedButton : editable;
|
|
@@ -19363,6 +19439,10 @@ function OhhwellsBridge() {
|
|
|
19363
19439
|
const handleKeyDown = (e) => {
|
|
19364
19440
|
if (e.key === "Escape" && document.querySelector("[data-ohw-section-picker]")) return;
|
|
19365
19441
|
if (e.key === "Escape" && document.querySelector("[data-ohw-more-menu]")) return;
|
|
19442
|
+
if (e.key === "Escape" && selectedMediaElRef.current) {
|
|
19443
|
+
clearMediaSelectionRef.current();
|
|
19444
|
+
return;
|
|
19445
|
+
}
|
|
19366
19446
|
if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === "a" && activeElRef.current) {
|
|
19367
19447
|
e.preventDefault();
|
|
19368
19448
|
selectAllTextInEditable(activeElRef.current);
|
|
@@ -20147,7 +20227,7 @@ function OhhwellsBridge() {
|
|
|
20147
20227
|
postToParent2({
|
|
20148
20228
|
type: "ow:ready",
|
|
20149
20229
|
version: "1",
|
|
20150
|
-
bridgeVersion: "0.1.
|
|
20230
|
+
bridgeVersion: "0.1.67",
|
|
20151
20231
|
path: pathname,
|
|
20152
20232
|
nodes: collectEditableNodes(editContentRef.current),
|
|
20153
20233
|
sections
|
|
@@ -20499,11 +20579,22 @@ function OhhwellsBridge() {
|
|
|
20499
20579
|
const showEditLink = toolbarShowEditLink;
|
|
20500
20580
|
const currentSections = sectionsByPath[pathname] ?? [];
|
|
20501
20581
|
linkPopoverOpenRef.current = linkPopover !== null;
|
|
20582
|
+
const handleMediaSelect = (0, import_react17.useCallback)((key) => {
|
|
20583
|
+
const el = hoveredImageRef.current?.dataset.ohwKey === key ? hoveredImageRef.current : Array.from(document.querySelectorAll(MEDIA_SELECTOR)).find(
|
|
20584
|
+
(m) => (m.dataset.ohwKey ?? "") === key
|
|
20585
|
+
) ?? null;
|
|
20586
|
+
if (!el) return;
|
|
20587
|
+
selectMediaElementRef.current(el);
|
|
20588
|
+
}, []);
|
|
20502
20589
|
const handleMediaReplace = (0, import_react17.useCallback)(
|
|
20503
20590
|
(key) => {
|
|
20504
|
-
postToParent2({
|
|
20591
|
+
postToParent2({
|
|
20592
|
+
type: "ow:image-pick",
|
|
20593
|
+
key,
|
|
20594
|
+
elementType: mediaHover?.elementType ?? selectedMedia?.elementType ?? "image"
|
|
20595
|
+
});
|
|
20505
20596
|
},
|
|
20506
|
-
[postToParent2, mediaHover?.elementType]
|
|
20597
|
+
[postToParent2, mediaHover?.elementType, selectedMedia?.elementType]
|
|
20507
20598
|
);
|
|
20508
20599
|
const handleEditCarousel = (0, import_react17.useCallback)(
|
|
20509
20600
|
(key) => {
|
|
@@ -20575,12 +20666,25 @@ function OhhwellsBridge() {
|
|
|
20575
20666
|
},
|
|
20576
20667
|
`uploading-${key}`
|
|
20577
20668
|
)),
|
|
20578
|
-
mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
20669
|
+
mediaHover && !(mediaHover.key in uploadingRects) && mediaHover.key !== selectedMedia?.key && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
20579
20670
|
MediaOverlay,
|
|
20580
20671
|
{
|
|
20581
20672
|
hover: mediaHover,
|
|
20582
20673
|
isUploading: false,
|
|
20583
20674
|
onReplace: handleMediaReplace,
|
|
20675
|
+
onSelect: handleMediaSelect,
|
|
20676
|
+
onVideoSettingsChange: handleVideoSettingsChange
|
|
20677
|
+
}
|
|
20678
|
+
),
|
|
20679
|
+
selectedMedia && !(selectedMedia.key in uploadingRects) && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
20680
|
+
MediaOverlay,
|
|
20681
|
+
{
|
|
20682
|
+
hover: selectedMedia,
|
|
20683
|
+
selected: true,
|
|
20684
|
+
hovered: mediaHover?.key === selectedMedia.key,
|
|
20685
|
+
isUploading: false,
|
|
20686
|
+
onReplace: handleMediaReplace,
|
|
20687
|
+
onSelect: handleMediaSelect,
|
|
20584
20688
|
onVideoSettingsChange: handleVideoSettingsChange
|
|
20585
20689
|
}
|
|
20586
20690
|
),
|