Drop `jquery-ujs` dependency

I mean that UJS should be standalone and framework independent. We have now document.querySelectorAll and it should be IMHO used to get all non-GET links, alerts, etc. I know that jQuery UJS do some more (like adding CSRF tag to each AJAX request), but this should be done elsewhere. Then it will not be problem if someone want’s to drop whole jQuery and replace it with i.e. MooTools or Angular (which do not do the same stuff, but can replace jQuery) or use Dart on webpage.

This is already true, see for example, prototype-ujs which implements
ujs via prototype.

Hey Łukasz,

Right now, you actually can switch to whatever JS framework or library you want. The jquery-ujs adapter is just one of the ujs adapters you can use. It also happens to be the default, in the same way that Test::Unit is the default testing framework. But just like switching to RSpec, you could easily switch to e.g. prototype-ujs (https://github.com/rails/prototype-ujs), by simply changing the gem.

That being said, if someone wanted to take the lead on developing a framework-agnostic version of UJS, just using plain JavaScript, that’d be pretty cool, and I’d even help. It probably wouldn’t be an easy task though, as there’s a lot more that UJS does beyond what you mentioned. You can have a look at the file itself (https://github.com/rails/jquery-ujs/blob/master/src/rails.js) to get an idea. The main things that would need to be accounted for if ditching the framework, would be cross-browser implementations of:

  • AJAX requests

  • Event binding and propagation

  • Selector engine (which as you pointed out could use querySelectorAll for all browsers excluding IE<9 (well sort of IE8 too))

Everything else would probably be relatively trivial to implement using plain JS.

– Steve Schwartz

jQuery 2 dropped support for IE8 as well, so IMHO it wouldn’t be so big problem. Events are simple in plain JS also isn’t that hard (see https://developer.mozilla.org/en-US/docs/Web/Guide/DOM/Events/Creating_and_triggering_events). Only AJAX requests are problem. As I know we cannot automatically add any headers to all requests. So only AJAX request will need to be done “by hand” (others than will be done by UJS) or used library will need to be configured right.

Lukas, jquery dropped IE8 support from jquery 2 as part of a long-term deprecation strategy that involved the concurrently maintained jquery 1.9 for IE<9 support. It’s not the same as dropping IE8 support outright.

Even if I think that UJS should be library agnostic. Only AJAX part should change between frameworks. Of coure there can still be jQuery UJS version, but library/framework agnostic is must-have.

I think you probably underestimated the complexity involved in maintaining JavaScript libraries that targets multiple browsers :slight_smile:

“I did X in 5 lines of pure JavaScript that worked great for my app in the 2 browsers that I care about” is not the same thing as “X is easy in JavaScript, who needs libraries!”. You should take a look at those “micro libraries” out there for doing query selector, AJAX etc - I think you will find that it requires more effort (and code) than you imagined. Maintaining something like this would be a huge distraction for the core team and not a very efficient use of their time/attention/energy considering many smart people have already devoted a lot of their time doing excellent jobs solving these problems.

It’s also unclear what are the benefit here, because most apps are already some sort of libraries that do all of those things (jquery, zepto, jqlite, etc). For these apps, using a “pure” JavaScript implementation would mean downloading more bytes, parsing more code, more weight, move moving parts and probably more bugs.

That said, if you are one of those that aren’t using any of those libraries and would like to pick this up, you should just do it. If it turns out that I’m wrong and it’s in fact a better, simpler and easier to maintain, I’m sure it will become the de facto standard and there probably won’t be much resistance to making it the default gem.

By the way – if you really want to do this, I’d strongly suggest looking at event delegation (attaching a single event handler on the , for example) instead of using querySelectorAll whenever possible.