Javascript Link Fixer

Converts Javascript links that open new windows into regular old links

目前為 2016-01-17 提交的版本,檢視 最新版本

// ==UserScript==
// @name          Javascript Link Fixer
// @namespace     DoomTay
// @description   Converts Javascript links that open new windows into regular old links
// @version       1.2.1
// @grant         none

// ==/UserScript==

var links = document.querySelectorAll("a[href *= 'javascript:']");

var paramTable = {};
	paramTable["open"] = 0;
	paramTable["window.open"] = 0;

for (var l = 0; l < links.length; l++)
{
	if(links[l].href.indexOf("void") > -1) continue;
	var hrefSplitter = /javascript:(\S+)\((\S+(?:,(?: )\S+)*)?\)/.exec(links[l].href);
	if(hrefSplitter == null) continue;
	var functionName = decodeURIComponent(hrefSplitter[1]).trim();
	var params = hrefSplitter[2] ? eval("[" + decodeURIComponent(hrefSplitter[2]) + "]") : [];
	var functionDig = deconstructFunction(functionName,params);
	if(functionDig != null)
	{
		//links[l].setAttribute("onclick","return " + decodeURIComponent(links[l].href).substring(links[l].href.indexOf("javascript:") + 11));
		links[l].setAttribute("onclick",decodeURIComponent(links[l].href).substring(links[l].href.indexOf("javascript:") + 11) + "; return false");
		links[l].href = functionDig;
	}
}

function deconstructFunction(functionName,params)
{
	if(functionName == "history.go") return null;
	var sourceCode = uneval(window[functionName]);
	var functionBody = sourceCode.substring(sourceCode.indexOf("{") + 1,sourceCode.lastIndexOf("}")).trim();
	while(functionBody.indexOf(functionName + ".arguments") > -1) functionBody = functionBody.replace(functionName + ".arguments","params");
	var args = /\(((?: )?\S+(?:,(?: )\S+)*)?(?: )?\)/.exec(sourceCode);
	args = args && args[1] ? args[1].split(/\s*,\s*/) : [];
	var containedFunctions = functionBody.match(/(\S+\(\S+(?:,(?: )?\S+)*\))/g) || [];
	var ifCollection = functionBody.match(/if ?\([a-zA-z '?=+&.<>!()0-9;]+\)[ \n\t]+?{[\s\S][\na-zA-z '?=+.,">\/()0-9;!@#$%^&*\t]+[\s]+}/g);
	var variableMatches = functionBody.match(/(\S+ ?= ?.+)/g);
	var variableDefs = [];
	if(variableMatches)
	{
		for(var m = 0; m < variableMatches.length; m++)
		{
			if(variableMatches[m].indexOf("==") > -1 || variableMatches[m].indexOf("!=") > -1 || variableMatches[m].indexOf("//") > -1) continue;
			if(containedFunctions != null && containedFunctions.some(elem => variableMatches[m].substring(variableMatches[m].indexOf("=") + 1).trim().indexOf(elem) > -1)) continue;
			if(/.+\(/.test(variableMatches[m]) && variableMatches[m].indexOf("eval(") == -1)
			{
				continue;
			}
			if(variableMatches[m].indexOf("+=") > -1)
			{
				continue;
			}
			variableDefs.push(variableMatches[m].match(/(\S+) ?= ?(.+?;)/).slice(1, 3));
		}
	}

	for(var a = 0; a < params.length; a++)
	{
		eval(args[a] + "= \"" + params[a] + "\"");
	}

	if(variableDefs)
	{
		for(var v = 0; v < variableDefs.length; v++)
		{
			//Making sure we're not altering any properties
			if(variableDefs[v][0].indexOf(".") == -1)
			{
				if(variableDefs[v][1].indexOf("eval(") > -1) variableDefs[v][1] = variableDefs[v][1].replace(/eval\((.+)\)/,"$1");
				eval(variableDefs[v][0] + "= " + variableDefs[v][1].toString());
			}
		}
	}
	if(ifCollection)
	{
		for(var i = 0; i < ifCollection.length; i++)
		{
			eval(ifCollection[i]);
		}
	}
	if(variableDefs)
	{
		for(var v = 0; v < variableDefs.length; v++)
		{
			if(variableDefs[v][0].indexOf(".location") > -1)
			{
				return eval(variableDefs[v][1]);
			}
		}
	}
	if(containedFunctions)
	{
		for(var f = 0; f < containedFunctions.length; f++)
		{
			var capture = /(\S+)\((\S+(?:,(?: )?\S+)*)?\);?/.exec(containedFunctions[f]);
			var statementName = capture[1];
			if(statementName == "if") continue;
			var statementParams = capture[2];
			statementParams = eval("[" + statementParams + "]");
			if(paramTable.hasOwnProperty(statementName)) return(statementParams[paramTable[statementName]]);
			var digDeeper = deconstructFunction(statementName,statementParams);
			if(digDeeper) return digDeeper;
		}
	}
	if(functionBody.indexOf(".location = ") > -1)
	{
		var test = /\.location ?= ?(\S+);/.exec(functionBody)[1];
		for(var p = 0; p < params.length; p++)
		{
			if(test == args[p]) return params[p];
		}
	}
	return null;
}