This repository has been archived by the owner on May 15, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4
/
userscript.js
75 lines (72 loc) · 2.59 KB
/
userscript.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
// ==UserScript==
// @name Disney+ | Picture in Picture
// @namespace https://victorwesterlund.com/
// @version 1.0
// @description Enable Picture in Picture on Disney+
// @author VictorWesterlund
// @match https://www.disneyplus.com/*
// @grant none
// ==/UserScript==
(function() {
'use strict';
// PIP SVG - Copied from Full Screen <button>
const PIPicon = '<div class="focus-hack-div" tabindex="-1"><svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24" tabindex="-1" focusable="false"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M19 11h-8v6h8v-6zm4 8V4.98C23 3.88 22.1 3 21 3H3c-1.1 0-2 .88-2 1.98V19c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2zm-2 .02H3V4.97h18v14.05z" fill="white"/></svg></div>';
let timeout = null;
function initPIP() {
const mediaControlsWrapper = document.getElementsByClassName("btm-media-overlays-container")[0];
const video = document.getElementsByTagName("video")[0];
video.removeAttribute("disablepictureinpicture");
function togglePIP() {
if(document.pictureInPictureElement) {
document.exitPictureInPicture();
} else {
if(document.pictureInPictureEnabled) {
video.requestPictureInPicture();
}
}
}
// Append the PIP button to target
function insertPIPtoggle(target) {
if(document.getElementById("pip-toggle") ?? false) {
return false;
}
const button = document.createElement("button");
button.setAttribute("id", "pip-toggle");
button.setAttribute("aria-label", "PIP");
button.setAttribute("role", "button");
button.classList.add("control-icon-btn");
button.addEventListener("click", () => togglePIP());
button.insertAdjacentHTML("beforeend", PIPicon);
target.appendChild(button);
}
// Attempt to locate target for PIP button
const mediaControlsMutated = (mutations, observer) => {
const target = mediaControlsWrapper.getElementsByClassName("controls__right")[0] ?? false;
if (!target || target.length < 1) {
return false;
}
insertPIPtoggle(target);
}
const mediaControls = new MutationObserver(mediaControlsMutated);
mediaControls.observe(mediaControlsWrapper, {
childList: true
});
}
// Poll document tree until video element is loaded
const init = (mutations, observer) => {
clearTimeout(timeout);
const pattern = /^\/?([A-Za-z-]*)?\/video\//i;
if(!pattern.test(window.location.pathname)) {
return false;
}
if(document.getElementsByTagName("video")[0]) {
initPIP();
return;
}
timeout = setTimeout(init, 500);
}
const page = new MutationObserver(init);
page.observe(document.body, {
childList: true
});
})();