@ohhwells/bridge 0.1.36-next.48 → 0.1.36-next.49
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 +135 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +135 -13
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -5866,6 +5866,9 @@ function collectEditableNodes() {
|
|
|
5866
5866
|
const url = raw.replace(/^url\(['"]?/, "").replace(/['"]?\)$/, "");
|
|
5867
5867
|
return { key: el.dataset.ohwKey ?? "", type: "bg-image", text: url };
|
|
5868
5868
|
}
|
|
5869
|
+
if (el.dataset.ohwEditable === "video") {
|
|
5870
|
+
return { key: el.dataset.ohwKey ?? "", type: "video", text: getVideoEl(el)?.src ?? "" };
|
|
5871
|
+
}
|
|
5869
5872
|
if (el.dataset.ohwEditable === "link") {
|
|
5870
5873
|
return { key: el.dataset.ohwKey ?? "", type: "link", text: getLinkHref(el) };
|
|
5871
5874
|
}
|
|
@@ -5880,8 +5883,62 @@ function collectEditableNodes() {
|
|
|
5880
5883
|
if (!key) return;
|
|
5881
5884
|
nodes.push({ key, type: "link", text: getLinkHref(el) });
|
|
5882
5885
|
});
|
|
5886
|
+
document.querySelectorAll('[data-ohw-editable="video"]').forEach((el) => {
|
|
5887
|
+
const key = el.dataset.ohwKey ?? "";
|
|
5888
|
+
const video = getVideoEl(el);
|
|
5889
|
+
if (!key || !video) return;
|
|
5890
|
+
nodes.push({ key: `${key}${VIDEO_AUTOPLAY_SUFFIX}`, type: "video-setting", text: String(video.autoplay) });
|
|
5891
|
+
nodes.push({ key: `${key}${VIDEO_MUTED_SUFFIX}`, type: "video-setting", text: String(video.muted) });
|
|
5892
|
+
});
|
|
5883
5893
|
return nodes;
|
|
5884
5894
|
}
|
|
5895
|
+
function isMediaEditable(el) {
|
|
5896
|
+
const t = el.dataset.ohwEditable;
|
|
5897
|
+
return t === "image" || t === "bg-image" || t === "video";
|
|
5898
|
+
}
|
|
5899
|
+
var MEDIA_SELECTOR = '[data-ohw-editable="image"], [data-ohw-editable="bg-image"], [data-ohw-editable="video"]';
|
|
5900
|
+
var NON_MEDIA_SELECTOR = '[data-ohw-editable]:not([data-ohw-editable="image"]):not([data-ohw-editable="bg-image"]):not([data-ohw-editable="video"])';
|
|
5901
|
+
function getVideoEl(el) {
|
|
5902
|
+
return el instanceof HTMLVideoElement ? el : el.querySelector("video");
|
|
5903
|
+
}
|
|
5904
|
+
var VIDEO_AUTOPLAY_SUFFIX = "__ohw_autoplay";
|
|
5905
|
+
var VIDEO_MUTED_SUFFIX = "__ohw_muted";
|
|
5906
|
+
function isBackgroundVideo(video) {
|
|
5907
|
+
return video.autoplay && video.muted;
|
|
5908
|
+
}
|
|
5909
|
+
function syncVideoPlayback(video) {
|
|
5910
|
+
const background = isBackgroundVideo(video);
|
|
5911
|
+
video.controls = !background;
|
|
5912
|
+
if (video.autoplay) void video.play().catch(() => {
|
|
5913
|
+
});
|
|
5914
|
+
else video.pause();
|
|
5915
|
+
}
|
|
5916
|
+
function applyVideoSrc(video, url) {
|
|
5917
|
+
const { autoplay, muted } = video;
|
|
5918
|
+
video.src = url;
|
|
5919
|
+
video.loop = true;
|
|
5920
|
+
video.playsInline = true;
|
|
5921
|
+
video.autoplay = autoplay;
|
|
5922
|
+
video.muted = muted;
|
|
5923
|
+
video.load();
|
|
5924
|
+
syncVideoPlayback(video);
|
|
5925
|
+
}
|
|
5926
|
+
function applyVideoSettingNode(key, val) {
|
|
5927
|
+
const isAutoplay = key.endsWith(VIDEO_AUTOPLAY_SUFFIX);
|
|
5928
|
+
const isMuted = key.endsWith(VIDEO_MUTED_SUFFIX);
|
|
5929
|
+
if (!isAutoplay && !isMuted) return false;
|
|
5930
|
+
const suffixLen = (isAutoplay ? VIDEO_AUTOPLAY_SUFFIX : VIDEO_MUTED_SUFFIX).length;
|
|
5931
|
+
const baseKey = key.slice(0, key.length - suffixLen);
|
|
5932
|
+
const on = val === "true";
|
|
5933
|
+
document.querySelectorAll(`[data-ohw-key="${baseKey}"]`).forEach((el) => {
|
|
5934
|
+
const video = getVideoEl(el);
|
|
5935
|
+
if (!video) return;
|
|
5936
|
+
if (isAutoplay) video.autoplay = on;
|
|
5937
|
+
else video.muted = on;
|
|
5938
|
+
syncVideoPlayback(video);
|
|
5939
|
+
});
|
|
5940
|
+
return true;
|
|
5941
|
+
}
|
|
5885
5942
|
function applyLinkByKey(key, val) {
|
|
5886
5943
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
5887
5944
|
if (el.dataset.ohwEditable === "link") applyLinkHref(el, val);
|
|
@@ -6870,6 +6927,7 @@ function OhhwellsBridge() {
|
|
|
6870
6927
|
const imageLoads = [];
|
|
6871
6928
|
for (const [key, val] of Object.entries(content)) {
|
|
6872
6929
|
if (key === "__ohw_sections") continue;
|
|
6930
|
+
if (applyVideoSettingNode(key, val)) continue;
|
|
6873
6931
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
6874
6932
|
if (el.dataset.ohwEditable === "image") {
|
|
6875
6933
|
const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
|
|
@@ -6883,6 +6941,15 @@ function OhhwellsBridge() {
|
|
|
6883
6941
|
} else if (el.dataset.ohwEditable === "bg-image") {
|
|
6884
6942
|
const next = `url('${val}')`;
|
|
6885
6943
|
if (el.style.backgroundImage !== next) el.style.backgroundImage = next;
|
|
6944
|
+
} else if (el.dataset.ohwEditable === "video") {
|
|
6945
|
+
const video = getVideoEl(el);
|
|
6946
|
+
if (video && video.src !== val) {
|
|
6947
|
+
applyVideoSrc(video, val);
|
|
6948
|
+
imageLoads.push(new Promise((resolve) => {
|
|
6949
|
+
video.onloadeddata = () => resolve();
|
|
6950
|
+
video.onerror = () => resolve();
|
|
6951
|
+
}));
|
|
6952
|
+
}
|
|
6886
6953
|
} else if (el.dataset.ohwEditable === "link") {
|
|
6887
6954
|
applyLinkHref(el, val);
|
|
6888
6955
|
} else if (el.innerHTML !== val) {
|
|
@@ -6931,6 +6998,7 @@ function OhhwellsBridge() {
|
|
|
6931
6998
|
try {
|
|
6932
6999
|
for (const [key, val] of Object.entries(content)) {
|
|
6933
7000
|
if (key === "__ohw_sections") continue;
|
|
7001
|
+
if (applyVideoSettingNode(key, val)) continue;
|
|
6934
7002
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
6935
7003
|
if (el.dataset.ohwEditable === "image") {
|
|
6936
7004
|
const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
|
|
@@ -6938,6 +7006,9 @@ function OhhwellsBridge() {
|
|
|
6938
7006
|
} else if (el.dataset.ohwEditable === "bg-image") {
|
|
6939
7007
|
const next = `url('${val}')`;
|
|
6940
7008
|
if (el.style.backgroundImage !== next) el.style.backgroundImage = next;
|
|
7009
|
+
} else if (el.dataset.ohwEditable === "video") {
|
|
7010
|
+
const video = getVideoEl(el);
|
|
7011
|
+
if (video && video.src !== val) applyVideoSrc(video, val);
|
|
6941
7012
|
} else if (el.dataset.ohwEditable === "link") {
|
|
6942
7013
|
applyLinkHref(el, val);
|
|
6943
7014
|
} else if (el.innerHTML !== val) {
|
|
@@ -7041,8 +7112,9 @@ function OhhwellsBridge() {
|
|
|
7041
7112
|
[data-ohw-editable] {
|
|
7042
7113
|
display: block;
|
|
7043
7114
|
}
|
|
7044
|
-
[data-ohw-editable]:not([contenteditable]):not([data-ohw-editable="image"]):not([data-ohw-editable="bg-image"]) { cursor: text !important; }
|
|
7115
|
+
[data-ohw-editable]:not([contenteditable]):not([data-ohw-editable="image"]):not([data-ohw-editable="bg-image"]):not([data-ohw-editable="video"]) { cursor: text !important; }
|
|
7045
7116
|
[data-ohw-editable="image"], [data-ohw-editable="image"] *,
|
|
7117
|
+
[data-ohw-editable="video"], [data-ohw-editable="video"] *,
|
|
7046
7118
|
[data-ohw-editable="bg-image"], [data-ohw-editable="bg-image"] * { cursor: pointer !important; }
|
|
7047
7119
|
[data-ohw-editable="link"], [data-ohw-editable="link"] * { cursor: pointer !important; }
|
|
7048
7120
|
[data-ohw-hovered]:not([contenteditable]):not([data-ohw-href-key]) {
|
|
@@ -7109,7 +7181,7 @@ function OhhwellsBridge() {
|
|
|
7109
7181
|
});
|
|
7110
7182
|
return;
|
|
7111
7183
|
}
|
|
7112
|
-
if (editable
|
|
7184
|
+
if (isMediaEditable(editable)) {
|
|
7113
7185
|
e.preventDefault();
|
|
7114
7186
|
e.stopPropagation();
|
|
7115
7187
|
postToParentRef.current({ type: "ow:image-pick", key: editable.dataset.ohwKey ?? "" });
|
|
@@ -7212,7 +7284,7 @@ function OhhwellsBridge() {
|
|
|
7212
7284
|
if (!editable) return;
|
|
7213
7285
|
const selected = selectedElRef.current;
|
|
7214
7286
|
if (selected && (selected === editable || selected.contains(editable))) return;
|
|
7215
|
-
if (editable
|
|
7287
|
+
if (!isMediaEditable(editable) && !editable.hasAttribute("contenteditable")) {
|
|
7216
7288
|
const hoverTarget = editable.closest("[data-ohw-href-key]") ?? editable;
|
|
7217
7289
|
if (hoverTarget.hasAttribute("data-ohw-href-key")) {
|
|
7218
7290
|
clearHrefKeyHover(hoverTarget);
|
|
@@ -7240,7 +7312,7 @@ function OhhwellsBridge() {
|
|
|
7240
7312
|
if (!editable) return;
|
|
7241
7313
|
const related = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
7242
7314
|
if (related?.closest("[data-ohw-drag-handle-container], [data-ohw-item-interaction]")) return;
|
|
7243
|
-
if (editable
|
|
7315
|
+
if (!isMediaEditable(editable)) {
|
|
7244
7316
|
const hoverTarget = editable.closest("[data-ohw-href-key]") ?? editable;
|
|
7245
7317
|
if (hoverTarget.hasAttribute("data-ohw-href-key")) {
|
|
7246
7318
|
if (!related?.closest("[data-ohw-href-key]")) {
|
|
@@ -7290,11 +7362,16 @@ function OhhwellsBridge() {
|
|
|
7290
7362
|
const r2 = getVisibleRect(imgEl);
|
|
7291
7363
|
const hasTextOverlap = forceTextOverlap ?? false;
|
|
7292
7364
|
hoveredImageHasTextOverlapRef.current = hasTextOverlap;
|
|
7365
|
+
const video = imgEl.dataset.ohwEditable === "video" ? getVideoEl(imgEl) : null;
|
|
7293
7366
|
postToParentRef.current({
|
|
7294
7367
|
type: "ow:image-hover",
|
|
7295
7368
|
key: imgEl.dataset.ohwKey ?? "",
|
|
7369
|
+
// Lets the parent pick the file-picker `accept`, overlay label/icon and drop
|
|
7370
|
+
// mime-check without a parallel ow:video-* message channel.
|
|
7371
|
+
elementType: imgEl.dataset.ohwEditable ?? "image",
|
|
7296
7372
|
rect: { top: r2.top, left: r2.left, width: r2.width, height: r2.height },
|
|
7297
7373
|
hasTextOverlap,
|
|
7374
|
+
...video ? { videoAutoplay: video.autoplay, videoMuted: video.muted } : {},
|
|
7298
7375
|
...isDragOver ? { isDragOver: true } : {}
|
|
7299
7376
|
});
|
|
7300
7377
|
const track = imgEl.closest("[data-ohw-hover-pause]");
|
|
@@ -7302,7 +7379,7 @@ function OhhwellsBridge() {
|
|
|
7302
7379
|
};
|
|
7303
7380
|
const findImageAtPoint = (clientX, clientY, fromParentViewport) => {
|
|
7304
7381
|
const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
7305
|
-
const images = Array.from(document.querySelectorAll(
|
|
7382
|
+
const images = Array.from(document.querySelectorAll(MEDIA_SELECTOR));
|
|
7306
7383
|
const matches = [];
|
|
7307
7384
|
for (let i = images.length - 1; i >= 0; i--) {
|
|
7308
7385
|
const el = images[i];
|
|
@@ -7318,7 +7395,9 @@ function OhhwellsBridge() {
|
|
|
7318
7395
|
if (x >= r2.left && x <= r2.left + r2.width && y >= r2.top && y <= r2.top + r2.height) matches.push(el);
|
|
7319
7396
|
}
|
|
7320
7397
|
if (matches.length === 0) return null;
|
|
7321
|
-
const imageTypeMatches = matches.filter(
|
|
7398
|
+
const imageTypeMatches = matches.filter(
|
|
7399
|
+
(el) => el.dataset.ohwEditable === "image" || el.dataset.ohwEditable === "video"
|
|
7400
|
+
);
|
|
7322
7401
|
const candidatePool = imageTypeMatches.length > 0 ? imageTypeMatches : matches;
|
|
7323
7402
|
const smallest = candidatePool.reduce((best, el) => {
|
|
7324
7403
|
const br = getVisibleRect(best);
|
|
@@ -7396,7 +7475,7 @@ function OhhwellsBridge() {
|
|
|
7396
7475
|
}
|
|
7397
7476
|
const isStateCardImage = !!imgEl.closest("[data-ohw-editable-state]");
|
|
7398
7477
|
const textEditable = Array.from(
|
|
7399
|
-
document.querySelectorAll(
|
|
7478
|
+
document.querySelectorAll(NON_MEDIA_SELECTOR)
|
|
7400
7479
|
).find((el) => {
|
|
7401
7480
|
const er = el.getBoundingClientRect();
|
|
7402
7481
|
return x >= er.left && x <= er.right && y >= er.top && y <= er.bottom;
|
|
@@ -7477,7 +7556,7 @@ function OhhwellsBridge() {
|
|
|
7477
7556
|
}
|
|
7478
7557
|
const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
7479
7558
|
const textEl = Array.from(
|
|
7480
|
-
document.querySelectorAll(
|
|
7559
|
+
document.querySelectorAll(NON_MEDIA_SELECTOR)
|
|
7481
7560
|
).find((el) => {
|
|
7482
7561
|
const er = el.getBoundingClientRect();
|
|
7483
7562
|
return x >= er.left && x <= er.right && y >= er.top && y <= er.bottom;
|
|
@@ -7602,7 +7681,9 @@ function OhhwellsBridge() {
|
|
|
7602
7681
|
if (!el) return;
|
|
7603
7682
|
const file = e.dataTransfer?.files?.[0];
|
|
7604
7683
|
if (file) {
|
|
7605
|
-
|
|
7684
|
+
const wantsVideo = el.dataset.ohwEditable === "video";
|
|
7685
|
+
const accepted = wantsVideo ? file.type.startsWith("video/") : file.type.startsWith("image/");
|
|
7686
|
+
if (accepted) {
|
|
7606
7687
|
const key = el.dataset.ohwKey ?? "";
|
|
7607
7688
|
const { name, type: mimeType } = file;
|
|
7608
7689
|
const r2 = el.getBoundingClientRect();
|
|
@@ -7618,6 +7699,30 @@ function OhhwellsBridge() {
|
|
|
7618
7699
|
resumeAnimTracks();
|
|
7619
7700
|
postToParentRef.current({ type: "ow:image-unhover" });
|
|
7620
7701
|
};
|
|
7702
|
+
const handleVideoSettings = (e) => {
|
|
7703
|
+
if (e.data?.type !== "ow:video-settings") return;
|
|
7704
|
+
const { key, autoplay, muted } = e.data;
|
|
7705
|
+
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
7706
|
+
const video = getVideoEl(el);
|
|
7707
|
+
if (!video) return;
|
|
7708
|
+
if (typeof autoplay === "boolean") video.autoplay = autoplay;
|
|
7709
|
+
if (typeof muted === "boolean") video.muted = muted;
|
|
7710
|
+
syncVideoPlayback(video);
|
|
7711
|
+
postToParentRef.current({
|
|
7712
|
+
type: "ow:change",
|
|
7713
|
+
nodes: [
|
|
7714
|
+
{ key: `${key}${VIDEO_AUTOPLAY_SUFFIX}`, text: String(video.autoplay) },
|
|
7715
|
+
{ key: `${key}${VIDEO_MUTED_SUFFIX}`, text: String(video.muted) }
|
|
7716
|
+
]
|
|
7717
|
+
});
|
|
7718
|
+
postToParentRef.current({
|
|
7719
|
+
type: "ow:video-settings-applied",
|
|
7720
|
+
key,
|
|
7721
|
+
autoplay: video.autoplay,
|
|
7722
|
+
muted: video.muted
|
|
7723
|
+
});
|
|
7724
|
+
});
|
|
7725
|
+
};
|
|
7621
7726
|
const handleImageUrl = (e) => {
|
|
7622
7727
|
if (e.data?.type !== "ow:image-url") return;
|
|
7623
7728
|
const { key, url } = e.data;
|
|
@@ -7669,6 +7774,19 @@ function OhhwellsBridge() {
|
|
|
7669
7774
|
requestAnimationFrame(() => onReady());
|
|
7670
7775
|
}
|
|
7671
7776
|
}
|
|
7777
|
+
} else if (el.dataset.ohwEditable === "video") {
|
|
7778
|
+
const video = getVideoEl(el);
|
|
7779
|
+
if (video) {
|
|
7780
|
+
found = true;
|
|
7781
|
+
const onReady = () => {
|
|
7782
|
+
video.onloadeddata = null;
|
|
7783
|
+
video.onerror = null;
|
|
7784
|
+
notify();
|
|
7785
|
+
};
|
|
7786
|
+
video.onloadeddata = onReady;
|
|
7787
|
+
video.onerror = onReady;
|
|
7788
|
+
applyVideoSrc(video, url);
|
|
7789
|
+
}
|
|
7672
7790
|
}
|
|
7673
7791
|
});
|
|
7674
7792
|
if (!found) notify();
|
|
@@ -7735,12 +7853,16 @@ function OhhwellsBridge() {
|
|
|
7735
7853
|
sectionsJson = val;
|
|
7736
7854
|
continue;
|
|
7737
7855
|
}
|
|
7856
|
+
if (applyVideoSettingNode(key, val)) continue;
|
|
7738
7857
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
7739
7858
|
if (el.dataset.ohwEditable === "image") {
|
|
7740
7859
|
const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
|
|
7741
7860
|
if (img) img.src = val;
|
|
7742
7861
|
} else if (el.dataset.ohwEditable === "bg-image") {
|
|
7743
7862
|
el.style.backgroundImage = `url('${val}')`;
|
|
7863
|
+
} else if (el.dataset.ohwEditable === "video") {
|
|
7864
|
+
const video = getVideoEl(el);
|
|
7865
|
+
if (video && video.src !== val) applyVideoSrc(video, val);
|
|
7744
7866
|
} else if (el.dataset.ohwEditable === "link") {
|
|
7745
7867
|
applyLinkHref(el, val);
|
|
7746
7868
|
} else {
|
|
@@ -8001,7 +8123,7 @@ function OhhwellsBridge() {
|
|
|
8001
8123
|
if (e.data?.type !== "ow:click-at") return;
|
|
8002
8124
|
const { clientX, clientY } = e.data;
|
|
8003
8125
|
const allImages = Array.from(
|
|
8004
|
-
document.querySelectorAll(
|
|
8126
|
+
document.querySelectorAll(MEDIA_SELECTOR)
|
|
8005
8127
|
).filter((el) => !!el.closest("[data-ohw-editable-state]"));
|
|
8006
8128
|
const stateCardImage = allImages.find((el) => {
|
|
8007
8129
|
const ownerCard = el.closest("[data-ohw-editable-state]");
|
|
@@ -8020,9 +8142,7 @@ function OhhwellsBridge() {
|
|
|
8020
8142
|
return;
|
|
8021
8143
|
}
|
|
8022
8144
|
const textEditable = Array.from(
|
|
8023
|
-
document.querySelectorAll(
|
|
8024
|
-
'[data-ohw-editable]:not([data-ohw-editable="image"]):not([data-ohw-editable="bg-image"])'
|
|
8025
|
-
)
|
|
8145
|
+
document.querySelectorAll(NON_MEDIA_SELECTOR)
|
|
8026
8146
|
).find((el) => {
|
|
8027
8147
|
const r2 = el.getBoundingClientRect();
|
|
8028
8148
|
return clientX >= r2.left && clientX <= r2.right && clientY >= r2.top && clientY <= r2.bottom;
|
|
@@ -8050,6 +8170,7 @@ function OhhwellsBridge() {
|
|
|
8050
8170
|
window.addEventListener("message", handleClearSchedulingWidget);
|
|
8051
8171
|
window.addEventListener("message", handleRemoveSchedulingSection);
|
|
8052
8172
|
window.addEventListener("message", handleImageUrl);
|
|
8173
|
+
window.addEventListener("message", handleVideoSettings);
|
|
8053
8174
|
window.addEventListener("message", handleAnimLock);
|
|
8054
8175
|
window.addEventListener("message", handleCanvasHeight);
|
|
8055
8176
|
window.addEventListener("message", handleParentScroll);
|
|
@@ -8097,6 +8218,7 @@ function OhhwellsBridge() {
|
|
|
8097
8218
|
window.removeEventListener("message", handleClearSchedulingWidget);
|
|
8098
8219
|
window.removeEventListener("message", handleRemoveSchedulingSection);
|
|
8099
8220
|
window.removeEventListener("message", handleImageUrl);
|
|
8221
|
+
window.removeEventListener("message", handleVideoSettings);
|
|
8100
8222
|
window.removeEventListener("message", handleAnimLock);
|
|
8101
8223
|
window.removeEventListener("message", handleCanvasHeight);
|
|
8102
8224
|
window.removeEventListener("message", handleParentScroll);
|