// ==UserScript==
// @name No Spam Results in Google Search
// @namespace http://tampermonkey.net/
// @version 0.3
// @description No more spam results in your google search!
// @author CY Fung
// @match https://www.google.com/search?*
// @match https://www.google.*.*/search?*
// @match http://*/*
// @match https://*/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=google.com
// @grant GM_getTab
// @grant GM_saveTab
// @license MIT
// @noframes
// ==/UserScript==
'use strict';
(function () {
'use strict';
const [window, document, hostname, location, history] = new Function('return [window, document, location.hostname, location, history];')(); // real window & document object
let isGoogleSearchPage = hostname.includes('.google')?/\w+\.(google|googleusercontent)\.com(\.\w{0,2}){0,2}/.test(hostname):false;
function purify(url){
let nt=null;
url = `${url}`;
try{
nt=new URL(url);
}catch(e){
return url;
}
return `${nt.origin}${nt.pathname}`;
}
function stringify(obj){
let res = JSON.stringify(obj);
res=res.replace(/\,\{\"/g,',\n{');
return res;
}
function elementCount(document){
if(!document) return null;
try{
return document.all.length;
}catch(e){
return document.getElementsByTagName("*").length;
}
}
function checkSpam(tabObject){
if( tabObject.hitAt>1 && Date.now()- tabObject.hitAt<30*1000){
let filteredTimeline = tabObject.timeline.filter(entry=>entry.timeAt>=tabObject.hitAt);
if(filteredTimeline.length<10 && filteredTimeline.length>=1 && filteredTimeline[0].type=='click'){
let completeOK=filteredTimeline.filter(entry=>entry.type=='complete').every(entry=>entry.elementCount<20);
let renderOK= true;
filteredTimeline.reduce((a,b)=>{
if(a && b && a.type=='start' && b.type=='complete' && a.shortHref === b.shortHref){
if(b.timeAt-a.timeAt>5000){
renderOK = false;
}
}
return b;
},null);
//alert([8989, filteredTimeline.length, completeOK, renderOK])
if(completeOK && renderOK){
let histCount = filteredTimeline.filter(entry=>entry.type=='start').length
let jsHistCount = filteredTimeline.map(entry=>entry.histCount)
let jsHistCountInOrder = true;
jsHistCount.reduce((a,b)=>{
if(a>-1 && b>-1 && a<=b){
}else{
jsHistCountInOrder=false;
}
return b;
},0);
if(histCount>=2 && jsHistCountInOrder){
return {filteredTimeline, jsHistCount};
}
}
}
}
}
GM_getTab(tabObject=>{
if(!tabObject.timeline)tabObject.timeline=[];
if(isGoogleSearchPage){
//alert(`${tabObject.hitAt} - ${stringify(tabObject.timeline)}`);
if(tabObject.hitAt<0){
history.pushState({},null);
}
tabObject.timeline.length=0;
tabObject.hitAt=0;
}else if(!tabObject.hitAt){
return;
}else if(Date.now()-tabObject.hitAt>30*1000){
tabObject.timeline.length=0;
tabObject.hitAt=0;
GM_saveTab(tabObject);
return;
}
// either isGoogleSearchPage or hitTime < 30s
tabObject.timeline.push({type:'start', shortHref: purify(location.href), pageHref:location.href, timeAt:Date.now() , histCount: history.length});
//alert(stringify(tabObject))
let resCheckSpam = checkSpam(tabObject);
if(resCheckSpam){
let {filteredTimeline, jsHistCount}=resCheckSpam;
tabObject.hitAt=-1;
GM_saveTab(tabObject);
alert(`spam website "${filteredTimeline[0].shortHref}" detected \n go back ${purify(filteredTimeline[0].pageHref)}`);
//location.href=filteredTimeline[0].pageHref;
history.go(-(jsHistCount[jsHistCount.length-1] - jsHistCount[0]));
}else{
GM_saveTab(tabObject);
}
function onReady(){
let emc = elementCount(document);
if(emc<40){ // including html, body, script, div, ... //7 16 33
emc-=document.querySelectorAll('script, style, meta, title, head, link, noscript').length; //remove count for non-visual elements //6 12
}
tabObject.timeline.push({type:'complete', shortHref: purify(location.href), pageHref:location.href, timeAt:Date.now(), elementCount: emc , histCount: history.length });
//alert(stringify(tabObject))
GM_saveTab(tabObject);
let hElems = null
if(isGoogleSearchPage){
hElems = [...document.querySelectorAll('a[href^="http"]')].filter(elm=>!/^https?\:\/\/\w+\.(google|googleusercontent)\.com(\.\w{0,2}){0,2}\//.test(elm.href))
for(const hElem of hElems){
hElem.addEventListener('click',function(){
tabObject.hitAt = Date.now();
tabObject.timeline.push({type:'click', shortHref:purify(hElem.href), pageHref:location.href, timeAt:tabObject.hitAt , histCount: history.length});
//alert(stringify(tabObject))
GM_saveTab(tabObject);
})
}
}else{
function fx(){
document.removeEventListener('mousedown',fx,true);
document.removeEventListener('keydown',fx,true);
tabObject.timeline.length=0;
tabObject.hitAt=0;
GM_saveTab(tabObject);
}
document.addEventListener('mousedown',fx,true);
document.addEventListener('keydown',fx,true);
}
}
;(function uiMain(){
if(document.documentElement == null) return window.requestAnimationFrame(uiMain)
if (document.readyState !== 'loading') {
onReady();
} else {
document.addEventListener('DOMContentLoaded', onReady);
}
})();
})
})();