I want to stop the execution of one single line from a site, so that the whole page is read by the browser except that single line. Or the browser may simply skip the execution of that javascript function.
OR
Is there way i can tweak the javascript somehow so that the random number generating function in javascript do not generate random number, but the numbers i want...
I dont have access to the site on which the script is hosted so all this needs to be done client side.
Firefox currently supports the beforescriptexecute event (as of Version 4, released on March 22, 2011)‡.
With that event and the // @run-at document-start
directive, Firefox and Greasemonkey now seem to do a good job intercepting specific <script>
tags.
This is still not possible for Chrome+Tampermonkey. For anything but Firefox+Greasemonkey, you will need to use techniques as shown in the other answers, below, of write a full browser extension.
The checkForBadJavascripts
function encapsulates this. For example, suppose the page had a <script>
tag like so:
<script>
alert (\"Sorry, Sucka! You\'ve got no money left.\");
</script>
You could use checkForBadJavascripts
like so:
checkForBadJavascripts ( [
[ false,
/Sorry, Sucka/,
function () {
addJS_Node (\'alert (\"Hooray, you\\\'re a millionaire.\");\');
}
]
] );
to get a much nicer message. (^_^)
See the inline documentation, in checkForBadJavascripts, for more.
To see a demonstration in a complete script, first visit this page at jsBin. You will see 3 lines of text, two of them added by JS.
Now, install this script (View source; it\'s also below.) and revisit the page. You will see that the GM-script deleted one bad tag and replaced another with our \"good\" JS.
‡ Note that only Firefox supports the beforescriptexecute
event. And it was removed from the HTML5 spec with no equivalent capability specified.
Complete GM script example (The same as the one at GitHub and jsBin):
Given this HTML:
<body onload=\"init()\">
<script type=\"text/javascript\" src=\"http://jsbin.com/evilExternalJS/js\"></script>
<script type=\"text/javascript\" language=\"javascript\">
function init () {
var newParagraph = document.createElement (\'p\');
newParagraph.textContent = \"I was added by the old, evil init() function!\";
document.body.appendChild (newParagraph);
}
</script>
<p>I\'m some initial text.</p>
</body>
Use this Greasemonkey script:
// ==UserScript==
// @name _Replace evil Javascript
// @include http://jsbin.com/ogudon*
// @run-at document-start
// ==/UserScript==
/****** New \"init\" function that we will use
instead of the old, bad \"init\" function.
*/
function init () {
var newParagraph = document.createElement (\'p\');
newParagraph.textContent = \"I was added by the new, good init() function!\";
document.body.appendChild (newParagraph);
}
/*--- Check for bad scripts to intercept and specify any actions to take.
*/
checkForBadJavascripts ( [
[false, /old, evil init()/, function () {addJS_Node (init);} ],
[true, /evilExternalJS/i, null ]
] );
function checkForBadJavascripts (controlArray) {
/*--- Note that this is a self-initializing function. The controlArray
parameter is only active for the FIRST call. After that, it is an
event listener.
The control array row is defines like so:
[bSearchSrcAttr, identifyingRegex, callbackFunction]
Where:
bSearchSrcAttr True to search the SRC attribute of a script tag
false to search the TEXT content of a script tag.
identifyingRegex A valid regular expression that should be unique
to that particular script tag.
callbackFunction An optional function to execute when the script is
found. Use null if not needed.
*/
if ( ! controlArray.length) return null;
checkForBadJavascripts = function (zEvent) {
for (var J = controlArray.length - 1; J >= 0; --J) {
var bSearchSrcAttr = controlArray[J][0];
var identifyingRegex = controlArray[J][1];
if (bSearchSrcAttr) {
if (identifyingRegex.test (zEvent.target.src) ) {
stopBadJavascript (J);
return false;
}
}
else {
if (identifyingRegex.test (zEvent.target.textContent) ) {
stopBadJavascript (J);
return false;
}
}
}
function stopBadJavascript (controlIndex) {
zEvent.stopPropagation ();
zEvent.preventDefault ();
var callbackFunction = controlArray[J][2];
if (typeof callbackFunction == \"function\")
callbackFunction ();
//--- Remove the node just to clear clutter from Firebug inspection.
zEvent.target.parentNode.removeChild (zEvent.target);
//--- Script is intercepted, remove it from the list.
controlArray.splice (J, 1);
if ( ! controlArray.length) {
//--- All done, remove the listener.
window.removeEventListener (
\'beforescriptexecute\', checkForBadJavascripts, true
);
}
}
}
/*--- Use the \"beforescriptexecute\" event to monitor scipts as they are loaded.
See https://developer.mozilla.org/en/DOM/element.onbeforescriptexecute
Note that it does not work on acripts that are dynamically created.
*/
window.addEventListener (\'beforescriptexecute\', checkForBadJavascripts, true);
return checkForBadJavascripts;
}
function addJS_Node (text, s_URL, funcToRun) {
var D = document;
var scriptNode = D.createElement (\'script\');
scriptNode.type = \"text/javascript\";
if (text) scriptNode.textContent = text;
if (s_URL) scriptNode.src = s_URL;
if (funcToRun) scriptNode.textContent = \'(\' + funcToRun.toString() + \')()\';
var targ = D.getElementsByTagName (\'head\')[0] || D.body || D.documentElement;
//--- Don\'t error check here. if DOM not available, should throw error.
targ.appendChild (scriptNode);
}
The answer depends on details which were not provided (The exact page and line of code would be best), but here\'s how you do it in general:
If the offending JS code does not fire right away (Fires after DOMContentLoaded
), then you can use Greasemonkey to replace the offending code. EG:
var scriptNode = document.createElement (\"script\");
scriptNode.textContent = \"Your JS code here\";
document.head.appendChild (scriptNode);
Done.
If the JS code fires immediately, then it gets more complicated.
First, grab a copy of the script and make the desired change to it. Save this locally.
Is the offending script in a file or is it in the main page HTML (<script src=\"Some File>
versus <script>Mess O\' Code</script>
)?
If the script is in a file, install Adblock Plus and use it to block loading of that script. Then use Greasemonkey to add your modified code to the page. EG:
var scriptNode = document.createElement (\"script\");
scriptNode.setAttribute (\"src\", \"Point to your modified JS file here.\");
document.head.appendChild (scriptNode);
If the script is in the main HTML page, then install either NoScript (best) or YesScript and use it to block JavaScript from that site.
This means that you will then need to use Greasemonkey to replace all scripts, from that site, that you do want to run.
Using TamperMonkey? All you need to add below your // @grant
in the TamperMonkey header is // @require http://urlofyoursite.com/myfile.js
. For example, here is the very top of my TamperMonkey thingie:
// ==UserScript==
// @name Project
// @namespace http://tampermonkey.net/
// @version 0.1
// @description try to take over the world!
// @author You
// @match https://docs.google.com/presentation/*
// @grant none
// @require http://cdnjs.cloudflare.com/ajax/libs/annyang/2.1.0/annyang.min.js
// ==/UserScript==
You can use what is called a bookmarklet.
Build the js file you want to run on the other site: your.js
Make an HTML page with the following code:
<html>
<body>
<a href=\"javascript:(function(){var s=document.createElement(\'SCRIPT\');s.src=\'/url/to/your.js?\'+(Math.random());document.getElementsByTagName(\'head\')[0].appendChild(s);})()\">
Drag\'n Drop this to your bookmarks
</a>
</body>
</html>
Replace /url/to/your.js
with the path of your js file.
Load that small page in your browser and drag\'n drop the link to your bookmark bar.
Go to the web site you want to hack, and click the bookmark you just created.
This will load your.js
in the page and run the code.
Note: the ?\'+(Math.random())
part is to avoid your js being cached, this is not mandatory but it is helpful when you develop your.js