3.0.0.13 release - dynamic selectors config loading from server added.

This commit is contained in:
Anarios
2023-12-04 11:04:14 +01:00
parent 0105c6c141
commit b6367ae334
11 changed files with 3107 additions and 6568 deletions
+20 -35
View File
@@ -1,77 +1,62 @@
//--- Import Button Functions ---//
import {
getButtons,
getLikeButton,
getDislikeButton,
checkForSignInButton,
} from "./src/buttons";
//--- Import State Functions ---//
import {
isMobile,
isShorts,
isVideoDisliked,
isVideoLiked,
getState,
setState,
setInitialState,
setLikes,
setDislikes,
getLikeCountFromButton,
LIKED_STATE,
DISLIKED_STATE,
NEUTRAL_STATE,
initExtConfig,
} from "./src/state";
//--- Import Video & Browser Functions ---//
import {
numberFormat,
getBrowser,
getVideoId,
isVideoLoaded,
cLog,
} from "./src/utils";
import { createRateBar } from "./src/bar";
import {
sendVote,
likeClicked,
dislikeClicked,
addLikeDislikeEventListener,
storageChangeHandler,
} from "./src/events";
initExtConfig();
await initExtConfig();
let jsInitChecktimer = null;
let isSetInitialStateDone = false;
function setEventListeners(evt) {
function checkForJS_Finish() {
async function setEventListeners (evt) {
async function checkForJS_Finish () {
try {
if (isShorts() || (getButtons()?.offsetParent && isVideoLoaded())) {
addLikeDislikeEventListener();
setInitialState();
isSetInitialStateDone = true;
getBrowser().storage.onChanged.addListener(storageChangeHandler);
clearInterval(jsInitChecktimer);
jsInitChecktimer = null;
}
} catch(exception) {
if(!isSetInitialStateDone) {
setInitialState();
addLikeDislikeEventListener();
await setInitialState();
isSetInitialStateDone = true;
getBrowser().storage.onChanged.addListener(storageChangeHandler);
}
} catch (exception) {
if (!isSetInitialStateDone) {
cLog("error");
await setInitialState();
}
}
}
jsInitChecktimer = setInterval(checkForJS_Finish, 111);
if (jsInitChecktimer !== null) clearInterval(jsInitChecktimer);
jsInitChecktimer = setInterval(await checkForJS_Finish, 111);
}
setEventListeners();
await setEventListeners();
document.addEventListener("yt-navigate-finish", function (event) {
document.addEventListener("yt-navigate-finish", async function (event) {
if (jsInitChecktimer !== null) clearInterval(jsInitChecktimer);
window.returnDislikeButtonlistenersSet = false;
setEventListeners();
await setEventListeners();
});
+1 -1
View File
@@ -60,7 +60,7 @@ function createRateBar(likes, dislikes) {
colorLikeStyle = "; background-color: " + getColorFromTheme(true);
colorDislikeStyle = "; background-color: " + getColorFromTheme(false);
}
let actions = isNewDesign() && getButtons().id === "top-level-buttons-computed"
let actions = isNewDesign() && getButtons().id === "top-level-buttons-computed"
? getButtons() : document.getElementById("menu-container");
(
actions || document.querySelector("ytm-slim-video-action-bar-renderer")
+26 -39
View File
@@ -1,16 +1,15 @@
import { isMobile, isShorts } from "./state";
import { isInViewport } from "./utils";
import { isMobile, isShorts, extConfig } from "./state";
import { isInViewport, querySelector, querySelectorAll } from './utils';
function getButtons() {
//--- If Watching Youtube Shorts: ---//
if (isShorts()) {
let elements = document.querySelectorAll(
isMobile()
? "ytm-like-button-renderer"
: "#like-button > ytd-like-button-renderer"
);
let elements = isMobile()
? querySelectorAll(extConfig.selectors.buttons.shorts.mobile)
: querySelectorAll(extConfig.selectors.buttons.shorts.desktop);
for (let element of elements) {
//Youtube Shorts can have multiple like/dislike buttons when scrolling through videos
//YouTube Shorts can have multiple like/dislike buttons when scrolling through videos
//However, only one of them should be visible (no matter how you zoom)
if (isInViewport(element)) {
return element;
@@ -19,48 +18,33 @@ function getButtons() {
}
//--- If Watching On Mobile: ---//
if (isMobile()) {
return document.querySelector(".slim-video-action-bar-actions");
return document.querySelector(extConfig.selectors.buttons.regular.mobile);
}
//--- If Menu Element Is Displayed: ---//
if (document.getElementById("menu-container")?.offsetParent === null) {
return document.querySelector("ytd-menu-renderer.ytd-watch-metadata > div");
if (querySelector(extConfig.selectors.menuContainer)?.offsetParent === null) {
return querySelector(extConfig.selectors.buttons.regular.desktopMenu)
//--- If Menu Element Isn't Displayed: ---//
} else {
return document
.getElementById("menu-container")
?.querySelector("#top-level-buttons-computed");
return querySelector(extConfig.selectors.buttons.regular.desktopNoMenu);
}
}
function getLikeButton() {
return getButtons().children[0].tagName ===
"YTD-SEGMENTED-LIKE-DISLIKE-BUTTON-RENDERER"
? document.querySelector("#segmented-like-button") !== null ? document.querySelector("#segmented-like-button") : getButtons().children[0].children[0]
: getButtons().querySelector("like-button-view-model") ?? getButtons().children[0];
'YTD-SEGMENTED-LIKE-DISLIKE-BUTTON-RENDERER'
? querySelector(extConfig.selectors.buttons.likeButton.segmented) ?? querySelector(extConfig.selectors.buttons.likeButton.segmentedGetButtons, getButtons())
: querySelector(extConfig.selectors.buttons.likeButton.notSegmented, getButtons())
}
function getLikeTextContainer() {
return (
getLikeButton().querySelector("#text") ??
getLikeButton().getElementsByTagName("yt-formatted-string")[0] ??
getLikeButton().querySelector("span[role='text']")
);
return querySelector(extConfig.selectors.likeTextContainer, getLikeButton());
}
function getDislikeButton() {
if (getButtons().children[0].tagName === 'YTD-SEGMENTED-LIKE-DISLIKE-BUTTON-RENDERER') {
if (getButtons().children[0].children[1] === undefined) {
return document.querySelector('#segmented-dislike-button');
} else {
return getButtons().children[0].children[1];
}
} else {
if (getButtons().querySelector("dislike-button-view-model")) {
return getButtons().querySelector("dislike-button-view-model");
} else {
return getButtons().children[1];
}
}
return getButtons().children[0].tagName ===
'YTD-SEGMENTED-LIKE-DISLIKE-BUTTON-RENDERER'
? querySelector(extConfig.selectors.buttons.dislikeButton.segmented) ?? querySelector(extConfig.selectors.buttons.dislikeButton.segmentedGetButtons, getButtons())
: querySelector(extConfig.selectors.buttons.dislikeButton.notSegmented, getButtons())
}
function createDislikeTextContainer() {
@@ -82,10 +66,13 @@ function createDislikeTextContainer() {
}
function getDislikeTextContainer() {
let result =
getDislikeButton().querySelector("#text") ??
getDislikeButton().getElementsByTagName("yt-formatted-string")[0] ??
getDislikeButton().querySelector("span[role='text']");
let result;
for (const selector of extConfig.selectors.dislikeTextContainer) {
result = getDislikeButton().querySelector(selector);
if (result !== null) {
break;
}
}
if (result == null) {
result = createDislikeTextContainer();
}
+47 -6
View File
@@ -11,8 +11,8 @@ import {
getVideoId,
cLog,
numberFormat,
getColorFromTheme,
} from "./utils";
getColorFromTheme, querySelector
} from './utils';
import { localize } from "./utils";
import { createStarRating } from "./starRating";
@@ -31,6 +31,33 @@ let extConfig = {
showTooltipPercentage: false,
tooltipPercentageMode: "dash_like",
numberDisplayReformatLikes: false,
selectors: {
dislikeTextContainer: [],
likeTextContainer: [],
buttons: {
shorts: {
mobile: [],
desktop: [],
},
regular: {
mobile: [],
desktopMenu: [],
desktopNoMenu: [],
},
likeButton: {
segmented: [],
segmentedGetButtons: [],
notSegmented: []
},
dislikeButton: {
segmented: [],
segmentedGetButtons: [],
notSegmented: []
}
},
menuContainer: [],
roundedDesign: [],
}
};
let storedData = {
@@ -52,7 +79,7 @@ function isNewDesign() {
}
function isRoundedDesign() {
return document.getElementById("segmented-like-button") !== null;
return querySelector(extConfig.selectors.roundedDesign) !== null;
}
let mutationObserver = new Object();
@@ -240,6 +267,7 @@ async function setState(storedData) {
? LIKED_STATE
: NEUTRAL_STATE;
let statsSet = false;
cLog("Video is loaded. Adding buttons...");
let videoId = getVideoId(window.location.href);
let likeCount = getLikeCountFromButton() || null;
@@ -266,11 +294,11 @@ async function setState(storedData) {
}
}
function setInitialState() {
setState(storedData);
async function setInitialState () {
await setState(storedData);
}
function initExtConfig() {
async function initExtConfig () {
initializeDisableVoteSubmission();
initializeColoredThumbs();
initializeColoredBar();
@@ -279,6 +307,19 @@ function initExtConfig() {
initializeTooltipPercentage();
initializeTooltipPercentageMode();
initializeNumberDisplayReformatLikes();
await initializeSelectors();
}
async function initializeSelectors () {
console.log("initializing selectors")
let result = await fetch(`${apiUrl}/configs/selectors`, {
method: "GET",
headers: {
Accept: "application/json",
}
}).then((response) => response.json()).catch((error) => {});
extConfig.selectors = result ?? extConfig.selectors;
console.log(result)
}
function initializeDisableVoteSubmission() {
+23
View File
@@ -143,6 +143,27 @@ function getColorFromTheme(voteIsLike) {
return colorString;
}
function querySelector(selectors, element) {
let result;
for (const selector of selectors) {
result = (element ?? document).querySelector(selector);
if (result !== null) {
return result;
}
}
}
function querySelectorAll(selectors) {
let result;
for (const selector of selectors) {
result = document.querySelectorAll(selector);
if (result.length !== 0) {
return result;
}
}
return result;
}
export {
numberFormat,
getBrowser,
@@ -152,4 +173,6 @@ export {
cLog,
getColorFromTheme,
localize,
querySelector,
querySelectorAll
};