@mochabug/adapt-web 1.0.1-rc.4 → 1.0.1-rc.6

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/esm/index.js CHANGED
@@ -681,6 +681,9 @@ export class AdaptWebClient {
681
681
  this.resizeObserver = null;
682
682
  this.messageHandler = null;
683
683
  this.backdropClickHandler = null;
684
+ // Per-iframe resize capability tracking (set when plugin sends adapt-init)
685
+ this.mainResizeCapable = false;
686
+ this.forkResizeCapable = false;
684
687
  this.destroyed = false;
685
688
  this.lastForkActive = null;
686
689
  // Status message element (stopped / error)
@@ -782,35 +785,82 @@ export class AdaptWebClient {
782
785
  if (!this.isValidMessageOrigin(event.origin))
783
786
  return;
784
787
  const data = event.data;
785
- if (!data || typeof data !== "object" || data.type !== "adapt-resize")
788
+ if (!data || typeof data !== "object")
786
789
  return;
787
- const { height } = data;
788
- if (typeof height !== "number" || !Number.isFinite(height) || height < 1)
789
- return;
790
- // Identify which iframe sent the message via source window
791
790
  const source = event.source;
792
- if (this.mainIframe?.contentWindow === source) {
793
- if (this.autoResizing) {
794
- this.mainIframe.style.height = `${height}px`;
791
+ // Handle adapt-init: plugin declaring its capabilities
792
+ if (data.type === "adapt-init" && typeof data.resize === "boolean") {
793
+ const isMain = this.mainIframe?.contentWindow === source;
794
+ const isFork = this.forkIframe?.contentWindow === source;
795
+ if (isMain) {
796
+ this.mainResizeCapable = data.resize;
797
+ if (!data.resize && this.mainIframe) {
798
+ this.mainIframe.style.height = "";
799
+ }
800
+ }
801
+ else if (isFork) {
802
+ this.forkResizeCapable = data.resize;
803
+ if (!data.resize && this.forkIframe) {
804
+ this.forkIframe.style.height = "";
805
+ // Reset dialog height too
806
+ if (this.dialogElement) {
807
+ this.dialogElement.style.height = "";
808
+ }
809
+ }
810
+ }
811
+ // Respond with adapt-autoResizing if parent supports resize AND plugin wants it
812
+ if (isMain || isFork) {
813
+ const iframe = isMain ? this.mainIframe : this.forkIframe;
814
+ const iframeSrc = iframe.src;
815
+ const targetOrigin = iframeSrc ? this.getOrigin(iframeSrc) : null;
816
+ if (targetOrigin) {
817
+ // For fork iframe in dialog mode with resizeToContent, always enable
818
+ let effective = this.autoResizing && data.resize;
819
+ if (isFork &&
820
+ data.resize &&
821
+ this.forkDisplay.mode === "dialog" &&
822
+ this.forkDisplay.resizeToContent) {
823
+ effective = true;
824
+ }
825
+ try {
826
+ iframe.contentWindow?.postMessage({ type: "adapt-autoResizing", autoResizing: effective }, targetOrigin);
827
+ iframe.contentWindow?.postMessage({ type: "adapt-darkMode", darkMode: this.darkMode }, targetOrigin);
828
+ }
829
+ catch { }
830
+ }
795
831
  }
832
+ return;
796
833
  }
797
- else if (this.forkIframe?.contentWindow === source) {
798
- if (this.autoResizing) {
799
- this.forkIframe.style.height = `${height}px`;
834
+ // Handle adapt-resize: only apply if iframe declared resize capability
835
+ if (data.type === "adapt-resize") {
836
+ const { height } = data;
837
+ if (typeof height !== "number" || !Number.isFinite(height) || height < 1)
838
+ return;
839
+ if (this.mainIframe?.contentWindow === source) {
840
+ if (this.mainResizeCapable && this.autoResizing) {
841
+ this.mainIframe.style.height = `${height}px`;
842
+ }
800
843
  }
801
- // Dialog resize-to-content: resize the dialog element to match fork content
802
- // Skip on narrow viewports where dialog is fullscreen via CSS
803
- if (this.forkDisplay.mode === "dialog" &&
804
- this.forkDisplay.resizeToContent &&
805
- this.dialogElement &&
806
- window.innerWidth > AdaptWebClient.DIALOG_FULLSCREEN_BREAKPOINT) {
807
- const toolbarHeight = this.forkToolbarElement?.offsetHeight ?? 36;
808
- const padding = 24; // 12px padding top + bottom in iframeContainer
809
- const border = 2; // 1px border top + bottom on dialog
810
- const totalHeight = Math.ceil(height) + toolbarHeight + padding + border;
811
- // Clamp between min-height (300px) and 90vh
812
- this.dialogElement.style.height = `clamp(300px, ${totalHeight}px, 90vh)`;
844
+ else if (this.forkIframe?.contentWindow === source) {
845
+ if (this.forkResizeCapable && this.autoResizing) {
846
+ this.forkIframe.style.height = `${height}px`;
847
+ }
848
+ // Dialog resize-to-content: resize the dialog element to match fork content
849
+ // Skip on narrow viewports where dialog is fullscreen via CSS
850
+ if (this.forkResizeCapable &&
851
+ this.forkDisplay.mode === "dialog" &&
852
+ this.forkDisplay.resizeToContent &&
853
+ this.dialogElement &&
854
+ window.innerWidth > AdaptWebClient.DIALOG_FULLSCREEN_BREAKPOINT) {
855
+ const toolbarHeight = this.forkToolbarElement?.offsetHeight ?? 36;
856
+ const padding = 24; // 12px padding top + bottom in iframeContainer
857
+ const border = 2; // 1px border top + bottom on dialog
858
+ const totalHeight = Math.ceil(height) + toolbarHeight + padding + border;
859
+ // Clamp between min-height (300px) and 90vh
860
+ this.dialogElement.style.height = `clamp(300px, ${totalHeight}px, 90vh)`;
861
+ }
813
862
  }
863
+ return;
814
864
  }
815
865
  };
816
866
  window.addEventListener("message", this.messageHandler);
@@ -835,41 +885,11 @@ export class AdaptWebClient {
835
885
  // Silently ignore errors - iframe may not be ready or cross-origin issues
836
886
  }
837
887
  }
838
- sendAutoResizingToIframe(iframe) {
888
+ sendAutoResizingMessageToIframe(iframe, enabled) {
839
889
  if (!iframe)
840
890
  return;
841
891
  const iframeSrc = iframe.src;
842
892
  const targetOrigin = iframeSrc ? this.getOrigin(iframeSrc) : null;
843
- if (!targetOrigin)
844
- return;
845
- // For the fork iframe in dialog mode with resizeToContent,
846
- // tell the iframe to report heights even if global autoResizing is off
847
- let effective = this.autoResizing;
848
- if (iframe === this.forkIframe &&
849
- this.forkDisplay.mode === "dialog" &&
850
- this.forkDisplay.resizeToContent) {
851
- effective = true;
852
- }
853
- const message = {
854
- type: "adapt-autoResizing",
855
- autoResizing: effective,
856
- };
857
- try {
858
- iframe.contentWindow?.postMessage(message, targetOrigin);
859
- }
860
- catch {
861
- // Silently ignore errors
862
- }
863
- }
864
- /**
865
- * Send autoResizing state specifically to the fork iframe.
866
- * Used by setDialogResizeToContent to toggle height reporting independently.
867
- */
868
- sendAutoResizingToForkIframe(enabled) {
869
- if (!this.forkIframe)
870
- return;
871
- const iframeSrc = this.forkIframe.src;
872
- const targetOrigin = iframeSrc ? this.getOrigin(iframeSrc) : null;
873
893
  if (!targetOrigin)
874
894
  return;
875
895
  const message = {
@@ -877,7 +897,7 @@ export class AdaptWebClient {
877
897
  autoResizing: enabled,
878
898
  };
879
899
  try {
880
- this.forkIframe.contentWindow?.postMessage(message, targetOrigin);
900
+ iframe.contentWindow?.postMessage(message, targetOrigin);
881
901
  }
882
902
  catch {
883
903
  // Silently ignore errors
@@ -912,9 +932,13 @@ export class AdaptWebClient {
912
932
  if (this.autoResizing === autoResizing)
913
933
  return;
914
934
  this.autoResizing = autoResizing;
915
- // Notify iframes of the change so they can send their current height
916
- this.sendAutoResizingToIframe(this.mainIframe);
917
- this.sendAutoResizingToIframe(this.forkIframe);
935
+ // Notify resize-capable iframes of the change so they can send their current height
936
+ if (this.mainResizeCapable) {
937
+ this.sendAutoResizingMessageToIframe(this.mainIframe, autoResizing);
938
+ }
939
+ if (this.forkResizeCapable) {
940
+ this.sendAutoResizingMessageToIframe(this.forkIframe, autoResizing);
941
+ }
918
942
  // If disabling, reset iframe heights to CSS default
919
943
  if (!autoResizing) {
920
944
  if (this.mainIframe)
@@ -985,10 +1009,14 @@ export class AdaptWebClient {
985
1009
  if (this.currentFork && this.forkIframe) {
986
1010
  this.showIframe(this.forkIframe);
987
1011
  }
988
- // Re-send auto-resize state so iframes report their height again
1012
+ // Re-send auto-resize state so resize-capable iframes report their height again
989
1013
  if (this.autoResizing) {
990
- this.sendAutoResizingToIframe(this.mainIframe);
991
- this.sendAutoResizingToIframe(this.forkIframe);
1014
+ if (this.mainResizeCapable) {
1015
+ this.sendAutoResizingMessageToIframe(this.mainIframe, true);
1016
+ }
1017
+ if (this.forkResizeCapable) {
1018
+ this.sendAutoResizingMessageToIframe(this.forkIframe, true);
1019
+ }
992
1020
  }
993
1021
  // If switching to side-by-side and there are queued forks but no current fork, activate one
994
1022
  // This handles the case where user closed dialog without fulfilling fork, then switched modes
@@ -1033,18 +1061,18 @@ export class AdaptWebClient {
1033
1061
  if (this.forkDisplay.resizeToContent === enabled)
1034
1062
  return;
1035
1063
  this.forkDisplay = { ...this.forkDisplay, resizeToContent: enabled };
1036
- // Send autoResizing to fork iframe so it reports height
1037
- if (enabled) {
1038
- this.sendAutoResizingToForkIframe(true);
1064
+ // Send autoResizing to fork iframe so it reports height (only if resize-capable)
1065
+ if (enabled && this.forkResizeCapable) {
1066
+ this.sendAutoResizingMessageToIframe(this.forkIframe, true);
1039
1067
  }
1040
- else {
1068
+ else if (!enabled) {
1041
1069
  // Clear any custom dialog height
1042
1070
  if (this.dialogElement) {
1043
1071
  this.dialogElement.style.height = "";
1044
1072
  }
1045
1073
  // If global autoResizing is off, tell fork to stop reporting
1046
- if (!this.autoResizing) {
1047
- this.sendAutoResizingToForkIframe(false);
1074
+ if (!this.autoResizing && this.forkResizeCapable) {
1075
+ this.sendAutoResizingMessageToIframe(this.forkIframe, false);
1048
1076
  }
1049
1077
  }
1050
1078
  }
@@ -1340,23 +1368,23 @@ export class AdaptWebClient {
1340
1368
  ttl: opts.ttl,
1341
1369
  mainUrl: this.mainUrl,
1342
1370
  mainToken: this.mainToken,
1343
- currentFork: this.currentFork
1371
+ currentFork: this.currentFork && !this.currentFork.completed
1344
1372
  ? {
1345
1373
  url: this.currentFork.url,
1346
1374
  token: this.currentFork.token,
1347
1375
  fork: this.currentFork.fork,
1348
1376
  depth: this.currentFork.depth,
1349
1377
  time: this.currentFork.time,
1350
- completed: this.currentFork.completed,
1351
1378
  }
1352
1379
  : null,
1353
- forkQueue: this.forkQueue.map((f) => ({
1380
+ forkQueue: this.forkQueue
1381
+ .filter((f) => !f.completed)
1382
+ .map((f) => ({
1354
1383
  url: f.url,
1355
1384
  token: f.token,
1356
1385
  fork: f.fork,
1357
1386
  depth: f.depth,
1358
1387
  time: f.time,
1359
- completed: f.completed,
1360
1388
  })),
1361
1389
  forkDisplayMode: this.forkDisplay.mode,
1362
1390
  splitPercentage: this.splitPercentage,
@@ -1418,8 +1446,8 @@ export class AdaptWebClient {
1418
1446
  : undefined;
1419
1447
  this.mainUrl = state.mainUrl;
1420
1448
  this.mainToken = state.mainToken;
1421
- this.forkQueue = state.forkQueue;
1422
- this.currentFork = state.currentFork;
1449
+ this.forkQueue = state.forkQueue.filter((f) => !f.completed);
1450
+ this.currentFork = state.currentFork?.completed ? null : state.currentFork;
1423
1451
  // Restore UI state if fork display mode is consistent with current options
1424
1452
  if (state.forkDisplayMode === this.forkDisplay.mode) {
1425
1453
  if (this.forkDisplay.mode === "side-by-side") {
@@ -1813,6 +1841,8 @@ export class AdaptWebClient {
1813
1841
  // Update iframe src if changed
1814
1842
  const newSrc = getIframeSrc(this.mainUrl, this.mainToken);
1815
1843
  if (this.mainIframe.src !== newSrc) {
1844
+ this.mainResizeCapable = false;
1845
+ this.mainIframe.style.height = "";
1816
1846
  this.mainIframe.src = newSrc;
1817
1847
  }
1818
1848
  // Show the iframe with fade-in
@@ -1826,6 +1856,11 @@ export class AdaptWebClient {
1826
1856
  if (!this.currentFork || !this.forkIframe)
1827
1857
  return;
1828
1858
  const newSrc = getIframeSrc(this.currentFork.url, this.currentFork.token);
1859
+ // Reset resize tracking for new fork content
1860
+ this.forkResizeCapable = false;
1861
+ if (this.dialogElement) {
1862
+ this.dialogElement.style.height = "";
1863
+ }
1829
1864
  // Replace iframe to force a fresh load — browsers don't reload when only
1830
1865
  // the hash fragment changes (same plugin URL, different fork token).
1831
1866
  const parent = this.forkIframe.parentElement;
@@ -2219,15 +2254,15 @@ export class AdaptWebClient {
2219
2254
  const iframe = document.createElement("iframe");
2220
2255
  iframe.className = this.options.classNames?.iframe || "mb-adapt__iframe";
2221
2256
  iframe.setAttribute("sandbox", "allow-downloads allow-same-origin allow-scripts allow-popups allow-popups-to-escape-sandbox allow-forms allow-modals");
2222
- iframe.setAttribute("allow", "geolocation; camera; microphone; fullscreen; display-capture; web-share");
2257
+ iframe.setAttribute("allow", "autoplay; geolocation; camera; microphone; fullscreen; display-capture; web-share");
2223
2258
  // Preload with blank page to initialize iframe and warm up browser resources
2224
2259
  iframe.src = "about:blank";
2225
- // Send state to iframe whenever it loads (handles src changes)
2260
+ // Send dark mode to iframe whenever it loads (handles src changes)
2261
+ // Don't send adapt-autoResizing here — wait for the plugin's adapt-init
2226
2262
  iframe.addEventListener("load", () => {
2227
2263
  // Only send messages to real URLs, not about:blank
2228
2264
  if (iframe.src && iframe.src !== "about:blank") {
2229
2265
  this.sendDarkModeToIframe(iframe);
2230
- this.sendAutoResizingToIframe(iframe);
2231
2266
  }
2232
2267
  });
2233
2268
  return iframe;
@@ -27,6 +27,10 @@ export interface AdaptAutoResizingMessage {
27
27
  type: "adapt-autoResizing";
28
28
  autoResizing: boolean;
29
29
  }
30
+ export interface AdaptInitMessage {
31
+ type: "adapt-init";
32
+ resize: boolean;
33
+ }
30
34
  /**
31
35
  * Clear persisted session state for a given automation ID.
32
36
  * Use this to force a fresh session on next page load.
@@ -76,6 +80,8 @@ export declare class AdaptWebClient {
76
80
  private resizeObserver;
77
81
  private messageHandler;
78
82
  private backdropClickHandler;
83
+ private mainResizeCapable;
84
+ private forkResizeCapable;
79
85
  private darkMode;
80
86
  private autoResizing;
81
87
  private forkDisplay;
@@ -91,12 +97,7 @@ export declare class AdaptWebClient {
91
97
  private isValidMessageOrigin;
92
98
  private setupMessageListener;
93
99
  private sendDarkModeToIframe;
94
- private sendAutoResizingToIframe;
95
- /**
96
- * Send autoResizing state specifically to the fork iframe.
97
- * Used by setDialogResizeToContent to toggle height reporting independently.
98
- */
99
- private sendAutoResizingToForkIframe;
100
+ private sendAutoResizingMessageToIframe;
100
101
  /**
101
102
  * Set dark mode state and notify all iframes.
102
103
  */
@@ -7518,7 +7518,7 @@ var MbAdapt = (() => {
7518
7518
  // src/index.ts
7519
7519
  if (typeof window !== "undefined" && true && !window.CAP_CUSTOM_WASM_URL) {
7520
7520
  window.CAP_CUSTOM_WASM_URL = new URL(
7521
- "https://cdn.mochabug.com/adapt/web/1.0.1-rc.4/cap_wasm.js",
7521
+ "https://cdn.mochabug.com/adapt/web/1.0.1-rc.6/cap_wasm.js",
7522
7522
  window.location.href
7523
7523
  ).href;
7524
7524
  }
@@ -8167,6 +8167,9 @@ cap-widget::part(attribution) {
8167
8167
  this.resizeObserver = null;
8168
8168
  this.messageHandler = null;
8169
8169
  this.backdropClickHandler = null;
8170
+ // Per-iframe resize capability tracking (set when plugin sends adapt-init)
8171
+ this.mainResizeCapable = false;
8172
+ this.forkResizeCapable = false;
8170
8173
  this.destroyed = false;
8171
8174
  this.lastForkActive = null;
8172
8175
  // Status message element (stopped / error)
@@ -8257,27 +8260,70 @@ cap-widget::part(attribution) {
8257
8260
  this.messageHandler = (event) => {
8258
8261
  if (!this.isValidMessageOrigin(event.origin)) return;
8259
8262
  const data = event.data;
8260
- if (!data || typeof data !== "object" || data.type !== "adapt-resize")
8261
- return;
8262
- const { height } = data;
8263
- if (typeof height !== "number" || !Number.isFinite(height) || height < 1)
8264
- return;
8263
+ if (!data || typeof data !== "object") return;
8265
8264
  const source = event.source;
8266
- if (this.mainIframe?.contentWindow === source) {
8267
- if (this.autoResizing) {
8268
- this.mainIframe.style.height = `${height}px`;
8265
+ if (data.type === "adapt-init" && typeof data.resize === "boolean") {
8266
+ const isMain = this.mainIframe?.contentWindow === source;
8267
+ const isFork = this.forkIframe?.contentWindow === source;
8268
+ if (isMain) {
8269
+ this.mainResizeCapable = data.resize;
8270
+ if (!data.resize && this.mainIframe) {
8271
+ this.mainIframe.style.height = "";
8272
+ }
8273
+ } else if (isFork) {
8274
+ this.forkResizeCapable = data.resize;
8275
+ if (!data.resize && this.forkIframe) {
8276
+ this.forkIframe.style.height = "";
8277
+ if (this.dialogElement) {
8278
+ this.dialogElement.style.height = "";
8279
+ }
8280
+ }
8269
8281
  }
8270
- } else if (this.forkIframe?.contentWindow === source) {
8271
- if (this.autoResizing) {
8272
- this.forkIframe.style.height = `${height}px`;
8282
+ if (isMain || isFork) {
8283
+ const iframe = isMain ? this.mainIframe : this.forkIframe;
8284
+ const iframeSrc = iframe.src;
8285
+ const targetOrigin = iframeSrc ? this.getOrigin(iframeSrc) : null;
8286
+ if (targetOrigin) {
8287
+ let effective = this.autoResizing && data.resize;
8288
+ if (isFork && data.resize && this.forkDisplay.mode === "dialog" && this.forkDisplay.resizeToContent) {
8289
+ effective = true;
8290
+ }
8291
+ try {
8292
+ iframe.contentWindow?.postMessage(
8293
+ { type: "adapt-autoResizing", autoResizing: effective },
8294
+ targetOrigin
8295
+ );
8296
+ iframe.contentWindow?.postMessage(
8297
+ { type: "adapt-darkMode", darkMode: this.darkMode },
8298
+ targetOrigin
8299
+ );
8300
+ } catch {
8301
+ }
8302
+ }
8273
8303
  }
8274
- if (this.forkDisplay.mode === "dialog" && this.forkDisplay.resizeToContent && this.dialogElement && window.innerWidth > _AdaptWebClient.DIALOG_FULLSCREEN_BREAKPOINT) {
8275
- const toolbarHeight = this.forkToolbarElement?.offsetHeight ?? 36;
8276
- const padding = 24;
8277
- const border = 2;
8278
- const totalHeight = Math.ceil(height) + toolbarHeight + padding + border;
8279
- this.dialogElement.style.height = `clamp(300px, ${totalHeight}px, 90vh)`;
8304
+ return;
8305
+ }
8306
+ if (data.type === "adapt-resize") {
8307
+ const { height } = data;
8308
+ if (typeof height !== "number" || !Number.isFinite(height) || height < 1)
8309
+ return;
8310
+ if (this.mainIframe?.contentWindow === source) {
8311
+ if (this.mainResizeCapable && this.autoResizing) {
8312
+ this.mainIframe.style.height = `${height}px`;
8313
+ }
8314
+ } else if (this.forkIframe?.contentWindow === source) {
8315
+ if (this.forkResizeCapable && this.autoResizing) {
8316
+ this.forkIframe.style.height = `${height}px`;
8317
+ }
8318
+ if (this.forkResizeCapable && this.forkDisplay.mode === "dialog" && this.forkDisplay.resizeToContent && this.dialogElement && window.innerWidth > _AdaptWebClient.DIALOG_FULLSCREEN_BREAKPOINT) {
8319
+ const toolbarHeight = this.forkToolbarElement?.offsetHeight ?? 36;
8320
+ const padding = 24;
8321
+ const border = 2;
8322
+ const totalHeight = Math.ceil(height) + toolbarHeight + padding + border;
8323
+ this.dialogElement.style.height = `clamp(300px, ${totalHeight}px, 90vh)`;
8324
+ }
8280
8325
  }
8326
+ return;
8281
8327
  }
8282
8328
  };
8283
8329
  window.addEventListener("message", this.messageHandler);
@@ -8296,39 +8342,17 @@ cap-widget::part(attribution) {
8296
8342
  } catch {
8297
8343
  }
8298
8344
  }
8299
- sendAutoResizingToIframe(iframe) {
8345
+ sendAutoResizingMessageToIframe(iframe, enabled) {
8300
8346
  if (!iframe) return;
8301
8347
  const iframeSrc = iframe.src;
8302
8348
  const targetOrigin = iframeSrc ? this.getOrigin(iframeSrc) : null;
8303
8349
  if (!targetOrigin) return;
8304
- let effective = this.autoResizing;
8305
- if (iframe === this.forkIframe && this.forkDisplay.mode === "dialog" && this.forkDisplay.resizeToContent) {
8306
- effective = true;
8307
- }
8308
- const message = {
8309
- type: "adapt-autoResizing",
8310
- autoResizing: effective
8311
- };
8312
- try {
8313
- iframe.contentWindow?.postMessage(message, targetOrigin);
8314
- } catch {
8315
- }
8316
- }
8317
- /**
8318
- * Send autoResizing state specifically to the fork iframe.
8319
- * Used by setDialogResizeToContent to toggle height reporting independently.
8320
- */
8321
- sendAutoResizingToForkIframe(enabled) {
8322
- if (!this.forkIframe) return;
8323
- const iframeSrc = this.forkIframe.src;
8324
- const targetOrigin = iframeSrc ? this.getOrigin(iframeSrc) : null;
8325
- if (!targetOrigin) return;
8326
8350
  const message = {
8327
8351
  type: "adapt-autoResizing",
8328
8352
  autoResizing: enabled
8329
8353
  };
8330
8354
  try {
8331
- this.forkIframe.contentWindow?.postMessage(message, targetOrigin);
8355
+ iframe.contentWindow?.postMessage(message, targetOrigin);
8332
8356
  } catch {
8333
8357
  }
8334
8358
  }
@@ -8355,8 +8379,12 @@ cap-widget::part(attribution) {
8355
8379
  setAutoResizing(autoResizing) {
8356
8380
  if (this.autoResizing === autoResizing) return;
8357
8381
  this.autoResizing = autoResizing;
8358
- this.sendAutoResizingToIframe(this.mainIframe);
8359
- this.sendAutoResizingToIframe(this.forkIframe);
8382
+ if (this.mainResizeCapable) {
8383
+ this.sendAutoResizingMessageToIframe(this.mainIframe, autoResizing);
8384
+ }
8385
+ if (this.forkResizeCapable) {
8386
+ this.sendAutoResizingMessageToIframe(this.forkIframe, autoResizing);
8387
+ }
8360
8388
  if (!autoResizing) {
8361
8389
  if (this.mainIframe) this.mainIframe.style.height = "";
8362
8390
  if (this.forkIframe) this.forkIframe.style.height = "";
@@ -8414,8 +8442,12 @@ cap-widget::part(attribution) {
8414
8442
  this.showIframe(this.forkIframe);
8415
8443
  }
8416
8444
  if (this.autoResizing) {
8417
- this.sendAutoResizingToIframe(this.mainIframe);
8418
- this.sendAutoResizingToIframe(this.forkIframe);
8445
+ if (this.mainResizeCapable) {
8446
+ this.sendAutoResizingMessageToIframe(this.mainIframe, true);
8447
+ }
8448
+ if (this.forkResizeCapable) {
8449
+ this.sendAutoResizingMessageToIframe(this.forkIframe, true);
8450
+ }
8419
8451
  }
8420
8452
  if (mode === "side-by-side" && !this.currentFork && this.forkQueue.length > 0) {
8421
8453
  this.activateNextFork();
@@ -8451,14 +8483,14 @@ cap-widget::part(attribution) {
8451
8483
  if (this.forkDisplay.mode !== "dialog") return;
8452
8484
  if (this.forkDisplay.resizeToContent === enabled) return;
8453
8485
  this.forkDisplay = { ...this.forkDisplay, resizeToContent: enabled };
8454
- if (enabled) {
8455
- this.sendAutoResizingToForkIframe(true);
8456
- } else {
8486
+ if (enabled && this.forkResizeCapable) {
8487
+ this.sendAutoResizingMessageToIframe(this.forkIframe, true);
8488
+ } else if (!enabled) {
8457
8489
  if (this.dialogElement) {
8458
8490
  this.dialogElement.style.height = "";
8459
8491
  }
8460
- if (!this.autoResizing) {
8461
- this.sendAutoResizingToForkIframe(false);
8492
+ if (!this.autoResizing && this.forkResizeCapable) {
8493
+ this.sendAutoResizingMessageToIframe(this.forkIframe, false);
8462
8494
  }
8463
8495
  }
8464
8496
  }
@@ -8699,21 +8731,19 @@ cap-widget::part(attribution) {
8699
8731
  ttl: opts.ttl,
8700
8732
  mainUrl: this.mainUrl,
8701
8733
  mainToken: this.mainToken,
8702
- currentFork: this.currentFork ? {
8734
+ currentFork: this.currentFork && !this.currentFork.completed ? {
8703
8735
  url: this.currentFork.url,
8704
8736
  token: this.currentFork.token,
8705
8737
  fork: this.currentFork.fork,
8706
8738
  depth: this.currentFork.depth,
8707
- time: this.currentFork.time,
8708
- completed: this.currentFork.completed
8739
+ time: this.currentFork.time
8709
8740
  } : null,
8710
- forkQueue: this.forkQueue.map((f) => ({
8741
+ forkQueue: this.forkQueue.filter((f) => !f.completed).map((f) => ({
8711
8742
  url: f.url,
8712
8743
  token: f.token,
8713
8744
  fork: f.fork,
8714
8745
  depth: f.depth,
8715
- time: f.time,
8716
- completed: f.completed
8746
+ time: f.time
8717
8747
  })),
8718
8748
  forkDisplayMode: this.forkDisplay.mode,
8719
8749
  splitPercentage: this.splitPercentage
@@ -8764,8 +8794,8 @@ cap-widget::part(attribution) {
8764
8794
  this.sessionExpiresAt = state.expiresAt ? new Date(state.expiresAt) : void 0;
8765
8795
  this.mainUrl = state.mainUrl;
8766
8796
  this.mainToken = state.mainToken;
8767
- this.forkQueue = state.forkQueue;
8768
- this.currentFork = state.currentFork;
8797
+ this.forkQueue = state.forkQueue.filter((f) => !f.completed);
8798
+ this.currentFork = state.currentFork?.completed ? null : state.currentFork;
8769
8799
  if (state.forkDisplayMode === this.forkDisplay.mode) {
8770
8800
  if (this.forkDisplay.mode === "side-by-side") {
8771
8801
  this.splitPercentage = state.splitPercentage;
@@ -9089,6 +9119,8 @@ cap-widget::part(attribution) {
9089
9119
  if (!this.rootElement || !this.mainUrl || !this.mainIframe) return;
9090
9120
  const newSrc = getIframeSrc(this.mainUrl, this.mainToken);
9091
9121
  if (this.mainIframe.src !== newSrc) {
9122
+ this.mainResizeCapable = false;
9123
+ this.mainIframe.style.height = "";
9092
9124
  this.mainIframe.src = newSrc;
9093
9125
  }
9094
9126
  this.showIframe(this.mainIframe);
@@ -9099,6 +9131,10 @@ cap-widget::part(attribution) {
9099
9131
  updateForkIframe() {
9100
9132
  if (!this.currentFork || !this.forkIframe) return;
9101
9133
  const newSrc = getIframeSrc(this.currentFork.url, this.currentFork.token);
9134
+ this.forkResizeCapable = false;
9135
+ if (this.dialogElement) {
9136
+ this.dialogElement.style.height = "";
9137
+ }
9102
9138
  const parent = this.forkIframe.parentElement;
9103
9139
  if (parent) {
9104
9140
  const fresh = this.createHiddenIframe();
@@ -9431,13 +9467,12 @@ cap-widget::part(attribution) {
9431
9467
  );
9432
9468
  iframe.setAttribute(
9433
9469
  "allow",
9434
- "geolocation; camera; microphone; fullscreen; display-capture; web-share"
9470
+ "autoplay; geolocation; camera; microphone; fullscreen; display-capture; web-share"
9435
9471
  );
9436
9472
  iframe.src = "about:blank";
9437
9473
  iframe.addEventListener("load", () => {
9438
9474
  if (iframe.src && iframe.src !== "about:blank") {
9439
9475
  this.sendDarkModeToIframe(iframe);
9440
- this.sendAutoResizingToIframe(iframe);
9441
9476
  }
9442
9477
  });
9443
9478
  return iframe;