☰

ImageFap Dark Mode

Dark theme for ImageFap with a toggle.

Você precisará instalar uma extensão como Tampermonkey, Greasemonkey ou Violentmonkey para instalar este script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

Você precisará instalar uma extensão como Tampermonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Userscripts para instalar este script.

Você precisará instalar uma extensão como o Tampermonkey para instalar este script.

Você precisará instalar um gerenciador de scripts de usuário para instalar este script.

(Eu já tenho um gerenciador de scripts de usuário, me deixe instalá-lo!)

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

(Eu já possuo um gerenciador de estilos de usuário, me deixar fazer a instalação!)

// ==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();
    }
})();