Zhaph - Ben Duguid
Zhaph - Ben Duguid

Reputation: 26956

How can I call a functions added to the jQuery Object from my GreaseMonkey script?

I've created a GreaseMonkey script based on an in-page script that I'd like to use on a site, however I'm having the following issue:

In the script, we've created our namespace (brickJax) that contains the bulk of the functions, and I've required jQuery as we're using the jQuery replaceText functions as well.

When I call the replaceText function from replaceSet I get the following error on the console:

uncaught exception: TypeError: $(node).replaceText is not a function

However, calling it as part of the GM_xmlhttpRequest onload callback works fine.

var brickJax = (function ($) {
  "use strict";
  var brickJax = {};

  //[Code here]

  function replaceSet(node, str, number, colour) {
    var text = '<a href="http://www.peeron.com/inv/sets/' + number + '-1">'
               + number + ' on Peeron</a>';

    // THIS LINE THROWS THE ERROR:
    $(node).replaceText(str, text);
  }

  function replaceImage(node, str, number, colour) {
    getBricksForImage(number, colour, node, str);
  }

  function getBricksForImage(number, colour, node, str) {
    GM_xmlhttpRequest({
        method: "POST",
        url: "http://brickjax.doodle.co.uk/bricks.aspx/JsonDetails/" + number 
             + "/" + colour,
        dataType: "jsonp",
        onload: function (data) {
            // THIS CALL WORKS PERFECTLY
            $(node).replaceText(str,
                                buildImage($.parseJSON(data.responseText)));
        }
    });
  };

  function buildImage(ajaxData) {
    var text = '<img style="max-height:100px;" src="' + ajaxData.Src 
               + '" alt="' + ajaxData.AltText + '" />';

    return text;
  }

  function replaceTags(element) {
    var elements = $(element).find('*').andSelf();
    elements = elements.not($('script,noscript,style,textarea,pre,code')
                       .find('*').andSelf());

    searchText(elements, /\[part:([\w\-]*)(?::([\w\-]*))?\]/gi, replaceImage);

    searchText(elements, /\[set:([\w\-]*)(?::([\w\-]*))?\]/gi, replaceSet);
  };

})(jQuery);

brickJax.replaceTags($('body'));

(function ($) { $.fn.replaceText = function (b, a, c) { [...] } })(jQuery);

In the actual script I've added logging, which shows that node is an HTML element in both cases.

What is it that I'm doing wrong in the call from replaceSet that is different from the call in callback that's causing this error?

In the hosted version both calls work as expected.

Apologies for the wall of script, I've tried to cut it down to the bare essentials.

Upvotes: 1

Views: 280

Answers (1)

Brock Adams
Brock Adams

Reputation: 93443

This is either closure related or due to the function being defined in an expression versus a declaration.

Either way, the solution should be the same, move the definition of replaceText physically before the var brickJax = ... stuff.

Upvotes: 1

Related Questions