Remove sensitive content spoilers from images and videos on baraag
// ==UserScript==
// @name Baraag Unspoiler NSFW Images
// @version 1.4
// @description Remove sensitive content spoilers from images and videos on baraag
// @match https://baraag.net/*
// @license public domain
// @namespace https://sleazyfork.org/users/1468364
// ==/UserScript==
(function() {
'use strict';
function hideHideButton() {
const observer = new MutationObserver((mutations) => {
document.querySelectorAll('.media-gallery__actions').forEach((el) => {
if (el.style.display !== 'none') {
el.style.display = 'none';
}
});
});
observer.observe(document.body, {
childList: true,
subtree: true,
});
}
function isUserProfilePage() {
return /^\/@[^\/]+(\/with_replies)?$/.test(window.location.pathname);
}
// Helper to verify poster image validity
function verifyAndFixVideoPoster(video) {
// Prevent double checking the specific video element
if (video.dataset.posterChecked) return;
const posterUrl = video.getAttribute('poster');
if (posterUrl) {
const img = new Image();
img.onload = function() {
// Check dimensions. 0x0 means a 0-byte or broken image
if (this.naturalWidth === 0 || this.naturalHeight === 0) {
video.removeAttribute('poster');
video.setAttribute('preload', 'metadata');
}
video.dataset.posterChecked = 'true';
};
img.onerror = function() {
video.removeAttribute('poster');
video.setAttribute('preload', 'metadata');
video.dataset.posterChecked = 'true';
};
img.src = posterUrl;
} else {
// No poster: Ensure we load metadata
video.setAttribute('preload', 'metadata');
video.dataset.posterChecked = 'true';
}
}
// Process videos
function processVideoPlayer(videoPlayer) {
// Only stop if we have successfully found AND processed the video tag before.
// If the video tag was missing on previous runs, we want to check again.
if (videoPlayer.dataset.unspoilerComplete === 'fixed') {
return;
}
// 1. Handle Spoiler Button
const spoilerButtonDiv = videoPlayer.querySelector('.spoiler-button');
if (spoilerButtonDiv && !spoilerButtonDiv.classList.contains('spoiler-button--hidden')) {
const spoilerButton = videoPlayer.querySelector('.spoiler-button button');
if (spoilerButton && !spoilerButton.dataset.unspoilerClicked) {
spoilerButton.dataset.unspoilerClicked = 'true';
spoilerButton.click();
}
// Hide canvas manually just in case
const canvas = videoPlayer.querySelector('.media-gallery__preview');
if (canvas) canvas.classList.add('media-gallery__preview--hidden');
}
// 2. Handle Video Tag (This might not exist yet due to lazy loading)
const video = videoPlayer.querySelector('video');
if (video) {
verifyAndFixVideoPoster(video);
// Only mark complete if we actually found and processed the video element
videoPlayer.dataset.unspoilerComplete = 'fixed';
} else {
// Video tag is missing (lazy loaded).
// Do NOT mark as complete. The MutationObserver will trigger again when
// the site injects the video tag, allowing us to process it then.
}
}
function processStatusCards() {
document.querySelectorAll('.status-card__image-image').forEach(img => {
if (img.style.visibility !== 'visible') {
img.style.visibility = 'visible';
const parentDiv = img.closest('.status-card__image');
if (parentDiv) {
parentDiv.parentNode.insertBefore(img, parentDiv);
}
}
});
}
function processAllContent() {
document.querySelectorAll('.video-player').forEach(videoPlayer => {
processVideoPlayer(videoPlayer);
});
if (!window.location.pathname.includes('/media')) {
document.querySelectorAll('.spoiler-button:not(.unspoiler-processed)').forEach(spoiler => {
if (spoiler.closest('.video-player')) return;
spoiler.classList.add('unspoiler-processed');
const button = spoiler.querySelector('button');
if (button && !button.dataset.unspoilerClicked) {
button.dataset.unspoilerClicked = 'true';
button.click();
}
});
}
if (window.location.pathname.includes('/media')) {
document.querySelectorAll('.media-gallery__item').forEach(item => {
const hasSpoilerOverlay = item.querySelector('.media-gallery__item__overlay .icon-eye-slash');
if (!item.querySelector('img') && hasSpoilerOverlay) {
const thumbnail = item.querySelector('.media-gallery__item-thumbnail');
if (thumbnail && !thumbnail.dataset.unspoilerProcessed) {
thumbnail.dataset.unspoilerProcessed = 'true';
thumbnail.click();
}
}
});
}
processStatusCards();
}
function initObserver() {
const observer = new MutationObserver(mutations => {
let needsProcessing = false;
let hasNewVideos = false;
mutations.forEach(mutation => {
mutation.addedNodes.forEach(node => {
if (node.nodeType === 1) {
if (node.matches('.video-player')) hasNewVideos = true;
else if (node.querySelector('.video-player')) hasNewVideos = true;
}
});
if (mutation.addedNodes.length) needsProcessing = true;
});
if (needsProcessing) {
if (hasNewVideos && isUserProfilePage()) {
setTimeout(processAllContent, 100);
} else {
debouncedProcess();
}
}
});
observer.observe(document.body, { childList: true, subtree: true });
}
const debouncedProcess = debounce(processAllContent, 1);
function debounce(func, wait) {
let timeout;
return function() {
clearTimeout(timeout);
timeout = setTimeout(func, wait);
};
}
function init() {
hideHideButton();
processAllContent();
initObserver();
window.addEventListener('scroll', debounce(function() {
const scrollThreshold = window.innerHeight * 2;
if (document.documentElement.scrollHeight - window.scrollY - window.innerHeight < scrollThreshold) {
var loadMoreButton = document.querySelector('.load-more');
if (loadMoreButton) {
loadMoreButton.click();
}
}
}, 100));
}
if (document.readyState !== 'loading') {
init();
} else {
document.addEventListener('DOMContentLoaded', init);
}
})();