您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds quick Watch Later button
- // ==UserScript==
- // @name YouTube Quick Watch Later
- // @namespace http://tampermonkey.net/
- // @version 2.4
- // @description Adds quick Watch Later button
- // @author kavinned
- // @match https://www.youtube.com/*
- // @grant GM_addStyle
- // @icon https://www.google.com/s2/favicons?sz=64&domain=YouTube.com
- // @license MIT
- // ==/UserScript==
- (function () {
- "use strict";
- // Configuration: Add "Save" translations here
- const SAVE_BUTTON_TEXTS = [
- "Save", // English
- "儲存", // Traditional Chinese
- "保存", // Simplified Chinese
- "Guardar", // Spanish
- "Sauvegarder", // French
- "Speichern", // German
- "Salvar", // Portuguese
- "Сохранить", // Russian
- "保存", // Japanese
- "저장", // Korean
- "บันทึก", // Thai
- "Simpan", // Indonesian
- "Lưu" // Vietnamese
- ];
- function addWatchLaterButton() {
- const targetDiv = document.querySelector(
- "#top-level-buttons-computed > segmented-like-dislike-button-view-model > yt-smartimation > div"
- );
- if (!targetDiv || document.querySelector(".quick-watch-later")) return;
- const button = document.createElement("button");
- button.className = "quick-watch-later";
- button.textContent = "WL";
- button.addEventListener("click", function () {
- // Helper function to check if text contains any of the save button texts
- function containsSaveText(text) {
- return SAVE_BUTTON_TEXTS.some(saveText => text.includes(saveText));
- }
- // First check if Save button is directly visible
- const directSaveButton = document.querySelector(
- "ytd-menu-renderer yt-button-view-model .yt-spec-button-shape-next__button-text-content"
- );
- const directSaveButtonWithText = Array.from(
- document.querySelectorAll("ytd-menu-renderer yt-button-view-model .yt-spec-button-shape-next__button-text-content")
- ).find(element => containsSaveText(element.textContent));
- if (directSaveButtonWithText) {
- // Save button is directly visible, click it
- console.log("Direct save button found, clicking it");
- directSaveButtonWithText.click();
- // Then proceed to click the Watch Later button
- setTimeout(function () {
- const watchLaterBox = document.querySelector(
- "#playlists > ytd-playlist-add-to-option-renderer:first-child #checkbox"
- );
- if (
- watchLaterBox &&
- watchLaterBox.getAttribute("aria-checked") === "true"
- ) {
- const confirmRemove = window.confirm(
- "This video is already in your Watch Later playlist. Do you want to remove it?"
- );
- if (confirmRemove) {
- watchLaterBox.click();
- const closeButton = document.querySelector(
- "#button > yt-icon > span"
- );
- if (closeButton) {
- closeButton.click();
- }
- } else {
- const closeButton = document.querySelector(
- "#button > yt-icon > span"
- );
- if (closeButton) {
- closeButton.click();
- }
- }
- } else {
- // If the video isn't in Watch Later, proceed with adding it
- watchLaterBox.click();
- const closeButton = document.querySelector(
- "#button > yt-icon > span"
- );
- if (closeButton) {
- closeButton.click();
- }
- }
- }, 1000);
- } else {
- // Save button is in submenu, use original logic
- console.log("Save button not directly visible, opening menu");
- // First click menu button
- const menuButton = document.querySelector(
- "#button-shape > button > yt-touch-feedback-shape > div"
- );
- menuButton.click();
- if (menuButton) {
- console.log("menu clicked");
- }
- // Next click the Save button
- setTimeout(function () {
- const saveButtons = document.querySelectorAll(
- "#items > ytd-menu-service-item-renderer > tp-yt-paper-item > yt-formatted-string"
- );
- const saveButton = Array.from(saveButtons).find((button) =>
- containsSaveText(button.textContent)
- );
- saveButton.click();
- // Then click the Watch Later button
- setTimeout(function () {
- const watchLaterBox = document.querySelector(
- "#playlists > ytd-playlist-add-to-option-renderer:first-child #checkbox"
- );
- if (
- watchLaterBox &&
- watchLaterBox.getAttribute("aria-checked") === "true"
- ) {
- const confirmRemove = window.confirm(
- "This video is already in your Watch Later playlist. Do you want to remove it?"
- );
- if (confirmRemove) {
- watchLaterBox.click();
- const closeButton = document.querySelector(
- "#button > yt-icon > span"
- );
- if (closeButton) {
- closeButton.click();
- }
- } else {
- const closeButton = document.querySelector(
- "#button > yt-icon > span"
- );
- if (closeButton) {
- closeButton.click();
- }
- }
- } else {
- // If the video isn't in Watch Later, proceed with adding it
- watchLaterBox.click();
- const closeButton = document.querySelector(
- "#button > yt-icon > span"
- );
- if (closeButton) {
- closeButton.click();
- }
- }
- }, 1000);
- }, 100);
- }
- });
- targetDiv.appendChild(button);
- }
- setTimeout(addWatchLaterButton, 2000);
- const observer = new MutationObserver(() => {
- if (window.location.href.includes("/watch?")) {
- setTimeout(addWatchLaterButton, 1000);
- }
- });
- observer.observe(document.body, { childList: true, subtree: true });
- GM_addStyle(
- `#top-level-buttons-computed > segmented-like-dislike-button-view-model > yt-smartimation > div {
- display: flex;
- flex-direction: row-reverse;
- gap: 5px;
- }
- #top-level-buttons-computed > segmented-like-dislike-button-view-model > yt-smartimation > div > button {
- flex-direction: row;
- border-radius: 24px;
- border: none;
- padding-left: 20px;
- padding-right: 20px;
- color: white;
- font-weight: bold;
- background: #272727;
- cursor: pointer;
- &:hover {
- background: #414141;
- }
- }
- .ryd-tooltip.ryd-tooltip-new-design {
- height: 0px !important;
- width: 0px !important;
- }
- @media only screen and (max-width: 1200px) {
- #top-level-buttons-computed > segmented-like-dislike-button-view-model > yt-smartimation > div {
- flex-direction: column;
- }
- #top-level-buttons-computed > segmented-like-dislike-button-view-model > yt-smartimation > div > button {
- padding: 10.5px 0px;
- }
- }
- }`
- );
- })();