@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.cjs
CHANGED
|
@@ -5925,6 +5925,9 @@ function collectEditableNodes() {
|
|
|
5925
5925
|
const url = raw.replace(/^url\(['"]?/, "").replace(/['"]?\)$/, "");
|
|
5926
5926
|
return { key: el.dataset.ohwKey ?? "", type: "bg-image", text: url };
|
|
5927
5927
|
}
|
|
5928
|
+
if (el.dataset.ohwEditable === "video") {
|
|
5929
|
+
return { key: el.dataset.ohwKey ?? "", type: "video", text: getVideoEl(el)?.src ?? "" };
|
|
5930
|
+
}
|
|
5928
5931
|
if (el.dataset.ohwEditable === "link") {
|
|
5929
5932
|
return { key: el.dataset.ohwKey ?? "", type: "link", text: getLinkHref(el) };
|
|
5930
5933
|
}
|
|
@@ -5939,8 +5942,62 @@ function collectEditableNodes() {
|
|
|
5939
5942
|
if (!key) return;
|
|
5940
5943
|
nodes.push({ key, type: "link", text: getLinkHref(el) });
|
|
5941
5944
|
});
|
|
5945
|
+
document.querySelectorAll('[data-ohw-editable="video"]').forEach((el) => {
|
|
5946
|
+
const key = el.dataset.ohwKey ?? "";
|
|
5947
|
+
const video = getVideoEl(el);
|
|
5948
|
+
if (!key || !video) return;
|
|
5949
|
+
nodes.push({ key: `${key}${VIDEO_AUTOPLAY_SUFFIX}`, type: "video-setting", text: String(video.autoplay) });
|
|
5950
|
+
nodes.push({ key: `${key}${VIDEO_MUTED_SUFFIX}`, type: "video-setting", text: String(video.muted) });
|
|
5951
|
+
});
|
|
5942
5952
|
return nodes;
|
|
5943
5953
|
}
|
|
5954
|
+
function isMediaEditable(el) {
|
|
5955
|
+
const t = el.dataset.ohwEditable;
|
|
5956
|
+
return t === "image" || t === "bg-image" || t === "video";
|
|
5957
|
+
}
|
|
5958
|
+
var MEDIA_SELECTOR = '[data-ohw-editable="image"], [data-ohw-editable="bg-image"], [data-ohw-editable="video"]';
|
|
5959
|
+
var NON_MEDIA_SELECTOR = '[data-ohw-editable]:not([data-ohw-editable="image"]):not([data-ohw-editable="bg-image"]):not([data-ohw-editable="video"])';
|
|
5960
|
+
function getVideoEl(el) {
|
|
5961
|
+
return el instanceof HTMLVideoElement ? el : el.querySelector("video");
|
|
5962
|
+
}
|
|
5963
|
+
var VIDEO_AUTOPLAY_SUFFIX = "__ohw_autoplay";
|
|
5964
|
+
var VIDEO_MUTED_SUFFIX = "__ohw_muted";
|
|
5965
|
+
function isBackgroundVideo(video) {
|
|
5966
|
+
return video.autoplay && video.muted;
|
|
5967
|
+
}
|
|
5968
|
+
function syncVideoPlayback(video) {
|
|
5969
|
+
const background = isBackgroundVideo(video);
|
|
5970
|
+
video.controls = !background;
|
|
5971
|
+
if (video.autoplay) void video.play().catch(() => {
|
|
5972
|
+
});
|
|
5973
|
+
else video.pause();
|
|
5974
|
+
}
|
|
5975
|
+
function applyVideoSrc(video, url) {
|
|
5976
|
+
const { autoplay, muted } = video;
|
|
5977
|
+
video.src = url;
|
|
5978
|
+
video.loop = true;
|
|
5979
|
+
video.playsInline = true;
|
|
5980
|
+
video.autoplay = autoplay;
|
|
5981
|
+
video.muted = muted;
|
|
5982
|
+
video.load();
|
|
5983
|
+
syncVideoPlayback(video);
|
|
5984
|
+
}
|
|
5985
|
+
function applyVideoSettingNode(key, val) {
|
|
5986
|
+
const isAutoplay = key.endsWith(VIDEO_AUTOPLAY_SUFFIX);
|
|
5987
|
+
const isMuted = key.endsWith(VIDEO_MUTED_SUFFIX);
|
|
5988
|
+
if (!isAutoplay && !isMuted) return false;
|
|
5989
|
+
const suffixLen = (isAutoplay ? VIDEO_AUTOPLAY_SUFFIX : VIDEO_MUTED_SUFFIX).length;
|
|
5990
|
+
const baseKey = key.slice(0, key.length - suffixLen);
|
|
5991
|
+
const on = val === "true";
|
|
5992
|
+
document.querySelectorAll(`[data-ohw-key="${baseKey}"]`).forEach((el) => {
|
|
5993
|
+
const video = getVideoEl(el);
|
|
5994
|
+
if (!video) return;
|
|
5995
|
+
if (isAutoplay) video.autoplay = on;
|
|
5996
|
+
else video.muted = on;
|
|
5997
|
+
syncVideoPlayback(video);
|
|
5998
|
+
});
|
|
5999
|
+
return true;
|
|
6000
|
+
}
|
|
5944
6001
|
function applyLinkByKey(key, val) {
|
|
5945
6002
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
5946
6003
|
if (el.dataset.ohwEditable === "link") applyLinkHref(el, val);
|
|
@@ -6929,6 +6986,7 @@ function OhhwellsBridge() {
|
|
|
6929
6986
|
const imageLoads = [];
|
|
6930
6987
|
for (const [key, val] of Object.entries(content)) {
|
|
6931
6988
|
if (key === "__ohw_sections") continue;
|
|
6989
|
+
if (applyVideoSettingNode(key, val)) continue;
|
|
6932
6990
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
6933
6991
|
if (el.dataset.ohwEditable === "image") {
|
|
6934
6992
|
const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
|
|
@@ -6942,6 +7000,15 @@ function OhhwellsBridge() {
|
|
|
6942
7000
|
} else if (el.dataset.ohwEditable === "bg-image") {
|
|
6943
7001
|
const next = `url('${val}')`;
|
|
6944
7002
|
if (el.style.backgroundImage !== next) el.style.backgroundImage = next;
|
|
7003
|
+
} else if (el.dataset.ohwEditable === "video") {
|
|
7004
|
+
const video = getVideoEl(el);
|
|
7005
|
+
if (video && video.src !== val) {
|
|
7006
|
+
applyVideoSrc(video, val);
|
|
7007
|
+
imageLoads.push(new Promise((resolve) => {
|
|
7008
|
+
video.onloadeddata = () => resolve();
|
|
7009
|
+
video.onerror = () => resolve();
|
|
7010
|
+
}));
|
|
7011
|
+
}
|
|
6945
7012
|
} else if (el.dataset.ohwEditable === "link") {
|
|
6946
7013
|
applyLinkHref(el, val);
|
|
6947
7014
|
} else if (el.innerHTML !== val) {
|
|
@@ -6990,6 +7057,7 @@ function OhhwellsBridge() {
|
|
|
6990
7057
|
try {
|
|
6991
7058
|
for (const [key, val] of Object.entries(content)) {
|
|
6992
7059
|
if (key === "__ohw_sections") continue;
|
|
7060
|
+
if (applyVideoSettingNode(key, val)) continue;
|
|
6993
7061
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
6994
7062
|
if (el.dataset.ohwEditable === "image") {
|
|
6995
7063
|
const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
|
|
@@ -6997,6 +7065,9 @@ function OhhwellsBridge() {
|
|
|
6997
7065
|
} else if (el.dataset.ohwEditable === "bg-image") {
|
|
6998
7066
|
const next = `url('${val}')`;
|
|
6999
7067
|
if (el.style.backgroundImage !== next) el.style.backgroundImage = next;
|
|
7068
|
+
} else if (el.dataset.ohwEditable === "video") {
|
|
7069
|
+
const video = getVideoEl(el);
|
|
7070
|
+
if (video && video.src !== val) applyVideoSrc(video, val);
|
|
7000
7071
|
} else if (el.dataset.ohwEditable === "link") {
|
|
7001
7072
|
applyLinkHref(el, val);
|
|
7002
7073
|
} else if (el.innerHTML !== val) {
|
|
@@ -7100,8 +7171,9 @@ function OhhwellsBridge() {
|
|
|
7100
7171
|
[data-ohw-editable] {
|
|
7101
7172
|
display: block;
|
|
7102
7173
|
}
|
|
7103
|
-
[data-ohw-editable]:not([contenteditable]):not([data-ohw-editable="image"]):not([data-ohw-editable="bg-image"]) { cursor: text !important; }
|
|
7174
|
+
[data-ohw-editable]:not([contenteditable]):not([data-ohw-editable="image"]):not([data-ohw-editable="bg-image"]):not([data-ohw-editable="video"]) { cursor: text !important; }
|
|
7104
7175
|
[data-ohw-editable="image"], [data-ohw-editable="image"] *,
|
|
7176
|
+
[data-ohw-editable="video"], [data-ohw-editable="video"] *,
|
|
7105
7177
|
[data-ohw-editable="bg-image"], [data-ohw-editable="bg-image"] * { cursor: pointer !important; }
|
|
7106
7178
|
[data-ohw-editable="link"], [data-ohw-editable="link"] * { cursor: pointer !important; }
|
|
7107
7179
|
[data-ohw-hovered]:not([contenteditable]):not([data-ohw-href-key]) {
|
|
@@ -7168,7 +7240,7 @@ function OhhwellsBridge() {
|
|
|
7168
7240
|
});
|
|
7169
7241
|
return;
|
|
7170
7242
|
}
|
|
7171
|
-
if (editable
|
|
7243
|
+
if (isMediaEditable(editable)) {
|
|
7172
7244
|
e.preventDefault();
|
|
7173
7245
|
e.stopPropagation();
|
|
7174
7246
|
postToParentRef.current({ type: "ow:image-pick", key: editable.dataset.ohwKey ?? "" });
|
|
@@ -7271,7 +7343,7 @@ function OhhwellsBridge() {
|
|
|
7271
7343
|
if (!editable) return;
|
|
7272
7344
|
const selected = selectedElRef.current;
|
|
7273
7345
|
if (selected && (selected === editable || selected.contains(editable))) return;
|
|
7274
|
-
if (editable
|
|
7346
|
+
if (!isMediaEditable(editable) && !editable.hasAttribute("contenteditable")) {
|
|
7275
7347
|
const hoverTarget = editable.closest("[data-ohw-href-key]") ?? editable;
|
|
7276
7348
|
if (hoverTarget.hasAttribute("data-ohw-href-key")) {
|
|
7277
7349
|
clearHrefKeyHover(hoverTarget);
|
|
@@ -7299,7 +7371,7 @@ function OhhwellsBridge() {
|
|
|
7299
7371
|
if (!editable) return;
|
|
7300
7372
|
const related = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
7301
7373
|
if (related?.closest("[data-ohw-drag-handle-container], [data-ohw-item-interaction]")) return;
|
|
7302
|
-
if (editable
|
|
7374
|
+
if (!isMediaEditable(editable)) {
|
|
7303
7375
|
const hoverTarget = editable.closest("[data-ohw-href-key]") ?? editable;
|
|
7304
7376
|
if (hoverTarget.hasAttribute("data-ohw-href-key")) {
|
|
7305
7377
|
if (!related?.closest("[data-ohw-href-key]")) {
|
|
@@ -7349,11 +7421,16 @@ function OhhwellsBridge() {
|
|
|
7349
7421
|
const r2 = getVisibleRect(imgEl);
|
|
7350
7422
|
const hasTextOverlap = forceTextOverlap ?? false;
|
|
7351
7423
|
hoveredImageHasTextOverlapRef.current = hasTextOverlap;
|
|
7424
|
+
const video = imgEl.dataset.ohwEditable === "video" ? getVideoEl(imgEl) : null;
|
|
7352
7425
|
postToParentRef.current({
|
|
7353
7426
|
type: "ow:image-hover",
|
|
7354
7427
|
key: imgEl.dataset.ohwKey ?? "",
|
|
7428
|
+
// Lets the parent pick the file-picker `accept`, overlay label/icon and drop
|
|
7429
|
+
// mime-check without a parallel ow:video-* message channel.
|
|
7430
|
+
elementType: imgEl.dataset.ohwEditable ?? "image",
|
|
7355
7431
|
rect: { top: r2.top, left: r2.left, width: r2.width, height: r2.height },
|
|
7356
7432
|
hasTextOverlap,
|
|
7433
|
+
...video ? { videoAutoplay: video.autoplay, videoMuted: video.muted } : {},
|
|
7357
7434
|
...isDragOver ? { isDragOver: true } : {}
|
|
7358
7435
|
});
|
|
7359
7436
|
const track = imgEl.closest("[data-ohw-hover-pause]");
|
|
@@ -7361,7 +7438,7 @@ function OhhwellsBridge() {
|
|
|
7361
7438
|
};
|
|
7362
7439
|
const findImageAtPoint = (clientX, clientY, fromParentViewport) => {
|
|
7363
7440
|
const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
7364
|
-
const images = Array.from(document.querySelectorAll(
|
|
7441
|
+
const images = Array.from(document.querySelectorAll(MEDIA_SELECTOR));
|
|
7365
7442
|
const matches = [];
|
|
7366
7443
|
for (let i = images.length - 1; i >= 0; i--) {
|
|
7367
7444
|
const el = images[i];
|
|
@@ -7377,7 +7454,9 @@ function OhhwellsBridge() {
|
|
|
7377
7454
|
if (x >= r2.left && x <= r2.left + r2.width && y >= r2.top && y <= r2.top + r2.height) matches.push(el);
|
|
7378
7455
|
}
|
|
7379
7456
|
if (matches.length === 0) return null;
|
|
7380
|
-
const imageTypeMatches = matches.filter(
|
|
7457
|
+
const imageTypeMatches = matches.filter(
|
|
7458
|
+
(el) => el.dataset.ohwEditable === "image" || el.dataset.ohwEditable === "video"
|
|
7459
|
+
);
|
|
7381
7460
|
const candidatePool = imageTypeMatches.length > 0 ? imageTypeMatches : matches;
|
|
7382
7461
|
const smallest = candidatePool.reduce((best, el) => {
|
|
7383
7462
|
const br = getVisibleRect(best);
|
|
@@ -7455,7 +7534,7 @@ function OhhwellsBridge() {
|
|
|
7455
7534
|
}
|
|
7456
7535
|
const isStateCardImage = !!imgEl.closest("[data-ohw-editable-state]");
|
|
7457
7536
|
const textEditable = Array.from(
|
|
7458
|
-
document.querySelectorAll(
|
|
7537
|
+
document.querySelectorAll(NON_MEDIA_SELECTOR)
|
|
7459
7538
|
).find((el) => {
|
|
7460
7539
|
const er = el.getBoundingClientRect();
|
|
7461
7540
|
return x >= er.left && x <= er.right && y >= er.top && y <= er.bottom;
|
|
@@ -7536,7 +7615,7 @@ function OhhwellsBridge() {
|
|
|
7536
7615
|
}
|
|
7537
7616
|
const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
7538
7617
|
const textEl = Array.from(
|
|
7539
|
-
document.querySelectorAll(
|
|
7618
|
+
document.querySelectorAll(NON_MEDIA_SELECTOR)
|
|
7540
7619
|
).find((el) => {
|
|
7541
7620
|
const er = el.getBoundingClientRect();
|
|
7542
7621
|
return x >= er.left && x <= er.right && y >= er.top && y <= er.bottom;
|
|
@@ -7661,7 +7740,9 @@ function OhhwellsBridge() {
|
|
|
7661
7740
|
if (!el) return;
|
|
7662
7741
|
const file = e.dataTransfer?.files?.[0];
|
|
7663
7742
|
if (file) {
|
|
7664
|
-
|
|
7743
|
+
const wantsVideo = el.dataset.ohwEditable === "video";
|
|
7744
|
+
const accepted = wantsVideo ? file.type.startsWith("video/") : file.type.startsWith("image/");
|
|
7745
|
+
if (accepted) {
|
|
7665
7746
|
const key = el.dataset.ohwKey ?? "";
|
|
7666
7747
|
const { name, type: mimeType } = file;
|
|
7667
7748
|
const r2 = el.getBoundingClientRect();
|
|
@@ -7677,6 +7758,30 @@ function OhhwellsBridge() {
|
|
|
7677
7758
|
resumeAnimTracks();
|
|
7678
7759
|
postToParentRef.current({ type: "ow:image-unhover" });
|
|
7679
7760
|
};
|
|
7761
|
+
const handleVideoSettings = (e) => {
|
|
7762
|
+
if (e.data?.type !== "ow:video-settings") return;
|
|
7763
|
+
const { key, autoplay, muted } = e.data;
|
|
7764
|
+
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
7765
|
+
const video = getVideoEl(el);
|
|
7766
|
+
if (!video) return;
|
|
7767
|
+
if (typeof autoplay === "boolean") video.autoplay = autoplay;
|
|
7768
|
+
if (typeof muted === "boolean") video.muted = muted;
|
|
7769
|
+
syncVideoPlayback(video);
|
|
7770
|
+
postToParentRef.current({
|
|
7771
|
+
type: "ow:change",
|
|
7772
|
+
nodes: [
|
|
7773
|
+
{ key: `${key}${VIDEO_AUTOPLAY_SUFFIX}`, text: String(video.autoplay) },
|
|
7774
|
+
{ key: `${key}${VIDEO_MUTED_SUFFIX}`, text: String(video.muted) }
|
|
7775
|
+
]
|
|
7776
|
+
});
|
|
7777
|
+
postToParentRef.current({
|
|
7778
|
+
type: "ow:video-settings-applied",
|
|
7779
|
+
key,
|
|
7780
|
+
autoplay: video.autoplay,
|
|
7781
|
+
muted: video.muted
|
|
7782
|
+
});
|
|
7783
|
+
});
|
|
7784
|
+
};
|
|
7680
7785
|
const handleImageUrl = (e) => {
|
|
7681
7786
|
if (e.data?.type !== "ow:image-url") return;
|
|
7682
7787
|
const { key, url } = e.data;
|
|
@@ -7728,6 +7833,19 @@ function OhhwellsBridge() {
|
|
|
7728
7833
|
requestAnimationFrame(() => onReady());
|
|
7729
7834
|
}
|
|
7730
7835
|
}
|
|
7836
|
+
} else if (el.dataset.ohwEditable === "video") {
|
|
7837
|
+
const video = getVideoEl(el);
|
|
7838
|
+
if (video) {
|
|
7839
|
+
found = true;
|
|
7840
|
+
const onReady = () => {
|
|
7841
|
+
video.onloadeddata = null;
|
|
7842
|
+
video.onerror = null;
|
|
7843
|
+
notify();
|
|
7844
|
+
};
|
|
7845
|
+
video.onloadeddata = onReady;
|
|
7846
|
+
video.onerror = onReady;
|
|
7847
|
+
applyVideoSrc(video, url);
|
|
7848
|
+
}
|
|
7731
7849
|
}
|
|
7732
7850
|
});
|
|
7733
7851
|
if (!found) notify();
|
|
@@ -7794,12 +7912,16 @@ function OhhwellsBridge() {
|
|
|
7794
7912
|
sectionsJson = val;
|
|
7795
7913
|
continue;
|
|
7796
7914
|
}
|
|
7915
|
+
if (applyVideoSettingNode(key, val)) continue;
|
|
7797
7916
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
7798
7917
|
if (el.dataset.ohwEditable === "image") {
|
|
7799
7918
|
const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
|
|
7800
7919
|
if (img) img.src = val;
|
|
7801
7920
|
} else if (el.dataset.ohwEditable === "bg-image") {
|
|
7802
7921
|
el.style.backgroundImage = `url('${val}')`;
|
|
7922
|
+
} else if (el.dataset.ohwEditable === "video") {
|
|
7923
|
+
const video = getVideoEl(el);
|
|
7924
|
+
if (video && video.src !== val) applyVideoSrc(video, val);
|
|
7803
7925
|
} else if (el.dataset.ohwEditable === "link") {
|
|
7804
7926
|
applyLinkHref(el, val);
|
|
7805
7927
|
} else {
|
|
@@ -8060,7 +8182,7 @@ function OhhwellsBridge() {
|
|
|
8060
8182
|
if (e.data?.type !== "ow:click-at") return;
|
|
8061
8183
|
const { clientX, clientY } = e.data;
|
|
8062
8184
|
const allImages = Array.from(
|
|
8063
|
-
document.querySelectorAll(
|
|
8185
|
+
document.querySelectorAll(MEDIA_SELECTOR)
|
|
8064
8186
|
).filter((el) => !!el.closest("[data-ohw-editable-state]"));
|
|
8065
8187
|
const stateCardImage = allImages.find((el) => {
|
|
8066
8188
|
const ownerCard = el.closest("[data-ohw-editable-state]");
|
|
@@ -8079,9 +8201,7 @@ function OhhwellsBridge() {
|
|
|
8079
8201
|
return;
|
|
8080
8202
|
}
|
|
8081
8203
|
const textEditable = Array.from(
|
|
8082
|
-
document.querySelectorAll(
|
|
8083
|
-
'[data-ohw-editable]:not([data-ohw-editable="image"]):not([data-ohw-editable="bg-image"])'
|
|
8084
|
-
)
|
|
8204
|
+
document.querySelectorAll(NON_MEDIA_SELECTOR)
|
|
8085
8205
|
).find((el) => {
|
|
8086
8206
|
const r2 = el.getBoundingClientRect();
|
|
8087
8207
|
return clientX >= r2.left && clientX <= r2.right && clientY >= r2.top && clientY <= r2.bottom;
|
|
@@ -8109,6 +8229,7 @@ function OhhwellsBridge() {
|
|
|
8109
8229
|
window.addEventListener("message", handleClearSchedulingWidget);
|
|
8110
8230
|
window.addEventListener("message", handleRemoveSchedulingSection);
|
|
8111
8231
|
window.addEventListener("message", handleImageUrl);
|
|
8232
|
+
window.addEventListener("message", handleVideoSettings);
|
|
8112
8233
|
window.addEventListener("message", handleAnimLock);
|
|
8113
8234
|
window.addEventListener("message", handleCanvasHeight);
|
|
8114
8235
|
window.addEventListener("message", handleParentScroll);
|
|
@@ -8156,6 +8277,7 @@ function OhhwellsBridge() {
|
|
|
8156
8277
|
window.removeEventListener("message", handleClearSchedulingWidget);
|
|
8157
8278
|
window.removeEventListener("message", handleRemoveSchedulingSection);
|
|
8158
8279
|
window.removeEventListener("message", handleImageUrl);
|
|
8280
|
+
window.removeEventListener("message", handleVideoSettings);
|
|
8159
8281
|
window.removeEventListener("message", handleAnimLock);
|
|
8160
8282
|
window.removeEventListener("message", handleCanvasHeight);
|
|
8161
8283
|
window.removeEventListener("message", handleParentScroll);
|