您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Block unsafe(uncomfortable) content on web pages by keywords
// ==UserScript== // @name blockunsafe // @namespace http://blockunsafe.com/ // @version 1.0 // @description Block unsafe(uncomfortable) content on web pages by keywords // @author gonetoorion // @match http*://*/* // @grant GM_getValue // @grant GM_setValue // @grant GM_deleteValue // @run-at document-start // @noframes // @license GPLv3 // ==/UserScript== (function() { 'use strict'; // Your code here... let test_value = 40; let is_first = true; let setting_btn; let config_domain = "blockunsafe.com"; let pattern_url = window.location.pathname; let pattern_key = location.hostname + 'urlpattern'; let max_class_key = location.hostname + 'classkeyx'; let dom_nouse = ['SCRIPT','STYLE','TEXTAREA','svg','LINK','IFRAME','EM','I','IMG','FIELDSET','LEGEND','BR','OPTION','SELECT','INPUT','BUTTON','FORM','STRONG','TEXTAREA','FOOTER','META']; let no_check_tag = ['LI','TR']; let dom_dict = {}; let no_target_class = []; let max_key = ''; let class_set = GM_getValue(max_class_key); let pattern_set = GM_getValue(pattern_key); let top_widths = []; let class_setx = class_set?class_set:[]; let warn_words = []; let filter_words_area = 'show_filter_keyword'; let config_url = "https://www.blockunsafe.com/config.html"; let config_url_marks = ["z", "e", "t"]; for(let i=0,len=config_url_marks.length; i<len; i++){ let www_config_url = "https://www.blockunsafe.com/"+config_url_marks[i]+"config.html"; let no_www_config_url = "https://blockunsafe.com/"+config_url_marks[i]+"config.html"; if(window.location.href.indexOf(www_config_url)==0||window.location.href.indexOf(no_www_config_url)==0){ window.addEventListener("load", init_config_page); return; } } let all_ok = class_set&&check_url_pattern(pattern_url); let f_key = get_f_key(); if(!f_key){ return; } if(f_key==config_domain){ return; } let orignal_f_key = f_key; f_key += '_fbkssousousous'; let filter_keywords = GM_getValue(f_key); if(document.body){ if(all_ok){ document.body.style.display = 'none'; } setTimeout(show_page, 2000); } function reset_rule(lhn){ let pattern_key = lhn + 'urlpattern'; let max_class_key = lhn + 'classkeyx'; GM_deleteValue(max_class_key); GM_deleteValue(pattern_key); } function init_config_page(){ let f_key = ""; let arg = window.location.search; arg = arg.replace("?", ""); if(arg.indexOf("f_key=")!=0){ config_error(); return; } if(arg.indexOf("&")==-1){ f_key = arg.slice(arg.indexOf("f_key=")+6); }else{ f_key = arg.slice(arg.indexOf("f_key=")+6, arg.indexOf("&")); } if(!f_key){ config_error(); return; } let lhn = arg.slice(arg.indexOf("lhn=")+4, arg.indexOf("&cltp")); if(!lhn){ config_error(); return; } document.getElementById("reset_filter_rule_btn").addEventListener('click', function(e){ if(confirm("Are you sure you want to reset the filter rules ? ")){ reset_rule(lhn); document.getElementById("add_sign").innerHTML = "Reset successfully"; document.getElementById("add_sign").style.display = "block"; setTimeout(function(){ document.getElementById("add_sign").style.display = "none"; }, 1500); } }); document.getElementById("domain_eff_page").innerHTML = f_key; f_key += "_fbkssousousous"; let filter_keywords = GM_getValue(f_key); if(filter_keywords!=undefined&&filter_keywords.length!=0){ for(let i=0,len=filter_keywords.length;i<len;i++){ add_keyword_span(filter_keywords[i], f_key); } } document.getElementById('add_kw_btn').addEventListener('click', function(e){ let keyword = document.getElementById('add_kw_v').value; let values = GM_getValue(f_key); keyword = keyword.trim(); if(keyword==''||keyword.replace(/\s*/g,"")==''){ alert('Please add blocked keywords'); return; } if(values==undefined||values.length==0){ values = [keyword]; }else{ if(values.indexOf(keyword)==-1){ values.push(keyword); }else{ alert("The keywords already exists,don't add it again~"); return; } } GM_setValue(f_key, values); add_keyword_span(keyword, f_key); }); } function config_error(){ document.body.innerHTML = "CONFIG ERROR!"; } function get_f_key(){ let host_info = location.hostname.split('.'); let temp_f_key = ""; for(let i=host_info.length-1,stop_i=host_info.length-3;i>stop_i;i--){ if(temp_f_key){ temp_f_key = host_info[i] + '.' + temp_f_key; }else{ temp_f_key = host_info[i]; } } return temp_f_key; } function check_dom(dom_node){ dom_node.style.display = 'none'; } function check_url_pattern(url){ if(!pattern_set){ return false; } if(url=='/'&&pattern_set.indexOf(url)!=-1){ return true; } let is_in = false; let url_param = url.split('/'); url_param.shift(); for(let i=0,len=pattern_set.length; i<len; i++){ let test_url_param = pattern_set[i].split('/'); test_url_param.shift(); if(test_url_param.length!=url_param.length){ continue; } let diff_count = 0; for(let ix=0,lenx=test_url_param.length; ix<lenx; ix++){ if(isNaN(test_url_param[ix])!=isNaN(url_param[ix])){ break; } if(test_url_param[ix]!=url_param[ix]&&isNaN(url_param[ix])){ diff_count += 1; } if(diff_count>1){ break; } if(ix==lenx-1){ is_in = true; } } if(is_in){ break; } } return is_in; } function save_pattern(pattern_url){ if(pattern_set){ if(pattern_set.indexOf(pattern_url)!=-1){ return; }else{ pattern_set.push(pattern_url); } }else{ pattern_set = [pattern_url]; } GM_setValue(pattern_key, pattern_set); } function parse_dom_nodes(dom_nodes){ let filter_dom_childs = []; for(let i=0,len=dom_nodes.length; i<len; i++){ if(dom_nodes[i].nodeType!=1||dom_nouse.indexOf(dom_nodes[i].nodeName)!=-1){ continue; } if(no_check_tag.indexOf(dom_nodes[i].nodeName)!=-1&&all_ok){ check_update(dom_nodes[i]); continue; } let class_tag = dom_nodes[i].getAttribute('class'); if(class_tag&&!all_ok){ class_tag = class_tag.replace(/(^\s*)|(\s*$)/g, ""); if(dom_dict[class_tag]==undefined){ dom_dict[class_tag] = 0; }else{ dom_dict[class_tag] = dom_dict[class_tag] + 1; } } if(dom_nodes[i].childNodes.length){ filter_dom_childs.push(...dom_nodes[i].childNodes); } } if(filter_dom_childs.length){ parse_dom_nodes(filter_dom_childs); } } function get_max_node(){ let max_key = ''; for(let key in dom_dict){ if(max_key==''||dom_dict[max_key]<dom_dict[key]){ max_key = key; } } return max_key; } function check_update(mut_node){ if(no_target_class.indexOf(mut_node.className)!=-1){ return; } for(let i=0,len=warn_words.length;i<len;i++){ if(mut_node.innerText.toLowerCase().indexOf(warn_words[i])!=-1){ check_dom(mut_node); break; } } } function analy_page(mut_nodes){ if(!filter_keywords||!filter_keywords.length){ return; } if(all_ok){ if(!mut_nodes.innerText||!mut_nodes.innerText.replace(/\s+/g, '')){ return; } for(let i=0,len=filter_keywords.length;i<len;i++){ if(mut_nodes.parentNode&&mut_nodes.parentNode.getAttribute('id')==filter_words_area){ return; } if(mut_nodes.innerText.toLowerCase().indexOf(filter_keywords[i].toLowerCase())!=-1){ warn_words.push(filter_keywords[i].toLowerCase()); } } if(!warn_words.length){ return; } if(no_check_tag.indexOf(mut_nodes.nodeName)!=-1){ check_dom(mut_nodes); return; } parse_dom_nodes(mut_nodes.childNodes); if(class_set.indexOf(mut_nodes.className)!=-1){ check_dom(mut_nodes); }else{ for(let i=0,len=class_set.length; i<len; i++){ let childs = mut_nodes.getElementsByClassName(class_set[i]); if(!childs){ continue; } for(let j=0,lenx=childs.length; j<lenx; j++){ check_update(childs[j]); } } } }else{ let class_tag = mut_nodes.getAttribute('class'); if(class_tag){ class_tag = class_tag.replace(/(^\s*)|(\s*$)/g, ""); if(dom_dict[class_tag]==undefined){ dom_dict[class_tag] = 0; }else{ dom_dict[class_tag] = dom_dict[class_tag] + 1; } } parse_dom_nodes(mut_nodes.childNodes); } } var dom_observer = new MutationObserver(function(mutations){ if(is_first&&document.body&&document.readyState=='complete'){ document.body.style.display = 'block'; add_filter_btn(setting_btn); is_first = false; } for(let mut of mutations){ let mut_add_nodes = mut.addedNodes; for(let mut_node of mut_add_nodes){ if(!(dom_nouse.indexOf(mut_node.nodeName)==-1&&mut_node.nodeType==1)){ continue; } warn_words = []; analy_page(mut_node); } } if(all_ok){ return; } for(let key in dom_dict){ if(document.body.style.display=='none'||document.body.style.display==''){ return; } let class_nodes = document.getElementsByClassName(key); if(class_nodes.length>1){ let test_node = class_nodes[0]; let count = 0; if(!test_node.offsetWidth){ no_target_class.push(key); continue } for(let i=1,len=class_nodes.length;i<len;i++){ if((class_nodes[i].innerText==test_node.innerText&&class_nodes[i].parentNode==test_node.parentNode)||(!class_nodes[i].offsetWidth&&!class_nodes[i].innerText)||class_nodes[i].offsetWidth!=test_node.offsetWidth){ no_target_class.push(key); break; } if(class_nodes[i].parentNode==test_node.parentNode){ count++; } if(count>2){ break; } } if(count==0){ no_target_class.push(key); } }else{ no_target_class.push(key); } } for(let i=0,len=no_target_class.length;i<len;i++){ if(no_target_class[i] in dom_dict){ delete dom_dict[no_target_class[i]]; } } max_key = get_max_node(); if(max_key){ let max_nodes = document.getElementsByClassName(max_key); if(!max_nodes){ delete dom_dict[max_key]; return; } let max_node_width = max_nodes[0].offsetWidth; if(max_node_width/document.body.clientWidth>0.9){ delete dom_dict[max_key]; return; } if(top_widths.indexOf(max_node_width)==-1){ top_widths.push(max_node_width); } if(Math.max.apply(null, top_widths)>max_node_width){ if(dom_dict[max_key]>5){ dom_dict[max_key] -= 5; } } if(class_set&&max_key==class_set[class_set.length-1]){ save_pattern(pattern_url); all_ok = true; return; } if(dom_dict[max_key]>test_value){ let s_top = document.documentElement.scrollTop || document.body.scrollTop; if(s_top<4000){ return; } for(let class_key in dom_dict){ if(class_key==max_key){ continue; } if(class_setx.indexOf(class_key)==-1){ class_setx.push(class_key); } } if(class_setx.indexOf(max_key)==-1){ class_setx.push(max_key); } GM_setValue(max_class_key, class_setx); save_pattern(pattern_url); location.reload(); class_set = class_setx; all_ok = true; } } }); dom_observer.observe(document, {childList: true, subtree: true, attributes: true}); function add_filter_btn(setting_btn){ setting_btn = document.createElement('a'); let color = 'rgb(198, 94, 36)'; let text_dec = ''; if(!all_ok){ color = '#F8C471'; text_dec = 'text-decoration:line-through;' } let lan = navigator.language || navigator.userLanguage; lan = lan.toLowerCase(); let lan_prefix = ""; if(lan=="zh-cn"){ lan_prefix = "z"; }else if(lan=="zh-hk"||lan=="zh-tw"){ lan_prefix = "t"; }else{ lan_prefix = "e"; } let last_hostname = location.hostname; let url = config_url.replace("config", lan_prefix+"config")+"?f_key="+orignal_f_key+"&lhn="+last_hostname+"&cltp=1"; setting_btn.setAttribute("href", url); setting_btn.setAttribute("target", "_blank"); setting_btn.innerHTML = '<div style="position:fixed;top:400px;right:0px;background-color:rgb(244, 234, 194);color:'+color+';'+text_dec+'padding-left:15px;padding-right:15px;padding-top:10px;padding-bottom:10px;font-size:15px;border-radius:5px 0 0 5px;cursor:pointer;z-index:10000;">Add</div>'; document.body.appendChild(setting_btn); } function add_keyword_span(keyword, f_key){ let span_dom = document.createElement('span'); let span_id = 'span_dom_xt_' + keyword; span_dom.style = "background-color:rgb(244, 234, 194);color:rgb(198, 94, 36);font-size:12px;padding:3px 12px 3px 15px;border-radius:3px 3px 3px 3px;margin-right:5px;margin-top:5px;"; span_dom.innerHTML = keyword+' <span style="color:#666;text-decoration:none;cursor:pointer;" id="'+span_id+'">x</span>'; document.getElementById('show_filter_keyword').appendChild(span_dom); document.getElementById(span_id).addEventListener('click', function(){ this.parentNode.remove(); let values = GM_getValue(f_key); values.splice(values.indexOf(keyword), 1); GM_setValue(f_key, values); }); } function show_page(){ if(is_first){document.body.style.display = 'block';} } })();