Skip to content

Commit f8d7851

Browse files
committed
Mutation Observer improvements
1 parent adc16ba commit f8d7851

File tree

4 files changed

+48
-31
lines changed

4 files changed

+48
-31
lines changed

dist/ytbsp.user.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Components/VideoComponent.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ export default class VideoComponent extends Component {
7979
});
8080
});
8181

82-
//this adds clicked video to a magical invisible youtube playlist
82+
// This adds clicked video to a magical invisible YouTube playlist.
8383
this.addToQueueItem.click(() => {
8484
pageService.addToQueue(video.id);
8585
queueService.setStartVideoId(video.id);

src/Services/PageService.ts

Lines changed: 37 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ class PageService {
149149
isDocumentReady = false;
150150
navigateInterval: Timeout = null;
151151
private observer: MutationObserver;
152+
private observerWorkScheduled = false;
152153
private oldHref: string;
153154
private isFullscreen: boolean;
154155
private onPageChangeCallbackList: (() => void)[] = [];
@@ -159,32 +160,7 @@ class PageService {
159160
constructor() {
160161
this.oldHref = document.location.href;
161162
// Setup page observer.
162-
this.observer = new MutationObserver(() => {
163-
// Detect page changes.
164-
const currentHref = document.location.href;
165-
if (this.oldHref !== currentHref) {
166-
this.oldHref = currentHref;
167-
this.onPageChangeCallbackList.forEach(callback => {
168-
callback();
169-
});
170-
}
171-
// Detect going fullscreen.
172-
if (0 !== $(YT_PLAYER_CONTROL).length && true === $(YT_PLAYER_CONTROL).get(0)["fullscreen"]) {
173-
if (!this.isFullscreen) {
174-
this.isFullscreen = true;
175-
this.onToggleFullscreenCallbackList.forEach(callback => {
176-
callback(true);
177-
});
178-
}
179-
} else {
180-
if (this.isFullscreen) {
181-
this.isFullscreen = false;
182-
this.onToggleFullscreenCallbackList.forEach(callback => {
183-
callback(false);
184-
});
185-
}
186-
}
187-
});
163+
this.observer = new MutationObserver(() => this.onMutationsObserved());
188164

189165
$(document).ready(() => {
190166
this.isDocumentReady = true;
@@ -197,7 +173,15 @@ class PageService {
197173
}
198174

199175
startPageObserver() {
200-
this.observer.observe(document.querySelector("body"), {"childList": true, "subtree": true});
176+
const target = document.querySelector(YT_APP);
177+
if (!target) {
178+
setTimeout(() => this.startPageObserver(), 250);
179+
return;
180+
}
181+
this.observer.observe(target, {
182+
"childList": true,
183+
"subtree": true
184+
});
201185
}
202186

203187
injectYTBSP(ytbsp: YTBSPComponent) {
@@ -420,6 +404,32 @@ class PageService {
420404
callback();
421405
});
422406
};
407+
408+
private onMutationsObserved() {
409+
if (!this.observerWorkScheduled) {
410+
this.observerWorkScheduled = true;
411+
window.requestAnimationFrame(() => this.flushPendingMutations());
412+
}
413+
}
414+
415+
private flushPendingMutations() {
416+
this.observerWorkScheduled = false;
417+
const currentHref = document.location.href;
418+
if (this.oldHref !== currentHref) {
419+
this.oldHref = currentHref;
420+
this.onPageChangeCallbackList.forEach(callback => {
421+
callback();
422+
});
423+
}
424+
const playerControl = $(YT_PLAYER_CONTROL);
425+
const isFullscreenNow = 0 !== playerControl.length && true === playerControl.get(0)["fullscreen"];
426+
if (isFullscreenNow !== this.isFullscreen) {
427+
this.isFullscreen = isFullscreenNow;
428+
this.onToggleFullscreenCallbackList.forEach(callback => {
429+
callback(this.isFullscreen);
430+
});
431+
}
432+
}
423433
}
424434

425435
const pageService = new PageService();

src/index.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,14 @@ import pageService, { PageState } from "./Services/PageService";
77
import persistenceService from "./Services/PersistenceService";
88

99
console.log("script start");
10-
setTimeout(() => {
10+
11+
if (document.location.pathname.length > 1 && 'requestIdleCallback' in window) {
12+
requestIdleCallback(startup, { timeout: 300000 });
13+
} else {
14+
setTimeout(startup, 0);
15+
}
16+
17+
function startup() {
1118
pageService.updateNativeStyleRuleModifications(PageState.LOADING);
1219

1320
const ytbspComponent = new YTBSPComponent();
@@ -43,4 +50,4 @@ setTimeout(() => {
4350
pageService.addThumbnailEnlargeCss();
4451
}).catch(e => console.error(e));
4552

46-
}, 0);
53+
}

0 commit comments

Comments
 (0)