Make Facebook Reel: Video Controls
当前为
// ==UserScript==
// @name Facebook Reel: Video Controls
// @namespace UserScript
// @match https://www.facebook.com/*
// @version 0.2.0
// @license MIT
// @author CY Fung
// @description Make Facebook Reel: Video Controls
// @run-at document-start
// @grant none
// @unwrap
// ==/UserScript==
(() => {
const resizeObserver = new ResizeObserver((entries) => {
for (const entry of entries) {
if (entry.contentRect.height > 0) {
document.documentElement.style.setProperty('--frvc-reel-control-height', entry.contentRect.height + 'px');
}
}
});
let addCSS = () => {
if (addCSS.done) return;
addCSS.done = true;
document.head.appendChild(document.createElement('style')).textContent = `
.frvc-div-might-empty:empty {
display: none;
}
.frvc-cursor-passthrough {
pointer-events: none;
}
.frvc-cursor-passthrough [role], .frvc-cursor-passthrough [tabindex] {
pointer-events: initial;
}
`
}
document.addEventListener('play', (evt) => {
const target = (evt || 0).target;
if (target instanceof HTMLVideoElement) {
if (target.hasAttribute('controls')) return;
if (location.href.indexOf('reel') < 0) return;
let buttonLayer = target.closest('div[class][role="button"][tabindex]');
if (!buttonLayer) return;
target.setAttribute('controls', '');
addCSS();
setTimeout(() => {
Object.assign(target.style, {
'position': 'relative',
'zIndex': 999,
'pointerEvents': 'all',
'height': 'calc(100% - var(--frvc-reel-control-height))'
});
let arr = [...buttonLayer.querySelectorAll('.x10l6tqk.x13vifvy:not(.x1m3v4wt)')].filter(elm => !elm.contains(target));
const clickable = buttonLayer.querySelectorAll('a[role="link"][href]');
const clickableHolder = [...new Set([...clickable].map(e => {
do {
if (arr.includes(e.parentNode)) return e;
} while ((e = e.parentNode) instanceof HTMLElement);
return null;
}))].filter(e => !!e);
for (const s of arr) {
Object.assign(s.style, {
'pointerEvents': 'none'
});
s.classList.add('frvc-cursor-passthrough')
}
for (const s of clickable) {
Object.assign(s.style, {
'pointerEvents': 'initial'
});
}
const videoElmBRect = target.getBoundingClientRect();
let p = null;
for (const s of clickableHolder) {
const clickableHolderBRect = s.getBoundingClientRect();
if (p === null && clickableHolderBRect.bottom === clickableHolderBRect.bottom && clickableHolderBRect.top > videoElmBRect.top && clickableHolderBRect.left === clickableHolderBRect.left && clickableHolderBRect.right === clickableHolderBRect.right) {
p = s;
}
Object.assign(s.style, {
'pointerEvents': 'initial',
'height': 'auto',
'boxSizing': 'border-box',
'paddingTop': '16px'
});
}
if (p) {
addCSS();
for (const s of p.querySelectorAll('div[class]:empty')) {
s.classList.add('frvc-div-might-empty');
}
resizeObserver.disconnect();
resizeObserver.observe(p);
}
}, 1)
}
}, true);
})();