MozillaZine

How To: Using jQuery 1.3.2 in your addon

Talk about add-ons and extension development.
Ziink
 
Posts: 49
Joined: July 27th, 2009, 8:37 am

Post Posted September 2nd, 2009, 12:23 am

I've started using jQuery 1.3.2 in my addon and I wanted to share my experience with others. I had to fix a couple of bugs to make it work although I believe jQuery 1.2.6 works without modification.

1. Include jQuery.


Option a)
Loading jQuery using loadSubScript
In your .js file add the following (after changing it suitably for your own addon)
Code: Select all
   loadLibraries: function(context){
      var loader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
                                        .getService(Components.interfaces.mozIJSSubScriptLoader);
      loader.loadSubScript("chrome://ziink/content/jquery-1.3.2.js",context);
      var jQuery = window.jQuery.noConflict(true);
      loader.loadSubScript("chrome://ziink/content/jquery.hoverIntent.min.js", jQuery);
      ziink.jQuery = jQuery;
   }


My addon introduces only one name 'ziink' in the global namespace and this function is within that object. Note the call to noConflict(true). This will restore any changes that my copy of jQuery makes. Also note that the call to load a jQuery module has a copy of our jQuery as the last arg ( the context within which the module will be loaded).

Call this function from code that gets run when your addon loads. e.g.
Code: Select all
// Load Libraries. For jQuery it doesn't really matter what the context is
ziink.loadLibraries(ziink);      


Option b) In your XUL file add : Not recommended as it can mess up other addons or your addon could get messed up by other's.

<script src="jquery-1.3.2.js"/>

2. Use jQuery in your functions.
Add the following lines in each function you want to use jQuery in. Note that 'window._content.document' might not be what you want the default to be. Change it to the document you are working with or to a node.
Code: Select all
var jQuery = ziink.jQuery;  // ziink.jQuery is the saved value from step 1
var $ = function(selector,context){ return new jQuery.fn.init(selector,context||window._content.document); };
$.fn = $.prototype = jQuery.fn;

3. Fix couple of bugs in jQuery 1.3.2
Bug a) Search for
Code: Select all
Array.prototype.slice.call( document.documentElement.childNodes );
. This is within a try block. Replace it with
Code: Select all
Array.prototype.slice.call( [] );
If you don't fix this bug, none of the addon toolbars will show along with other XUL problems.

Bug b) Find the function clone(). Change the line
Code: Select all
return jQuery.clean([html.replace(/ jQuery\d+="(?:\d+|null)"/g, "").replace(/^\s*/, "")])[0];

to
Code: Select all
return jQuery.clean([html.replace(/ jQuery\d+="(?:\d+|null)"/g, "").replace(/^\s*/, "")], this.ownerDocument)[0];

If you don't fix this bug, jQuery uses the XULDocument instead of the document that owns the object you are trying to clone. There might be other similar bugs. I didn't really look for other similar bugs.

4. Now use jQuery as you normally would.

5. Example Addon : Ziink Web Helper
Feel free to download my addon from AMO https://addons.mozilla.org/en-US/firefox/addons/versions/13180 to see it in action. You'll have to download version 0.0.11 or newer.

6. Add your own experience and tips to this thread.
Good luck!




Gotchas
1. $('html string').appendTo(selector) does not work.
Last edited by Ziink on September 9th, 2009, 6:30 am, edited 3 times in total.
----------------------
Craigslist Helper: Image, Ad & Forum Previews, Distance Search and All of CL Search, Notes, Alerts etc.
For Firefox, Chrome & Safari : http://ziink.com

rRob
 
Posts: 26
Joined: August 14th, 2009, 2:01 am

Post Posted September 2nd, 2009, 4:36 am

Ziink wrote:4. Fix couple of bugs in jQuery 1.3.2
Bug a) Search for
Code: Select all
Array.prototype.slice.call( document.documentElement.childNodes );
. This is within a try block. Replace it with
Code: Select all
Array.prototype.slice.call( [] );
If you don't fix this bug, none of the addon toolbars will show along with other XUL problems.

Aha! That's why my toolbar button didn't work. Making that change fixed it. I did not make any of the other changes though and it seems to work OK.

Ziink
 
Posts: 49
Joined: July 27th, 2009, 8:37 am

Post Posted September 2nd, 2009, 11:02 am

On further investigation I found that including jQuery in your XUL file leaves your addon at the mercy of other addons. Whichever addon loads last has it's copy of jQuery overwrite any jQuery version loaded before it.

The solution is to use Step 1, Option B. However, Option B as listed earlier was not complete. I'll edit the original post after I've posted this to reflect the changes.

Step 1, Option B: Loading jQuery using loadSubScript
In your .js file add the following (after changing it suitably for your own addon)
Code: Select all
   loadLibraries: function(context){
      var loader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
                                        .getService(Components.interfaces.mozIJSSubScriptLoader);
      loader.loadSubScript("chrome://ziink/content/jquery-1.3.2.js",context);
      var jQuery = window.jQuery.noConflict(true);
      loader.loadSubScript("chrome://ziink/content/jquery.hoverIntent.min.js", jQuery);
      ziink.jQuery = jQuery;
   }


My addon introduces only one name 'ziink' in the global namespace and this function is within that object. Note the call to noConflict(true). This will restore any changes that my copy of jQuery makes. Also note that the call to load a jQuery module has a copy of our jQuery as the last arg ( the context within which the module will be loaded).

Call this function from code that gets run when your addon loads. e.g.
Code: Select all
// Load Libraries. For jQuery it doesn't really matter what the context is
ziink.loadLibraries(ziink);      


That's it for step 1.

Step 2 becomes redundant

Step 3 needs an addition line
Code: Select all
var jQuery = ziink.jQuery;

This is needed before the two other lines so that they have the jQuery object available to them.

Ziink wrote:I've started using jQuery 1.3.2 in my addon and I wanted to share my experience with others. I had to fix a couple of bugs to make it work although I believe jQuery 1.2.6 works without modification.

1. Include jQuery.

Option a) In your XUL file add (I used option a)
<script src="jquery-1.3.2.js"/>

Option b)
Load the script in your addon's .js file in your onLoad (or similar) function
Code: Select all
var loader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
               .getService(Components.interfaces.mozIJSSubScriptLoader);
loader.loadSubScript("chrome://ziink/content/jquery-1.3.2.js.js");

Option b works if you do not use any addon for jQuery. I had trouble when I l followed up loading jQuery with an addon for it.

2. Call in your addon's .js file

Code: Select all
jQuery.noConflict();

3. Use jQuery in your functions.
Add the following lines in each function you want to use jQuery in. Note that 'window._content.document' might not be what you want the default to be. Change it to the document you are working with or to a node.
Code: Select all
var $ = function(selector,context){ return new jQuery.fn.init(selector,context||window._content.document); };
$.fn = $.prototype = jQuery.fn;

4. Fix couple of bugs in jQuery 1.3.2
Bug a) Search for
Code: Select all
Array.prototype.slice.call( document.documentElement.childNodes );
. This is within a try block. Replace it with
Code: Select all
Array.prototype.slice.call( [] );
If you don't fix this bug, none of the addon toolbars will show along with other XUL problems.

Bug b) Find the function clone(). Change the line
Code: Select all
return jQuery.clean([html.replace(/ jQuery\d+="(?:\d+|null)"/g, "").replace(/^\s*/, "")])[0];

to
Code: Select all
return jQuery.clean([html.replace(/ jQuery\d+="(?:\d+|null)"/g, "").replace(/^\s*/, "")], this.ownerDocument)[0];

If you don't fix this bug, jQuery uses the XULDocument instead of the document that owns the object you are trying to clone. There might be other similar bugs. I didn't really look for other similar bugs.

5. Now use jQuery as you normally would.

6. Example Addon : Ziink Web Helper
Feel free to download my addon from AMO https://addons.mozilla.org/en-US/firefox/addons/versions/13180 to see it in action. You'll have to download version 0.0.10 or newer.

7. Add your own experience and tips to this thread.
Good luck!
----------------------
Craigslist Helper: Image, Ad & Forum Previews, Distance Search and All of CL Search, Notes, Alerts etc.
For Firefox, Chrome & Safari : http://ziink.com

bridget.almas
 
Posts: 2
Joined: September 9th, 2009, 5:34 am

Post Posted September 9th, 2009, 5:38 am

Thanks for posting this info. I had found the problem with the clone function, but I am not sure of the need for the change in the test for the makeArray definition (Array.prototype.slice.call( document.documentElement.childNodes );).

Can you provide more information on what problems this causes and why? As far as I can tell, the slice call succeeds and returns an array object as expected.

Thanks!

Ziink
 
Posts: 49
Joined: July 27th, 2009, 8:37 am

Post Posted September 9th, 2009, 6:25 am

The prototype.slice.call needs two arguments, so you have a bug right there. I don't know what exactly
Code: Select all
Array.prototype.slice.call( document.documentElement.childNodes );
does but the end result is that you lose all addon toolbars and icons. So if you had a Google toolbar or a LastPass toolbar, you'd be unable to see them any more.
----------------------
Craigslist Helper: Image, Ad & Forum Previews, Distance Search and All of CL Search, Notes, Alerts etc.
For Firefox, Chrome & Safari : http://ziink.com

bridget.almas
 
Posts: 2
Joined: September 9th, 2009, 5:34 am

Post Posted September 10th, 2009, 1:02 pm

I think that may actually be a red herring. Slice should work with just a single argument (and your fix also only has a single argument, an empty array). I think this problem may actually be related to the reference to the document.documentElement property before an XUL dialog fully loads. See https://bugzilla.mozilla.org/show_bug.cgi?id=381168.

Note that there are also several other problems with the jQuery code, as it builds up the jQuery.supports object, it does a number of tests which use document.createElement to create and HTML elements for tests, and the tests fail when loaded into a chrome window, for which the base document object is not HTML. It may be possible to work around that by using document.createElementNS (insted of document.createElement) specifying the xhtml namespace, but that may not always produce the desired results.

Ziink
 
Posts: 49
Joined: July 27th, 2009, 8:37 am

Post Posted September 10th, 2009, 4:01 pm

You are probably right about it having to do with document.documentElement property but changing the said call in jQuery is still important since otherwise non of the custom toolbars work.
----------------------
Craigslist Helper: Image, Ad & Forum Previews, Distance Search and All of CL Search, Notes, Alerts etc.
For Firefox, Chrome & Safari : http://ziink.com

moodboom
 
Posts: 2
Joined: September 21st, 2009, 5:07 pm

Post Posted September 21st, 2009, 5:22 pm

Ziink, bridget.almas...

Were you able to load and use jquery to your satisfaction? It sounded like there were still some unresolved issues. I'm trying to save myself trouble and I'll skip the whole attempt if it's still a bit dodgy. :>

Thanks a bunch mates.

Ziink
 
Posts: 49
Joined: July 27th, 2009, 8:37 am

Post Posted September 21st, 2009, 5:46 pm

To me, it's still worthwhile using jQuery.
----------------------
Craigslist Helper: Image, Ad & Forum Previews, Distance Search and All of CL Search, Notes, Alerts etc.
For Firefox, Chrome & Safari : http://ziink.com

alexanderfrey
 
Posts: 13
Joined: July 4th, 2009, 8:43 am

Post Posted September 28th, 2009, 2:08 am

Hi,

thanks for your documentation ! I can use jquery now in my extension but I would also like to use a jquery plugin (http://www.trendskitchens.co.nz/jquery/contextmenu/) in my extension.
<script type="application/x-javascript" src="chrome://plug/content/javascripts/jquery.contextMenu.js"></script>

When I include the jquery.contentsMenu.js in my overlay.xul I get an error in the firefox message window that says "Jquery can not be found". I tested if the variable jquery is empty or not and it is indeed referencing to an object.

What am I missing ? Has somebody an idea ?


Thanks, Alexander

Ziink
 
Posts: 49
Joined: July 27th, 2009, 8:37 am

Post Posted September 28th, 2009, 5:22 am

In the first code segment I've loaded a plugin too.

Code: Select all
      loader.loadSubScript("chrome://ziink/content/jquery-1.3.2.js",context);
      var jQuery = window.jQuery.noConflict(true);
      loader.loadSubScript("chrome://ziink/content/jquery.hoverIntent.min.js", jQuery);


So, basically, use loadSubScript instead of adding it to the xul.
----------------------
Craigslist Helper: Image, Ad & Forum Previews, Distance Search and All of CL Search, Notes, Alerts etc.
For Firefox, Chrome & Safari : http://ziink.com

superm401
 
Posts: 5
Joined: September 28th, 2006, 9:34 pm

Post Posted November 1st, 2009, 12:03 am

Thank you! I added jQuery to my extension in order to use the query plugin (and maybe more in the future). I initially used script src, and had the exact problems described here (toolbars breaking). I switched to loadSubScript as described, with minor changes, and it's working well.

emafuma
 
Posts: 7
Joined: September 10th, 2010, 3:23 am

Post Posted September 14th, 2010, 8:01 am

I followed this tutorial and it seems ok but if I use $.getJSON, I get an error saying $.getJSON( it's not a function.
It's ok if I do things like: var textToEnrich = $("#testo").text();

is the prbolem this?
$.fn = $.prototype = jQuery.fn;

diegogc
 
Posts: 12
Joined: October 20th, 2010, 7:48 pm

Post Posted October 20th, 2010, 7:51 pm

I followed these instructions and I can modify the XUL elements but I get the error $.ajax is not a function. When I include jquery in the xul file .$ajax works well.. any idea?

superm401
 
Posts: 5
Joined: September 28th, 2006, 9:34 pm

Post Posted October 21st, 2010, 10:47 am

diegogc, if you follow these instructions, you must use the jQuery variable, not $.

Return to Extension Development


Who is online

Users browsing this forum: No registered users and 2 guests