@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.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);
@@ -6016,6 +6073,22 @@ function placeCaretAtPoint(el, x, y) {
6016
6073
  }
6017
6074
  }
6018
6075
  }
6076
+ function selectAllTextInEditable(el) {
6077
+ const selection = window.getSelection();
6078
+ if (!selection) return;
6079
+ const range = document.createRange();
6080
+ range.selectNodeContents(el);
6081
+ selection.removeAllRanges();
6082
+ selection.addRange(range);
6083
+ }
6084
+ function getNavigationLabelEditable(target) {
6085
+ const editable = target.closest('[data-ohw-editable="text"]');
6086
+ if (!editable) return null;
6087
+ const hrefCtx = getHrefKeyFromElement(editable);
6088
+ const navAnchor = hrefCtx ? getNavigationItemAnchor(hrefCtx.anchor) : null;
6089
+ if (!navAnchor) return null;
6090
+ return { editable, navAnchor };
6091
+ }
6019
6092
  function collectSections() {
6020
6093
  return collectSectionsFromDom();
6021
6094
  }
@@ -6854,6 +6927,7 @@ function OhhwellsBridge() {
6854
6927
  const imageLoads = [];
6855
6928
  for (const [key, val] of Object.entries(content)) {
6856
6929
  if (key === "__ohw_sections") continue;
6930
+ if (applyVideoSettingNode(key, val)) continue;
6857
6931
  document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
6858
6932
  if (el.dataset.ohwEditable === "image") {
6859
6933
  const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
@@ -6867,6 +6941,15 @@ function OhhwellsBridge() {
6867
6941
  } else if (el.dataset.ohwEditable === "bg-image") {
6868
6942
  const next = `url('${val}')`;
6869
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
+ }
6870
6953
  } else if (el.dataset.ohwEditable === "link") {
6871
6954
  applyLinkHref(el, val);
6872
6955
  } else if (el.innerHTML !== val) {
@@ -6915,6 +6998,7 @@ function OhhwellsBridge() {
6915
6998
  try {
6916
6999
  for (const [key, val] of Object.entries(content)) {
6917
7000
  if (key === "__ohw_sections") continue;
7001
+ if (applyVideoSettingNode(key, val)) continue;
6918
7002
  document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
6919
7003
  if (el.dataset.ohwEditable === "image") {
6920
7004
  const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
@@ -6922,6 +7006,9 @@ function OhhwellsBridge() {
6922
7006
  } else if (el.dataset.ohwEditable === "bg-image") {
6923
7007
  const next = `url('${val}')`;
6924
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);
6925
7012
  } else if (el.dataset.ohwEditable === "link") {
6926
7013
  applyLinkHref(el, val);
6927
7014
  } else if (el.innerHTML !== val) {
@@ -7025,8 +7112,9 @@ function OhhwellsBridge() {
7025
7112
  [data-ohw-editable] {
7026
7113
  display: block;
7027
7114
  }
7028
- [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; }
7029
7116
  [data-ohw-editable="image"], [data-ohw-editable="image"] *,
7117
+ [data-ohw-editable="video"], [data-ohw-editable="video"] *,
7030
7118
  [data-ohw-editable="bg-image"], [data-ohw-editable="bg-image"] * { cursor: pointer !important; }
7031
7119
  [data-ohw-editable="link"], [data-ohw-editable="link"] * { cursor: pointer !important; }
7032
7120
  [data-ohw-hovered]:not([contenteditable]):not([data-ohw-href-key]) {
@@ -7093,7 +7181,7 @@ function OhhwellsBridge() {
7093
7181
  });
7094
7182
  return;
7095
7183
  }
7096
- if (editable.dataset.ohwEditable === "image" || editable.dataset.ohwEditable === "bg-image") {
7184
+ if (isMediaEditable(editable)) {
7097
7185
  e.preventDefault();
7098
7186
  e.stopPropagation();
7099
7187
  postToParentRef.current({ type: "ow:image-pick", key: editable.dataset.ohwKey ?? "" });
@@ -7105,6 +7193,7 @@ function OhhwellsBridge() {
7105
7193
  e.preventDefault();
7106
7194
  e.stopPropagation();
7107
7195
  if (selectedElRef.current === navAnchor) {
7196
+ if (e.detail >= 2) return;
7108
7197
  activateRef.current(editable, { caretX: e.clientX, caretY: e.clientY });
7109
7198
  return;
7110
7199
  }
@@ -7158,6 +7247,28 @@ function OhhwellsBridge() {
7158
7247
  deselectRef.current();
7159
7248
  deactivateRef.current();
7160
7249
  };
7250
+ const handleDblClick = (e) => {
7251
+ const target = e.target;
7252
+ if (target.closest("[data-ohw-toolbar]")) return;
7253
+ if (target.closest("[data-ohw-state-toggle]")) return;
7254
+ if (target.closest("[data-ohw-max-badge]")) return;
7255
+ if (isInsideLinkEditor(target)) return;
7256
+ if (target.closest('[data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
7257
+ return;
7258
+ }
7259
+ const navLabel = getNavigationLabelEditable(target);
7260
+ if (!navLabel) return;
7261
+ const { editable } = navLabel;
7262
+ e.preventDefault();
7263
+ e.stopPropagation();
7264
+ if (activeElRef.current !== editable) {
7265
+ activateRef.current(editable);
7266
+ }
7267
+ requestAnimationFrame(() => {
7268
+ selectAllTextInEditable(editable);
7269
+ refreshActiveCommandsRef.current();
7270
+ });
7271
+ };
7161
7272
  const handleMouseOver = (e) => {
7162
7273
  const target = e.target;
7163
7274
  const navAnchor = getNavigationItemAnchor(target);
@@ -7173,7 +7284,7 @@ function OhhwellsBridge() {
7173
7284
  if (!editable) return;
7174
7285
  const selected = selectedElRef.current;
7175
7286
  if (selected && (selected === editable || selected.contains(editable))) return;
7176
- if (editable.dataset.ohwEditable !== "image" && editable.dataset.ohwEditable !== "bg-image" && !editable.hasAttribute("contenteditable")) {
7287
+ if (!isMediaEditable(editable) && !editable.hasAttribute("contenteditable")) {
7177
7288
  const hoverTarget = editable.closest("[data-ohw-href-key]") ?? editable;
7178
7289
  if (hoverTarget.hasAttribute("data-ohw-href-key")) {
7179
7290
  clearHrefKeyHover(hoverTarget);
@@ -7201,7 +7312,7 @@ function OhhwellsBridge() {
7201
7312
  if (!editable) return;
7202
7313
  const related = e.relatedTarget instanceof Element ? e.relatedTarget : null;
7203
7314
  if (related?.closest("[data-ohw-drag-handle-container], [data-ohw-item-interaction]")) return;
7204
- if (editable.dataset.ohwEditable !== "image" && editable.dataset.ohwEditable !== "bg-image") {
7315
+ if (!isMediaEditable(editable)) {
7205
7316
  const hoverTarget = editable.closest("[data-ohw-href-key]") ?? editable;
7206
7317
  if (hoverTarget.hasAttribute("data-ohw-href-key")) {
7207
7318
  if (!related?.closest("[data-ohw-href-key]")) {
@@ -7251,11 +7362,16 @@ function OhhwellsBridge() {
7251
7362
  const r2 = getVisibleRect(imgEl);
7252
7363
  const hasTextOverlap = forceTextOverlap ?? false;
7253
7364
  hoveredImageHasTextOverlapRef.current = hasTextOverlap;
7365
+ const video = imgEl.dataset.ohwEditable === "video" ? getVideoEl(imgEl) : null;
7254
7366
  postToParentRef.current({
7255
7367
  type: "ow:image-hover",
7256
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",
7257
7372
  rect: { top: r2.top, left: r2.left, width: r2.width, height: r2.height },
7258
7373
  hasTextOverlap,
7374
+ ...video ? { videoAutoplay: video.autoplay, videoMuted: video.muted } : {},
7259
7375
  ...isDragOver ? { isDragOver: true } : {}
7260
7376
  });
7261
7377
  const track = imgEl.closest("[data-ohw-hover-pause]");
@@ -7263,7 +7379,7 @@ function OhhwellsBridge() {
7263
7379
  };
7264
7380
  const findImageAtPoint = (clientX, clientY, fromParentViewport) => {
7265
7381
  const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
7266
- const images = Array.from(document.querySelectorAll('[data-ohw-editable="image"], [data-ohw-editable="bg-image"]'));
7382
+ const images = Array.from(document.querySelectorAll(MEDIA_SELECTOR));
7267
7383
  const matches = [];
7268
7384
  for (let i = images.length - 1; i >= 0; i--) {
7269
7385
  const el = images[i];
@@ -7279,7 +7395,9 @@ function OhhwellsBridge() {
7279
7395
  if (x >= r2.left && x <= r2.left + r2.width && y >= r2.top && y <= r2.top + r2.height) matches.push(el);
7280
7396
  }
7281
7397
  if (matches.length === 0) return null;
7282
- const imageTypeMatches = matches.filter((el) => el.dataset.ohwEditable === "image");
7398
+ const imageTypeMatches = matches.filter(
7399
+ (el) => el.dataset.ohwEditable === "image" || el.dataset.ohwEditable === "video"
7400
+ );
7283
7401
  const candidatePool = imageTypeMatches.length > 0 ? imageTypeMatches : matches;
7284
7402
  const smallest = candidatePool.reduce((best, el) => {
7285
7403
  const br = getVisibleRect(best);
@@ -7357,7 +7475,7 @@ function OhhwellsBridge() {
7357
7475
  }
7358
7476
  const isStateCardImage = !!imgEl.closest("[data-ohw-editable-state]");
7359
7477
  const textEditable = Array.from(
7360
- document.querySelectorAll('[data-ohw-editable]:not([data-ohw-editable="image"]):not([data-ohw-editable="bg-image"])')
7478
+ document.querySelectorAll(NON_MEDIA_SELECTOR)
7361
7479
  ).find((el) => {
7362
7480
  const er = el.getBoundingClientRect();
7363
7481
  return x >= er.left && x <= er.right && y >= er.top && y <= er.bottom;
@@ -7438,7 +7556,7 @@ function OhhwellsBridge() {
7438
7556
  }
7439
7557
  const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
7440
7558
  const textEl = Array.from(
7441
- document.querySelectorAll('[data-ohw-editable]:not([data-ohw-editable="image"]):not([data-ohw-editable="bg-image"])')
7559
+ document.querySelectorAll(NON_MEDIA_SELECTOR)
7442
7560
  ).find((el) => {
7443
7561
  const er = el.getBoundingClientRect();
7444
7562
  return x >= er.left && x <= er.right && y >= er.top && y <= er.bottom;
@@ -7563,7 +7681,9 @@ function OhhwellsBridge() {
7563
7681
  if (!el) return;
7564
7682
  const file = e.dataTransfer?.files?.[0];
7565
7683
  if (file) {
7566
- if (file.type.startsWith("image/")) {
7684
+ const wantsVideo = el.dataset.ohwEditable === "video";
7685
+ const accepted = wantsVideo ? file.type.startsWith("video/") : file.type.startsWith("image/");
7686
+ if (accepted) {
7567
7687
  const key = el.dataset.ohwKey ?? "";
7568
7688
  const { name, type: mimeType } = file;
7569
7689
  const r2 = el.getBoundingClientRect();
@@ -7579,6 +7699,30 @@ function OhhwellsBridge() {
7579
7699
  resumeAnimTracks();
7580
7700
  postToParentRef.current({ type: "ow:image-unhover" });
7581
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
+ };
7582
7726
  const handleImageUrl = (e) => {
7583
7727
  if (e.data?.type !== "ow:image-url") return;
7584
7728
  const { key, url } = e.data;
@@ -7630,6 +7774,19 @@ function OhhwellsBridge() {
7630
7774
  requestAnimationFrame(() => onReady());
7631
7775
  }
7632
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
+ }
7633
7790
  }
7634
7791
  });
7635
7792
  if (!found) notify();
@@ -7696,12 +7853,16 @@ function OhhwellsBridge() {
7696
7853
  sectionsJson = val;
7697
7854
  continue;
7698
7855
  }
7856
+ if (applyVideoSettingNode(key, val)) continue;
7699
7857
  document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
7700
7858
  if (el.dataset.ohwEditable === "image") {
7701
7859
  const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
7702
7860
  if (img) img.src = val;
7703
7861
  } else if (el.dataset.ohwEditable === "bg-image") {
7704
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);
7705
7866
  } else if (el.dataset.ohwEditable === "link") {
7706
7867
  applyLinkHref(el, val);
7707
7868
  } else {
@@ -7731,6 +7892,15 @@ function OhhwellsBridge() {
7731
7892
  };
7732
7893
  window.addEventListener("message", handleDeactivate);
7733
7894
  const handleKeyDown = (e) => {
7895
+ if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === "a" && activeElRef.current) {
7896
+ const navAnchor = getNavigationItemAnchor(activeElRef.current);
7897
+ if (navAnchor) {
7898
+ e.preventDefault();
7899
+ selectAllTextInEditable(activeElRef.current);
7900
+ refreshActiveCommandsRef.current();
7901
+ return;
7902
+ }
7903
+ }
7734
7904
  if (e.key === "Escape" && linkPopoverOpenRef.current) {
7735
7905
  setLinkPopoverRef.current(null);
7736
7906
  return;
@@ -7953,7 +8123,7 @@ function OhhwellsBridge() {
7953
8123
  if (e.data?.type !== "ow:click-at") return;
7954
8124
  const { clientX, clientY } = e.data;
7955
8125
  const allImages = Array.from(
7956
- document.querySelectorAll('[data-ohw-editable="image"], [data-ohw-editable="bg-image"]')
8126
+ document.querySelectorAll(MEDIA_SELECTOR)
7957
8127
  ).filter((el) => !!el.closest("[data-ohw-editable-state]"));
7958
8128
  const stateCardImage = allImages.find((el) => {
7959
8129
  const ownerCard = el.closest("[data-ohw-editable-state]");
@@ -7972,9 +8142,7 @@ function OhhwellsBridge() {
7972
8142
  return;
7973
8143
  }
7974
8144
  const textEditable = Array.from(
7975
- document.querySelectorAll(
7976
- '[data-ohw-editable]:not([data-ohw-editable="image"]):not([data-ohw-editable="bg-image"])'
7977
- )
8145
+ document.querySelectorAll(NON_MEDIA_SELECTOR)
7978
8146
  ).find((el) => {
7979
8147
  const r2 = el.getBoundingClientRect();
7980
8148
  return clientX >= r2.left && clientX <= r2.right && clientY >= r2.top && clientY <= r2.bottom;
@@ -8002,6 +8170,7 @@ function OhhwellsBridge() {
8002
8170
  window.addEventListener("message", handleClearSchedulingWidget);
8003
8171
  window.addEventListener("message", handleRemoveSchedulingSection);
8004
8172
  window.addEventListener("message", handleImageUrl);
8173
+ window.addEventListener("message", handleVideoSettings);
8005
8174
  window.addEventListener("message", handleAnimLock);
8006
8175
  window.addEventListener("message", handleCanvasHeight);
8007
8176
  window.addEventListener("message", handleParentScroll);
@@ -8014,6 +8183,7 @@ function OhhwellsBridge() {
8014
8183
  };
8015
8184
  window.addEventListener("resize", handleViewportResize, { passive: true });
8016
8185
  document.addEventListener("click", handleClick, true);
8186
+ document.addEventListener("dblclick", handleDblClick, true);
8017
8187
  document.addEventListener("paste", handlePaste, true);
8018
8188
  document.addEventListener("input", handleInput, true);
8019
8189
  document.addEventListener("mouseover", handleMouseOver, true);
@@ -8028,6 +8198,7 @@ function OhhwellsBridge() {
8028
8198
  window.addEventListener("scroll", handleScroll, true);
8029
8199
  return () => {
8030
8200
  document.removeEventListener("click", handleClick, true);
8201
+ document.removeEventListener("dblclick", handleDblClick, true);
8031
8202
  document.removeEventListener("paste", handlePaste, true);
8032
8203
  document.removeEventListener("input", handleInput, true);
8033
8204
  document.removeEventListener("mouseover", handleMouseOver, true);
@@ -8047,6 +8218,7 @@ function OhhwellsBridge() {
8047
8218
  window.removeEventListener("message", handleClearSchedulingWidget);
8048
8219
  window.removeEventListener("message", handleRemoveSchedulingSection);
8049
8220
  window.removeEventListener("message", handleImageUrl);
8221
+ window.removeEventListener("message", handleVideoSettings);
8050
8222
  window.removeEventListener("message", handleAnimLock);
8051
8223
  window.removeEventListener("message", handleCanvasHeight);
8052
8224
  window.removeEventListener("message", handleParentScroll);