// ==UserScript==
// @name YouTube Defaulter
// @namespace https://greasyfork.org/ru/users/901750-gooseob
// @version 1.11.19
// @description Set speed, quality, subtitles and volume as default globally or specialize for each channel
// @author GooseOb
// @license MIT
// @grant window.onurlchange
// @match https://www.youtube.com/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=youtube.com
// ==/UserScript==
(function(){// src/config/update.ts
var update = (cfg) => {
const doUpdate = cfg._v !== 4;
if (doUpdate) {
switch (cfg._v) {
case 2:
cfg.flags.standardMusicSpeed = false;
cfg._v = 3;
case 3:
cfg.global.quality = cfg.global.qualityMax;
delete cfg.global.qualityMax;
for (const key in cfg.channels) {
const currCfg = cfg.channels[key];
currCfg.quality = currCfg.qualityMax;
delete currCfg.qualityMax;
}
cfg._v = 4;
}
}
return doUpdate;
};
// src/config/value.ts
var cfgLocalStorage = localStorage.YTDefaulter;
var value = cfgLocalStorage ? JSON.parse(cfgLocalStorage) : {
_v: 4,
global: {},
channels: {},
flags: {
shortsToUsual: false,
newTab: false,
copySubs: false,
standardMusicSpeed: false,
enhancedBitrate: false
}
};
// src/config/save.ts
var saveLS = (newCfg) => {
saveLSRaw(JSON.stringify(newCfg));
};
var saveLSRaw = (raw) => {
localStorage.YTDefaulter = raw;
};
var save = (raw) => {
const newCfg = JSON.parse(raw);
if (typeof newCfg !== "object" || !newCfg._v) {
throw new Error("Invalid data");
}
if (update(newCfg)) {
saveLS(newCfg);
} else {
saveLSRaw(raw);
}
Object.assign(value, newCfg);
};
// src/config/prune.ts
var prune = () => {
outer:
for (const key in value.channels) {
const channelCfg = value.channels[key];
if (channelCfg.subtitles)
continue;
for (const cfgKey in channelCfg) {
if (cfgKey !== "subtitles")
continue outer;
}
delete value.channels[key];
}
};
// src/utils/ref.ts
var ref = (val) => ({ val });
// src/config/current-channel.ts
var username = ref("");
var channel = () => value.channels[username.val] ||= {};
// src/text.ts
var translations = {
"be-BY": {
OPEN_SETTINGS: "Адкрыць дадатковыя налады",
SUBTITLES: "Субтытры",
SPEED: "Хуткасьць",
CUSTOM_SPEED: "Свая хуткасьць",
CUSTOM_SPEED_HINT: 'Калі вызначана, будзе выкарыстоўвацца замест "Хуткасьць"',
QUALITY: "Якасьць",
VOLUME: "Гучнасьць, %",
GLOBAL: "глябальна",
LOCAL: "гэты канал",
SHORTS: "Адкрываць shorts як звычайныя",
NEW_TAB: "Адкрываць відэа ў новай картцы",
COPY_SUBS: "Капіяваць субтытры ў поўнаэкранным, Ctrl+C",
STANDARD_MUSIC_SPEED: "Звычайная хуткасьць на каналах музыкаў",
ENHANCED_BITRATE: "Палепшаны бітрэйт (для карыстальнікаў Premium)",
SAVE: "Захаваць",
EXPORT: "Экспарт",
IMPORT: "Імпарт"
}
};
var text = {
OPEN_SETTINGS: "Open additional settings",
SUBTITLES: "Subtitles",
SPEED: "Speed",
CUSTOM_SPEED: "Custom speed",
CUSTOM_SPEED_HINT: 'If defined, will be used instead of "Speed"',
QUALITY: "Quality",
VOLUME: "Volume, %",
GLOBAL: "global",
LOCAL: "this channel",
SHORTS: "Open shorts as a usual video",
NEW_TAB: "Open videos in a new tab",
COPY_SUBS: "Copy subtitles by Ctrl+C in fullscreen mode",
STANDARD_MUSIC_SPEED: "Normal speed on artist channels",
ENHANCED_BITRATE: "Quality: Enhanced bitrate (for Premium users)",
SAVE: "Save",
DEFAULT: "-",
EXPORT: "Export",
IMPORT: "Import"
};
// src/utils/$.ts
var $ = (id) => document.getElementById(id);
// src/utils/debounce.ts
var debounce = (callback, delay) => {
let timeout;
return (...args) => {
clearTimeout(timeout);
timeout = window.setTimeout(() => {
callback(...args);
}, delay);
};
};
// src/utils/is-descendant-or-the-same.ts
var isDescendantOrTheSame = (child, parents) => {
while (child !== null) {
if (parents.includes(child))
return true;
child = child.parentNode;
}
return false;
};
// src/utils/restore-focus-after.ts
var restoreFocusAfter = (cb) => {
const el = document.activeElement;
cb();
el.focus();
};
// src/utils/until.ts
var until = (getItem, check, msToWait = 1e4, msReqTimeout = 20) => new Promise((res, rej) => {
const item = getItem();
if (check(item))
return res(item);
const reqLimit = msToWait / msReqTimeout;
let i = 0;
const interval = setInterval(() => {
const item2 = getItem();
if (check(item2)) {
clearInterval(interval);
res(item2);
} else if (++i > reqLimit) {
clearInterval(interval);
rej(new Error("Timeout: item wasn't found"));
}
}, msReqTimeout);
});
var untilAppear = (getItem, msToWait) => until(getItem, Boolean, msToWait);
// src/utils/find-in-node-list.ts
var findInNodeList = (list, finder) => {
for (const item of list) {
if (finder(item))
return item;
}
return null;
};
// src/utils/get-el-creator.ts
var getElCreator = (tag) => (props) => Object.assign(document.createElement(tag), props);
// src/utils/delay.ts
var delay = (ms) => new Promise((res) => setTimeout(res, ms));
// src/style.ts
var m = "#" + "YTDef-menu";
var d = " div";
var i = " input";
var s = " select";
var bg = "var(--yt-spec-menu-background)";
var underline = "border-bottom: 2px solid var(--yt-spec-text-primary);";
var style = getElCreator("style")({
textContent: `
#${"YTDef-btn"} {position: relative; margin-left: 8px}
${m} {
display: flex;
visibility: hidden;
color: var(--yt-spec-text-primary);
font-size: 14px;
flex-direction: column;
position: fixed;
background: ${bg};
border-radius: 2rem;
padding: 1rem;
text-align: center;
box-shadow: 0px 4px 32px 0px var(--yt-spec-static-overlay-background-light);
z-index: 2202
}
.control-cont > button {margin: .2rem}
${m + d} {display: flex; margin-bottom: 1rem}
${m + d + d} {
flex-direction: column;
margin: 0 2rem
}
${m + d + d + d} {
flex-direction: row;
margin: 1rem 0
}
${m + s}, ${m + i} {
text-align: center;
background: ${bg};
border: none;
${underline}
color: inherit;
width: 5rem;
padding: 0;
margin-left: auto
}
${m} .${"YTDef-setting-hint"} {margin: 0; text-align: end}
${m + i} {outline: none}
${m + d + d + d}:focus-within > label, ${m} .check-cont:focus-within > label {${underline}}
${m} .check-cont {padding: 0 1rem}
${m + s} {appearance: none; outline: none}
${m} label {margin-right: 1.5rem; white-space: nowrap}
${m + i}::-webkit-outer-spin-button,
${m + i}::-webkit-inner-spin-button {-webkit-appearance: none; margin: 0}
${m + i}[type=number] {-moz-appearance: textfield}
${m + s}::-ms-expand {display: none}`
});
// src/listeners/click.ts
var onClick = (e) => {
const { shortsToUsual, newTab } = value.flags;
if (shortsToUsual || newTab) {
let el = e.target;
if (el.tagName !== "A") {
el = el.closest("a");
}
if (el) {
const isShorts = el.href.includes("/shorts/");
if (shortsToUsual && isShorts) {
el.href = el.href.replace("shorts/", "watch?v=");
}
const isUsual = el.href.includes("/watch?v=");
if (newTab && (isShorts || isUsual)) {
el.target = "_blank";
e.stopPropagation();
}
}
}
};
// src/element-getters.ts
var plr = () => $("movie_player");
var aboveTheFold = () => $("above-the-fold");
var actionsBar = () => $("actions")?.querySelector("ytd-menu-renderer");
var getPlrGetter = (plr2) => (selector) => () => plr2.querySelector(selector);
var plrGetters = (plr2) => {
const get = getPlrGetter(plr2);
return {
ad: get(".ytp-ad-player-overlay"),
video: get(".html5-main-video"),
subtitlesBtn: get(".ytp-subtitles-button"),
muteBtn: get(".ytp-mute-button"),
menu: {
element: get(".ytp-settings-menu"),
btn: get(".ytp-settings-button")
}
};
};
var plrMenuItemsGetter = (menu) => () => menu.querySelectorAll('.ytp-menuitem[role="menuitem"]');
var menuSubItems = (item) => item.querySelectorAll(".ytp-menuitem-label");
var channelUsernameElementGetter = (aboveTheFold2) => () => aboveTheFold2.querySelector(".ytd-channel-name > a");
var artistChannelBadge = (aboveTheFold2) => aboveTheFold2.querySelector(".badge-style-type-verified-artist");
var videoPlr = () => document.querySelector(".html5-video-player");
var videoPlrCaptions = (plr2) => plr2.querySelectorAll(".captions-text > span");
var popupContainer = () => document.querySelector("ytd-popup-container");
// src/player/menu.ts
var set = (getEl) => {
element ||= getEl.menu.element();
btn ||= getEl.menu.btn();
};
var element = null;
var btn = null;
var clickBtn = () => {
btn.click();
};
var isOpen = () => {
return element.style.display !== "none";
};
var setOpen = (bool) => {
if (bool !== isOpen())
btn.click();
};
var openItem = (item) => {
setOpen(true);
item.click();
return menuSubItems(element);
};
var settingItems = {
speed: null,
quality: null
};
var setSettingItems = (items) => {
const findIcon = (d2) => findInNodeList(items, (el) => !!el.querySelector(`path[d="${d2}"]`));
settingItems.speed = findIcon("M10,8v8l6-4L10,8L10,8z M6.3,5L5.7,4.2C7.2,3,9,2.2,11,2l0.1,1C9.3,3.2,7.7,3.9,6.3,5z M5,6.3L4.2,5.7C3,7.2,2.2,9,2,11 l1,.1C3.2,9.3,3.9,7.7,5,6.3z M5,17.7c-1.1-1.4-1.8-3.1-2-4.8L2,13c0.2,2,1,3.8,2.2,5.4L5,17.7z M11.1,21c-1.8-0.2-3.4-0.9-4.8-2 l-0.6,.8C7.2,21,9,21.8,11,22L11.1,21z M22,12c0-5.2-3.9-9.4-9-10l-0.1,1c4.6,.5,8.1,4.3,8.1,9s-3.5,8.5-8.1,9l0.1,1 C18.2,21.5,22,17.2,22,12z");
settingItems.quality = findIcon("M15,17h6v1h-6V17z M11,17H3v1h8v2h1v-2v-1v-2h-1V17z M14,8h1V6V5V3h-1v2H3v1h11V8z M18,5v1h3V5H18z M6,14h1v-2v-1V9H6v2H3v1 h3V14z M10,12h11v-1H10V12z");
};
var findInItem = (name, finder) => {
const prevItems = new Set(menuSubItems(element));
return findInNodeList(openItem(settingItems[name]), (item) => !prevItems.has(item) && finder(item));
};
// src/player/plr.ts
var setPlr = async (el) => {
const getEl = plrGetters(el);
isSpeedApplied = false;
await delay(1000);
await until(getEl.ad, (ad) => !ad, 200000);
video ||= getEl.video();
subtitlesBtn ||= getEl.subtitlesBtn();
muteBtn ||= getEl.muteBtn();
set(getEl);
restoreFocusAfter(clickBtn);
await delay(50);
restoreFocusAfter(clickBtn);
setSettingItems(await until(plrMenuItemsGetter(element), (arr) => !!arr.length));
if (!speedNormal)
restoreFocusAfter(() => {
speedNormal = findInItem("speed", (btn2) => !+btn2.textContent).textContent;
});
};
var isSpeedApplied = false;
var toggleSpeed = () => {
isSpeedApplied = !isSpeedApplied;
};
var speedNormal = "";
var video = null;
var subtitlesBtn = null;
var muteBtn = null;
// src/logger.ts
var err = (...msgs) => {
console.error("[YT-Defaulter]", ...msgs);
};
var outOfRange = (what) => {
err(what, "value is out of range");
};
// src/player/value-setters.ts
var comparators = {
quality: (target, current) => +target >= parseInt(current) && (value.flags.enhancedBitrate || !current.toLowerCase().includes("premium")),
speed: (target, current) => target === current
};
var setYT = (settingName) => (value3) => {
const isOpen2 = isOpen();
const compare = comparators[settingName];
const btn2 = findInItem(settingName, (btn3) => compare(value3, btn3.textContent));
if (btn2) {
btn2.click();
}
setOpen(isOpen2);
};
var valueSetters = {
speed: (value3) => {
setYT("speed")(isSpeedApplied ? speedNormal : value3);
toggleSpeed();
},
customSpeed: (value3) => {
try {
video.playbackRate = isSpeedApplied ? 1 : +value3;
toggleSpeed();
} catch {
outOfRange("Custom speed");
}
},
subtitles: (value3) => {
if (subtitlesBtn.ariaPressed !== value3.toString())
subtitlesBtn.click();
},
volume: (value3) => {
const num = +value3;
const isMuted = muteBtn.dataset.titleNoTooltip !== "Mute";
if (num === 0) {
if (!isMuted)
muteBtn.click();
} else {
if (isMuted)
muteBtn.click();
try {
video.volume = num / 100;
} catch {
outOfRange("Volume");
}
}
},
quality: setYT("quality")
};
// src/player/apply-settings.ts
var applySettings = (settings) => {
if (!isNaN(+settings.customSpeed)) {
valueSetters.customSpeed(settings.customSpeed);
}
delete settings.customSpeed;
restoreFocusAfter(() => {
for (const setting in settings) {
valueSetters[setting](settings[setting]);
}
setOpen(false);
});
};
// src/compute-settings.ts
var computeSettings = (doUseNormalSpeed) => {
const channel2 = channel();
const settings = {
...value.global,
...channel2
};
if (doUseNormalSpeed) {
settings.speed = speedNormal;
delete settings.customSpeed;
} else if ("customSpeed" in channel2) {
delete settings.speed;
} else if ("speed" in channel2) {
delete settings.customSpeed;
} else if ("customSpeed" in settings) {
delete settings.speed;
}
return settings;
};
// src/listeners/keyup.ts
var onKeyup = (e) => {
if (e.code === "Enter") {
onClick(e);
} else if (e.ctrlKey && !e.shiftKey) {
if (value.flags.copySubs && e.code === "KeyC") {
const plr3 = videoPlr();
if (plr3?.classList.contains("ytp-fullscreen")) {
const text2 = Array.from(videoPlrCaptions(plr3), (line) => line.textContent).join(" ");
navigator.clipboard.writeText(text2);
}
} else if (e.code === "Space") {
e.stopPropagation();
e.preventDefault();
const settings = computeSettings(false);
if (settings.speed) {
restoreFocusAfter(() => {
valueSetters.speed(settings.speed);
});
} else if (settings.customSpeed) {
valueSetters.customSpeed(settings.customSpeed);
}
}
}
};
// src/menu/controls.ts
var updateValuesIn = (controls, cfgPart) => {
controls.speed.value = cfgPart.speed || text.DEFAULT;
controls.customSpeed.value = cfgPart.customSpeed || "";
controls.quality.value = cfgPart.quality || text.DEFAULT;
controls.volume.value = cfgPart.volume || "";
controls.subtitles.checked = cfgPart.subtitles || false;
};
var channelControls = () => ({
speed: null,
customSpeed: null,
quality: null,
volume: null,
subtitles: null
});
var sections = {
global: channelControls(),
thisChannel: channelControls()
};
var flags = {
shortsToUsual: null,
newTab: null,
copySubs: null,
standardMusicSpeed: null,
enhancedBitrate: null
};
var updateThisChannel = () => {
updateValuesIn(sections.thisChannel, channel());
};
var updateValues = (cfg) => {
updateValuesIn(sections.global, cfg.global);
updateThisChannel();
for (const key in cfg.flags) {
flags[key].checked = cfg.flags[key];
}
};
// src/utils/with.ts
var withHint = (hint, getItem) => [hint.element, getItem(hint).item];
var withOnClick = (elem, listener) => {
elem.addEventListener("click", listener);
return elem;
};
var withListeners = (elem, listeners) => {
for (const key in listeners) {
elem.addEventListener(key, listeners[key]);
}
return elem;
};
var controlWith = (withFn) => (obj, ...args) => {
withFn(obj.elem, ...args);
return obj;
};
var withControlListeners = controlWith(withListeners);
// src/utils/element-creators.ts
var div = getElCreator("div");
var input = getElCreator("input");
var checkbox = (props) => input({ type: "checkbox", ...props });
var option = getElCreator("option");
var _label = getElCreator("label");
var labelEl = (forId, props) => {
const elem = _label(props);
elem.setAttribute("for", forId);
return elem;
};
var selectEl = getElCreator("select");
var btnClass = "yt-spec-button-shape-next";
var btnClassFocused = btnClass + "--focused";
var _button = getElCreator("button");
var button = (textContent, props) => withListeners(_button({
textContent,
className: `${btnClass} ${btnClass}--tonal ${btnClass}--mono ${btnClass}--size-m`,
...props
}), {
focus() {
this.classList.add(btnClassFocused);
},
blur() {
this.classList.remove(btnClassFocused);
}
});
// src/menu/get-controls-creators.ts
var getControlCreators = (getCreator) => ({
numericInput: getCreator((props) => input({ type: "number", ...props }), (elem) => ({
get: () => elem.value,
set: (value3) => {
elem.value = value3;
},
default: ""
})),
checkbox: getCreator(checkbox, (elem) => ({
get: () => elem.checked.toString(),
set: (value3) => {
elem.checked = value3 === "true";
},
default: text.DEFAULT
})),
select: getCreator(({
values,
getText
}) => {
const elem = selectEl({ value: text.DEFAULT });
elem.append(option({
value: text.DEFAULT,
textContent: text.DEFAULT
}), ...values.map((value3) => option({
value: value3,
textContent: getText(value3)
})));
return elem;
}, (elem) => ({
get: () => elem.value,
set: (value3) => {
elem.value = value3;
},
default: "false"
}))
});
// src/menu/validate-volume.ts
var validateVolume = (value3) => {
const num = +value3;
return num < 0 || num > 100 ? "out of range" : isNaN(num) ? "not a number" : null;
};
// src/hint.ts
class Hint {
constructor(prefix) {
this.element = div();
this.element.className ||= "YTDef-setting-hint";
this.prefix = prefix;
this.hide();
}
hide() {
this.element.style.display = "none";
}
show(msg) {
this.element.style.display = "block";
this.element.textContent = this.prefix + msg;
}
prefix;
element;
}
// src/menu/close.ts
var close = () => {
element2.style.visibility = "hidden";
stopListening();
};
var listenForClose = () => {
document.addEventListener("click", onClick2);
document.addEventListener("keyup", onKeyUp);
};
var stopListening = () => {
document.removeEventListener("click", onClick2);
document.removeEventListener("keyup", onKeyUp);
};
var onClick2 = (e) => {
const el = e.target;
if (!isDescendantOrTheSame(el, [element2, btn2]))
close();
};
var onKeyUp = (e) => {
if (e.code === "Escape") {
close();
btn2.focus();
}
};
// src/menu/value.ts
var set2 = (el, btnEl) => {
element2 = el;
btn2 = btnEl;
};
var element2 = null;
var btn2 = null;
var isOpen2 = false;
var menuWidth = 0;
var adjustWidth = () => {
menuWidth = element2.getBoundingClientRect().width;
};
var firstFocusable = ref(null);
var toggle = debounce(() => {
isOpen2 = !isOpen2;
if (isOpen2) {
fixPosition();
element2.style.visibility = "visible";
listenForClose();
firstFocusable.val.focus();
} else {
close();
}
}, 100);
var fixPosition = () => {
const { y, height, width, left } = btn2.getBoundingClientRect();
element2.style.top = y + height + 8 + "px";
element2.style.left = left + width - menuWidth + "px";
};
// src/menu/section.ts
var section = (sectionId, title, sectionCfg) => {
const control = getControlCreators((createElement, initVal) => (name, label, props) => {
const item = div();
const id = "YTDef-" + name + "-" + sectionId;
const elem = Object.assign(createElement(props), props, {
id,
name
});
elem.addEventListener("change", () => {
const value3 = val.get();
if (value3 === val.default) {
delete sectionCfg[name];
} else {
sectionCfg[name] = value3;
}
});
const val = initVal(elem);
const cfgValue = sectionCfg[name];
if (cfgValue) {
setTimeout(() => {
val.set(cfgValue.toString());
});
}
item.append(labelEl(id, { textContent: label }), elem);
sections[sectionId][name] = elem;
return { item, elem };
});
const speedSelect = control.select("speed", text.SPEED, {
values: ["2", "1.75", "1.5", "1.25", speedNormal, "0.75", "0.5", "0.25"],
getText: (val) => val
});
if (sectionId === "global")
firstFocusable.val = speedSelect.elem;
const sectionElement = div({ role: "group" });
sectionElement.setAttribute("aria-labelledby", sectionId);
sectionElement.append(getElCreator("span")({ textContent: title, id: sectionId }), speedSelect.item, ...withHint(new Hint(""), (hint) => withControlListeners(control.numericInput("customSpeed", text.CUSTOM_SPEED), {
blur: () => {
hint.hide();
},
focus: () => {
hint.show(text.CUSTOM_SPEED_HINT);
}
})), control.select("quality", text.QUALITY, {
values: [
"144",
"240",
"360",
"480",
"720",
"1080",
"1440",
"2160",
"4320"
],
getText: (val) => val + "p"
}).item, ...withHint(new Hint("Warning: "), (hint) => withControlListeners(control.numericInput("volume", text.VOLUME, {
min: "0",
max: "100"
}), {
blur() {
const warning = validateVolume(this.value);
if (warning) {
hint.show(warning);
} else {
hint.hide();
}
}
})), control.checkbox("subtitles", text.SUBTITLES, checkbox()).item);
return sectionElement;
};
// src/menu/settings-icon.ts
var settingsIcon = () => {
const element3 = document.createElementNS("http://www.w3.org/2000/svg", "svg");
for (const [prop, value3] of [
["viewBox", "0 0 24 24"],
["width", "24"],
["height", "24"],
["fill", "var(--yt-spec-text-primary)"]
]) {
element3.setAttribute(prop, value3);
}
element3.append($("settings"));
return element3;
};
// src/menu/init.ts
var controlCheckboxDiv = (id, flagName, textContent) => {
const cont = div({ className: "check-cont" });
id = "YTDef-" + id;
const elem = withOnClick(checkbox({
id,
checked: value.flags[flagName]
}), function() {
value.flags[flagName] = this.checked;
});
flags[flagName] = elem;
cont.append(labelEl(id, { textContent }), elem);
return cont;
};
var init = () => {
const sections2 = div({ className: "YTDef-" + "sections" });
sections2.append(section("global", text.GLOBAL, value.global), section("thisChannel", text.LOCAL, channel()));
const controlStatus = div();
const updateControlStatus = (content) => {
controlStatus.textContent = `[${new Date().toLocaleTimeString()}] ${content}`;
};
const controlDiv = div({ className: "control-cont" });
controlDiv.append(withOnClick(button(text.SAVE), () => {
prune();
saveLS(value);
updateControlStatus(text.SAVE);
}), withOnClick(button(text.EXPORT), () => {
navigator.clipboard.writeText(localStorage.YTDefaulter).then(() => {
updateControlStatus(text.EXPORT);
});
}), withOnClick(button(text.IMPORT), () => {
navigator.clipboard.readText().then((raw) => {
save(raw);
updateValues(value);
return text.IMPORT;
}).catch((e) => text.IMPORT + ": " + e.message).then(updateControlStatus);
}));
set2(div({
id: "YTDef-menu"
}), withOnClick(button("", {
id: "YTDef-btn",
ariaLabel: text.OPEN_SETTINGS,
tabIndex: 0
}), toggle));
btn2.setAttribute("aria-controls", "YTDef-menu");
btn2.classList.add(btnClass + "--icon-button");
btn2.append(settingsIcon());
element2.append(sections2, controlCheckboxDiv("shorts", "shortsToUsual", text.SHORTS), controlCheckboxDiv("new-tab", "newTab", text.NEW_TAB), controlCheckboxDiv("copy-subs", "copySubs", text.COPY_SUBS), controlCheckboxDiv("standard-music-speed", "standardMusicSpeed", text.STANDARD_MUSIC_SPEED), controlCheckboxDiv("enhanced-bitrate", "enhancedBitrate", text.ENHANCED_BITRATE), controlDiv, controlStatus);
element2.addEventListener("keyup", (e) => {
const el = e.target;
if (e.code === "Enter" && el.type === "checkbox")
el.checked = !el.checked;
});
untilAppear(actionsBar).then((actionsBar2) => {
actionsBar2.insertBefore(btn2, actionsBar2.lastChild);
popupContainer().append(element2);
adjustWidth();
sections2.style.maxWidth = sections2.offsetWidth + "px";
});
const listener = () => {
if (isOpen2)
fixPosition();
};
window.addEventListener("scroll", listener);
window.addEventListener("resize", listener);
};
// src/listeners/video-page.ts
var onVideoPage = async () => {
const aboveTheFold2 = await untilAppear(aboveTheFold);
username.val = (await untilAppear(channelUsernameElementGetter(aboveTheFold2))).href || "";
untilAppear(plr).then(setPlr).then(() => {
const doNotChangeSpeed = value.flags.standardMusicSpeed && !!artistChannelBadge(aboveTheFold2);
applySettings(computeSettings(doNotChangeSpeed));
if (!element2) {
init();
}
});
if (element2) {
updateThisChannel();
}
};
// src/listeners/page-change.ts
var lastUrl;
var onPageChange = (url) => {
if (lastUrl !== url) {
lastUrl = url;
if (location.pathname === "/watch") {
setTimeout(onVideoPage, 1000);
}
}
};
// src/index.ts
Object.assign(text, translations[document.documentElement.lang]);
if (update(value)) {
saveLS(value);
}
var updatePage = () => {
onPageChange(location.href);
};
if (window.onurlchange === null) {
window.addEventListener("urlchange", ({ url }) => {
onPageChange(url);
});
updatePage();
} else {
setInterval(updatePage, 1000);
}
document.addEventListener("click", onClick, { capture: true });
document.addEventListener("keyup", onKeyup, { capture: true });
document.head.append(style);
})()