@ohhwells/bridge 0.1.36-next.47 → 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 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);
@@ -6075,6 +6132,22 @@ function placeCaretAtPoint(el, x, y) {
6075
6132
  }
6076
6133
  }
6077
6134
  }
6135
+ function selectAllTextInEditable(el) {
6136
+ const selection = window.getSelection();
6137
+ if (!selection) return;
6138
+ const range = document.createRange();
6139
+ range.selectNodeContents(el);
6140
+ selection.removeAllRanges();
6141
+ selection.addRange(range);
6142
+ }
6143
+ function getNavigationLabelEditable(target) {
6144
+ const editable = target.closest('[data-ohw-editable="text"]');
6145
+ if (!editable) return null;
6146
+ const hrefCtx = getHrefKeyFromElement(editable);
6147
+ const navAnchor = hrefCtx ? getNavigationItemAnchor(hrefCtx.anchor) : null;
6148
+ if (!navAnchor) return null;
6149
+ return { editable, navAnchor };
6150
+ }
6078
6151
  function collectSections() {
6079
6152
  return collectSectionsFromDom();
6080
6153
  }
@@ -6913,6 +6986,7 @@ function OhhwellsBridge() {
6913
6986
  const imageLoads = [];
6914
6987
  for (const [key, val] of Object.entries(content)) {
6915
6988
  if (key === "__ohw_sections") continue;
6989
+ if (applyVideoSettingNode(key, val)) continue;
6916
6990
  document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
6917
6991
  if (el.dataset.ohwEditable === "image") {
6918
6992
  const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
@@ -6926,6 +7000,15 @@ function OhhwellsBridge() {
6926
7000
  } else if (el.dataset.ohwEditable === "bg-image") {
6927
7001
  const next = `url('${val}')`;
6928
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
+ }
6929
7012
  } else if (el.dataset.ohwEditable === "link") {
6930
7013
  applyLinkHref(el, val);
6931
7014
  } else if (el.innerHTML !== val) {
@@ -6974,6 +7057,7 @@ function OhhwellsBridge() {
6974
7057
  try {
6975
7058
  for (const [key, val] of Object.entries(content)) {
6976
7059
  if (key === "__ohw_sections") continue;
7060
+ if (applyVideoSettingNode(key, val)) continue;
6977
7061
  document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
6978
7062
  if (el.dataset.ohwEditable === "image") {
6979
7063
  const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
@@ -6981,6 +7065,9 @@ function OhhwellsBridge() {
6981
7065
  } else if (el.dataset.ohwEditable === "bg-image") {
6982
7066
  const next = `url('${val}')`;
6983
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);
6984
7071
  } else if (el.dataset.ohwEditable === "link") {
6985
7072
  applyLinkHref(el, val);
6986
7073
  } else if (el.innerHTML !== val) {
@@ -7084,8 +7171,9 @@ function OhhwellsBridge() {
7084
7171
  [data-ohw-editable] {
7085
7172
  display: block;
7086
7173
  }
7087
- [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; }
7088
7175
  [data-ohw-editable="image"], [data-ohw-editable="image"] *,
7176
+ [data-ohw-editable="video"], [data-ohw-editable="video"] *,
7089
7177
  [data-ohw-editable="bg-image"], [data-ohw-editable="bg-image"] * { cursor: pointer !important; }
7090
7178
  [data-ohw-editable="link"], [data-ohw-editable="link"] * { cursor: pointer !important; }
7091
7179
  [data-ohw-hovered]:not([contenteditable]):not([data-ohw-href-key]) {
@@ -7152,7 +7240,7 @@ function OhhwellsBridge() {
7152
7240
  });
7153
7241
  return;
7154
7242
  }
7155
- if (editable.dataset.ohwEditable === "image" || editable.dataset.ohwEditable === "bg-image") {
7243
+ if (isMediaEditable(editable)) {
7156
7244
  e.preventDefault();
7157
7245
  e.stopPropagation();
7158
7246
  postToParentRef.current({ type: "ow:image-pick", key: editable.dataset.ohwKey ?? "" });
@@ -7164,6 +7252,7 @@ function OhhwellsBridge() {
7164
7252
  e.preventDefault();
7165
7253
  e.stopPropagation();
7166
7254
  if (selectedElRef.current === navAnchor) {
7255
+ if (e.detail >= 2) return;
7167
7256
  activateRef.current(editable, { caretX: e.clientX, caretY: e.clientY });
7168
7257
  return;
7169
7258
  }
@@ -7217,6 +7306,28 @@ function OhhwellsBridge() {
7217
7306
  deselectRef.current();
7218
7307
  deactivateRef.current();
7219
7308
  };
7309
+ const handleDblClick = (e) => {
7310
+ const target = e.target;
7311
+ if (target.closest("[data-ohw-toolbar]")) return;
7312
+ if (target.closest("[data-ohw-state-toggle]")) return;
7313
+ if (target.closest("[data-ohw-max-badge]")) return;
7314
+ if (isInsideLinkEditor(target)) return;
7315
+ if (target.closest('[data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
7316
+ return;
7317
+ }
7318
+ const navLabel = getNavigationLabelEditable(target);
7319
+ if (!navLabel) return;
7320
+ const { editable } = navLabel;
7321
+ e.preventDefault();
7322
+ e.stopPropagation();
7323
+ if (activeElRef.current !== editable) {
7324
+ activateRef.current(editable);
7325
+ }
7326
+ requestAnimationFrame(() => {
7327
+ selectAllTextInEditable(editable);
7328
+ refreshActiveCommandsRef.current();
7329
+ });
7330
+ };
7220
7331
  const handleMouseOver = (e) => {
7221
7332
  const target = e.target;
7222
7333
  const navAnchor = getNavigationItemAnchor(target);
@@ -7232,7 +7343,7 @@ function OhhwellsBridge() {
7232
7343
  if (!editable) return;
7233
7344
  const selected = selectedElRef.current;
7234
7345
  if (selected && (selected === editable || selected.contains(editable))) return;
7235
- if (editable.dataset.ohwEditable !== "image" && editable.dataset.ohwEditable !== "bg-image" && !editable.hasAttribute("contenteditable")) {
7346
+ if (!isMediaEditable(editable) && !editable.hasAttribute("contenteditable")) {
7236
7347
  const hoverTarget = editable.closest("[data-ohw-href-key]") ?? editable;
7237
7348
  if (hoverTarget.hasAttribute("data-ohw-href-key")) {
7238
7349
  clearHrefKeyHover(hoverTarget);
@@ -7260,7 +7371,7 @@ function OhhwellsBridge() {
7260
7371
  if (!editable) return;
7261
7372
  const related = e.relatedTarget instanceof Element ? e.relatedTarget : null;
7262
7373
  if (related?.closest("[data-ohw-drag-handle-container], [data-ohw-item-interaction]")) return;
7263
- if (editable.dataset.ohwEditable !== "image" && editable.dataset.ohwEditable !== "bg-image") {
7374
+ if (!isMediaEditable(editable)) {
7264
7375
  const hoverTarget = editable.closest("[data-ohw-href-key]") ?? editable;
7265
7376
  if (hoverTarget.hasAttribute("data-ohw-href-key")) {
7266
7377
  if (!related?.closest("[data-ohw-href-key]")) {
@@ -7310,11 +7421,16 @@ function OhhwellsBridge() {
7310
7421
  const r2 = getVisibleRect(imgEl);
7311
7422
  const hasTextOverlap = forceTextOverlap ?? false;
7312
7423
  hoveredImageHasTextOverlapRef.current = hasTextOverlap;
7424
+ const video = imgEl.dataset.ohwEditable === "video" ? getVideoEl(imgEl) : null;
7313
7425
  postToParentRef.current({
7314
7426
  type: "ow:image-hover",
7315
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",
7316
7431
  rect: { top: r2.top, left: r2.left, width: r2.width, height: r2.height },
7317
7432
  hasTextOverlap,
7433
+ ...video ? { videoAutoplay: video.autoplay, videoMuted: video.muted } : {},
7318
7434
  ...isDragOver ? { isDragOver: true } : {}
7319
7435
  });
7320
7436
  const track = imgEl.closest("[data-ohw-hover-pause]");
@@ -7322,7 +7438,7 @@ function OhhwellsBridge() {
7322
7438
  };
7323
7439
  const findImageAtPoint = (clientX, clientY, fromParentViewport) => {
7324
7440
  const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
7325
- const images = Array.from(document.querySelectorAll('[data-ohw-editable="image"], [data-ohw-editable="bg-image"]'));
7441
+ const images = Array.from(document.querySelectorAll(MEDIA_SELECTOR));
7326
7442
  const matches = [];
7327
7443
  for (let i = images.length - 1; i >= 0; i--) {
7328
7444
  const el = images[i];
@@ -7338,7 +7454,9 @@ function OhhwellsBridge() {
7338
7454
  if (x >= r2.left && x <= r2.left + r2.width && y >= r2.top && y <= r2.top + r2.height) matches.push(el);
7339
7455
  }
7340
7456
  if (matches.length === 0) return null;
7341
- const imageTypeMatches = matches.filter((el) => el.dataset.ohwEditable === "image");
7457
+ const imageTypeMatches = matches.filter(
7458
+ (el) => el.dataset.ohwEditable === "image" || el.dataset.ohwEditable === "video"
7459
+ );
7342
7460
  const candidatePool = imageTypeMatches.length > 0 ? imageTypeMatches : matches;
7343
7461
  const smallest = candidatePool.reduce((best, el) => {
7344
7462
  const br = getVisibleRect(best);
@@ -7416,7 +7534,7 @@ function OhhwellsBridge() {
7416
7534
  }
7417
7535
  const isStateCardImage = !!imgEl.closest("[data-ohw-editable-state]");
7418
7536
  const textEditable = Array.from(
7419
- document.querySelectorAll('[data-ohw-editable]:not([data-ohw-editable="image"]):not([data-ohw-editable="bg-image"])')
7537
+ document.querySelectorAll(NON_MEDIA_SELECTOR)
7420
7538
  ).find((el) => {
7421
7539
  const er = el.getBoundingClientRect();
7422
7540
  return x >= er.left && x <= er.right && y >= er.top && y <= er.bottom;
@@ -7497,7 +7615,7 @@ function OhhwellsBridge() {
7497
7615
  }
7498
7616
  const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
7499
7617
  const textEl = Array.from(
7500
- document.querySelectorAll('[data-ohw-editable]:not([data-ohw-editable="image"]):not([data-ohw-editable="bg-image"])')
7618
+ document.querySelectorAll(NON_MEDIA_SELECTOR)
7501
7619
  ).find((el) => {
7502
7620
  const er = el.getBoundingClientRect();
7503
7621
  return x >= er.left && x <= er.right && y >= er.top && y <= er.bottom;
@@ -7622,7 +7740,9 @@ function OhhwellsBridge() {
7622
7740
  if (!el) return;
7623
7741
  const file = e.dataTransfer?.files?.[0];
7624
7742
  if (file) {
7625
- if (file.type.startsWith("image/")) {
7743
+ const wantsVideo = el.dataset.ohwEditable === "video";
7744
+ const accepted = wantsVideo ? file.type.startsWith("video/") : file.type.startsWith("image/");
7745
+ if (accepted) {
7626
7746
  const key = el.dataset.ohwKey ?? "";
7627
7747
  const { name, type: mimeType } = file;
7628
7748
  const r2 = el.getBoundingClientRect();
@@ -7638,6 +7758,30 @@ function OhhwellsBridge() {
7638
7758
  resumeAnimTracks();
7639
7759
  postToParentRef.current({ type: "ow:image-unhover" });
7640
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
+ };
7641
7785
  const handleImageUrl = (e) => {
7642
7786
  if (e.data?.type !== "ow:image-url") return;
7643
7787
  const { key, url } = e.data;
@@ -7689,6 +7833,19 @@ function OhhwellsBridge() {
7689
7833
  requestAnimationFrame(() => onReady());
7690
7834
  }
7691
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
+ }
7692
7849
  }
7693
7850
  });
7694
7851
  if (!found) notify();
@@ -7755,12 +7912,16 @@ function OhhwellsBridge() {
7755
7912
  sectionsJson = val;
7756
7913
  continue;
7757
7914
  }
7915
+ if (applyVideoSettingNode(key, val)) continue;
7758
7916
  document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
7759
7917
  if (el.dataset.ohwEditable === "image") {
7760
7918
  const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
7761
7919
  if (img) img.src = val;
7762
7920
  } else if (el.dataset.ohwEditable === "bg-image") {
7763
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);
7764
7925
  } else if (el.dataset.ohwEditable === "link") {
7765
7926
  applyLinkHref(el, val);
7766
7927
  } else {
@@ -7790,6 +7951,15 @@ function OhhwellsBridge() {
7790
7951
  };
7791
7952
  window.addEventListener("message", handleDeactivate);
7792
7953
  const handleKeyDown = (e) => {
7954
+ if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === "a" && activeElRef.current) {
7955
+ const navAnchor = getNavigationItemAnchor(activeElRef.current);
7956
+ if (navAnchor) {
7957
+ e.preventDefault();
7958
+ selectAllTextInEditable(activeElRef.current);
7959
+ refreshActiveCommandsRef.current();
7960
+ return;
7961
+ }
7962
+ }
7793
7963
  if (e.key === "Escape" && linkPopoverOpenRef.current) {
7794
7964
  setLinkPopoverRef.current(null);
7795
7965
  return;
@@ -8012,7 +8182,7 @@ function OhhwellsBridge() {
8012
8182
  if (e.data?.type !== "ow:click-at") return;
8013
8183
  const { clientX, clientY } = e.data;
8014
8184
  const allImages = Array.from(
8015
- document.querySelectorAll('[data-ohw-editable="image"], [data-ohw-editable="bg-image"]')
8185
+ document.querySelectorAll(MEDIA_SELECTOR)
8016
8186
  ).filter((el) => !!el.closest("[data-ohw-editable-state]"));
8017
8187
  const stateCardImage = allImages.find((el) => {
8018
8188
  const ownerCard = el.closest("[data-ohw-editable-state]");
@@ -8031,9 +8201,7 @@ function OhhwellsBridge() {
8031
8201
  return;
8032
8202
  }
8033
8203
  const textEditable = Array.from(
8034
- document.querySelectorAll(
8035
- '[data-ohw-editable]:not([data-ohw-editable="image"]):not([data-ohw-editable="bg-image"])'
8036
- )
8204
+ document.querySelectorAll(NON_MEDIA_SELECTOR)
8037
8205
  ).find((el) => {
8038
8206
  const r2 = el.getBoundingClientRect();
8039
8207
  return clientX >= r2.left && clientX <= r2.right && clientY >= r2.top && clientY <= r2.bottom;
@@ -8061,6 +8229,7 @@ function OhhwellsBridge() {
8061
8229
  window.addEventListener("message", handleClearSchedulingWidget);
8062
8230
  window.addEventListener("message", handleRemoveSchedulingSection);
8063
8231
  window.addEventListener("message", handleImageUrl);
8232
+ window.addEventListener("message", handleVideoSettings);
8064
8233
  window.addEventListener("message", handleAnimLock);
8065
8234
  window.addEventListener("message", handleCanvasHeight);
8066
8235
  window.addEventListener("message", handleParentScroll);
@@ -8073,6 +8242,7 @@ function OhhwellsBridge() {
8073
8242
  };
8074
8243
  window.addEventListener("resize", handleViewportResize, { passive: true });
8075
8244
  document.addEventListener("click", handleClick, true);
8245
+ document.addEventListener("dblclick", handleDblClick, true);
8076
8246
  document.addEventListener("paste", handlePaste, true);
8077
8247
  document.addEventListener("input", handleInput, true);
8078
8248
  document.addEventListener("mouseover", handleMouseOver, true);
@@ -8087,6 +8257,7 @@ function OhhwellsBridge() {
8087
8257
  window.addEventListener("scroll", handleScroll, true);
8088
8258
  return () => {
8089
8259
  document.removeEventListener("click", handleClick, true);
8260
+ document.removeEventListener("dblclick", handleDblClick, true);
8090
8261
  document.removeEventListener("paste", handlePaste, true);
8091
8262
  document.removeEventListener("input", handleInput, true);
8092
8263
  document.removeEventListener("mouseover", handleMouseOver, true);
@@ -8106,6 +8277,7 @@ function OhhwellsBridge() {
8106
8277
  window.removeEventListener("message", handleClearSchedulingWidget);
8107
8278
  window.removeEventListener("message", handleRemoveSchedulingSection);
8108
8279
  window.removeEventListener("message", handleImageUrl);
8280
+ window.removeEventListener("message", handleVideoSettings);
8109
8281
  window.removeEventListener("message", handleAnimLock);
8110
8282
  window.removeEventListener("message", handleCanvasHeight);
8111
8283
  window.removeEventListener("message", handleParentScroll);