Partially block embedded JavaScript in Firefox

Is there a Firefox extension capable of blocking a single function from embedded javascript in a page?

<html>
    <head>
        <script type='text/javascript'>
            function onLoad(){
                setTimeout(annoying, 1800000);
            }    

            function annoying(){
                //do something annoying
            }


            function useful(){
                //do something useful
            }
        </script>
    </HEAD>
    <BODY  onload="onLoad()">
        <!--rest of page goes here-->
    </BODY>
</HTML>

Upvotes: 2

Views: 2405

Answers (4)

looped
looped

Reputation: 129

This does not help but instead exacerbates the problem.

The following are particularly pernicious and ugly if javascript is enabled:

<script>
    setInterval("alert('irritate')",10)
</script>

or

<script>
    (function(){(function r(){alert('irritate');setTimeout(r,10)})()})()
</script>

though this can be stopped (and all future TimeOuts) by:

javascript:setTimeout=function(){}

perhaps as the URI of a bookmark, provided it can be clicked fast enough.
However,

setInterval("alert('irritate')",10)

can only be stopped by

javascript:setInterval=function(){}

BEFORE the script is run.

Good luck with:

<script>
    (function(){(function r(){alert('irritate');r()})()})()
</script>

or even simpler

<script>
    ( function r(){alert('irritate');r()} ) ()
</script>

Setting alert=function(){} will stop all messages but the script and its recursion of r will not stop until SO or system time out. Also, r is not in the global environment so r=function(){} is ineffective.

Some FF versions need an interesting solution, found on SO, if the alert response is mandatory, to kill the annoying page w/o killing the browser and other open tabs, by using ctrl-F4 to close the tab of the offending page. To aid the manual reflex and dexterity required to do this fast enough, ctrl-Enter is used to respond to the prompt and while ctrl-Enter is pressed F4 is typed.

Upvotes: 0

Sarien
Sarien

Reputation: 7002

I've posted a solution here: https://stackoverflow.com/a/9699686/6355

Since it's little more than a link here it goes again: http://userscripts.org/scripts/show/125936

Upvotes: 1

ppostma1
ppostma1

Reputation: 3676

I know how to block it per page... I have a script here that is bugging me:

<script type="text/JavaScript">
<!--
function timedRefresh(timeoutPeriod) {
    setTimeout("location.reload(true);",timeoutPeriod);
}
//   -->
</script>
</head> 
<body onload="JavaScript:timedRefresh(300000);">

What these idiots refuse to consider is that if I'm looking around for solutions, I could wind up with 10+ of these page open and 90% of my CPU time is then dedicated to refreshing their pages in the background! grr

I have firebug handy for web development and I just enter this JS command into the console

timedRefresh = function(value){alert(value);}

smile, click ok, and go on my way.

Upvotes: 1

jakub.g
jakub.g

Reputation: 41478

Perhaps Greasemonkey is the way to go.

The answer below is quite detailed technical, sorry if I went too far ;)

It depends a bit on how the function annoying() is used by the scripts. I am not yet an expert in JavaScript, some more experienced person's voice could be useful.

If annoying() is used by functions like window.setInterval(), window.setTimeout(), you probably can't overwrite the function directly, because of JavaScript quirks with scoping (closures). When the code window.setTimeout(annoying, 600) is executed, a reference to the "old" annoying is stored and that "old" version is executed. You might then try to get rid of the code that is invoking window.setTimeout on annoying instead.

In other cases, you can add a function with the same name and de facto overwrite the function with the following Greasemonkey userscript:

  function addScript(sourceCode)
  {
     var script = document.createElement('script');
     script.innerHTML = sourceCode;
     var head = document.getElementsByTagName("head")[0];
     head.insertBefore(script, head.firstChild); // insert the script as a first child of <HEAD>
  }
  addScript('function annoying(){alert("overwritten")}');

If you have code like below (I am unable to provide live demo, because it works differently on JSFiddle perhaps because its sandboxing), and the userscript above is launched for that domain, then after 600 milliseconds after page loads, you will have "Nasty alert" alert, but then any time you click the text, you will have "overwritten" alert.

<html>
   <head>
      <script type='text/javascript'>
         function annoying(){
             alert("Nasty alert");
         }

         function useful(){
             //do something useful
         }

         window.setTimeout(annoying, 600); // closure; binds to the function as it is at the moment of execution
      </script>
   </head>
<body>
   <a onclick="annoying()">Click me</a>
</body>
</html>

Upvotes: 2

Related Questions