Hover a thumbnail on youtube.com and click an icon at the right: "Not interested" and "Don't recommend channel"
目前為
// ==UserScript==
// @name YT: not interested in one click
// @description Hover a thumbnail on youtube.com and click an icon at the right: "Not interested" and "Don't recommend channel"
// @version 1.1.1
//
// @match https://www.youtube.com/*
//
// @noframes
// @grant none
//
// @author wOxxOm
// @namespace wOxxOm.scripts
// @license MIT License
// ==/UserScript==
const ME = 'yt-one-click-dismiss';
const THUMB_TAG = 'ytd-thumbnail';
const PREVIEW = '#buttons';
const COMMANDS = {
NOT_INTERESTED: {block: 'video', text: 'Not interested'},
REMOVE: {block: 'channel', text: "Don't recommend channel"},
DELETE: {block: 'unwatch', text: "Remove from 'Watch later'"},
};
let STYLE;
addEventListener('mouseover', onHover);
addEventListener('click', onClick, true);
function onHover(e) {
for (const el of e.composedPath()) {
const thumb = el.localName === THUMB_TAG && el ||
el.id === 'media-container-link' && el.querySelector(THUMB_TAG);
if (!thumb) continue;
const elems = [...getMenuItems(thumb)].map(cmd => cmd.element);
const parent = thumb.matches('.ytd-video-preview')
? el.closest('#video-preview-container').querySelector(PREVIEW)
: thumb;
if (elems.some(el => el.parentNode !== parent)) {
parent.append(...elems);
}
break;
}
}
async function onClick(e) {
const {target} = e;
const {block} = target.classList.contains(ME) && target.dataset;
if (!block)
return;
e.stopPropagation();
e.preventDefault();
try {
const index = STYLE.sheet.insertRule('ytd-menu-popup-renderer { display: none !important }');
for (let more, el = target; el; el = el.parentElement) {
if ((more = el.querySelector('.dropdown-trigger'))) {
await 0;
more.dispatchEvent(new Event('click'));
await 0;
break;
}
}
for (const el of document.querySelector('ytd-menu-popup-renderer [role="listbox"]').children) {
if (block === (COMMANDS[getProp(el, 'data.icon.iconType')] || {}).block) {
el.click();
await new Promise(setTimeout);
break;
}
}
document.body.click();
STYLE.sheet.deleteRule(index);
} catch (e) {}
}
function *getMenuItems(thumb) {
for (const item of getProp(thumb, 'data.menu.menuRenderer.items') || []) {
const type = getProp(item, 'menuServiceItemRenderer.icon.iconType');
const data = COMMANDS[type];
if (data) {
if (!data.element) {
const el = data.element = document.createElement('div');
const text = getProp(item, 'menuServiceItemRenderer.text');
el.className = ME;
el.dataset.block = data.block;
el.title = text.runs.map(r => r.text).join('') || data.text;
}
yield data;
}
}
if (!STYLE) initStyle();
}
function getProp(obj, path) {
return path.split('.').reduce((res, name) => res && res[name],
(obj.wrappedJSObject || {}).__data || obj);
}
function initStyle() {
STYLE = document.createElement('style');
STYLE.textContent = /*CSS*/ `
ytd-video-preview[mini-mode] #buttons.ytd-video-preview {
padding-right: 30px;
position: relative;
}
${PREVIEW} .${ME} {
opacity: .5;
}
${PREVIEW} .${ME},
${THUMB_TAG}:hover .${ME} {
display: block;
}
.${ME} {
display: none;
position: absolute;
width: 16px;
height: 16px;
border-radius: 100%;
border: 2px solid #fff;
right: 8px;
background: #0006;
box-shadow: .5px .5px 7px #000;
cursor: pointer;
opacity: .75;
z-index: 11000;
}
${PREVIEW} .${ME}:hover,
.${ME}:hover {
opacity: 1;
}
.${ME}:active {
color: yellow;
}
.${ME}[data-block] { top: 70px; }
.${ME}[data-block="channel"] { top: 100px; }
${PREVIEW} .${ME}[data-block] { top: 9px; right: 0; }
${PREVIEW} .${ME}[data-block="channel"] { top: 50px; right: 0; }
.ytd-playlist-video-renderer .${ME}[data-block="unwatch"] {
top: 15px;
}
ytd-compact-video-renderer .${ME}[data-block] {
top: 70px;
right: 7px;
box-shadow: .5px .5px 4px 6px #000;
background: #000;
}
ytd-compact-video-renderer .${ME}[data-block="channel"] {
right: 37px;
}
.${ME}::after {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
height: 0;
margin: auto;
border: none;
border-bottom: 2px solid #fff;
}
.${ME}[data-block="video"]::after {
transform: rotate(45deg);
}
.${ME}[data-block="channel"]::after {
margin: auto 3px;
}
`.replace(/;/g, '!important;');
document.head.appendChild(STYLE);
}