adjustColor2

convert colors to eye-friendly - webページの配色を目に優しく変更します (Flash対応)

当前为 2015-06-08 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name        adjustColor2
// @namespace   http://chiebukuro.yahoo.co.jp/my/gbjyn273
// @author Syakku
// @description	convert colors to eye-friendly - webページの配色を目に優しく変更します (Flash対応)
// @include     *
// @version     1.1
// @run-at     document-start  
// ==/UserScript==

//	================≪ OPTION ≫================

	//	----------------< white" & "black" color >----------------
	var FILTER_COLOR_W = "rgb(234, 229, 227)";
	var FILTER_COLOR_B = "rgb(41, 34, 29)";
	var INNER_COLOR_W = "rgb(211, 203, 198)";
	var INNER_COLOR_B = "rgb(41, 34, 29)";	//	gb is disabled
	
	//	OPTION : apply to Flash object
	var FLASH = true;
	
	//	OPTION : skip <a> tag (link anchor)
	//	OPTION : <a> タグ、つまりリンク文字列を処理から除外します
	//	ex: [] or ["google.co.jp", "youtube", "&link=important"] or [*]
	var _A_SKIP_URL = [""];
	
	
// ================≪ 初期化 ≫================
	var _win = document.defaultView;	
	
	var fCw = rgbSplit(FILTER_COLOR_W);
	var fCb = rgbSplit(FILTER_COLOR_B);
	var iCw = rgbSplit(INNER_COLOR_W);
	var iCb = rgbSplit(INNER_COLOR_B);
	
	// ----------------< インナーがフィルターを超えていたら修正 >----------------
	for (var i=0; i<3; i++){
		if (iCw[i] > fCw[i]){iCw[i] = fCw[i];}
		if (iCb[i] < fCb[i]){iCb[i] = fCb[i];}
	}
	
	// ----------------< フィルタ関連の初期化 >----------------
	var fColor = createFilter(fCw, fCb);
	var filterR = fColor[0], filterG = fColor[1], filterB = fColor[2],	filterA = fColor[3], filterAa = 1-filterA;
	
	//	色変換で使うので先に計算
	var filterRA = filterR * filterA, filterGA = filterG * filterA, filterBA = filterB * filterA;
	var _pr = (iCw[0] - iCb[0]) / 255, _pg = (iCw[1] - iCb[1]) / 255, _pb = (iCw[2] - iCb[2]) / 255;
	var _pr2 = iCb[0], _pg2 = iCb[1], _pb2 = iCb[2];
	
	// ----------------< 色変換の結果保持配列 >----------------
	var list = [];
	var lFg = [];
	var lCount = 0;


	// ----------------< 背景画像処理 >----------------
	var bgFilter = createBgFilter();
	var bgfCount = bgFilter.substring(0, 30);
	var bgfcLength = bgfCount.length;
	
	function createBgFilter(){
		var tw=[], tb=[];
		tw[0] = Math.floor((iCw[0] - filterRA) / filterAa);
		tw[1] = Math.floor((iCw[1] - filterGA) / filterAa);
		tw[2] = Math.floor((iCw[2] - filterBA) / filterAa);
		tb[0] = Math.floor((iCb[0] - filterRA) / filterAa);
		var bfColor = createFilter(tw, tb);
		var _rgba = bfColor[4];
		return("linear-gradient(" + _rgba + ',' + _rgba + "),");
	}

	// ----------------< URLフィルタ >----------------
	var _skip = false;
	for (var i=0; i<_A_SKIP_URL.length; i++){
		if (location.href.indexOf(_A_SKIP_URL[i]) !== -1 || _A_SKIP_URL[i] === "*"){_skip = true;}
	}
	
	
		
// ################################################ //
// ################### メイン処理部 ################### //
// ################################################ //


// ================≪ 起動処理 ≫================
	var FAST = true;
	 if (window === window.parent){
		if (FAST === true){loadFilter();}
		else {_win.addEventListener("DOMContentLoaded", loadFilter, false)}
	}
	_win.addEventListener("DOMContentLoaded", afterTouch, false);
	_win.addEventListener("load", afterTouch, false);
	
	if (FLASH === true){_win.addEventListener("DOMContentLoaded", flashMode, false);}

	
// ================≪ フィルタの適用 ≫================
function loadFilter(_fast){
	var _filter = document.createElement("ac_filter"); 
	_filter.id = "adjustColor"; 
	_filter.style.backgroundColor = fColor[4];
	_filter.style.pointerEvents = "none";
	_filter.style.height = "100%";
	_filter.style.width = "100%";
	_filter.style.position = "fixed";
	_filter.style.zIndex = 9999;

	var _nodes = document.getElementsByTagName("html")[0].childNodes;
	for (var i=0; i<_nodes.length; i++){
		var _node = _nodes[i];
		if (_node.tagName === "BODY"){
			var _style = _node.style;
			_style.position = "absolute";
			//	absolute にすると中央揃えでなくなってしまう
			_style.left = 0;
			_style.right =  0;
			_style.top = 0;
			_style.bottom = 0;
			// unset なのはブラウザ標準スタイルシートでマージンが存在するため
			_style.margin = "unset auto";
			break;
		} else if (_node.tagName === "FRAMESET"){
			document.getElementsByTagName("html")[0].insertBefore(_filter, _node);
			return;
		}
	}
	document.getElementsByTagName("html")[0].appendChild(_filter);
}


// ================≪ 追加処理 ≫================
function afterTouch(){
    var elm = document.getElementsByTagName("*");
	var elm_length = elm.length;

	for (var i = 0; i < elm_length; i++) {

		var tElm = elm[i];
		// <A>タグ
		if (tElm.tagName === "A" && _skip === true) {continue;}
        var style = _win.getComputedStyle(tElm, null);
		var fgColor = style.getPropertyValue("color");
		
		// ----------------< 背景 >----------------
		fg:{
			
			//	処理する必要のないカラーは省く
			for (var n=0; n<lCount; n++){
				if (fgColor === list[n]){break fg;}
			}
						
			//	既存のカラーは省エネ
			for (var n=0; n<lCount; n++){
				if (fgColor === lFg[n]){
					tElm.style.color = list[n];
					break fg;
				}
			}

			var _tColorF = convColor(fgColor);
			lFg[lCount] = fgColor;
			list[lCount] = _tColorF;
			lCount++;
			tElm.style.color = list[n];
		}
	}
}


//	================ <背景色レンジ縮小 ≫================
function convColor(_bg) {

	var _col = rgbSplit(_bg);
	
    var _colR = _col[0] * _pr + _pr2*1;
    var _colG = _col[1] * _pg + _pg2*1;
    var _colB = _col[2] * _pb + _pb2*1;
	
	_colR = Math.floor((_colR - filterRA) / filterAa);
	_colG = Math.floor((_colG - filterGA) / filterAa);
	_colB = Math.floor((_colB - filterBA) / filterAa);

    if (typeof _col[3] === "undefined") {
        return ("rgb(" + _colR + ", " + _colG + ", " + _colB + ")");
    }
    return ("rgb(" + _colR + ", " + _colG + ", " + _colB + ", " + _col[3] + ")"); //	rgba
}


// ================≪ RGB値の分割 ≫================
function rgbSplit(_col){
	if (_col.substring(0, 4) === "rgb("){_col = _col.slice(4, -1)}
	else {_col = _col.slice(5, -1)}
	var _ret = _col.split(", ");
	return (_ret);
}


// ================≪ 白・黒の範囲を与えてフィルタを作成 ≫================
function createFilter(_w, _b){
	var br = _b[0], wr = _w[0], wg = _w[1], wb = _w[2];
	var tr = wr - br;
	var r = tr / (255 - tr) * br + br*1;
	var a = br/ r;	// 中心値 r が気をつけないと 0 や 255 になって 0 除算になる
	if (isNaN(a) === true){a = (wr-255) / (r-255);}

	var g = r - (wr - wg) / a;
	var b = r - (wr - wb) / a;
	
	// r, g, b, a, rgba の値を配列で返す
	return ([r, g, b, a, "rgba(" + Math.floor(r) + ", " + Math.floor(g) + ", " + Math.floor(b) + ", " + a + ")"]);
}


// ================≪ フラッシュにもフィルタを適用 ≫================
function flashMode(){
	 for (var objs = document.getElementsByTagName("object"), i = 0, obj; obj = objs[i]; i++){
	 
        if (obj.type === "application/x-shockwave-flash"){
            var skip = false;

            for (var params = obj.getElementsByTagName("param"), j = 0, param; param = params[j]; j++){
			
                if (param.getAttribute("name") == "wmode"){
                    skip = true;
                    param.setAttribute("value", "transparent");
					obj.parentNode.appendChild(obj);
                    break;
                }
            }
            if(skip) {continue;}
			
            var param = document.createElement("param");
            param.setAttribute("name", "wmode");
            param.setAttribute("value", "transparent");
            obj.appendChild(param);
			obj.parentNode.appendChild(obj);
        }
	}
}