-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathswap.user.js
105 lines (98 loc) · 5.11 KB
/
swap.user.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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
// ==UserScript==
// @name YT Swap
// @namespace k3rielit.ytswap
// @version 2.0
// @description Swaps between Shorts and Watch UI for the current video.
// @author github.com/k3rielit
// @match *://*.youtube.com/*
// @match *://*.youtu.be/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=youtube.com
// @grant none
// @updateURL https://github.com/k3rielit/scripts/raw/main/youtube/swap.user.js
// @downloadURL https://github.com/k3rielit/scripts/raw/main/youtube/swap.user.js
// ==/UserScript==
console.log('[YTSwap] Loaded');
// Components
const components = {
lineawesome: `<link rel="stylesheet" href="https://maxst.icons8.com/vue-static/landings/line-awesome/line-awesome/1.3.0/css/line-awesome.min.css">`,
flexmincss: `.container,.row>*{width:100%}.row{display:flex;flex-wrap:wrap}.row>*{flex-shrink:0;max-width:100%}.col{flex:1 0 0%}.col-auto{flex:0 0 auto;width:auto}`,
buttoncss: `.k-btn{cursor:pointer;border:0;display:inline;border-radius:30px;padding:8px 10px;font-size:20px;max-height:40px;max-width:40px;font-family:Roboto,Arial,sans-serif;font-weight:700;color:var(--yt-spec-text-primary);margin-left:10px}.k-btn:hover{background-color:rgba(255,255,255,.1)}`,
buttonHome: `<a id="ytsw-home" class="k-btn" href="/"><i class="las la-house-damage"></i></a>`,
buttonSwapToShorts: `<a id="ytsw-swap" class="k-btn" href="#"><i class="las la-compress"></i></a>`,
buttonSwapToWatch: `<a id="ytsw-swap" class="k-btn" href="#"><i class="las la-expand"></i></a>`,
buttonInfo: `<a id="ytsw-info" class="k-btn"><i class="las la-chart-bar"></i></a>`,
buttonQRCode: `<a id="ytsw-qr" class="k-btn"><i class="las la-qrcode"></i></a>`,
};
// Functions
// https://stackoverflow.com/questions/5525071/how-to-wait-until-an-element-exists
function waitForElement(selector) {
return new Promise(resolve => {
if (document.querySelector(selector)) {
return resolve(document.querySelector(selector));
}
console.log('[waitForElement] Waiting for: '+selector);
const observer = new MutationObserver((mutationList, observer) => {
if (document.querySelector(selector)) {
console.log(document.querySelector(selector));
resolve(document.querySelector(selector));
observer.disconnect();
}
});
observer.observe(document.body, {
attributes: true, childList: true, subtree: true
});
});
}
function stringToElement(str) {
let template = document.createElement('template');
template.innerHTML = str.trim();
return template.content.firstChild;
}
function injectCSS(css) {
let style = document.createElement('style');
style.innerHTML = css;
document.head.appendChild(style);
}
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
// Main
(async function() {
await waitForElement('div#buttons.style-scope.ytd-masthead yt-icon');
const topRightButtonContainer = await waitForElement('div#buttons.style-scope.ytd-masthead');
const topLeftLogo = await waitForElement('div#start.style-scope.ytd-masthead > #logo');
document.head.appendChild(stringToElement(components.lineawesome));
injectCSS(components.flexmincss);
injectCSS(components.buttoncss);
let lastHref = window.location.href;
// YT rerenders UI on route change
while(true) {
await sleep(111).then(() => {
if(lastHref != window.location.href || !document.getElementById('ytsw-home')) {
lastHref = window.location.href;
topLeftLogo.innerText = '';
// waitForElement('#voice-search-button').then((elem) => elem.remove());
// Determine what components to render
topLeftLogo.appendChild(stringToElement(components.buttonHome));
const currentUI = window.location.pathname.split('/')[1];
if(currentUI == 'shorts' || currentUI == 'watch') {
const videoId = window.location.href.includes('?v=') ? window.location.href.split('?v=')[1].substring(0,11) : window.location.pathname.split('/')[2];
switch(currentUI) {
case 'shorts':
topLeftLogo.appendChild(stringToElement(components.buttonSwapToWatch.replace(`href="#"`,`href="https://www.youtube.com/watch?v=${videoId}"`)));
break;
case 'watch':
topLeftLogo.appendChild(stringToElement(components.buttonSwapToShorts.replace(`href="#"`,`href="https://www.youtube.com/shorts/${videoId}"`)));
break;
}
topLeftLogo.appendChild(stringToElement(components.buttonInfo));
topLeftLogo.appendChild(stringToElement(components.buttonQRCode));
}
}
// Replace redirect links
document.querySelectorAll('a[href*="https://www.youtube.com/redirect"]').forEach((elem,index) => {
elem.href = new URL(elem.href).searchParams.get('q');
});
});
}
})();