Skip to content

Commit 3d2564f

Browse files
committed
fix: prevent double load on Vimeo video remount by deferring teardown
1 parent 12f379e commit 3d2564f

1 file changed

Lines changed: 24 additions & 8 deletions

File tree

packages/vimeo-video-element/vimeo-video-element.js

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,8 @@ class VimeoVideoElement extends MediaPlayedRangesMixin(globalThis.HTMLElement ??
113113
* See load()
114114
*/
115115
#wasDisconnected = false;
116+
/** A disconnect whose teardown hasn't run yet. See disconnectedCallback(). */
117+
#pendingTeardown = false;
116118

117119
constructor() {
118120
super();
@@ -238,20 +240,34 @@ class VimeoVideoElement extends MediaPlayedRangesMixin(globalThis.HTMLElement ??
238240
}
239241

240242
connectedCallback() {
241-
if (this.#wasDisconnected) {
243+
// Re-attached before the deferred teardown ran (transient move/remount):
244+
// keep the existing iframe and playback state. See disconnectedCallback.
245+
if (this.#pendingTeardown) {
246+
this.#pendingTeardown = false;
247+
} else if (this.#wasDisconnected) {
248+
// Re-attached after a real teardown: reload since attributes don't change
249+
// on re-attach and wouldn't otherwise fire attributeChangedCallback.
250+
// load() reads #wasDisconnected (remount vs SSR hydration) and clears it.
242251
this.load();
243252
}
244253
super.connectedCallback?.();
245254
}
246255

247256
disconnectedCallback() {
248-
this.#wasDisconnected = true;
249-
this.#loadRequested = null;
250-
this.#hasLoaded = null;
251-
this.#isInit = null;
252-
this.loadComplete = new PublicPromise();
253-
this.api?.destroy?.();
254-
this.api = null;
257+
// Defer teardown so a synchronous detach + re-attach (React remount) can
258+
// cancel it via connectedCallback, avoiding a needless destroy + rebuild (#249).
259+
this.#pendingTeardown = true;
260+
queueMicrotask(() => {
261+
if (!this.#pendingTeardown) return;
262+
this.#pendingTeardown = false;
263+
this.#wasDisconnected = true;
264+
this.#loadRequested = null;
265+
this.#hasLoaded = null;
266+
this.#isInit = null;
267+
this.loadComplete = new PublicPromise();
268+
this.api?.destroy?.();
269+
this.api = null;
270+
});
255271
super.disconnectedCallback?.();
256272
}
257273

0 commit comments

Comments
 (0)