Page MenuHomePhabricator

Allow for deferred clicks on personal tools while Javascript is loading
Open, Needs TriagePublic

Description

For users that have Javascript enabled, the JS files can take a bit of time to initially load. While they're loading, there's a risk that a user clicks a link in personal tools before the javascript is ready.

This is best demonsrated by Notifications' badges; when first loading a page, if the user clicks the badge before the JS is loaded, the system didn't have "time" to take over the click handler to open the popup -- so the result is that the badge link is activated and the user is redirected to Special:Notifications. This is super annoying, and it's not the behavior we'd like to see for users clicking the badge. If they don't have JS enabled, the link should still work, though.

This task is meant to discuss potential solutions to this problem. Attached is an initial idea that allows the use of a "deferredAction" method to trigger the action later. It safely creates an onClick handler that collects the click behavior, and allows the component to request the clicks (or in the case of Notifications, the latest click only) and then act on it. If JS is not enabled, the onClick is obviously ignored.

There are still issues with this patch, so take into account it's a preliminary idea; there are several more ideas on the table to consider, as well, and we should discuss and see if we can come up with a good relatively generic way to solve this problem for other components that need to defer action for clicks -- perhaps even outside of "personal tools" in general.

Note: Applications like "Structured Discussions" for example, can also benefit from that -- they load their DOM from the server, but the clicks on the board links are being taken over by Javascript when it is ready. If the user clicks "reply" or "thank" before JS is ready, they are redirected to a static page as if their JS is disabled. To prevent that, we use tricks like blocking actions on the page while it loads - but that's not ideal.

Event Timeline

Mooeypoo created this task.Jan 3 2018, 1:15 AM
Restricted Application added a project: Collaboration-Team-Triage. · View Herald TranscriptJan 3 2018, 1:15 AM
Restricted Application added a subscriber: Aklapper. · View Herald Transcript

Change 401639 had a related patch set uploaded (by Mooeypoo; owner: Mooeypoo):
[mediawiki/core@master] [poc] Allow for 'deferredAction' in links

https://gerrit.wikimedia.org/r/401639

Change 401640 had a related patch set uploaded (by Mooeypoo; owner: Mooeypoo):
[mediawiki/extensions/Echo@master] [poc] Defer badge click until Javascript is loaded

https://gerrit.wikimedia.org/r/401640

Note -- I think it was @Catrope that showed me a trick (and may have said it was @Krinkle who used it?) where we redefine the 'push' method of the array that was used to collect clicks before JS is loaded. If we do that, we can replace the 'getDeferredActions' with a subscription process, and have the 'push' be replaced with something like "triggerHandler" that trigger 'click' action; this would make the onClick relevant pre-JS load, and also after without having to remove the onClick from the node.

This sounds like the same idea as T183720: Avoid or minimise impact of "unready" Grade A state , have you been working on this together with @Krinkle or just two great minds thinking alike?

This sounds like the same idea as T183720: Avoid or minimise impact of "unready" Grade A state , have you been working on this together with @Krinkle or just two great minds thinking alike?

I didn't know about that task, neat! @Krinkle, can we merge efforts? :)

For me this started as a thought experiment with Structured Discussions; I was working on trying to see if we can convert some of Structured Discussions into OOUI-PHP. For various reasons, this will probably be abandoned, but it led to some great conclusions. One of those conclusions was an attempt similar to the patch above, where I added 'onClick' behavior to OOUI ButtonWidget: https://gerrit.wikimedia.org/r/#/c/392717/3/includes/OOUI/FlowButtonWidget.php

In the patch above it, I used that to create a super rudamentary semi-generalized lazyloading routine: https://gerrit.wikimedia.org/r/#/c/395664/2/modules/flow/experimental/initialization.js

There are tons of issues with this, and if we would have gone with that strategy, I'd have changed it to use proper factories and registries, but I think the underlying idea may have some merit, if we can find a way to do something more general with it -- perhaps with ResourceLoader itself?

Change 401640 abandoned by Mooeypoo:
[poc] Defer badge click until Javascript is loaded

Reason:
Experimental example; can be reopened if needed, or referred to when building a correct approach.

https://gerrit.wikimedia.org/r/401640

Restricted Application added a project: Growth-Team. · View Herald TranscriptNov 2 2018, 12:05 PM