Greasy Fork

Greasy Fork is available in English.

Enhanced word highlight

Enhanced keywords highlight for Search Engines and All !

当前为 2017-10-13 提交的版本,查看 最新版本

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name           Enhanced word highlight
// @namespace      http://userscripts.org/users/86496
// @description    Enhanced keywords highlight for Search Engines and All !
// @include        http://*
// @include        https://*
// @exclude        http://maps.google.com/*
// @exclude        https://maps.google.com/*
// @grant          GM_log
// @grant          GM_xmlhttpRequest
// @grant          GM_getValue
// @grant          GM_setValue
// @grant          GM_openInTab
// @grant          GM_registerMenuCommand
// @version        1.6.0
// ==/UserScript==

// great credit for original script wright os0x [http://userscripts.org/scripts/show/43419]
// hzhbest modded  | detail in http://userscripts.org/scripts/show/64877

//console.time("highlight");
//var l = function(){var len = arguments.length; var tx=''; for(i=0;i<len;i++){tx += (arguments[i] + '; ');} GM_log(tx.toString())};//+'['+len+']'
function l(message) {if (typeof console == 'object') {console.log(message)} else {GM_log(message)}}
(function word_hightlight(loaded){
	
	//if (window.top != window.self) return; //don't run on frames or iframes
    
	// check browser
	if (!loaded && window.opera && document.readyState == 'interactive') {
		document.addEventListener('DOMContentLoaded', function(){
			loaded = true;
			word_hightlight(true);
		}, false);
		window.addEventListener('load', function(){
			if (!loaded)
				word_hightlight(true);
		}, false);
		return;
	}
	if (document.contentType && !/html/i.test(document.contentType))
		return;
	// check api
	if (typeof GM_getValue == "function") {
		var getv = GM_getValue;
		var setv = GM_setValue;
	} else { // workaround functions, creadit to ww_start_t
		var setv = function(cookieName, cookieValue, lifeTime){
			if (!cookieName) {return;}
			if (lifeTime == "delete") {lifeTime = -10;} else {lifeTime = 31536000;}
			document.cookie = escape(cookieName)+ "=" + escape(getRecoverableString(cookieValue))+
				";expires=" + (new Date((new Date()).getTime() + (1000 * lifeTime))).toGMTString() + ";path=/";
		};
		var getv = function(cookieName, oDefault){
			var cookieJar = document.cookie.split("; ");
			for (var x = 0; x < cookieJar.length; x++ ) {
				var oneCookie = cookieJar[x].split("=");
				if (oneCookie[0] == escape(cookieName)) {
					try {
						eval('var footm = '+unescape(oneCookie[1]));
					} catch (e) {return oDefault;}
					return footm;
				}
			}
			return oDefault;
		};
	}
		
//{	values >
	var isOpera = !!this.opera,
		isFirefox = !!this.Components,
		isChromium = !!this.chromium,
		isSafari = this.getMatchedCSSRules && !isChromium;
		
	var STYLE_COLOR = ['#FFFF80','#99ccff','#ff99cc','#66cc66','#cc99ff','#ffcc66','#66aaaa','#dd9966','#aaaaaa','#dd6699'];
	var BORDER_COLOR = ['#aaaa20','#4477aa','#aa4477','#117711','#7744aa','#aa7711','#115555','#884411','#555555','#881144'];
	var STYLE_COLOR_2 = ['#FFFFa0','#bbeeff','#ffbbcc','#88ee88','#ccbbff','#ffee88','#88cccc','#ffbb88','#cccccc','#ffaabb'];
	var BORDER_COLOR_2 = ['#aaaa40','#6699aa','#aa6699','#339933','#9966aa','#aa9933','#337777','#aa6633','#777777','#aa3366'];
	var but_c = '#99cc99', but_ca = '#FFD000', but_cd = '#999999', but_cb = '#669966'; // button normal/active/disable background color/border color.
	
	// Initialize value
	var PRE = 'wordhighlight', ID_PRE = PRE + '_id', ST_PRE = PRE + '_store', PO_PRE = PRE + '_position', CO_PRE = PRE + '_config';
	var STYLE_CLASS = '0123456789'.split('').map(function(a,i){return PRE + '_word'+i;});
	var setuped = false;
	var highlight_off = false;
	var addKeyword = true;
	var keyword = '', words = [], word_lists = [], word_inputs_list, layers, positions = [];
	var words_off = [];
	var xp_all = new $XE('descendant::span[starts-with(@name,"' + PRE + '_word")]', document.body);
	var keyCodeStr = {
		8:  'BAC',
		9:  'TAB',
		10: 'RET',
		13: 'RET',
		27: 'ESC',
		33: 'PageUp',
		34: 'PageDown',
		35: 'End',
		36: 'Home',
		37: 'Left',
		38: 'Up',
		39: 'Right',
		40: 'Down',
		45: 'Insert',
		46: 'Delete',
		112: 'F1',
		113: 'F2',
		114: 'F3',
		115: 'F4',
		116: 'F5',
		117: 'F6',
		118: 'F7',
		119: 'F8',
		120: 'F9',
		121: 'F10',
		122: 'F11',
		123: 'F12'
	};
	var whichStr = {
		32: 'SPC'
	};
	var htmlDoc = isChromium ? document.implementation.createHTMLDocument('hogehoge') : document;
	var highlight_reset = function(){};
	var canvas, cw, c2context, nav;
	var root = /BackCompat/i.test(document.compatMode) ? document.body : document.documentElement;
	var CanvasWidth = 150;
	var ratio = 1;
	var aside, section, td0, lock, edit, off, text_input, posi_tip, posi_tip_timer, inputBOX;  // panel elements
	var sheet, main_sheet, move_sheet, inst_sheet;  // style sheets
	
	//language detection
	if ((navigator.userAgent.toLowerCase().indexOf('zh-') == -1) || ((navigator.userAgent.toLowerCase().indexOf('firefox') != -1) && (navigator.language.indexOf('zh-') == -1))) {
		_L = 0;
	} else _L = 1;
	//var _L = (!!(navigator.userAgent.toLowerCase().indexOf('zh-') == -1))? 0:1;
	//if(navigator.userAgent.toLowerCase().indexOf('firefox') != -1) 
	//{_L = (!!(navigator.language.indexOf('zh-') == -1))? 0:1;} // Thanks to SoIN(http://userscripts.org/users/302257)
	var _ti = { // en/zh locale string for tooltip.
		edit: ['Edit current keywords','编辑现有关键词'],
		edit_a: ['Confirm editing keywords','确认编辑关键词'],
		off:  ['Toggle all keywords\' highlight','切换全部关键词的高亮'],
		td0:  ['Double-click to minimize the panel','双击最小化面板'],
		td0_a:  ['Double-click to restore EWH panel','双击恢复 EWH 面板'],
		lock: ['Lock current set of keywords','锁定当前的关键词组'],
		lock_a: ['Current locked keyword(s):','当前锁定的关键词组:'],
		lock_u: ['Function not supported by this browser','此浏览器不支持该功能'],
		close: ['Close Enhanced word highlight','关闭关键词高亮'],
		kwL:  ['Left click to the next; Right click to the previous','左击跳到下一个;右击跳到上一个'],
		check: [['Toggle highlight of "','"'],['切换“','”的高亮']],
		mapl:['Toggle highlight map locking status','切换高亮分布图的锁定状态'],
		ad_nw: ['Toggle add/new keywords for highlight','切换添加/取代关键词的高亮'],
		subm: ['Submit keywords','提交关键词'],
		clos: ['Close input box','关闭输入框']
	};
	var _di = { // en/zh locale string for dialog.
		update: [['There is an update available for the Greasemonkey script "','."\nWould you like to go to the install page now?','No update is available for "','."','An error occurred while checking for updates:\n',' - Manual Update Check'],
				['发现 GM 脚本“','”有更新,\n是否现在打开脚本发布页?','没找到“','”脚本的更新。','检查更新时出现了一个错误:\n',' - 手动检查更新']],
		confT:  ['Enhanced word highlight Advanced Config','Enhanced word highlight 高级设置'],
		conf:   [['What auto-pager tool do you mostly use?',
				'Turn off highlight of short keywords by default?',
				'Disable auto-highlight (auto-capture keywords for highlight) ?',
				'Sort keyword for more accurate highlight (Recommended, except for regular expression users)',
				'Save panel position',
				'Show indicator bar when navigating'],
				['你主要用那种自动翻页工具?',
				'是否默认停用短关键词的高亮?',
				'是否禁用自动高亮(自动抓取关键词来高亮)?',
				'排列关键词以更准确高亮(推荐;需要高亮正则表达式的用户除外)',
				'保存面板位置',
				'查找关键词时显示指示条']],
		confR:  [[['Autopagerize GM script','Autopager extension','Other (can handle all auto-pager tools but works slow)'],
				['Don\'t turn off','One-letter/digit word','One- and two-letter/digit word'],
				['Enable','Completely disable','Disable on pages opened from supported search results','Disable on supported search result pages']],
				[['Autopagerize GM 脚本','Autopager 扩展','其他(能应付任何自动翻页工具但运作较慢)'],
				['否','是;针对单个字母/数字','是,针对单/两个字母/数字'],
				['不禁用','完全禁用','仅在从支持的搜索结果中打开的页面上禁用','仅在支持的搜索结果页面上禁用']]]
	};
//}
		
	var urlArr = [], queryArr = [];

//{	Config I >
// #### Config I #### --------------------------{{
	
	// List of url patterns; Array('NAME', 'KEYWORD_PREFIX', 'URL_PATTERN')
	urlArr[0] = ['Google',	 'q=',	 'www.google.'];
	urlArr[1] = ['Yahoo',	 'p=',	 'search.yahoo.c'];
	urlArr[2] = ['Baidu',	 'wd=',	 'www.baidu.com'];
	urlArr[3] = ['Baidu',	 'word=', '.baidu.com'];
	urlArr[4] = ['Ask',		 'q=',	 'www.ask.com'];
	urlArr[5] = ['Bing',	 'q=',	 '.bing.com'];
	urlArr[6] = ['Youdao',	 'q=',	 'www.youdao.com'];
	
	// List of IDs of query input boxes; Array('#SEARCHBOX_ID#', 'SEARCHPAGE SPEC_URL')
	queryArr[0] = ['query', '/search'];		// most common
	queryArr[1] = ['search', ''];				// most common
	queryArr[2] = ['script_q', 'userscripts.org/scripts/search'];			// userscripts.org
	queryArr[3] = ['top-search-input', 'www.verycd.com/search/folders'];	// verycd.com
	queryArr[4] = ['search-q', '/search'];		// addons.mozilla.org
		
	// keybinds
	var KEY_NEXT = 'n';		// "n"			Next occurrence
	var KEY_PREV = 'N';		// "Shift-n"	Previous occurrence
	var KEY_SEARCH = 'M-/';	// "Alt-/"		Add keywords
	var KEY_OFF = 'M-,';	// "Alt-,"		Suspend highlight
	var KEY_CLOSE = 'C-M-/';	// "Ctrl-Alt-/"		Disable highlight
	var KEY_EDIT = 'M-.';	// "Alt-."		Edit highlight
	var KEY_REFRESH = 'r';	// "r"			Refresh highlight

	// delay of highlighting (ms)
	var delay = 500;
	
	// instant highlight selected keywords
	var instant = true;

	// restore focus and scroll position after closing keyword input box with shortcut key?
	// mainly useful for keyboard navigation, not recommend for mouse navigation.
	var refocus = false;
	
	// minimize the panel initially?
	var panel_hide = false;

// #### Config I #### --------------------------}}
//}
	if (window.top != window.self) panel_hide = true; //hide panel in iframes

//{	Config II >
// #### Config II #### --------------------------{{
	// What's your main auto-pager tool?
	// 0 - Autopagerize (GM script)
	// 1 - AuroPager (Firefox Extension)
	// 2 - Other (Other auto-pager scripts, site-specific scripts, bookmarklets, etc.)
	//<!> From top option to botom one, the compatibility of the script
	//	will be strengthened while the performance of highlight will be lower.
	var ap_option = 0;
	
	// turn off short keywords (one or two letters or number) by default?
	//	0-no, 1-one letter, 2-one or two letters
	var off_short_words = 1;

	// Stop auto-highlight on supported pages?
	// 0-no, 1-yes, 2-only those from search results, 3-only search results
	var no_auto_hili = 0;
	
	// sort keywords? 0-no, 1-yes 
	//<!> Setting this to "yes" will produce better highlight result,
	//	while "no" will perform faster and support ReExp input better.
	var sort_keywords = 1;
	
	// save panel position?
	var save_panel_pos = false;
	
	// show indicator bar when navigating?
	var show_indc_bar = false;
// #### Config II #### --------------------------}}
//}

	// var config = {
		// key: {next:'n', prev:'N', srch:'C-/', off:'M-.', clos:'C-M-/', edit:'M-/', rfsh:'r'},
		// delay:500,
		// instant:true,
		// refocus:false,
		
		// ap_comp: {
			// name: '',
			// val: getv('ap_comp', 0),
			// dom: {label:'LABLE', type:'radio', set:['set1','set2','set3']}
		// },
		// short_w: {
			// name: '',
			// val: getv('short_w', 1),
			// dom: {label:'LABLE', type:'radio', set:['set1','set2','set3']}
		// },
		// sort_kw: {
			// name: '',
			// val: getv('sort_kw', true),
			// dom: {label:'LABLE', type:'checkbox', set:['set1']}
		// }
	// }

	
	// GM APIs available?
	if (typeof GM_getValue == "function") var gm_ok = true;
	// Configs
	if (!gm_ok) {


		//
		var Ewh_configs = [ap_option, off_short_words, no_auto_hili, sort_keywords, save_panel_pos, show_indc_bar];
	} else {
		var Ewh_configs = GM_getValue(CO_PRE, '0|1|0|1|0|0').split('|');
	}
	for (i in Ewh_configs) {Ewh_configs[i] = Number(Ewh_configs[i]);}
	// Locked keywords
	if (gm_ok) var keyword_store = GM_getValue(ST_PRE);
	// Saved position
	var panel_pos_arr = ['right:-1px;','bottom:-1px;'];
	if (Ewh_configs[4] && gm_ok) panel_pos_arr = GM_getValue(PO_PRE, panel_pos_arr.join('|')).split('|');
	// Configs menu
	if (gm_ok) window.addEventListener('load', function(){GM_registerMenuCommand(_di.confT[_L], config_box);}, false);
	
	if (gm_ok) {
		unsafeWindow.EWH_iSearch = function() {instant_search(false, null);};
		unsafeWindow.EWH_cClose = function() {command_close();};
	}

	// main process
	init_keyboard();
	if (load_keyword() !== false || init_keyword() !== false) {
		//window.addEventListener('load', go, false);
		setTimeout(go, delay);
	}
	
	// var oldurl = window.location.href;
	// window.addEventListener('DOMNodeInserted', function(e){ l(window.location.href);
		// if (window.location.href !== oldurl) {
			// if (load_keyword() !== false || init_keyword() !== false) {
				
				// setTimeout(go, delay*2);
			// }
		// }
	// }, false);
	
	function go(){
	setup();
	
/*	// CHECK FOR UPDATE //
	if (gm_ok) {var SUC_script_num = 64877;
	try{function updateCheck(forced){if ((forced) || (parseInt(GM_getValue('SUC_last_update', '0')) + 86400000 <= (new Date().getTime()))){try{GM_xmlhttpRequest({method: 'GET',url: 'http://userscripts.org/scripts/source/'+SUC_script_num+'.meta.js?'+new Date().getTime(),headers: {'Cache-Control': 'no-cache'},onload: function(resp){var local_version, remote_version, rt, script_name;rt=resp.responseText;GM_setValue('SUC_last_update', new Date().getTime()+'');remote_version=parseInt(/@uso:version\s*(.*?)\s*$/m.exec(rt)[1]);local_version=parseInt(GM_getValue('SUC_current_version', '-1'));if(local_version!=-1){script_name = (/@name\s*(.*?)\s*$/m.exec(rt))[1];GM_setValue('SUC_target_script_name', script_name);if (remote_version > local_version){if(confirm(_di.update[_L][0]+script_name+_di.update[_L][1])){GM_openInTab('http://userscripts.org/scripts/show/'+SUC_script_num);GM_setValue('SUC_current_version', remote_version);}}else if (forced)alert(_di.update[_L][2]+script_name+_di.update[_L][3]);}else GM_setValue('SUC_current_version', remote_version+'');}});}catch (err){if (forced)alert(_di.update[_L][4]+err);}}}GM_registerMenuCommand(GM_getValue('SUC_target_script_name', 'BPT') + _di.update[_L][5], function(){updateCheck(true);});updateCheck(false);}catch(err){}
	}*/
	
	}

	
// Functions
	
	function highlight(doc, ext_word) {
		var _words = words.filter(function(w,i){return !words_off[i];});
		if (_words.length <= 0)
			return;
		var _index;
		if (ext_word && ext_word.words) {
			_words = ext_word.words;
			_index = ext_word.index;
		}
		var exd_words, xw;
		if (_words.length === 1 && _words[0].exp) {
			exd_words = _words.map(function(e){return e.exp;});
			xw = '';
		} else {
			exd_words = _words.map(function(w){return w.test ? w : new RegExp('(' + w.replace(/\W/g,'\\$&') + ')(?!##)', 'ig');});
			xw = ' and (' + _words.map(function(w){return ' contains(translate(self::text(),"abcdefghijklmnopqrstuvwxyz","ABCDEFGHIJKLMNOPQRSTUVWXYZ"),'+escapeXPathExpr(w.toUpperCase())+') ';}).join(' or ') + ') ';
		}
		$X('descendant::text()[string-length(normalize-space(self::text())) > 0 ' + xw +' and not(ancestor::textarea or ancestor::script or ancestor::style or ancestor::aside)]', doc).forEach(function(text_node) {
			var df, text = text_node.nodeValue, id_index = 0,
			parent = text_node.parentNode, range = document.createRange(), replace_strings = [],
			new_text = reduce(exd_words, function(text,ew,i) {
				var _i = _index || i;
				return text.replace(ew,function($0,$1) {
					replace_strings[id_index] = '<span id="' + ID_PRE + id_index + '" class="' + STYLE_CLASS[_i%10] + '" name="'+PRE+'_word'+_i+'">' + $1 + '</span>';
					return '##'+(id_index++)+'##';
				});
			}, text).
				replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').
				replace(/##(\d+)##/g, function($0,$1) {
				return replace_strings[$1] || '';
			});
			if (replace_strings.length) {
				try {
					if (isChromium) {
						range.selectNodeContents(htmlDoc.documentElement);
					} else {
						range.selectNode(text_node);
					}
					df = range.createContextualFragment(new_text);
					if (df.firstChild) parent.replaceChild(df, text_node);
					range.detach();
				} catch (e) {
					error(e);
				}
			}
		});
	}

	function addsheet() {
		if (!main_sheet) {
		var hilistyles = STYLE_COLOR.map(function(rgb,i){
			return 'span.' + PRE + '_word'+i+',.' + PRE + '_item'+i+'{background:'+rgb+'!important;}';
			});
		var borderstyles = BORDER_COLOR.map(function(rgb,i){
			return 'li.' + PRE + '_item'+i+'{outline:1px solid '+rgb+'!important;}';
			});
		sheet = addCSS([
			//Additional Style
			'span[class^="' + PRE + '_word"]{color:black!important;font:inherit!important;display:inline!important;margin:0!important;padding:0!important;text-align:inherit!important;float:none!important;position:static!important;}', //vertical-align:inherit !important;
			'#' + PRE + '_words, #' + PRE + '_words *{font-family: Arial ;}',
			'#' + PRE + '_words{line-height:1;position:fixed;z-index:60000;opacity:0.8;list-style-type:none;margin:0;padding:0;width:auto;max-width:100%;' + panel_pos_arr[0] + panel_pos_arr[1] +'}',
			'#' + PRE + '_words > section{clear:right;line-height:1;border:1px solid #666;/*border-left-width:10px;*/background:#fff;display:block;position:relative;}',
			'#' + PRE + '_words * {margin:0;padding:0;width:auto;height:auto;}',
			'#' + PRE + '_words:hover{opacity:1;}',
			'#' + PRE + '_words:hover > section{opacity:1;border-color:#333;}',
			'#' + PRE + '_words #_ewh_handle{background:#666;width:10px;cursor:move;}',
			'#' + PRE + '_words:hover #_ewh_handle{background:#333;}',
			'#' + PRE + '_words.ewh_hide #_ewh_handle{cursor:pointer;}',
//			'#' + PRE + '_words.ewh_hide:hover #_ewh_handle{width:10px;}',
//			'#' + PRE + '_words.ewh_hide > section form.' + PRE + '_ctrl > input.c_b{display:none;}',
			'#' + PRE + '_words > nav{display:none;width:100%;padding:3px;position:relative;}',
			'#' + PRE + '_words > nav > canvas.backport{background:rgba(0,0,0,0.5);cursor:pointer;position:absolute;right:6px;z-index:3;}',
			'#' + PRE + '_words > nav > canvas.viewport{background:rgba(79,168,255,0.7);cursor:default;position:absolute;bottom:0px;right:6px;}',//outline:6px solid rgba(79,168,255,0.7);
//			'#' + PRE + '_words > nav:hover > canvas.backport{background:rgba(0,0,0,0.5);}',
			'#' + PRE + '_words:hover > nav{display:block;}',
			'#' + PRE + '_words > nav._locked{display:block;}',
			'#' + PRE + '_words:hover > nav > canvas.backport{bottom:0px;}',
			'#' + PRE + '_words > nav._locked > canvas.backport{bottom:0px;}',
			'#' + PRE + '_words.ewh_edit{opacity:1;}',
			'#' + PRE + '_words.ewh_edit #' + PRE + '_word_inputs_list{display:none;}',
			'#' + PRE + '_words form.' + PRE + '_editor{display:none;}',
			'#' + PRE + '_words.ewh_edit form.' + PRE + '_editor{display:inline-block;}',
			'#' + PRE + '_words.ewh_edit form.' + PRE + '_editor input{min-width:80px;}',
			'#' + PRE + '_words li{display:inline-block;margin:0.1em 0.2em;line-height:1.3em;font-size:medium;}',
			'#' + PRE + '_words > section > * {vertical-align:middle;}',
			'#' + PRE + '_words > section td {border:none;}',
			'#' + PRE + '_words > section > h3.' + PRE + '_title{display:inline-block;background:#333;color:#fff;padding:0.1em 0.3em;border:none;margin:0 0.2em;}',
			'#' + PRE + '_words > section  form.' + PRE + '_ctrl{display:inline-block;}',
			'#' + PRE + '_words > section  form.' + PRE + '_ctrl > input{display:inline;width:1.3em;margin:0.1em 0.1em;background:'+ but_c +';border:1px solid '+ but_cb +';cursor:pointer;font-size:10pt;color:black;}',
			'#' + PRE + '_words > section  form.' + PRE + '_ctrl > input._active{background:'+ but_ca +';}',
			'#' + PRE + '_words > section  form.' + PRE + '_ctrl > input._disable{background:'+ but_cd +' !important;cursor:default;}',
			'#' + PRE + '_words > section  form.' + PRE + '_ctrl > input:hover{outline:1px solid '+ but_cb +'!important;}',
			'#' + PRE + '_word_inputs_list {padding:0!important;margin:0.2em!important;display:inline-block;border:none!important;}',
			'#' + PRE + '_word_inputs_list > li{position:relative;padding:0 4px;}',
			'#' + PRE + '_word_inputs_list > li.ewh_disable{background:white!important;outline:1px solid #999!important;}',
			'#' + PRE + '_word_inputs_list > li > label{cursor:pointer;color:black!important;}',
			'#' + PRE + '_word_inputs_list > li > input{cursor:pointer;}',
//			'#' + PRE + '_word_inputs_list > li > label > input[type=image]{vertical-align:top;padding:0;height:12px;}',
			'#' + PRE + '_word_inputs_list > li > input[type=checkbox]{display:none;position:absolute;right:0px;top:0px;opacity:0.7;}',
			'#' + PRE + '_word_inputs_list > li:hover{outline-width:2px!important;}',
			'#' + PRE + '_word_inputs_list > li:hover > input[type=checkbox]{display:block;}',
			'#' + PRE + '_word_inputs_list > li > input[type=checkbox]:hover{opacity:1;}',
			'#' + PRE + '_words > section td+td+td > input {display:inline;width:1.3em;margin:0.1em 0.1em;background:#FAFAFA;border:1px solid #aaaaaa;cursor:pointer;font-size:10pt;color:black;}',
		].concat(hilistyles, borderstyles).join('\n'));
		main_sheet = true;
		}
		if (!move_sheet) addmovesheet()
	}
	
	function addmovesheet() {
		addCSS('.wordhighlight_em{outline:4px solid #FF7B00;-webkit-outline:4px solid #FF7B00;text-decoration:blink;}');
		move_sheet = true;
	}
	
	function setup(init) {
		setuped = true;
		addsheet();

	// build ui
		aside = creaElemIn('aside', document.body);
			aside.id = PRE + '_words';
		section = creaElemIn('section', aside);
		var table_COL = creaElemIn('table', section);
			table_COL.setAttribute('style', 'border:0;margin:0;padding:0;border-spacing:2px;border-collapse:separate!important;');
			table_COL.setAttribute('cellspacing', '0');
			table_COL.setAttribute('cellpadding', '0');
		var tbdy_COL = creaElemIn('tbody', table_COL);
		var tr_COL = creaElemIn('tr', tbdy_COL);
		td0 = creaElemIn('td', tr_COL);
			td0.id = '_ewh_handle';
			td0.title = _ti.td0[_L];
		var td1 = creaElemIn('td', tr_COL);
			td1.setAttribute('style', 'border-right: 1px solid black; padding:0.2em 0.3em 0 0;vertical-align:top;');//width:7.2em;
		var td2 = creaElemIn('td', tr_COL);
		var td3 = creaElemIn('td', tr_COL);
		var editor = creaElemIn('form', td2);
			editor.className = PRE + '_editor';
		text_input = creaElemIn('input', editor);
			text_input.type = 'text';
		var ctrl = creaElemIn('form', td1);
			ctrl.className = PRE + '_ctrl';
		var close_button = creaElemIn('input', ctrl);
			close_button.type = 'button';
			close_button.className = 'c_b';
			close_button.value = 'X';
			close_button.title = _ti.close[_L];
		off = creaElemIn('input', ctrl);
			off.type = 'button';
			off.value = 'O';
			off.title = _ti.off[_L];
		lock = creaElemIn('input', ctrl);
			lock.type = 'button';
			lock.value = 'L';
		edit = creaElemIn('input', ctrl);
			edit.type = 'button';
			edit.value = 'E';
			edit.title = _ti.edit[_L];
		word_inputs_list = creaElemIn('ul', td2);
			word_inputs_list.id = PRE + '_word_inputs_list';
			word_inputs_list.className = PRE + '_inputs';
		var maplock = creaElemIn('input', td3);
			maplock.type = 'button';
			maplock.value = '<';
			maplock.title = _ti.mapl[_L];

	// add interactivity
		edit.addEventListener('click',command_edit,false);
		off.addEventListener('click',command_off,false);
		close_button.addEventListener('click',command_close,false);
		editor.addEventListener('submit',function(e){
				command_edit();
				e.preventDefault();
			},false);
		if (gm_ok) {
			lock.title = _ti.lock[_L];
			lock.className = (keyword_store)? '_active' : '';
			lock.addEventListener('click',function(){
				if (aside.className == 'ewh_edit') return;
				if (keyword_store) {
					lock.className = '';
					lock.title = _ti.lock[_L];
					GM_setValue(ST_PRE, '');
					keyword_store = '';
	//				lock.value = 'Lock: Off';
				} else {
					lock.className = '_active';
					lock.title = _ti.lock_a[_L] + ' ' + keyword;
					GM_setValue(ST_PRE, keyword);
					keyword_store = keyword;
	//				lock.value = 'Lock: On';
				}
			},false);
		} else {
			lock.title = _ti.lock_u[_L];
			lock.className = '_disable';
		}
		td0.addEventListener('dblclick',function(evt){//l(panel_hide,window.innerWidth - aside.offsetLeft,1);
				if (panel_hide)	{//l('O');
					aside.style.right = '0px';
					aside.className = '';
					panel_hide = false;
					this.title = _ti.td0[_L];
				}else{//l(panel_hide);
					aside.style.right = (14 - aside.offsetWidth) +'px';
					aside.className = 'ewh_hide';
					panel_hide = true;//l(panel_hide,3);
					this.title = _ti.td0_a[_L];
				}
			}, false);
		maplock.addEventListener('click',function(){
				if(!nav.className) {nav.className = '_locked'; this.value = '>';}
				else {nav.className = ''; this.value = '<';}
			},false);
		
	// enable drag
		var drag = endrag(aside,{x:'right',y:'bottom'});
		drag.hook('__drag_begin', function(e){
			if (this.element && ((this.element.className === 'ewh_edit') || (this.element.className === 'ewh_hide'))) // || /^canvas$/i.test(e.target.localName) || /^lable$/i.test(e.target.localName))
				return false;
		});

	// build map
		nav = document.createElement('nav');
		aside.insertBefore(nav,aside.firstChild);
		canvas = creaElemIn('canvas', nav);
			canvas.className='backport';
		cw = creaElemIn('canvas', nav);
			cw.className='viewport';
		var c2 = c2context = canvas.getContext('2d');

	// /+drag codes by grea
		// scrolling per events
		this.perf = 2, this.perfic = 0;
		this.moveTo = function(evt){
			if (perfic++ % perf || !window.drgg) return;
			var x = (evt.offsetX || evt.layerX)/ratio - root.clientWidth/2;
			var y = (evt.offsetY || evt.layerY)/ratio - root.clientHeight/2;
			window.scrollTo(x, y);
		}
		with(canvas){
			addEventListener('mousedown', function(e){ window.drgg = true; moveTo(e); },false);
			addEventListener('mousemove', function(e){ moveTo(e); },false);
			addEventListener('mouseup', function(e){ window.drgg = false; moveTo(e); },false);
			addEventListener('mouseout', function(e){ window.drgg = false; moveTo(e); },false);
		}
	// +/codes end
		
	// add AutoPager page change detector
		if (Ewh_configs[0]) {
			this.pagef = 5, this.pagefic = 0;
			var docHeight = document.body.scrollHeight, pageChanged;
			this.checkpage = function(){
				if ((pagefic++ % pagef == 0) && (document.body.scrollHeight > docHeight)) {
					switch (Ewh_configs[0]) {
					case 1:
						after_load();
						break;
					case 2:
						resetup();
						break;
					}
					docHeight = document.body.scrollHeight;
				}
			}
		}

	// sync with map & check page
		window.addEventListener('scroll',function(){
			var x = window.pageXOffset * ratio;
			var y = window.pageYOffset * ratio;
			cw.style.bottom = (canvas.height - cw.height - y) + 'px';
			cw.style.right = (-x + 6) + 'px';
			if (Ewh_configs[0]) checkpage();
		},false);
		
	// go to highlight
		highlight(document.body);
		word_lists = create_inputlist(words);
		layers = xp_all.get();
		draw_wordmap();
		if (!Ewh_configs[0]) init_autopager();
		if (panel_hide && !init){
			aside.style.right = (14 - aside.offsetWidth) +'px';
			aside.className = 'ewh_hide';
			td0.title = _ti.td0_a[_L];
		}
	}

	function restore_words(words) {
		(words||xp_all.get()).forEach(function(layer,i){
			var parent = layer.parentNode;
			while (layer.firstChild){
				parent.insertBefore(layer.firstChild, layer);
			}
			parent.removeChild(layer);
		});
	}

	function draw_wordmap() {
		var c2 = c2context;