darkmode
by
nanikamado
2018-06-19 [2018/06/19 21:24:26]
サイトの背景色を黒にし、文字色を明るくします。詳しい説明はソースコード内の先頭のコメントを見てください。
@@ -21,49 +21,57 @@
(() => {
'use strict';
const set_color = (nodes) => {
- nodes.forEach((node) => {
- if (!node.style) return;
- if (node.getAttribute('dark_before_style') === null) node.setAttribute('dark_before_style', node.style.cssText);
- const computed_style = window.getComputedStyle(node);
- if (!computed_style.color) return;
- const [r, g, b] = computed_style.color.match(/\d+/g).slice(0, 3).map(Number);
- const s = 255 - Math.max(r, g, b);
- if (node.tagName === 'A')
- node.style.color = `rgb(${r+s},${g+s},${b+s})`;
- else
- node.style.setProperty('color', `rgb(${r+s},${g+s},${b+s})`, 'important');
-
- if (computed_style.backgroundColor.indexOf('a') === -1)
- node.style.setProperty('background-color', '#000', 'important');
- else if (computed_style.backgroundColor.indexOf('rgba(0, 0, 0, 0)') === -1)
- node.style.setProperty('background-color', 'rgba(0, 0, 0,' +
- computed_style.backgroundColor.replace(/[^,]*,[^,]+,[^,]+,[^,\d]*(\d?.?\d+)/, '$1'), 'important');
-
- if (computed_style.backgroundImage.indexOf('gradient') !== -1)
- node.style.backgroundImage = computed_style.backgroundImage
- .replace(/[^,]*gradient\((?:[^\(\)]*\((?:[^\(\)]*\([^\(\)]*\))*[^\(\)]*[^\(\)]*\))*[^\(\)]*\),?/, '') || 'none';
- });
- };
- const set_color_all = () => {
- set_color(document.body.querySelectorAll('*'));
- set_color([document.body, document.body.parentNode]);
- document.body.querySelectorAll('iframe[src]').forEach(iframe => {
- if (!iframe.src) return;
- if ((new URL(iframe.src, location.href)).origin === location.origin || iframe.src === 'about:blank') {
- set_color(iframe.contentDocument.body.querySelectorAll('*'));
- let if_dc_b = iframe.contentDocument.body || console.error(iframe);
- if_dc_b.style.backgroundColor = '#000';
- }
- });
- document.body.style.backgroundColor = '#000';
- };
- const main = () => {
- switch (document.body.getAttribute('dark_mode_state') || '0') {
- case '0':
- let observer = new MutationObserver((maa) => {
- if (document.body.getAttribute('dark_mode_state') === '0') {
+ nodes.forEach(node => {
+ if (!node.style) return;
+ if (node.getAttribute('dark_before_style') === null) node.setAttribute('dark_before_style', node.style.cssText);
+ const computed_style = window.getComputedStyle(node);
+ if (!computed_style.color) return;
+ const [r, g, b] = computed_style.color.match(/\d+/g).slice(0, 3).map(Number);
+ const s = 255 - Math.max(r, g, b);
+ //color
+ if (node.tagName === 'A') node.style.color = `rgb(${r+s},${g+s},${b+s})`;
+ else node.style.setProperty('color', `rgb(${r+s},${g+s},${b+s})`, 'important');
+ //backgroundColor
+ if (computed_style.backgroundColor.indexOf('a') === -1)
+ node.style.setProperty('background-color', '#000', 'important');
+ else if (computed_style.backgroundColor.indexOf('rgba(0, 0, 0, 0)') === -1)
+ node.style.setProperty('background-color', 'rgba(0, 0, 0,' +
+ computed_style.backgroundColor.replace(/[^,]*,[^,]+,[^,]+,[^,\d]*(\d?.?\d+)/, '$1'), 'important');
+ //backgroundImage gradient
+ if (computed_style.backgroundImage.indexOf('gradient') !== -1)
+ node.style.backgroundImage = computed_style.backgroundImage
+ .replace(/[^,]*gradient\((?:[^\(\)]*\((?:[^\(\)]*\([^\(\)]*\))*[^\(\)]*[^\(\)]*\))*[^\(\)]*\),?/gi, '') || 'none';
+ });
+ },
+ set_color_all = () => {
+ set_color(document.body.querySelectorAll('*'));
+ set_color([document.body, document.body.parentNode]);
+ document.body.querySelectorAll('iframe[src]').forEach(iframe => {
+ if (!iframe.src) return;
+ if ((new URL(iframe.src, location.href)).origin === location.origin || iframe.src === 'about:blank') {
+ set_color(iframe.contentDocument.body.querySelectorAll('*'));
+ const if_dc_b = iframe.contentDocument.body || console.error(iframe);
+ if_dc_b.style.backgroundColor = '#000';
+ };
+ });
+ document.body.style.setProperty('background-color', '#000', 'important');
+ },
+ main = () => {
+ let dark_visited_style;
+ if (dark_visited_style = document.body.querySelector('.dark_visited_style')) { //even times
+ document.querySelectorAll('*').forEach(node => {
+ if (!node.style) return;
+ const style = node.getAttribute('dark_before_style');
+ if (style === null) return;
+ node.style.cssText = style;
+ });
+ dark_visited_style.remove();
+ console.log('1');
+ } else { //odd times
+ const observer = new MutationObserver((maa) => {
+ if (!document.body.querySelector('.dark_visited_style')) {
observer.disconnect();
- }
+ };
maa.forEach(ma => {
set_color(ma.addedNodes);
ma.addedNodes.forEach(added_node => {
@@ -74,75 +82,33 @@
console.log('reseted');
});
- let resize_timer,
- resize_listener = () => {
- console.log('resizing');
- if (resize_timer) clearTimeout(resize_timer);
- resize_timer = setTimeout(() => {
- switch (document.body.getAttribute('dark_mode_state')) {
- case '0':
- window.removeEventListener('resize', resize_listener);
- break;
- case '1':
- set_color_all();
- break;
- }
- }, 500);
- };
+ let resize_timer;
+ const resize_listener = () => {
+ console.log('resizing');
+ if (resize_timer) clearTimeout(resize_timer);
+ resize_timer = setTimeout(() => {
+ if (document.body.querySelector('.dark_visited_style')) set_color_all();
+ else window.removeEventListener('resize', resize_listener);
+ }, 500);
+ };
window.addEventListener('resize', resize_listener);
- let dark_style = document.createElement('style');
- dark_style.textContent = `a:visited {
- color: #b553ff!important
- }
- *{
- text-shadow:none!important;
- }
-
- ::before,::after{
- background-color:transparent!important;
- }
-
- ::-webkit-scrollbar {
- overflow: hidden;
- width: .8rem;
- background: #000;
- }
-
- ::-webkit-scrollbar-thumb {
- overflow: hidden;
- border-radius: .4rem;
- background: #ddd;
- }`;
+ const dark_style = document.createElement('style');
+ dark_style.textContent = `a:visited{color:#b553ff!important}
+ *{text-shadow:none!important}:after,:before{background-color:transparent!important}
+ ::-webkit-scrollbar{overflow:hidden;width:.8rem;background:#000}
+ ::-webkit-scrollbar-thumb{overflow:hidden;border-radius:.4rem;background:#ddd}`;
dark_style.className = 'dark_visited_style';
document.body.appendChild(dark_style);
- document.body.setAttribute('dark_mode_state', '1');
set_color_all();
observer.observe(document.body, {
childList: true,
- subtree: true
+ subtree: true,
});
console.log('0');
- break;
-
- case '1':
- document.body.setAttribute('dark_mode_state', '0');
- document.querySelectorAll('*').forEach(node => {
- if (!node.style) return;
- const style = node.getAttribute('dark_before_style');
- if (style === null) return;
- node.style.cssText = style;
- });
- document.body.getElementsByClassName('dark_visited_style')[0].remove();
- console.log('1');
- break;
- }
- };
-
- if (document.readyState == 'loading') {
- document.addEventListener('DOMContentLoaded', main);
- } else {
- main()
- }
+ };
+ };
+ if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', main);
+ else main();
})();
/*
* @title darkmode
* @description サイトの背景色を黒にし、文字色を明るくします。詳しい説明はソースコード内の先頭のコメントを見てください。
* @include http://*
* @include https://*
* @contributor noromanba http://let.hatelabo.jp/noromanba/let/hJmc5cn7v_h5
* @license MIT license https://opensource.org/licenses/MIT
* @javascript_url
*/
// 背景の色を黒にします。ただし、背景が透明の場合は変更しません。
// 文字色の彩度を最大にします。
// 訪問したことのあるリンクの色を紫にします。
// 稀に色を変えられないこともあります。仕様です。
// 画像の色は変わりません。
// 一度実行した状態でもう一度実行すると、もとに戻ります。
//http://let.hatelabo.jp/nanikamado/let/hLHU5aii3YU5 の改良版です。
(() => {
'use strict';
const set_color = (nodes) => {
nodes.forEach(node => {
if (!node.style) return;
if (node.getAttribute('dark_before_style') === null) node.setAttribute('dark_before_style', node.style.cssText);
const computed_style = window.getComputedStyle(node);
if (!computed_style.color) return;
const [r, g, b] = computed_style.color.match(/\d+/g).slice(0, 3).map(Number);
const s = 255 - Math.max(r, g, b);
//color
if (node.tagName === 'A') node.style.color = `rgb(${r+s},${g+s},${b+s})`;
else node.style.setProperty('color', `rgb(${r+s},${g+s},${b+s})`, 'important');
//backgroundColor
if (computed_style.backgroundColor.indexOf('a') === -1)
node.style.setProperty('background-color', '#000', 'important');
else if (computed_style.backgroundColor.indexOf('rgba(0, 0, 0, 0)') === -1)
node.style.setProperty('background-color', 'rgba(0, 0, 0,' +
computed_style.backgroundColor.replace(/[^,]*,[^,]+,[^,]+,[^,\d]*(\d?.?\d+)/, '$1'), 'important');
//backgroundImage gradient
if (computed_style.backgroundImage.indexOf('gradient') !== -1)
node.style.backgroundImage = computed_style.backgroundImage
.replace(/[^,]*gradient\((?:[^\(\)]*\((?:[^\(\)]*\([^\(\)]*\))*[^\(\)]*[^\(\)]*\))*[^\(\)]*\),?/gi, '') || 'none';
});
},
set_color_all = () => {
set_color(document.body.querySelectorAll('*'));
set_color([document.body, document.body.parentNode]);
document.body.querySelectorAll('iframe[src]').forEach(iframe => {
if (!iframe.src) return;
if ((new URL(iframe.src, location.href)).origin === location.origin || iframe.src === 'about:blank') {
set_color(iframe.contentDocument.body.querySelectorAll('*'));
const if_dc_b = iframe.contentDocument.body || console.error(iframe);
if_dc_b.style.backgroundColor = '#000';
};
});
document.body.style.setProperty('background-color', '#000', 'important');
},
main = () => {
let dark_visited_style;
if (dark_visited_style = document.body.querySelector('.dark_visited_style')) { //even times
document.querySelectorAll('*').forEach(node => {
if (!node.style) return;
const style = node.getAttribute('dark_before_style');
if (style === null) return;
node.style.cssText = style;
});
dark_visited_style.remove();
console.log('1');
} else { //odd times
const observer = new MutationObserver((maa) => {
if (!document.body.querySelector('.dark_visited_style')) {
observer.disconnect();
};
maa.forEach(ma => {
set_color(ma.addedNodes);
ma.addedNodes.forEach(added_node => {
if (added_node.nodeName === '#text') return;
set_color(added_node.querySelectorAll('*'));
});
});
console.log('reseted');
});
let resize_timer;
const resize_listener = () => {
console.log('resizing');
if (resize_timer) clearTimeout(resize_timer);
resize_timer = setTimeout(() => {
if (document.body.querySelector('.dark_visited_style')) set_color_all();
else window.removeEventListener('resize', resize_listener);
}, 500);
};
window.addEventListener('resize', resize_listener);
const dark_style = document.createElement('style');
dark_style.textContent = `a:visited{color:#b553ff!important}
*{text-shadow:none!important}:after,:before{background-color:transparent!important}
::-webkit-scrollbar{overflow:hidden;width:.8rem;background:#000}
::-webkit-scrollbar-thumb{overflow:hidden;border-radius:.4rem;background:#ddd}`;
dark_style.className = 'dark_visited_style';
document.body.appendChild(dark_style);
set_color_all();
observer.observe(document.body, {
childList: true,
subtree: true,
});
console.log('0');
};
};
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', main);
else main();
})();
- Permalink
- このページへの個別リンクです。
- RAW
- 書かれたコードへの直接のリンクです。
- Packed
- 文字列が圧縮された書かれたコードへのリンクです。
- Userscript
- Greasemonkey 等で利用する場合の .user.js へのリンクです。
- Loader
- @require やソースコードが長い場合に多段ロードする Loader コミのコードへのリンクです。
- Metadata
- コード中にコメントで @xxx と書かれたメタデータの JSON です。