Search code examples
javascriptgreasemonkey

What could stop Array.prototype.filter() from running in greasemonkey script that runs fine in console


Here is the code:

function fil(val) {
  console.log('fil'); // never written to console when run in greasemonkey
  return true;
}
var temp = unsafeWindow.someobject;
console.log(temp); // looks fine
temp.filter(fil); // never happens in greasemonkey

If I run the very same code (without unsafeWindow of course) on the same object in the firebug console it outputs just fine. What could be the reason?

Edit to clarify: when run in greasemonkey the string 'fil' never is written to the console which shows that fil() is never called. Also if I do something like console.log(temp.filter(fil)); I never get to see a result from that in the console when the code runs from greasemonkey. (although I know it should because the line above tells me temp exists and the code runs up to that point.


Solution

  • In my case, in Firefox 45 and Greasemonkey 3.7, this code works fine:

    // ==UserScript==
    // @name        Array.prototype.filter() test
    // @namespace   http://stackoverflow.com/questions/33675675/
    // @include     http://stackoverflow.com/questions/33675675/*
    // @version     1.0
    // @grant       none
    // ==/UserScript==
    
    function fil(val) {
      console.log('fil'); // never written to console when run in greasemonkey
      return true;
    }
    var temp = unsafeWindow.allowedHosts;
    console.log(temp); // looks fine
    temp.filter(fil); // never happens in greasemonkey
    

    And outputs:

    Array [ "stackoverflow.com", "serverfault.com" ]
    fil
    fil
    

    But changing none to, for example, GM_getValue in line:

    // @grant       none
    

    Outputs only:

    Array [ "stackoverflow.com", "serverfault.com" ]
    

    This is because passing to @grant any value other than none enables the sandbox, and from what I can see, the wrapped objects don't support methods that take callback functions as arguments.

    You may be able to replace some GM_* privileges with the compatibility layer that you can find in the link above. Then you could disable the sandbox by setting @grant none and you're all set.

    However, if you need the original functions, you could use [].filter.call(temp, fil) instead of temp.filter(fil), as mentioned in the comments.