Search code examples
javascriptjqueryjquery-mobilewindowglobal

How to do I attach jQuery Mobile to my own namespaced version of jQuery?


For my personal library which uses jQuery as a dependency, I took the version of jQuery I was using, and changed their code to attach jQuery to my own personal object, rather than directly to the window object.

so instead of

window.jQuery

my jQuery is accessed as

window.myObjectName.jQuery

This works fine, however, I am now incorporating jQuery mobile, and I am unable to find which parts of the code in jQuery mobile to change in order to attach it to the jQuery under myObjectName.

Is there anyone out there that can help me with this? It would be greatly appreciated, please let me know if you need any more information, thank you!


Solution

  • I managed to figure out a solution for this, and will post the solutions for others who are interested.

    jQuery mobile v1.4.5

    Looking at the prettified version of jQuery Mobile, we can see that there are multiple encapsulations, at the top of this code we can see an argument passed in by the name of "root"

    (function ( root, doc, factory ) {
        if ( typeof define === "function" && define.amd ) {
            // AMD. Register as an anonymous module.
            define( [ "jquery" ], function ( $ ) {
                factory( $, root, doc );
                return $.mobile;
            });
        } else {
            // Browser globals
            factory( root.jQuery, root, doc );
        }
    }( this, document, function ( jQuery, window, document, undefined ) {/*!
    

    This top function is a factory function which calls the rest of the code. If you log the value of "root", The argument namespaced window object, followed by the document, and a callback function. The namespaced window object must be changed from "this" to the name of the object you have attached jQuery to, such as this:

    }( window.myObject, document, function ( jQuery, window, document, undefined ) {/*!
    

    This will almost work, there is one more step in this, as this will cause jQuery mobile to throw an error when referencing the namespaced window object at these three points in the code:

    line 1472: window.navigator.userAgent.indexOf("Firefox")
    line 1473: window.navigator.userAgent.search(/CriOS/)
    line 1499: var ua = window.navigtor.userAgent;
    

    The window object jQueryM is referencing for these are the root namespace that you changed above. A simple fix for these three lines of code are to set a variable to the window object outside of jQuery Mobile, such as something like this:

    var pseudoWindow = window;
    (function ( root, doc, factory ) {
        if ( typeof define === "function" && define.amd ) {
    

    and then setting the window reference for the three lines of code above to reference this variable

    line 1472: pseudoWindow.navigator.userAgent.indexOf("Firefox")
    line 1473: pseudoWindow.navigator.userAgent.search(/CriOS/)
    line 1499: var ua = pseudoWindow.navigtor.userAgent;
    

    This will successfully make jQuery mobile attach itself to a jQuery that is not directly attached to the window.

    Just for documentation, and to answer @twernt, here is how I attach jQuery to my own custom object.

    If you open up the jQuery library, you can find near the bottom where jQuery attaches itself directly to the window object:

    var
    
        // Map over jQuery in case of overwrite
        _jQuery = window.jQuery,
    
        // Map over the $ in case of overwrite
        _$ = window.$;
    
    jQuery.noConflict = function( deep ) {
        if ( window.$ === jQuery ) {
            window.$ = _$;
        }
    
        if ( deep && window.jQuery === jQuery ) {
            window.jQuery = _jQuery;
        }
    
        return jQuery;
    };
    
    // Expose jQuery and $ identifiers, even in
    // AMD (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
    // and CommonJS for browser emulators (#13566)
    if ( !noGlobal ) {
        window.jQuery = window.$ = jQuery;
    }
    
    return jQuery;
    

    and I simply change jQueries code accordingly to attach itself to my object like this:

    var
    
        // Map over jQuery in case of overwrite
        _jQuery = window.myObject.jQuery,
    
        // Map over the $ in case of overwrite
        _$ = window.$;
    
    jQuery.noConflict = function( deep ) {
        if ( window.$ === jQuery ) {
            window.$ = _$;
        }
    
        if ( deep && window.jQuery === jQuery ) {
            window.jQuery = _jQuery;
        }
    
        return jQuery;
    };
    
    // Expose jQuery and $ identifiers, even in
    // AMD (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
    // and CommonJS for browser emulators (#13566)
    if ( !noGlobal ) {
        window.myObject.jQuery = window.myObject.$ = jQuery;
    }
    
    return jQuery;
    

    So as you can see here, jQuery is never attached directly to the window object in the first place, so referencing jQuery directly from the window such as window.jQuery will not work.