refactored, added volume indicator on scroll, added endless play mode

This commit is contained in:
Maxim Stewart 2020-05-15 20:36:21 -05:00
parent faed6edee5
commit d845c9ce4f
9 changed files with 301 additions and 238 deletions

View File

@ -4,18 +4,29 @@ Better YouTube + works to improve the YouTube experience by providing quick acce
* It allows quick thumbnail access of the video. * It allows quick thumbnail access of the video.
* It allows setting the loop mode easily. * It allows setting the loop mode easily.
* It allows setting the loop mode to a ranged set. * It allows setting the loop mode to a ranged set.
* It allows the video to be toggled to fixed or floating with drag functionality. * It allows the video to be toggled to fixed or floating. (With drag functionality!)
* It allows volume control through the mouse-wheel when hovering over the player. * It allows volume control through the mouse-wheel when hovering over the player.
* It allows for quick access to the YouTube video slug. * It allows for quick access to the YouTube video slug.
* It lets Unix, Linux, and MacOS systems the ability to download the video using native app calls. * It allows for NonStop watch mode. (i.e, no "Are you still there?" dialog.)
* It shows volume level as you scroll.
* It lets Unix, Linux, and MacOS systems have the ability to download the video using native app calls.
# Version: 1.4.3 # Version: 1.5.0
* Added mutation observation for (un)fullscreen action. * Refactored code.
* Cleaned up some log cruft and fixed CSS... * Resolved volume change not always sticking on Linux. (I think fixed...)
* Added a quick volume indicator when scrolling.
* Added NonStop watch mode.
# Download # Download
https://addons.mozilla.org/en-US/firefox/addon/better-youtube-plus/ https://addons.mozilla.org/en-US/firefox/addon/better-youtube-plus/
# Images
![1 Controls... ](images/pic1.png)
![2 Thumbnail list... ](images/pic2.png)
![3 Secondary controls... ](images/pic3.png)
![4 Video in float mode... ](images/pic4.png)
![5 Video moved around in float mode... ](images/pic5.png)
# NOTE # NOTE
On *Nix systems download youtube-dl and use provided app in this repo to download videos. On *Nix systems download youtube-dl and use provided app in this repo to download videos.

BIN
images/pic1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

BIN
images/pic2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 386 KiB

BIN
images/pic3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

BIN
images/pic4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 424 KiB

BIN
images/pic5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 768 KiB

View File

@ -1,13 +1,12 @@
{ {
"manifest_version": 2, "manifest_version": 2,
"name": "Better Youtube +", "name": "Better Youtube +",
"version": "1.4.0", "version": "1.5.0",
"description": "Enhancements for Youtube to have a better experience.", "description": "Enhancements for Youtube to have a better experience.",
"applications": { "applications": {
"gecko": { "gecko": {
"id": "betterYoutube@itdominator.com", "id": "betterYoutube@itdominator.com"
"strict_min_version": "50.0"
} }
}, },

View File

@ -1,182 +1,183 @@
(function() { (function() {
// Declare variables const menuTemplate = `
let slugInputTag, ytThumbImgMenu, ytEnhancerMenu; // Menu systems <div class="ytMenuStyle" id="enhancerMenuID" style="display: block;">
let ytThumbnailBttn, ytMaxDefaultImg, ytHqDefaultImg, // Buttons & Images <div id="ytThumbnailBttn" class="imageStyle" title="Video Thumbnails..."></div>
ytLoopBttn, ytFloatBttn, ytAMaxDefaultImg, ytAHqDefaultImg; <div id="ytLoopBttn" class="imageStyle" title="Start Loop..."/></div>
<div id="ytFloatBttn" class="imageStyle" title="Float Video Container"/></div>
<div id="ytDownloadBttn" class="imageStyle" title="Download Video..."/></div>
</div>
`
const slugTemplate = `
<div id="enhancerMenuID2">
<div id="volumeContainerID" style="">
Volume <label id="volumeValueLbl"></label>
</div>
<input id="slugCopyZone" type="text">
<label>Loop Range Start:&nbsp;&nbsp;</label>
<input type="text" id="rangeStartID"/>
<label>Loop Range End:&nbsp;&nbsp;</label>
<input id="rangeEndID" type="text"/>
<label for="endlessPlayID">Endless Play</label>
<input type="checkbox" checked id="endlessPlayID" name="endlessPlayID"/>
</div>
`
const thumbnailTemplate = `
<div id="ytThumbMenuID" class="ytThumbMenuStyle" style="display: none;">
<a id="ytAMaxDefaultImgID" target="_blank" href=""><img id="ytMaxDefaultImgID" class="thumbImageStyle" src="" title="Max Resolution Default"/></a>
<a id="ytAHqDefaultImgID" target="_blank" href=""><img id="ytHqDefaultImgID" class="thumbImageStyle" src="" title="High Quality Default"/></a>
<a id="ytAMedDefaultImgID" target="_blank" href=""><img id="ytMqDefaultImgID" class="thumbImageStyle" src="" title="Medium Quality Default"></a>
<a id="ytASdDefaultImgID" target="_blank" href=""><img id="ytSdDefaultImgID" class="thumbImageStyle" src="" title="Standard Quality Default"/></a>
</div>
`
const popedContainerTemplate = `
<div id="draggable" style="display:none; block; top: 114px; left: 408px;">
<iframe id="popIframe" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
autoplay="" allowfullscreen="true" width="650px" height="400px" frameborder="0" src="" />
</iframe>
</div>
`
let mastHead, mainContentArea, playerWindow; // Youtube Player container // Declare other variables
let video, containerOfPlyrWndow, poppedContainer; // Video accessor let ytThumbImgMenu, ytEnhancerMenu, ytEnhancerMenu2; // Menu systems
let part, videoSlug, temp; // Image part let ytThumbnailBttn, ytLoopBttn, ytFloatBttn, ytDownloadBttn; // Menu Buttons
let ytMaxDefaultImg, ytHqDefaultImg, ytAMaxDefaultImg, ytAHqDefaultImg; // Thumbnail images
let mainContentArea, playerWindow, containerOfPlyrWndow, video; // Youtube Player container
let videoTimeLength, videoTimeCurent, ytRangeStart, ytRangeEnd, let videoTimeLength, videoTimeCurent, ytRangeStart, ytRangeEnd,
ytdVideoIntervalLoop; slugInputTag, endlessPlayTag, ytVideoIntervalLoop;
let poppedContainer, videoSlug, volumeLbl, part;
let loopingInterval = false; let loopingInterval = false;
let count = 0; let shouldHideVol = true;
let OSName = ""; let OSName = "";
let count = 0;
// confirm dialog elm
const isYoutubeMusic = window.location.hostname === 'music.youtube.com';
let dialogElementQueryRef = isYoutubeMusic ? 'ytmusic-you-there-renderer' : 'yt-confirm-dialog-renderer';
// Options for the observer (which mutations to observe) // Options for the observer (which mutations to observe)
const config = { attributes: true }; let observer, observer2;
const observerConfig = { attributes: true };
const observerConfig2 = { childList: true, subtree: true };
const preSetupProc = () => { const preSetupProc = () => {
if (navigator.appVersion.indexOf("Win")!=-1) OSName = "Windows"; // Look to add saving image from video elm.
if (navigator.appVersion.indexOf("Mac")!=-1) OSName = "MacOS"; // path = "/html/body/ytd-app/div/ytd-page-manager/ytd-watch-flexy/div[4]/div[1]/div/div[1]/div/div/div/ytd-player/div/div/div[1]/video"
if (navigator.appVersion.indexOf("X11")!=-1) OSName = "UNIX"; // elm = document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
if (navigator.appVersion.indexOf("Linux")!=-1) OSName ="Linux"; if (navigator.appVersion.indexOf("Win")!=-1) OSName = "Windows";
if (navigator.appVersion.indexOf("Mac")!=-1) OSName = "MacOS";
video = document.getElementsByTagName("video")[0]; // Video Controler if (navigator.appVersion.indexOf("X11")!=-1) OSName = "UNIX";
slugInputTag = document.createElement("INPUT"); if (navigator.appVersion.indexOf("Linux")!=-1) OSName = "Linux";
ytRangeEnd = document.createElement("INPUT");
slugInputTag.id = "slugCopyZone";
ytRangeEnd.id = "rangeEndID";
slugInputTag.type = "text";
ytRangeEnd.type = "text";
// We need to wait for info to load before getting full duration
setTimeout(function () {
videoTimeLength = document.getElementsByClassName("ytp-time-duration")[0].innerHTML;
if (!document.getElementById("rangeEndID")) {
} else {
ytRangeEnd = document.getElementById("rangeEndID");
}
ytRangeEnd.value = videoTimeLength;
}, 1000);
// check if we've loaded elements already...
if (!document.getElementById("slugCopyZone")) { if (!document.getElementById("slugCopyZone")) {
document.body.appendChild(slugInputTag); document.body.insertAdjacentHTML( 'beforeend', slugTemplate );
document.body.insertAdjacentHTML( 'beforeend', menuTemplate );
document.body.insertAdjacentHTML( 'beforeend', thumbnailTemplate );
document.body.insertAdjacentHTML( 'beforeend', popedContainerTemplate );
controlsWereLoaded = false;
} else { } else {
slugInputTag = document.getElementById("slugCopyZone"); controlsWereLoaded = true;
} }
slugInputTag.value = video.baseURI.slice(32, 32+11); ytEnhancerMenu = document.getElementById("enhancerMenuID");
ytEnhancerMenu2 = document.getElementById("enhancerMenuID2");
ytThumbnailBttn = document.getElementById("ytThumbnailBttn");
ytLoopBttn = document.getElementById("ytLoopBttn");
ytRangeEnd = document.getElementById("rangeEndID");
ytRangeStart = document.getElementById("rangeStartID");
ytFloatBttn = document.getElementById("ytFloatBttn");
ytDownloadBttn = document.getElementById("ytDownloadBttn");
volumeContainer = document.getElementById("volumeContainerID");
volumeLbl = document.getElementById("volumeValueLbl");
endlessPlayTag = document.getElementById("endlessPlayID");
ytThumbImgMenu = document.getElementById("ytThumbMenuID");
ytAMaxDefaultImg = document.getElementById("ytAMaxDefaultImgID");
ytAHqDefaultImg = document.getElementById("ytAHqDefaultImgID");
ytAMedDefaultImg = document.getElementById("ytAMedDefaultImgID");
ytASdDefaultImg = document.getElementById("ytASdDefaultImgID");
ytMaxDefaultImg = document.getElementById("ytMaxDefaultImgID");
ytHqDefaultImg = document.getElementById("ytHqDefaultImgID");
ytMqDefaultImg = document.getElementById("ytMqDefaultImgID");
ytSdDefaultImg = document.getElementById("ytSdDefaultImgID");
poppedContainer = document.getElementById("draggable");
ytIfrm = document.getElementById("popIframe");
slugInputTag = document.getElementById("slugCopyZone");
// Video Controler
video = document.getElementsByTagName("video")[0];
// Container of actual player (Used for floating window)
containerOfPlyrWndow = document.getElementById("player-container");
} }
const setupProc = () => { const setupProc = () => {
poppedContainer = document.createElement("DIV"); part = "https://img.youtube.com/vi/";
ytThumbImgMenu = document.createElement("DIV"); slugInputTag.value = video.baseURI.slice(32, 32+11);
ytEnhancerMenu = document.createElement("DIV"); ytRangeStart.value = "0:00";
ytThumbnailBttn = document.createElement("IMG");
ytDownloadBttn = document.createElement("IMG");
ytLoopBttn = document.createElement("IMG");
ytFloatBttn = document.createElement("IMG");
ytMaxDefaultImg = document.createElement("IMG");
ytHqDefaultImg = document.createElement("IMG");
ytMqDefaultImg = document.createElement("IMG");
ytSdDefaultImg = document.createElement("IMG");
ytAMaxDefaultImg = document.createElement("A"); // We need to wait for info to load before getting full duration
ytAHqDefaultImg = document.createElement("A"); setTimeout(function () {
ytAMedDefaultImg = document.createElement("A"); videoTimeLength = document.getElementsByClassName("ytp-time-duration")[0].innerText;
ytASdDefaultImg = document.createElement("A"); ytRangeEnd.value = videoTimeLength;
ytIfrm = document.createElement("IFRAME"); }, 2000);
// Loop range controls // Only setting these up if we need to load controls' info
ytRangeSection = document.createElement("SECTION"); if (!controlsWereLoaded) {
ytRangeStart = document.createElement("INPUT"); setbuttonImage(ytThumbnailBttn, "/icons/thumbnailOff.png");
setbuttonImage(ytLoopBttn, "/icons/loopFalse.png");
setbuttonImage(ytFloatBttn, "/icons/floatPlayer.png");
setbuttonImage(ytDownloadBttn, "/icons/downloadVid.png");
// Get nodes for page work // Set onclick actions
containerOfPlyrWndow = document.getElementById("player-container"); // Container of actual player - Used for floating window ytThumbnailBttn.addEventListener("click", showThumbImageVew);
part = "https://img.youtube.com/vi/"; ytLoopBttn.addEventListener("click", setLoop);
ytFloatBttn.addEventListener("click", toggleFloat);
endlessPlayTag.addEventListener("click", toggleEndlessPlay);
ytDownloadBttn.addEventListener("click", downloadVideo);
video.addEventListener("wheel", manageVolume);
// Dragable window for floating video event setup
dragVideo(poppedContainer);
// Append to nodes as required // Remove download button if system doesn't support youtube-dl functionality
ytThumbnailBttn.title = "Video Thumbnails..."; if (!OSName.includes("MacOS") && !OSName.includes("UNIX") && !OSName.includes("Linux")) {
ytLoopBttn.title = "Start Loop..."; console.log("System does not support downloader...");
ytFloatBttn.title = "Float Video Container"; ytEnhancerMenu.removeChild(ytDownloadBttn);
ytRangeStart.title = "Loop Range Start"; }
ytRangeEnd.title = "Loop Range End";
ytRangeStart.type = "text";
ytRangeStart.value = "0:00";
// Insert
ytEnhancerMenu.appendChild(ytThumbnailBttn);
ytEnhancerMenu.appendChild(ytLoopBttn);
ytEnhancerMenu.appendChild(ytRangeSection);
ytEnhancerMenu.appendChild(ytFloatBttn);
if (OSName.includes("MacOS") || OSName.includes("UNIX") ||
OSName.includes("Linux")) {
console.log("System supports downloader...");
console.log("OS is : " + OSName);
ytEnhancerMenu.appendChild(ytDownloadBttn);
} }
ytRangeSection.append(ytRangeStart); // ---- Hide controls if fullscreen using obsever ----
ytRangeSection.append(ytRangeEnd);
document.body.appendChild(poppedContainer);
document.body.appendChild(ytThumbImgMenu);
document.body.appendChild(ytEnhancerMenu);
ytAMaxDefaultImg.appendChild(ytMaxDefaultImg);
ytAHqDefaultImg.appendChild(ytHqDefaultImg);
ytAMedDefaultImg.appendChild(ytMqDefaultImg);
ytASdDefaultImg.appendChild(ytSdDefaultImg);
ytThumbImgMenu.appendChild(ytAMaxDefaultImg);
ytThumbImgMenu.appendChild(ytAHqDefaultImg);
ytThumbImgMenu.appendChild(ytAMedDefaultImg);
ytThumbImgMenu.appendChild(ytASdDefaultImg);
poppedContainer.appendChild(ytIfrm);
// Set onclick actions
ytThumbnailBttn.addEventListener("click", showThumbImageVew);
ytLoopBttn.addEventListener("click", setLoop);
ytFloatBttn.addEventListener("click", toggleFloat);
ytDownloadBttn.addEventListener("click", downloadVideo);
video.addEventListener("wheel", manageVolume);
// Observer target for fullscreen action... // Observer target for fullscreen action...
targetNode = document.getElementsByTagName('ytd-app')[0]; let targetNode = document.getElementsByTagName('ytd-app')[0];
// Create an observer instance linked to the callback function // Create an observer instance linked to the callback function
const observer = new MutationObserver(mutationcallback); observer = new MutationObserver(mutationCallback);
// Start observing the target node for configured mutations // Start observing the target node for configured mutations
observer.observe(targetNode, config); observer.observe(targetNode, observerConfig);
// Dragable window for floating video // ---- Endless play obsever ----
dragVideo(poppedContainer); // Create an observer instance linked to the callback function
observer2 = new MutationObserver(mutationCallback);
ytThumbnailBttn.src = browser.extension.getURL("/icons/thumbnailOff.png"); // Start observing the target node for configured mutations
ytLoopBttn.src = browser.extension.getURL("/icons/loopFalse.png"); if (endlessPlayTag.checked == true) {
ytFloatBttn.src = browser.extension.getURL("/icons/floatPlayer.png"); endlessPlayTag.setAttribute("checked", true);
ytDownloadBttn.src = browser.extension.getURL("/icons/downloadVid.png"); console.log("Endless play checked. Starting observer...");
observer2.observe(document, observerConfig2);
// Set trget of Thumbnails of video }
ytAMaxDefaultImg.target = "_blank";
ytAHqDefaultImg.target = "_blank";
ytAMedDefaultImg.target = "_blank";
ytASdDefaultImg.target = "_blank";
// Theming & Apply Styles
ytThumbImgMenu.className = "ytThumbMenuStyle";
ytMaxDefaultImg.className = "thumbImageStyle";
ytHqDefaultImg.className = "thumbImageStyle";
ytMqDefaultImg.className = "thumbImageStyle";
ytSdDefaultImg.className = "thumbImageStyle";
ytEnhancerMenu.className = "ytMenuStyle";
ytThumbnailBttn.className = "imageStyle";
ytLoopBttn.className = "imageStyle";
ytFloatBttn.className = "imageStyle";
ytDownloadBttn.className = "imageStyle";
ytEnhancerMenu.id = "enhancerMenuIDRef";
poppedContainer.id = "draggable";
ytRangeStart.id = "rangeStartID";
ytRangeEnd.id = "rangeEndID";
poppedContainer.style.display = "none";
ytEnhancerMenu.style.display = "block";
slugInputTag.style.display = "block";
ytIfrm.setAttribute("allow", "accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture");
ytIfrm.setAttribute("frameborder", "0");
ytIfrm.setAttribute("autoplay", "");
ytIfrm.setAttribute("allowfullscreen", "true");
ytIfrm.setAttribute("width", "650px");
ytIfrm.setAttribute("height", "400px");
} }
// Functions // Functions
// Callback function to execute when mutations are observed // Callback function to execute when mutations are observed
const mutationcallback = (mutationsList, observer) => { const mutationCallback = (mutationsList, observer) => {
for(let mutation of mutationsList) { for(let mutation of mutationsList) {
if (mutation.type === 'attributes') { if (mutation.type === 'attributes') {
controlManager(mutation.target); controlManager(mutation.target);
} else if (mutation.type === 'childList') {
let elm = document.querySelector(dialogElementQueryRef).parentElement;
elmDisplayState = elm.style.display;
if (elmDisplayState !== 'none') {
clickDialog();
}
} }
} }
}; };
@ -184,16 +185,34 @@
const controlManager = (elm) => { const controlManager = (elm) => {
attrib = elm.getAttribute('masthead-hidden_'); attrib = elm.getAttribute('masthead-hidden_');
if (attrib == null) { // if out of fullscreen if (attrib == null) { // if out of fullscreen
ytEnhancerMenu.style.display = "block"; ytEnhancerMenu.style.display = "block";
slugInputTag.style.display = "block"; ytEnhancerMenu2.style.display = "block";
} else { // if fullscreen } else { // if fullscreen
ytEnhancerMenu.style.display = "none"; ytEnhancerMenu.style.display = "none";
slugInputTag.style.display = "none"; ytEnhancerMenu2.style.display = "none";
} }
} }
const downloadVideo = () => { const clickDialog = () => {
browser.runtime.sendMessage( { "url": video.baseURI } ); console.log("Clicking dialog confirm to continue playing...");
document
.querySelector(dialogElementQueryRef)
.querySelector('yt-button-renderer[dialog-confirm]')
.click();
}
const toggleEndlessPlay = () => {
isChecked = endlessPlayTag.getAttribute("checked");
if (isChecked) {
endlessPlayTag.setAttribute("checked", false);
console.log("Stopping endless play...");
observer2.disconnect();
} else {
endlessPlayTag.setAttribute("checked", true);
console.log("Starting endless play...");
observer2.observe(confirmDialogElement, observerConfig2);
}
console.log(observer2);
} }
const showThumbImageVew = (e) => { const showThumbImageVew = (e) => {
@ -201,7 +220,7 @@
if (ytThumbImgMenu.style.display == "block") { if (ytThumbImgMenu.style.display == "block") {
ytThumbImgMenu.style.display = "none"; ytThumbImgMenu.style.display = "none";
ytThumbnailBttn.src = browser.extension.getURL("/icons/thumbnailOff.png"); setbuttonImage(ytThumbnailBttn, "/icons/thumbnailOff.png");
} else { } else {
ytAMaxDefaultImg.href = part + videoSlug + "/maxresdefault.jpg"; ytAMaxDefaultImg.href = part + videoSlug + "/maxresdefault.jpg";
ytAHqDefaultImg.href = part + videoSlug + "/hqdefault.jpg"; ytAHqDefaultImg.href = part + videoSlug + "/hqdefault.jpg";
@ -211,12 +230,7 @@
ytHqDefaultImg.src = part + videoSlug + "/hqdefault.jpg"; ytHqDefaultImg.src = part + videoSlug + "/hqdefault.jpg";
ytMqDefaultImg.src = part + videoSlug + "/mqdefault.jpg"; ytMqDefaultImg.src = part + videoSlug + "/mqdefault.jpg";
ytSdDefaultImg.src = part + videoSlug + "/sddefault.jpg"; ytSdDefaultImg.src = part + videoSlug + "/sddefault.jpg";
ytMaxDefaultImg.title = "Max Resolution Default"; setbuttonImage(ytThumbnailBttn, "/icons/thumbnailOn.png");
ytHqDefaultImg.title = "High Quality Default";
ytMqDefaultImg.title = "Medium Quality Default";
ytSdDefaultImg.title = "Standard Quality Default";
ytThumbnailBttn.src = browser.extension.getURL("/icons/thumbnailOn.png");
ytThumbImgMenu.style.display = "block"; ytThumbImgMenu.style.display = "block";
} }
return; return;
@ -228,10 +242,11 @@
if (loopingInterval) { if (loopingInterval) {
console.log("Unsetting interval for loop check..."); console.log("Unsetting interval for loop check...");
clearInterval(ytdVideoIntervalLoop); clearInterval(ytVideoIntervalLoop);
loopingInterval = false; loopingInterval = false;
ytLoopBttn.title = "Start Loop..."; ytLoopBttn.title = "Start Loop...";
ytLoopBttn.src = browser.extension.getURL("/icons/loopFalse.png"); let ipath = browser.extension.getURL("/icons/loopFalse.png");
setbuttonImage(ytLoopBttn, ipath);
return ; return ;
} }
@ -240,12 +255,14 @@
console.log("Setting default loop marker..."); console.log("Setting default loop marker...");
video.loop = true; video.loop = true;
ytLoopBttn.title = "Stop Loop..."; ytLoopBttn.title = "Stop Loop...";
ytLoopBttn.src = browser.extension.getURL("/icons/loopTrue.png"); let ipath = browser.extension.getURL("/icons/loopTrue.png");
setbuttonImage(ytLoopBttn, ipath);
} else { } else {
console.log("Unsetting default loop marker..."); console.log("Unsetting default loop marker...");
video.loop = false; video.loop = false;
ytLoopBttn.title = "Start Loop..."; ytLoopBttn.title = "Start Loop...";
ytLoopBttn.src = browser.extension.getURL("/icons/loopFalse.png"); let ipath = browser.extension.getURL("/icons/loopFalse.png");
setbuttonImage(ytLoopBttn, ipath);
} }
return ; return ;
} else { } else {
@ -285,11 +302,12 @@
// Setup interval check for 1 sec and compare value of current pos to end // Setup interval check for 1 sec and compare value of current pos to end
ytLoopBttn.title = "Stop Loop..."; ytLoopBttn.title = "Stop Loop...";
ytLoopBttn.src = browser.extension.getURL("/icons/loopTrue.png"); let ipath = browser.extension.getURL("/icons/loopTrue.png");
setbuttonImage(ytLoopBttn, ipath);
loopingInterval = true; loopingInterval = true;
console.log("Setting interval for loop check..."); console.log("Setting interval for loop check...");
ytdVideoIntervalLoop = setInterval(checkLoopStuff, 1000); ytVideoIntervalLoop = setInterval(checkLoopStuff, 1000);
} }
} }
@ -326,10 +344,33 @@
let delta; let delta;
e.preventDefault(); // Keep page from scrolling while in video area e.preventDefault(); // Keep page from scrolling while in video area
shouldHideVol = false;
volumeContainer.style.display = "block";
// Detect scroll direction // Detect scroll direction
let incramentType = "+";
if (e.wheelDelta) delta = e.wheelDelta; else delta = -1 * e.deltaY; if (e.wheelDelta) delta = e.wheelDelta; else delta = -1 * e.deltaY;
// Vol UP || Vol DOWN // Vol UP || Vol DOWN
if (delta > 0) video.volume += 0.05; else if (delta < 0) video.volume -= 0.05; let tmpVol = video.volume.toFixed(2);
let volume = Math.round((tmpVol * 100), 2).toFixed(0);
if (delta > 0) {
incramentType = "+";
while ((volume % 5) !== 0) { volume += 1; }
video.volume = (volume/100) + 0.05;
} else if (delta < 0) {
incramentType = "-";
while ((volume % 5) !== 0) { volume -= 1; }
video.volume = (volume/100) - 0.05;
}
volumeLbl.innerText = incramentType + Math.round((video.volume * 100), 1).toFixed(0);
setTimeout(function () {
if (shouldHideVol) {
volumeContainer.style.display = "none";
}
}, 1000);
shouldHideVol = true;
} }
const dragVideo = (elmnt) => { const dragVideo = (elmnt) => {
@ -375,28 +416,15 @@
} }
} }
const checkPg = () => { const downloadVideo = () => {
if (!document.getElementById("enhancerMenuIDRef")) { browser.runtime.sendMessage( { "url": video.baseURI } );
let existCondition = setInterval(function() { }
if (document.getElementById("masthead-container")) {
clearInterval(existCondition); const setbuttonImage = (elm, path) => {
preSetupProc(); elm.style.backgroundImage = "url('" + browser.extension.getURL(path); + "')";
setupProc();
count = 0;
} else {
if (count == 12) { // ~ 6 sec through half sec loops
count = 0;
clearInterval(existCondition);
} else {
count++;
}
}
}, 500); // check every 500ms
} else {
preSetupProc();
}
} }
// Start init // Start init
checkPg(); preSetupProc();
setupProc();
}()); }());

View File

@ -1,4 +1,16 @@
#slugCopyZone, .ytThumbMenuStyle, .ytMenuStyle { /* Tag CSS */
/* Youtube stylers based off of its tags... */
yt-formatted-string > a {
color: rgba(125, 65, 0, 0.84) !important;
}
yt-formatted-string > a:hover {
color: rgba(150, 21, 176, 0.97);
}
/* ID CSS */
#enhancerMenuID2, .ytThumbMenuStyle, .ytMenuStyle {
z-index: 100; z-index: 100;
position: fixed; position: fixed;
background: rgba(0,0,0,0.64); background: rgba(0,0,0,0.64);
@ -6,52 +18,26 @@
overflow: auto; overflow: auto;
} }
#slugCopyZone { #enhancerMenuID2 {
bottom: 0%; bottom: 0%;
left: 35%; left: 10%;
width: 10em; width: auto;
text-align: center; color: #ffffff;
color: #fff;
} }
#enhancerMenuIDRef, #slugCopyZone { #enhancerMenuID, #enhancerMenuID2 {
z-index: 5; z-index: 5;
} }
.ytThumbMenuStyle { #volumeContainerID {
display: none; display: none;
bottom: 20px; font-size:200%;
} color: #ffffff;
text-align: center;
.ytMenuStyle {
top: 45%;
width: 4em;
}
.imageStyle {
width: 32px;
height: 32px;
margin-right: 0.5em;
}
.imageStyle:hover {
background:rgba(12,160,193,.64);
cursor: pointer;
}
#xIconHoverTop {
margin-bottom: 80px;
}
.thumbImageStyle {
width: 200px;
height: 100px;
margin: 0em 1em 0em 1em;
float: left;
} }
#draggable { #draggable {
z-index: 100; z-index: 9999;
position: fixed; position: fixed;
right: 0px; right: 0px;
bottom: 0px; bottom: 0px;
@ -63,12 +49,51 @@
background: rgba(64, 64, 64, 0.64) background: rgba(64, 64, 64, 0.64)
} }
#rangeEndID, #rangeStartID {
/* Youtube stylers based off of its tags... */ width: 56px;
yt-formatted-string > a { overflow-x: scroll;
color: rgba(125, 65, 0, 0.84) !important; overflow-y: hidden;
} }
yt-formatted-string > a:hover { #slugCopyZone, #rangeEndID, #rangeStartID {
color: rgba(150, 21, 176, 0.97); text-align: center;
background: rgba(0,0,0,0.0);
color: #fff;
}
/* Class CSS */
.ytMenuStyle {
top: 40%;
width: 42px;
overflow: hidden;
}
.ytThumbMenuStyle {
display: none;
bottom: 20px;
}
.imageStyle {
width: 42px;
height: 42px;
background-repeat: no-repeat;
background-position: center;
background-color: rgba(0,0,0,.64);
background-size: 42px 42px;
}
.imageStyle:hover {
background: rgba(12,160,193,.64);
cursor: pointer;
background-repeat: no-repeat;
background-position: center;
background-size: 28px 28px;
}
.thumbImageStyle {
width: 200px;
height: 100px;
margin: 0em 1em 0em 1em;
float: left;
} }