1

Changing a document, jQuery working with, is very important in Firefox/Chrome extension developing. It needs to use $(...) or jQuery(...) call . Now I forced to use jQuery this way:

var jQDoc = jQuery(content.document);
var someElements = jQDoc.find('.some-selector');

I wanna something like this

jQuery.setActiveDocument(content.document);
var someElements = jQuery('.some-selector');

Is it possible without jQuery code change?


Update

All what I need: will work with overload of the jQuery(...) function this way:

(function(){
    /*overloading of jQuery(...) function*/
    var _$ = jQuery;
    $ = jQuery = function(){
        var args = Array.prototype.slice.call(arguments);
        if (arguments.length == 1){
            args.push(_$._defaultRoot);
        }
        return _$.apply(_$, args);
    }
    jQuery.setDefaultRoot = function(element){_$._defaultRoot = element;}

    for(var key in _$) {
        if (_$.hasOwnProperty(key)) {
            jQuery[key] = _$[key];
        }
    }
})();

For example you can execute it in firebug, in stackoverflow question page (after execution of first code-block):

$.setDefaultRoot('.post-text:first');
$('span');

But I'm not sure this is the best way (noConflict will not work for example) . Works good for me :)

Alexander Goncharov
  • 1,572
  • 17
  • 20

2 Answers2

2

jQuery relies heavily on the use of the document variable. In a Firefox extension, you are often in a context where the variables document, and window, etc. are not defined, or are not defined as the <document> or <window> you are expecting them to be. You can usually solve this type of issue by defining window and document appropriately.

Without additional information, it is not possible to provide something that is guaranteed to work for you. You have not stated what scope you are working in, nor described the <document> that you desire to operate upon. Thus, the code below provides a generic solution that will find a <window> and <document> which will work in most circumstances, but you might be wanting them to be something else.

Firefox add-ons generally run in a scope where there are multiple object which could be reasonably referred to by the window and document variables. If those variables are defined and, if defined, what objects they actually refer to, depends on how the portion of your code that is currently running was entered. Even if they are defined, they are often not defined as the <window>, or <document> which jQuery would be expecting (the <window>/<document> of the content for the current tab). You will probably need to obtain a reference to both objects for the most recently accessed window/tab.

If a browser window exists (in some instances you could be running where no browser window exists, yet, e.g. at start-up), you can obtain a reference to the most recent browser window, document, and gBrowser with:

if (window === null || typeof window !== "object") {
    //If you do not already have a window reference, you need to obtain one:
    //  Add/remove a "/" to comment/un-comment the code appropriate for your add-on type.
    /* Add-on SDK:
    var window = require('sdk/window/utils').getMostRecentBrowserWindow();
    //*/
    //* Overlay and bootstrap (from almost any context/scope):
    var window=Components.classes["@mozilla.org/appshell/window-mediator;1"]
                         .getService(Components.interfaces.nsIWindowMediator)
                         .getMostRecentWindow("navigator:browser");        
    //*/
}
if (typeof document === "undefined") {
    //If there is no document defined, get it
    var document = window.content.document;
}
if (typeof gBrowser === "undefined") {
    //If there is no gBrowser defined, get it
    var gBrowser = window.gBrowser;
}

If you are running the code in response to an event (e.g. a button command event), you can obtain the current window with:

var window = event.view

The lack of having the global window and document variables available, or having them reference objects other than what you are expecting, is something that many people encounter as a problem when writing Firefox add-ons.

Note: If you are wanting to be natively compatible with multi-process Firefox (Electrolysis, or e10s), then gaining access to the content of the current document is more complex. There are shims in place which should make your code continue to work with multi-process Firefox for some time, but they may/will eventually go away. If you are writing new add-on code and you are wanting access to the <document>, or <window> associated with the content of a web page, then you should be using a content script of some sort (there are a variety of types). Which type of content script you should use depends on the what type of Firefox add-on you are writing and what you are doing with the script.

References:

  1. nsIWindowMediator
  2. Working with windows in chrome code
  3. SDK: window/utils
  4. SDK: windows

Large portions of this answer were copied from my earlier answers, including this link and here.

Community
  • 1
  • 1
Makyen
  • 31,849
  • 12
  • 86
  • 121
-2

You could try using

jQuery(content.document,function( $ ) {
  // Your code using failsafe $ alias here...
});
Chris
  • 1
  • 1
  • I tried [code]jQuery(content.document,function($){ alert(1); })[/code] but callback wasn't executed – Alexander Goncharov Mar 17 '16 at 14:40
  • The second parameter to jQuery is `context`, but you have used the element version of jQuery. First, can you expound on how this sets the context to the new document and what the callback is for? Also it helps to provide a working snippet *(JavaScript/HTML/CSS snippet Ctrl-M)* – Shanimal Mar 17 '16 at 16:24