Search code examples
javascriptfirefoxprototypegreasemonkeytampermonkey

Greasemonkey doesn't allow to augment Element.prototype, saying "not a function"


I need to define a method inside Element.prototype in my userscript but when I try to to that, I get weird errors:

// ==UserScript==
// <...>
// @grant        none
// ==/UserScript==

;[Element.prototype, Text.prototype].forEach(e => {
  e.findParent = function(selector) {
    let node = this
    while(node && !node.matches(selector)) {
      node = node.parentNode
      if (! node.matches) return null;
    }
    return node
  }
}

[...].forEach(...) is not a function

function augmentPrototype(e) {
  e.findParent = function(selector) {
    /* <...> */
  }
}
augmentPrototype(Element.prototype)

augmentPrototype is not a function

(e => {
  e.findParent = function(selector) {
    /* <...> */
  }

})(Element.prototype)

(intermediate value)(...) is not a function

It seems whatever function is being called on Element.prototype, it immediately becomes "not a function" to Greasemonkey, even [].forEach.

No such problem in normal Firefox console. Also I modify Event.prototype as well and it works fine.

Update: same problem on Tampermonkey for Firefox, so it's not just Greasemonkey's problem.


Solution

  • Sorry, false alarm. Turns out, next to this in my code I have an immediately invoking function starting with (... and I don't use semicolons. Leading semicolon just before that IIF fixed the problem. Apparently automatic semicolon insertion works slightly differently in Firefox because it worked fine in Chrome.