CTools has a feature called 'cache-warming'. With this feature, properly marked AJAX calls can be made in the backgorund and the response held in a warm cache. Then, when the user actually triggers the ajax (typically by clicking on an item) the response is ready to go and the user does not have to wait. This is useful for scrolling slideshows and tabs where the response time could be a factor, without having to have the entirety of the HTML actually in the original download.
In order to accomplish this, CTools needs to change the actual click responder. However, in ajax.js, this is an anonymous function and cannot be changed out.
Recently we modified the 'options' array so that it is named, rather than a local variable, so that CTools could modify the URL late in the process. A similar change here converts the anonymous trigger response into a named function. By being named, this means that it can be replaced by a contrib module, allowing CTools to retain its cache-warming functionality without having to abandon the ajax object entirely.
Patch forthcoming.
| Comment | File | Size | Author |
|---|---|---|---|
| #24 | drupal.ajax-event-handlers.24.patch | 4.35 KB | sun |
| #22 | 939568-named-ajax-trigger-function.patch | 4.84 KB | merlinofchaos |
| #21 | 939568-named-ajax-trigger-function.patch | 4.71 KB | merlinofchaos |
| #18 | 939568-named-ajax-trigger-function.patch | 4.05 KB | merlinofchaos |
| #17 | drupal.ajax-event-handlers.17.patch | 4.35 KB | sun |
Comments
Comment #1
merlinofchaos commentedThis patch should have absolutely zero apparent functionality change to core, other than the anonymous function being replaceable.
As a bonus, by naming the function I was forced to document it.
Comment #2
ksenzeeThis looks good to me on visual inspection, but I need to step through and verify, and I haven't found time to do that yet. (In other words, subscribing.)
Comment #3
rfaysubscribe
Comment #4
effulgentsia commentedsubscribe.
Comment #5
merlinofchaos commentedBump. Can one of you give this a review? CTools is waiting on this to be able to implement the cache-warming feature properly.
Comment #6
rfayHi Earl - If you could just say a little about the general benefits of this, and what the risks might be, and how we can test it manually, I think we'll be more capable of taking it up. Right now it's just some code that ctools needs, and of course we all want ctools to have what it needs. But we don't want to break anything or cripple anything that now works.
Could you follow up on this a bit?
Comment #7
merlinofchaos commentedrfay: Did you read the initial post? I explained pretty thoroughly, I thought. Do I need to explain again or are there specific parts of my explanation I can clarify?
Comment #8
merlinofchaos commentedIn answer to part two -- we can't test javascript that I know of, so I can't help there.
Comment #9
merlinofchaos commentedLet me clarify:
All this code is doing is replacing two anonymous functions with named functions. In terms of actual functionality change, there should be zero.
Anonymous functions are bad because they cannot be referenced. Once they are created, they just hang around (anonymously) and that's all you can do.
Named functions on the ajax object can be called externally and/or replaced.
Two benefits:
1) Someone wanting to use the ajax framework and the Drupal.ajax object can replace the event responder (i.e, the code that actually responds to the click event) with something else. As a back-of-the-napkin example:
You could use this to do something before or after the actual ajax call. You could use it to replace the guts of the ajax call with something else. Right now, it is very difficult to affect things. The actual use-case for cache warming is way too complicated to explain here, it would only confuse the actual issue.
2) Someone wanting to control the event that triggers the AJAX can do so by directly calling the object. Right now, I have example code (that I'm presenting Saturday and will post somewhere for people to peruse) that performs AJAX operations on a timer. It works, but it's mildly annoying because the only way to trigger the AJAX call is through a single event. That's doable but it's limited. Here is the actual code I have in place, right now. This code is based largely on the current use of the 'use-ajax' class in ajax.js right now:
The comment in there shows where calling ajax.eventResponse() would probably be more straightforward than having to go through an event. Plus, if there are multiple paths that could call this, a single event could become problematic, since right now the event cannot carry any payload. Plus, we can't actually change the behavior of the event response anyway.
Comment #10
rfayYou explained what the change means to ctools, but not what the change means to core. Since we need to get reviews that will get it into core, I'm trying to get you to go into detail about what it means to core.
I'm trying to be helpful, not annoying. We need some review, but this is presented as "ctools needs this". Which is OK. But it doesn't get it reviewed.
Comment #11
merlinofchaos commentedActually I did, Randy, in my very first post:
By being named, this means that it can be replaced by a contrib module,
And then I followed up and wrote a book. What more do you want? This is way, way, way, way, way more work than a patch that doesn't do much should take. :/
Comment #12
rfay@merlinofchaos, I apologize. Somehow I didn't see your #9, and my #10 was responding to #7.
Thanks for the explanation, and sorry for the cross-post (not that it was a cross-post; must be something the wrong with my ability to parse an issue)
Comment #13
merlinofchaos commentedThis really needs love from someone to get in. I've done all I can to demonstrate what it is and why it's important.
Tagging per webchick's advice.
Comment #14
effulgentsia commented#1: 939568-named-ajax-trigger-function.patch queued for re-testing.
Comment #15
effulgentsia commented@merlinofchaos: Sorry. Since ksenzee is a much better JS programmer than I am, I was leaving it for her to RTBC. But she's on vacation. Patch no longer applies. Please post a new one, and I'll review.
Comment #17
sunRe-rolled against HEAD. Also added pass-through of the actual event to eventResponse().
Looks ready to fly for me.
Comment #18
merlinofchaos commentedOk, reroll of the patch. I have:
1) Confirmed everything using node/add/poll and the ajax response example in my D7 presentation, which is available on my blog.
2) Confirmed that the eventResponse function is swappable by modifying the aajax response module with this:
Ok testbot: Tell me this is ok!
Comment #19
merlinofchaos commentedI also confirmed that both clicks and keypresses trigger ajax appropriately.
Comment #20
merlinofchaos commentedaw crap. I didn't see your reroll, sun, and we crossposted.
Comment #21
merlinofchaos commentedComparing sun's patch to mine, they both had bugs. sun's reverted the setClick bug that was fixed recently and mine didn't properly pass the actual triggering event through (which most things did not really use).
This merges the two patches.
Comment #22
merlinofchaos commentedNope, missed one other item. Not sure how that disappeared.
Comment #23
sunCan we rename the first arguments to 'element'? All the code comments refer to an element already, and since we cannot use 'this', 'element' would make most sense.
Powered by Dreditor.
Comment #24
sunMerely changed the local 'trigger' variable to 'element' in the callbacks.
Aside from that, this patch is identical to #22, which in turn is almost identical to my last, except that this.element became ajax.element.
Comment #25
merlinofchaos commentedLooks good.
Comment #26
webchickThis smelled very D8-y to me upon first read, but ksenzee and sun explained to me that this isn't a "feature", per se, but more of a code clean-up caused by the AJAX framework in core first being used right now. If JS code is written correctly, you basically get altering for free, so this is not a new "feature" in that respect like other patches I've been moving to D8 tonight.
Extra bonus is that there's no functionality change in core since it's basically just re-writing a function, and merlinofchaos is right that we've allowed similar patches more recently to clean up regressions from CTools.
So, committed #24 to HEAD. Thanks!
Comment #27
rfayCongrats on getting this done! Wow.
I don't see an obvious API change that current users will trip over, so will not announce this unless somebody thinks otherwise.