-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathReturnYouTubeMetadata.user.js
More file actions
95 lines (76 loc) · 3.98 KB
/
ReturnYouTubeMetadata.user.js
File metadata and controls
95 lines (76 loc) · 3.98 KB
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
// ==UserScript==
// @name Return YouTube Metadata
// @namespace https://github.com/paradoxepoch
// @version 1.0.1
// @description Returns the precise video view count and upload date to above the fold where it belongs!
// @author ParadoxEpoch
// @match https://www.youtube.com/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=youtube.com
// @grant none
// ==/UserScript==
(function() {
'use strict';
let metadata;
const sleep = m => new Promise(r => setTimeout(r, m));
const tooltipSelector = 'ytd-watch-metadata #description #tooltip';
const escapeHTMLPolicy = trustedTypes.createPolicy("forceInner", {
createHTML: (to_escape) => to_escape
})
async function init() {
// Wait for video metadata to be loaded into the DOM, then proceed...
let isReady = false
while (!isReady) {
await sleep(500);
console.log('Waiting for video metadata to load...');
isReady = !!document.querySelector(tooltipSelector) && !!document.querySelector('#above-the-fold #title h1 > yt-formatted-string') && !!document.querySelector(tooltipSelector).innerText.trim();
}
// Clear the contents of the metadata element if it already exists
if (document.querySelectorAll('#aboveTheFoldMetadata').length) document.querySelector('#aboveTheFoldMetadata').innerText = 'Loading...';
// Wait 1 sec to prevent race condition when changing videos
await sleep(1000);
// Fetch metadata string
metadata = document.querySelector(tooltipSelector).innerText.trim();
// If our element to inject already exists in the DOM, just update its contents. Otherwise, create the element and inject it now.
// ? The element already exists when navigating to another video directly from a watch page since the title container element doesn't get reset.
if (document.querySelectorAll('#aboveTheFoldMetadata').length) {
document.querySelector('#aboveTheFoldMetadata').innerText = metadata;
} else {
document.querySelector('#above-the-fold #title h1 > yt-formatted-string').insertAdjacentHTML('beforeend', escapeHTMLPolicy.createHTML(`<span id="aboveTheFoldMetadata" style="font-size: smaller; position: absolute; right: 0px; color: rgb(255 255 255 / 75%);">${metadata}</span>`));
}
}
// * Only start looking for video metadata if the user is on a watch page.
if (location.pathname === '/watch') init();
// * Create a MutationObserver instance on page load to watch for URL state changes.
let oldHref = document.location.href;
window.onload = function () {
const bodyList = document.querySelector("body")
const observer = new MutationObserver(function (mutations) {
mutations.forEach(async function (mutation) {
if (oldHref != document.location.href) {
oldHref = document.location.href;
// If this is not a watch page, set metadata to null and return here.
if (location.pathname !== '/watch') {
metadata = null;
return;
}
const currentMetadataElem = document.querySelector('#aboveTheFoldMetadata');
if (currentMetadataElem) currentMetadataElem.innerText = '';
let isReady = false
while (!isReady) {
await sleep(500);
console.log('Waiting for metadata update...');
isReady = currentMetadataElem
? document.querySelector(tooltipSelector).innerText.trim() !== metadata
: true;
if (isReady) init();
}
}
});
});
const config = {
childList: true,
subtree: true
};
observer.observe(bodyList, config);
};
})();