Dark theme for ImageFap with a toggle.
// ==UserScript==
// @name ImageFap Dark Mode
// @namespace imagefap@nereids
// @version 1.0.0
// @description Dark theme for ImageFap with a toggle.
// @author nereids
// @license MIT
// @match *://imagefap.com/*
// @match *://*.imagefap.com/*
// @icon https://icons.duckduckgo.com/ip3/imagefap.com.ico
// @run-at document-start
// @grant none
// ==/UserScript==
(function () {
'use strict';
// Set to true to desaturate photos and video as well. The chrome is always grayscale.
var GRAYSCALE_MEDIA = false;
var STORAGE_KEY = 'if-dark-mode';
function isOn() {
try {
var v = localStorage.getItem(STORAGE_KEY);
return v === null || v === '1';
} catch (e) {
return true;
}
}
function setOn(on) {
try {
localStorage.setItem(STORAGE_KEY, on ? '1' : '0');
} catch (e) {}
}
var CSS = [
'html.if-dark {',
' color-scheme: dark !important;',
' background: #141414 !important;',
' scrollbar-color: #4a4a4a #141414;',
'}',
'html.if-dark body {',
' background: #141414 !important;',
' color: #cfcfcf !important;',
'}',
'html.if-dark body,',
'html.if-dark table,',
'html.if-dark tbody,',
'html.if-dark thead,',
'html.if-dark tfoot,',
'html.if-dark tr,',
'html.if-dark td,',
'html.if-dark th,',
'html.if-dark div,',
'html.if-dark span,',
'html.if-dark p,',
'html.if-dark font,',
'html.if-dark center,',
'html.if-dark li,',
'html.if-dark ul,',
'html.if-dark ol,',
'html.if-dark dl,',
'html.if-dark dt,',
'html.if-dark dd,',
'html.if-dark h1,',
'html.if-dark h2,',
'html.if-dark h3,',
'html.if-dark h4,',
'html.if-dark label,',
'html.if-dark small,',
'html.if-dark big,',
'html.if-dark blockquote,',
'html.if-dark pre,',
'html.if-dark i,',
'html.if-dark em,',
'html.if-dark u,',
'html.if-dark s {',
' background-color: transparent !important;',
' color: #cfcfcf !important;',
' border-color: #3a3a3a !important;',
' outline-color: #5a5a5a !important;',
'}',
'html.if-dark b,',
'html.if-dark strong {',
' background-color: transparent !important;',
' color: #f2f2f2 !important;',
'}',
'html.if-dark hr,',
'html.if-dark .hr {',
' background-color: #3a3a3a !important;',
' border-color: #3a3a3a !important;',
' color: #3a3a3a !important;',
'}',
'html.if-dark [class$="_hdr"],',
'html.if-dark h1#title,',
'html.if-dark td.colhead,',
'html.if-dark .right_side_top,',
'html.if-dark .our_niches,',
'html.if-dark .announceBox .close,',
'html.if-dark #playlist .head,',
'html.if-dark #flag .head,',
'html.if-dark #share .head,',
'html.if-dark .gallerylist table tr.head,',
'html.if-dark .gallerylist table tr.head td {',
' background-color: #343434 !important;',
' color: #f3f3f3 !important;',
' border-color: #4a4a4a !important;',
'}',
'html.if-dark [class^="blk_"]:not(a):not([class$="_hdr"]),',
'html.if-dark #controlpanel,',
'html.if-dark div#controlpanel div.content,',
'html.if-dark .left_side,',
'html.if-dark .right_side {',
' background-color: #1b1b1b !important;',
' color: #cfcfcf !important;',
' border-color: #3a3a3a !important;',
'}',
'html.if-dark .avatar {',
' border: none !important;',
' background-color: #242424 !important;',
' border-color: #555 !important;',
' color: #ddd !important;',
'}',
'html.if-dark .avatar .subscribers,',
'html.if-dark .avatar .comments {',
' color: #cfcfcf !important;',
'}',
'html.if-dark img.gal_thumb,',
'html.if-dark .gal_thumb {',
' border-color: #6a6a6a !important;',
' background-color: #111 !important;',
'}',
'html.if-dark #cat {',
' background-color: #1c1c1c !important;',
' border-color: #4a4a4a !important;',
'}',
'html.if-dark .msgCont,',
'html.if-dark .relCont,',
'html.if-dark .relatedgalleriescontainer,',
'html.if-dark .relatedgalleriescontainer .relateditem,',
'html.if-dark #flag,',
'html.if-dark #share,',
'html.if-dark #playlist,',
'html.if-dark .blockwidgetpopup,',
'html.if-dark #cat_tooltip,',
'html.if-dark .tooltip,',
'html.if-dark .sample_popup,',
'html.if-dark .sample_popup div,',
'html.if-dark .announceBox,',
'html.if-dark div#controlpanel div.messages ul,',
'html.if-dark div#controlpanel div.content ul.tabs,',
'html.if-dark div#controlpanel div.content ul.tabs li a,',
'html.if-dark div#controlpanel div.content div.tabs-content,',
'html.if-dark div#controlpanel div.content table.list thead tr th,',
'html.if-dark div#controlpanel div.content table.list tbody tr td,',
'html.if-dark table.request tr td {',
' background-color: #262626 !important;',
' color: #e0e0e0 !important;',
' border-color: #555 !important;',
' box-shadow: none !important;',
'}',
'html.if-dark .itemCounter,',
'html.if-dark .isblocked,',
'html.if-dark .notblocked {',
' background-color: #3f3f3f !important;',
' color: #f5f5f5 !important;',
' border-color: #6a6a6a !important;',
'}',
'html.if-dark div#controlpanel div.content p.pagination strong {',
' background-color: #4a4a4a !important;',
' color: #ffffff !important;',
' border-color: #4a4a4a !important;',
'}',
'html.if-dark .tnaBarBlueWrap {',
' filter: grayscale(1) brightness(0.55) contrast(1.05);',
'}',
'html.if-dark a[title="ImageFap.com"] img,',
'html.if-dark img[alt="ImageFap.com"] {',
' filter: invert(1) grayscale(1) contrast(1.15) !important;',
' background: transparent !important;',
'}',
'html.if-dark.if-gray-media img,',
'html.if-dark.if-gray-media video {',
' filter: grayscale(1) !important;',
'}',
'html.if-dark.if-gray-media a[title="ImageFap.com"] img,',
'html.if-dark.if-gray-media img[alt="ImageFap.com"] {',
' filter: invert(1) grayscale(1) contrast(1.15) !important;',
'}',
'html.if-dark input:not([type="checkbox"]):not([type="radio"]):not([type="image"]):not([type="hidden"]),',
'html.if-dark textarea,',
'html.if-dark select,',
'html.if-dark button {',
' background-color: #1c1c1c !important;',
' color: #e8e8e8 !important;',
' border: 1px solid #5c5c5c !important;',
' box-shadow: none !important;',
'}',
'html.if-dark input::placeholder,',
'html.if-dark textarea::placeholder {',
' color: #8a8a8a !important;',
'}',
'html.if-dark ::selection {',
' background: #3a3a3a !important;',
' color: #ffffff !important;',
'}',
'html.if-dark a,',
'html.if-dark a:link,',
'html.if-dark a:visited,',
'html.if-dark a *,',
'html.if-dark a font,',
'html.if-dark a span,',
'html.if-dark a b,',
'html.if-dark a i,',
'html.if-dark a u {',
' color: #3f75aa !important;',
' background-color: transparent !important;',
'}',
'html.if-dark a:visited,',
'html.if-dark a:visited *,',
'html.if-dark a:visited font,',
'html.if-dark a:visited b {',
' color: #6573b1 !important;',
'}',
'html.if-dark a:hover,',
'html.if-dark a:hover *,',
'html.if-dark a:hover font,',
'html.if-dark a:hover b {',
' color: #4d87c2 !important;',
'}',
'html.if-dark .blockwidget a,',
'html.if-dark .blockwidget a:hover,',
'html.if-dark .isblocked a,',
'html.if-dark .notblocked a,',
'html.if-dark .itemCounter a {',
' color: #f5f5f5 !important;',
'}',
'html.if-dark a[class$="_hdr"],',
'html.if-dark a[class$="_hdr"] *,',
'html.if-dark .gallerylist table tr.head a,',
'html.if-dark .gallerylist table tr.head a * {',
' color: #6cb6ff !important;',
'}',
'html.if-dark .gallerylist table tbody tr * {',
' background-color: #141414 !important;',
'}',
'html.if-dark .gallerylist table tbody tr td center img {',
' filter: invert(1) contrast(1.05) hue-rotate(170deg) opacity(50%) !important;',
' background: transparent !important;',
'}',
'html.if-dark a[class$="_hdr"]:visited,',
'html.if-dark a[class$="_hdr"]:visited * {',
' color: #9aa8e8 !important;',
'}',
'html.if-dark a[class$="_hdr"]:hover,',
'html.if-dark a[class$="_hdr"]:hover *,',
'html.if-dark .gallerylist table tr.head a:hover,',
'html.if-dark .gallerylist table tr.head a:hover * {',
' color: #b9dcff !important;',
'}',
'html.if-dark img._lazy {',
' border: none !important;',
'}',
'html.if-dark img.gal_thumb',
'html.if-dark img.lazy',
'html.if-dark #mainPhoto',
'html.if-dark #slideshow img',
'html.if-dark #gallery img',
'html.if-dark #_navi_cavi img',
'html.if-dark #playlist li.thumb img {',
' border: 0 !important;',
' padding: 0 !important;',
' background: transparent !important;',
' background-color: transparent !important;',
' box-shadow: none !important;',
'}',
'#if-dark-toggle {',
' position: fixed !important;',
' right: 12px !important;',
' bottom: 12px !important;',
' z-index: 2147483647 !important;',
' margin: 0 !important;',
' padding: 6px 6px !important;',
' background: #2a2a2a !important;',
' color: #e8e8e8 !important;',
' border: none !important;',
' border-radius: 50px !important;',
' font: 22px/1.2 Verdana, Tahoma, sans-serif !important;',
' cursor: pointer !important;',
'}',
].join('\n');
function applyRoot(on) {
var root = document.documentElement;
if (!root) return;
root.classList.toggle('if-dark', !!on);
root.classList.toggle('if-gray-media', !!on && GRAYSCALE_MEDIA);
if (!on) unpaint();
}
function parseColor(c) {
if (!c) return null;
c = String(c).trim().toLowerCase();
var m;
if ((m = /^#([0-9a-f]{3})$/.exec(c))) {
return [
parseInt(m[1].charAt(0) + m[1].charAt(0), 16),
parseInt(m[1].charAt(1) + m[1].charAt(1), 16),
parseInt(m[1].charAt(2) + m[1].charAt(2), 16)
];
}
if ((m = /^#([0-9a-f]{6})$/.exec(c))) {
return [
parseInt(m[1].slice(0, 2), 16),
parseInt(m[1].slice(2, 4), 16),
parseInt(m[1].slice(4, 6), 16)
];
}
if ((m = /^rgba?\(\s*(\d+)[,\s]+(\d+)[,\s]+(\d+)/.exec(c))) {
return [+m[1], +m[2], +m[3]];
}
var named = {
white: [255, 255, 255],
black: [0, 0, 0],
red: [255, 0, 0],
blue: [0, 0, 255],
green: [0, 128, 0],
yellow: [255, 255, 0],
gray: [128, 128, 128],
grey: [128, 128, 128],
silver: [192, 192, 192]
};
return named[c] || null;
}
// Light page colors fold into a short dark-gray ramp. Saturated blues become mid gray bars.
function grayFor(rgb) {
var y = (0.2126 * rgb[0] + 0.7152 * rgb[1] + 0.0722 * rgb[2]) / 255;
var sat = (Math.max(rgb[0], rgb[1], rgb[2]) - Math.min(rgb[0], rgb[1], rgb[2])) / 255;
if (y < 0.16 && sat < 0.25) return null;
var out;
if (y >= 0.94) out = 20;
else if (y >= 0.82) out = 34;
else if (y >= 0.62) out = 42;
else out = 56;
var h = out.toString(16);
if (h.length < 2) h = '0' + h;
return '#' + h + h + h;
}
function declaredBackground(el) {
var attr = el.getAttribute && el.getAttribute('bgcolor');
if (attr) return attr;
var style = el.getAttribute && el.getAttribute('style');
if (!style || style.indexOf('background') === -1) return null;
var m = /background(?:-color)?\s*:\s*([^;]+)/i.exec(style);
if (!m) return null;
var v = m[1];
var hex = /#(?:[0-9a-f]{3}|[0-9a-f]{6})\b/i.exec(v);
if (hex) return hex[0];
var named = /\b(white|black|red|blue|green|yellow|gray|grey|silver)\b/i.exec(v);
return named ? named[1] : null;
}
function paint(el) {
if (!el || el.nodeType !== 1 || el.id === 'if-dark-toggle') return;
if (el.hasAttribute('data-if-painted')) return;
var raw = declaredBackground(el);
if (!raw) return;
var rgb = parseColor(raw);
if (!rgb) return;
var gray = grayFor(rgb);
if (!gray) return;
el.setAttribute('data-if-prev-bg', el.style.getPropertyValue('background-color') || '');
el.setAttribute('data-if-prev-pri', el.style.getPropertyPriority('background-color') || '');
el.setAttribute('data-if-painted', '1');
el.style.setProperty('background-color', gray, 'important');
}
function scan(root) {
if (!root || !document.documentElement.classList.contains('if-dark')) return;
if (root.nodeType === 1) paint(root);
if (!root.querySelectorAll) return;
var nodes = root.querySelectorAll('[bgcolor], [style*="background"]');
for (var i = 0; i < nodes.length; i++) paint(nodes[i]);
}
function unpaint() {
var nodes = document.querySelectorAll('[data-if-painted]');
for (var i = 0; i < nodes.length; i++) {
var el = nodes[i];
var prev = el.getAttribute('data-if-prev-bg');
var pri = el.getAttribute('data-if-prev-pri');
if (prev) el.style.setProperty('background-color', prev, pri || '');
else el.style.removeProperty('background-color');
el.removeAttribute('data-if-prev-bg');
el.removeAttribute('data-if-prev-pri');
el.removeAttribute('data-if-painted');
}
}
function updateButton() {
var b = document.getElementById('if-dark-toggle');
if (!b) return;
var on = document.documentElement.classList.contains('if-dark');
b.textContent = on ? '🌞' : '🌙';
b.setAttribute('aria-pressed', on ? 'true' : 'false');
}
function mountToggle() {
if (document.getElementById('if-dark-toggle') || !document.body) return;
var b = document.createElement('button');
b.id = 'if-dark-toggle';
b.type = 'button';
b.addEventListener('click', function (ev) {
ev.preventDefault();
ev.stopPropagation();
var on = !document.documentElement.classList.contains('if-dark');
setOn(on);
applyRoot(on);
if (on) scan(document);
updateButton();
}, true);
document.body.appendChild(b);
updateButton();
}
applyRoot(isOn());
var style = document.createElement('style');
style.id = 'if-dark-style';
style.textContent = CSS;
document.documentElement.appendChild(style);
function boot() {
mountToggle();
if (document.documentElement.classList.contains('if-dark')) scan(document);
if (window.MutationObserver && document.body) {
var obs = new MutationObserver(function (muts) {
if (!document.documentElement.classList.contains('if-dark')) return;
for (var i = 0; i < muts.length; i++) {
var added = muts[i].addedNodes;
for (var j = 0; j < added.length; j++) {
var n = added[j];
if (n.nodeType === 1 && n.id !== 'if-dark-toggle') scan(n);
}
}
});
obs.observe(document.body, { childList: true, subtree: true });
}
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', boot);
} else {
boot();
}
})();