Skip to content

Commit

Permalink
Fix interoperability with scripts that set onYouTubeIframeAPIReady
Browse files Browse the repository at this point in the history
Scripts (e.g. Google analytics) appears to set onYouTubeIframeAPIReady on window.
So this updates so that the component still loads when it's set.

Fixes #607
  • Loading branch information
markcellus committed Jun 28, 2023
1 parent 45a966a commit fa519d0
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 10 deletions.
23 changes: 13 additions & 10 deletions src/youtube-video.ts
Original file line number Diff line number Diff line change
Expand Up @@ -205,16 +205,19 @@ export class YoutubeVideoElement extends HTMLElement {
if (!YoutubeVideoElement.scriptLoadPromise) {
YoutubeVideoElement.scriptLoadPromise = new Promise((resolve) => {
// NOTE: youtube's iframe api ready only fires once after first script load
if (!window.onYouTubeIframeAPIReady) {
YoutubeVideoElement.triggerYoutubeIframeAPIReady = resolve;
window.onYouTubeIframeAPIReady = () => {
window.onYouTubeIframeAPIReady = null;
// once the script loads once, we are guaranteed for it to
// be ready even after destruction of all instances (if consumer
// doesnt mangle with it)
YoutubeVideoElement.triggerYoutubeIframeAPIReady();
};
}
const originalOnYouTubeIframeAPIReady =
window.onYouTubeIframeAPIReady;
YoutubeVideoElement.triggerYoutubeIframeAPIReady = resolve;
window.onYouTubeIframeAPIReady = (...args) => {
window.onYouTubeIframeAPIReady = null;
// once the script loads once, we are guaranteed for it to
// be ready even after destruction of all instances (if consumer
// doesnt mangle with it)
YoutubeVideoElement.triggerYoutubeIframeAPIReady();
if (originalOnYouTubeIframeAPIReady) {
originalOnYouTubeIframeAPIReady(...args);
}
};
return ResourceManager.loadScript(this.scriptPath);
});
}
Expand Down
25 changes: 25 additions & 0 deletions tests/youtube-video-tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,31 @@ describe('Youtube Video Tests', function () {
window.YT = origYT;
});

it('does not override original window.onYouTubeIframeAPIReady if exists', async () => {
const onYouTubeIframeAPIReadyStub = sinon.stub();
Object.defineProperty(window, 'onYouTubeIframeAPIReady', {
get() {
return onYouTubeIframeAPIReadyStub;
},
configurable: true,
});
var videoEl = document.createElement(
'youtube-video'
) as YoutubeVideoElement;
videoEl.setAttribute('width', '640');
videoEl.setAttribute('height', '360');
videoEl.setAttribute(
'src',
'http://www.youtube.com/watch?v=nOEw9iiopwI'
);
testContainer.appendChild(videoEl);
await videoEl.load(); // wait for API to be ready
assert.equal(onYouTubeIframeAPIReadyStub.callCount, 0);
window.onYouTubeIframeAPIReady();
assert.equal(onYouTubeIframeAPIReadyStub.callCount, 1);
testContainer.removeChild(videoEl);
});

it('should load proper iFrame player api script when load() is called and remove it from the dom when removed', async function () {
var videoEl = document.createElement(
'youtube-video'
Expand Down

0 comments on commit fa519d0

Please sign in to comment.