Pending

User tests: Successful: Unsuccessful:

avatar jlleblanc
jlleblanc
31 May 2012

At J! and Beyond, we discussed ways of implementing jQuery in Joomla 3.0. Here is what we have so far:

  • A minified copy of jQuery 1.7.2
  • A file with jQuery.noConflict();
  • An additional method for JHtmlBehavior (would require Platfrom merge, unless we have a standard way of doing this in the CMS library)

Calling JHTML::_('behavior.jquery'); loads both jQuery and the separate file with noConflict. This is being done because Joomla currently loads all of the JavaScript files first, then loads all of the JavaScript declarations afterwards. If you load jQuery, then MooTools (or another file that pre-defines $), then call jQuery.noConflict(), it will not work: http://www.designvsdevelop.com/jquery-in-joomla-i-was-wrong/

This approach works, but it is sub-optimal as you have to incur the overhead of two HTTP requests. There are two workarounds we could pursue:

  • Manually add jQuery.noConflict(); at the end of jquery.min.js. We would have to do this every time we update jQuery. This is what WordPress does.
  • Add new code to JDocument and JDocumentRenderer that would allow declarations to be added immediately before or after a script is loaded. (I believe @beat mentioned he had a pull request for this on the platform)

Another thing we may want to consider is adding an option in Joomla that will let you specify a CDN copy of jQuery to use in place of the local one.

UPDATE 4 June: The latest commits now implement code in JDocument for "post script" functionality. This allows inline JavaScript to be added immediately after a linked script. These commits also make it possible to specify an alternative path through JHTML::_('behavior.jquery'). This alternate path can be another copy of jQuery on the server, or the full URL to a CDN copy.

UPDATE 18 June: Prescript functionality has been added, exactly the same as "post script", just before the script loads instead of after. Also, an uncompressed debug copy of jQuery is now available, and is loaded when Joomla is in debug mode.

avatar jlleblanc jlleblanc - open - 31 May 2012
avatar jlleblanc
jlleblanc - comment - 31 May 2012

Also, a jQuery integration plan has been added here: http://docs.joomla.org/JavaScript_Working_Group#jQuery_Integration_Plan

avatar infograf768
infograf768 - comment - 31 May 2012

Please create a Joomla Feature tracker in http://joomlacode.org/gf/project/joomla/tracker/?action=TrackerItemBrowse&tracker_id=8549 and reference here.

avatar laoneo
laoneo - comment - 31 May 2012

Can't wait till jQuery will be available in joomla core!! The folk of the G4J project will thank you...I think jQuery.noConflict(); should be in a separate file. Users which care abut site speed do have a javascript minifier like jFinalizer installed anyway which packs all javascript files into one....

avatar gnomeontherun
gnomeontherun - comment - 31 May 2012

I recommend adding jQuery.noConflict(); to the end of the jQuery file.

avatar kyleledbetter
kyleledbetter - comment - 31 May 2012

Not sure if this question or request belongs here, but should we also offer a toggle to use a CDN/hosted version of jQuery in the core? Thx for working on this btw

avatar jlleblanc
jlleblanc - comment - 31 May 2012

@kyleledbetter yup, that's part of what I'm asking. I know we're loathe to add more options in the configuration.php file and a plugin seems overweight. I'm wondering if we might want to introduce an "extended" configuration panel for Joomla 3.0 that isn't tied to configuration.php and would allow for later-breaking features like this.

@gnomeontherun I lean towards appending jQuery.noConflict(); directly to the file as well. Some people brought up the fact that this adds One More Thing To Remember To Do whenever a new version of jQuery comes out, which is a valid concern.

avatar gnomeontherun
gnomeontherun - comment - 31 May 2012

@jlleblanc valid concern, but also something that could be automated during the build process.

avatar beat
beat - comment - 31 May 2012

Hi all,
For reference here is my pull request which might be reviewed with "new eyes" now that jQuery inclusion has been decided:
joomla/joomla-platform#736

For pre- and post- javascript files inclusions javascript code (required for CDN downloading of jquery) you can take a look at the proposed patches for the 2 files:
libraries/joomla/document/document.php
libraries/joomla/document/html/renderer/head.php

here:

https://github.com/joomla/joomla-platform/pull/736/files

Pretty easy to do and would do that job and solve many other valid uses of defining JS variables before including JS files...

I'm still to avoid changing imported libraries, and above solution is clean, elegant and same inclusion if from joomla install (which should be default for security reasons) or from a CDN.

Finally, changes to file:
libraries/joomla/html/html/behavior.php
on that page allow to solve all the dependencies of jQuery plugins, and at same time of jquery versioning.

Let me know what you think, and if there are parts that you think are not useful.

avatar jlleblanc
jlleblanc - comment - 1 Jun 2012

@beat ah, yes, I'd forgotten that the CDN was one of the reasons appending noConflict to the end was a non-starter.

avatar DaveOzric
DaveOzric - comment - 1 Jun 2012

This would be simply awesome!

avatar jlleblanc
jlleblanc - comment - 5 Jun 2012

I've now added updates for "post scripts" to be added immediately after linked scripts. I've also added the possibility of using a CDN URL in place of a local copy of jQuery.

avatar anibalsanchez
anibalsanchez - comment - 8 Jun 2012

Coool, I'm eagerly waiting for the Joomla 3.0 September release!

avatar nikosdion
nikosdion - comment - 9 Jun 2012

That's a great idea and a very well thought out implementation. Especially the CDN part, I love it!

avatar nonumber
nonumber - comment - 10 Jun 2012

Can't the HTML method for jquery not simply output a <script type="text/javascript">jQuery.noConflict();</script> right after the script file tag?

avatar beat
beat - comment - 10 Jun 2012

@nonumber : That's exactly what this proposal does: line 92 of proposed behavior.php does (see diff tab) using new addPostScript method:
$document->addPostScript($path, 'jQuery.noConflict();');

avatar beat
beat - comment - 10 Jun 2012

Regarding file media/system/js/jquery.min.js :

I'm proposing to also include the non-minified file:
media/system/js/jquery.js

And to use the non-minified file when Joomla debug is on. That way, debugging javascript is much easier. I believe there is already a standard way in Joomla to do that, and if I recall correctly, I used that in my original patch proposal.

avatar infograf768
infograf768 - comment - 10 Jun 2012

Indeed.
Codemirror example;
$uncompressed = JFactory::getApplication()->getCfg('debug') ? '-uncompressed' : '';
JHtml::('script', $this->basePath . 'js/codemirror'.$uncompressed.'.js', false, false, false, false);

avatar realityking
realityking - comment - 10 Jun 2012

Actually JHtml does this automatically for you, the uncompressed file just has to be jquery-uncompressed.js, the compressed file jquery.js.

avatar beat
beat - comment - 10 Jun 2012

Yes, but in case of CDN, the convention for jQuery and for all jQuery plugins is .min.js for compressed and .js for uncompressed. Thus in the fetch from CDN, it should be treated by this patch. Then for consistency, we need to decide if we follow Mootools conventions for jQuery, or jQuery conventions in case of the file in Joomla too ;-)

While Mootool's convention saves 4 characters output in the minified version, and would seem at first glance more optimal html-output-wise, the .min.js convention is more broadly used, and specially consitently used by all jQuery plugins.

Once jQuery is there, the next big thing is jQuery plugins, e.g. Bootstrap has one, that needs to be included too. And all of them have .min.js as convention. Thus I suggest that for jQuery plugins, we follow the jQuery convention with .min js, and apply the "if" that is needed for CDN also for Joomla core jquery one. JHtml checks if file exists before adding uncompressed to the filename, so that will not break the jQuery convention.

avatar realityking
realityking - comment - 10 Jun 2012

It's not the Mootools convention, it's the Joomla convention ;)

As for CDNs, the automatic discovery of uncompressed versions won't work there anyway because it relies on filesystem access. That will just have to be part of the extra code for a CDN use.

Anyway bigger point - and more directed at the PLT especially @severdia - what exactly is the the vision on jQuery and Bootstrap? Is there supposed to be a selection of library involved or are they both to be loaded on the same page?

Depending on the answer I might have more comments on this pull ;)

avatar beat
beat - comment - 10 Jun 2012

@realityking : sorry for wrong attribution of the js files convention invention ;)

Regarding your technical "strategy" question: it's not jquery or bootstrap choice, but bootstrap's original javascript libraries require jQuery core library as they are jQuery plugins :
http://twitter.github.com/bootstrap/javascript.html

I don't know what Kyle's and Joe's plans are for those plugins yet, if they want to keep the dozen files separate or just append those used in admin area to a single file. But all of them require that core jQuery plugin be loaded before them.

My [original pull request 736][joomla/joomla-platform#736] has a complete way to manage those jQuery plugins, including dependancies, if there are any. For bootstrap jQuery plugins, I think there is no dependencies. Obviously as jQuery goes into core, the "JQUERY BEHAVIOR HANDLER" "class" i proposed should probably be used differently than i originally proposed. Obviously there are other ways to achieve the same result. ;-)

avatar realityking
realityking - comment - 10 Jun 2012

I know what bootstrap requires - but there are MooTools ports of these too so the question remains.

avatar jlleblanc
jlleblanc - comment - 10 Jun 2012

@realityking I found this MooTools port of Bootstrap: https://github.com/anutron/mootools-bootstrap I'm assuming this is the best one available; if this is not the case, please let me know so we can discuss the best one.

One of the main concerns is that MooTools ports of tools tend to fall behind on patches. Right now, the MooTools Boostrap port mentioned above is three patches behind the standard version of Bootstrap. Also, although we're not using it in this case, the MooTools port of Backbone is currently one patch behind the standard version.

Another concern is that MooTools ports are often incomplete. This is the case with the Bootstrap port: the ScrollSpy functionality is not supported. I'm assuming that there's more ported over than the http://anutron.github.com/mootools-bootstrap/ suggests, but it appears as though there may be quite a bit missing when you compare to the original.

The markup for MooTools Boostrap is also different from the original. MooTools Bootstrap uses data attributes to assign behaviors to HTML elements, where the original does not. Part of the advantage of using something like Bootstrap is that someone coming from outside of the Joomla world will be able to use a familiar tool immediately. When we break that by using a slightly different variant, we're making it more difficult for people to adopt Joomla.

For these reasons, MooTools Bootstrap is not preferable.

This pull request makes it possible for jQuery and MooTools to properly coexist on the same page, so adding jQuery shouldn't be a problem.

avatar nikosdion
nikosdion - comment - 10 Jun 2012

I agree with Joe that there is no point adding anything else except the original (jQuery-based) version of Bootstrap. Besides, if we are using a popular CDN like Google's to deliver the jQuery and MooTools JavaScript files then there is no point discussing performance. Since so many sites out there already use the same files from the same CDNs there's a big chance that these files are already in the cache of the visitor's browser cache. IMHO, we Joomla! extensions developers are causing a much bigger pain in the rear of webmasters and web visitors alike since each one of us has to load his own private, namespaced copy of jQuery on a page. Usually with a system plugin. On every page. Ugh! Having One True Solution(tm) for loading jQuery off a CDN would let us allow Joomla! users build faster loading sites while at the same time using all the power of mooTools and rapid development of jQuery.

avatar realityking
realityking - comment - 10 Jun 2012

@jlleblanc
I'm not saying it's perfect ;) I just wanted to have it clarified what the vision set out by the PLT is because Ron's post was very short and it leaves some questions open.

Also the data attributes are very much in the jQuery bootstrap as well. You can use either with data attributes or without. (Kyle chose with BTW)

@nikosdion
I'm eagerly awaiting the complains of developers when the CMS ships an incompatible jQuery version ;) Look at wordpress where you end up with 2-3 jQuery versions when you're unlucky. IIRC Beat mentioned he can't update the jQuery version in Community Builder because CB plug-ins rely on it. I'm not totally against including jQuery into the core (I'm against using it in the core thou) I just hope people realize it's not a magic bullet to solve their jQuery problems.

As for the performance question. The browser still has to execute two big libraries on each request (think mobile). As much as it pains me to say but it would make far more sense to just switch the complete thing to jQuery than to deal with two libraries.

As for the CDN argument, I'm not quite sold on that and hard stats are almost impossible to come by. Browser caches are by default surprisingly small (Opera 20MB, Firefox 50MB). Considering the different CDN providers, jQuery versions (21 hosted by Google by my count), etc. the chance it's in the cache is certainly far higher than a local version but I'm not sure it's as high as most people think it is. That's not to say it's not a good idea to use it - but I don't think ti's good enough to justify loading an additional 80KB.

avatar nikosdion
nikosdion - comment - 10 Jun 2012

Rouven, I am a moron when it comes to JavaScript. I somehow managed to update all of my jQuery, most of which I have written over two years ago and can't explain you how it works even if you held me at gunpoint. In other words, there is nothing impossible. It's merely a question of ROI. If the net gain (faster site, less compatibility issues) outweighs the drawbacks (rewriting code, rare cases of workarounds to support multiple versions) developers will follow suit. If we were just negatively predisposed individuals we would have never worked on making our software compatible with Joomla! 2.x ;)

Regarding performance. I have only used Joomla! websites on iPad 2, iPhone 4S and HTC Desire (1GHz single and dual core processors). In all cases the bottleneck on mobile is the download weight, especially on 3G connections due to the huge lag. All of my devices didn't even blink parsing jQuery and mooTools. But, yes, if we could get Joomla!'s own JS to be jQuery based it would be slightly better.

Regarding CDNs, I agree with you. But! The more sites using the same file from the same CDN the more likely is the browser caching the file. I will tell you my unscientific, very objective findings so far. Ever since I had Kickstart load jQuery off a CDN people have been telling me how much faster it is. It would be interesting to have analytics about that, but I have no idea where to look or start.

In any case, even if the cache was busted and we ended up loading one copy of jQuery during the user's first visit it would still be better than the typical site I see today. In the typical site we have at least two extensions loading two different jQuery versions. In this case, 80Kb with a single HTTP request guaranteed to get cached in the following page loads is better than 2 * 80Kb HTTP requests which most usually won't get cached because there is neither an Expires not an Etag header. Of course if someone is merely using stock Joomla! it will make the page slightly heavier, by 80Kb. Well, we do get the option, as extension developers, to choose whether we want to load jQuery, don't we?

avatar jlleblanc
jlleblanc - comment - 10 Jun 2012

@realityking Thanks for the clarification on data attributes. I stand corrected.

I believe the plan is to get as much of the frontend core JavaScript converted to jQuery as possible first. This way, MooTools won't be required to load and can be pulled in on an as-needed basis. If we can get everything converted over to jQuery for Joomla 3.0, that would be ideal, but it might also be too aggressive of a timeline.

Long term, MooTools will most likely continue to be available in core for legacy code, just pulled in only when necessary. Obviously, having two libraries load is not ideal, but we can make an effort to ensure it isn't the norm.

And yes, there will always be people out there shipping code relying on out of date versions of jQuery, no matter how much we beg for people to upgrade. There are indeed no silver bullets, but having one specific copy available in core will definitely encourage people to avoid including their own.

avatar anibalsanchez
anibalsanchez - comment - 10 Jun 2012

BTW, Is Joomla 3.0 a transition from mootools to jQuery (with both libraries bundled) ? And, is Joomla 3.5 going to ship both libraries or just jQuery?

avatar jlleblanc
jlleblanc - comment - 10 Jun 2012

@anibalsanchez Both libraries will be bundled with Joomla 3.0. There is no current plan to remove MooTools itself.

avatar beat
beat - comment - 10 Jun 2012

Just to clarify: jQuery is extremely well backwards compatible. Actually one of the most backwards compatible libraries I ever saw. So that is not an issue imho. In jQuery's "history" there was only one minor change with backwards incompatibility in jQuery 1.6.

Yes, we decided in CB 1.7 to not upgrade jQuery to the at that time just released 1.6, as it was pretty new, and that not all of the jQuery plugins we use got adapted at that time. Now that's not an issue anymore as all plugins have been adapted.

My proposal for multiple versions support was

1) just a way to make sure that in case there is a major release somewhere in the future, we have a solution already in our API.

2) a solution for Joomla 2.5 to introduce jQuery support without having the library part of the core, and in that case we needed to manage multiple versions (that was the consensus on the google groups thread, so instead of discussing, i've coded a solution to the issue.

3) also showcasing how we can add jQuery support in a deeply non-conflicting mode while staying compatible, and protecting Joomla itself from "wildely" loaded jQuerys in simple non-conflict mode or not even non-conflict mode by many templates and extensions nowadays.

4) giving a solid Joomla API and library to developers needing a newer version than what's in the core (there may be very valid reasons for that !, e.g. in LTS releases) to still be able to still load their own version without conflicting (and without having to spend days like I did to understand how to be able to do deep-non-conflict (actually I modestly contributed to better documenting the non-conflict wiki chapter of jQuery doc on that aspect some years back).

That said, we have implemented in CB 1.8 a version of the jQuery deep-non-conflict method that I proposed to Joomla in my pull request, to protect CB from any modules and other jQuery or mootools loaders. That method allows to get completely out of the global variables space except with a dynamically named variable, and still be compatible with all current uses of $ and of jQuery global variables in jQuery plugins and jQuery javascript code that is properly loaded.

Since then we didn't have any single Javascript conflict reported for CB anymore !!!! What a dream for our support team and most importantly for webmasters :-) I'm still recommending the deep non-conflict mode to avoid any conflicts, but of course living with a "normal" non-conflict standard jquery library in joomla is still much better than with none :-D

@jlleblanc : Regarding your latest patch:
1. The non-minified version of jquery.js still needs to get used in Joomla debug mode
2. Great for the post-javascript files load script code, but it would be very useful to have the same for same functionality just before loading the js files. E.g. for defining language vars. Is it possible to add that too for consistency ?

avatar Skullbock
Skullbock - comment - 20 Jun 2012

Can't wait to see this in the core. Great job @jlleblanc

avatar jlleblanc
jlleblanc - comment - 22 Jun 2012

Created a Joomla Platform pull request: joomla/joomla-platform#1298

avatar Serhioromano
Serhioromano - comment - 27 Sep 2012

I think it is too complicated. Post script pre scripts. Then new developer have to learn what each method does. That will not add clearness to Joomla.

I think the only thing that have to be done is to call jQuery as very first script in head() and immediately after that call jQuery.noConflict();. That is it. No problems any more. Then let everyone load any scripts they want in any order they want (of course load mootools first)

But basically the princip of not conflicting is simple. Load Jquery and all its related scripts and then load Mootools and all its related scripts. it is all about order.

I was suggestion to add $script_type to $document->addScrpt($url, false, false, 'jquery') which would group scripts and call them inside needed group.

avatar jlleblanc
jlleblanc - comment - 27 Sep 2012

The post and pre script feature isn't required: it's something that would be available if you need it. And typically the people needing it would understand how this works and why they'd want to use it. The idea was to build something that could handle multiple JavaScript libraries, not just general purpose DOM manipulators like jQuery.

But I'm closing this PR, as I also closed the one on Platform. Didn't have enough time to smooth out the rough edges, and jQuery is now included in 3.0 anyway.

avatar jlleblanc jlleblanc - close - 27 Sep 2012
avatar awc737
awc737 - comment - 8 Nov 2012

Was post and pre not implemented? Right now, addScript() adds scripts to the very top, BEFORE jQuery. This is a horrible bug, breaking all scripts.

avatar jlleblanc
jlleblanc - comment - 8 Nov 2012

No, they were not, but that shouldn't be breaking the scripts. If you're calling a script that relies on jQuery and do JHtml::_('jquery.framework'); before you call addScript(), it will order them correctly.

avatar awc737
awc737 - comment - 8 Nov 2012

Thank you jlleblanc, shortly afterward I realized I could do JHtml::_('bootstrap.framework');, but jquery.framework is even better because I may end up using Zurb Foundation. Thanks a lot!

Add a Comment

Login with GitHub to post a comment