Skip to content

Commit 7defaa6

Browse files
crisbetojelbourn
authored andcommitted
fix(youtube-player): avoid clobbering api loaded callback (#17850)
The YouTube player component adds a global callback for when the API is loaded, however if one existed already it'll be overwritten. These changes ensure that the previous callback is preserved.
1 parent 2d407a2 commit 7defaa6

File tree

2 files changed

+29
-5
lines changed

2 files changed

+29
-5
lines changed

src/youtube-player/youtube-player.spec.ts

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ describe('YoutubePlayer', () => {
3737

3838
afterEach(() => {
3939
delete window.YT;
40+
window.onYouTubeIframeAPIReady = undefined;
4041
});
4142

4243
it('initializes a youtube player', () => {
@@ -281,17 +282,18 @@ describe('YoutubePlayer', () => {
281282
beforeEach(() => {
282283
api = window.YT;
283284
delete window.YT;
284-
285-
fixture = TestBed.createComponent(TestApp);
286-
testComponent = fixture.debugElement.componentInstance;
287-
fixture.detectChanges();
288285
});
289286

290287
afterEach(() => {
291288
delete window.YT;
289+
window.onYouTubeIframeAPIReady = undefined;
292290
});
293291

294292
it('waits until the api is ready before initializing', () => {
293+
fixture = TestBed.createComponent(TestApp);
294+
testComponent = fixture.debugElement.componentInstance;
295+
fixture.detectChanges();
296+
295297
expect(playerCtorSpy).not.toHaveBeenCalled();
296298

297299
window.YT = api!;
@@ -306,6 +308,22 @@ describe('YoutubePlayer', () => {
306308
height: DEFAULT_PLAYER_HEIGHT,
307309
}));
308310
});
311+
312+
it('should not override any pre-existing API loaded callbacks', () => {
313+
const spy = jasmine.createSpy('other API loaded spy');
314+
window.onYouTubeIframeAPIReady = spy;
315+
316+
fixture = TestBed.createComponent(TestApp);
317+
testComponent = fixture.debugElement.componentInstance;
318+
fixture.detectChanges();
319+
320+
expect(playerCtorSpy).not.toHaveBeenCalled();
321+
322+
window.YT = api!;
323+
window.onYouTubeIframeAPIReady!();
324+
325+
expect(spy).toHaveBeenCalled();
326+
});
309327
});
310328

311329
});

src/youtube-player/youtube-player.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ export class YouTubePlayer implements AfterViewInit, OnDestroy, OnInit {
160160
private _youtubeContainer = new Subject<HTMLElement>();
161161
private _destroyed = new Subject<void>();
162162
private _player: Player | undefined;
163+
private _existingApiReadyCallback: (() => void) | undefined;
163164

164165
constructor(
165166
private _ngZone: NgZone,
@@ -189,7 +190,12 @@ export class YouTubePlayer implements AfterViewInit, OnDestroy, OnInit {
189190
}
190191

191192
const iframeApiAvailableSubject = new Subject<boolean>();
193+
this._existingApiReadyCallback = window.onYouTubeIframeAPIReady;
194+
192195
window.onYouTubeIframeAPIReady = () => {
196+
if (this._existingApiReadyCallback) {
197+
this._existingApiReadyCallback();
198+
}
193199
this._ngZone.run(() => iframeApiAvailableSubject.next(true));
194200
};
195201
iframeApiAvailableObs = iframeApiAvailableSubject.pipe(take(1), startWith(false));
@@ -262,7 +268,7 @@ export class YouTubePlayer implements AfterViewInit, OnDestroy, OnInit {
262268
ngOnDestroy() {
263269
if (this._player) {
264270
this._player.destroy();
265-
window.onYouTubeIframeAPIReady = undefined;
271+
window.onYouTubeIframeAPIReady = this._existingApiReadyCallback;
266272
}
267273

268274
this._videoIdObs.complete();

0 commit comments

Comments
 (0)