-
Improvement
-
Resolution: Fixed
-
Minor
-
4.0
-
MOODLE_400_STABLE
-
MOODLE_400_STABLE
-
MDL-70990-master -
-
0
-
Internationals - 3.11 Sprint 7, Internationals - 3.11 Sprint 8, Internationals - 3.11 Sprint 9, Internationals - 4.0 Sprint 1
The notifiers in the core/event module currently trigger using both jQuery and YUI custom events, however neither of these are compatible with native events:
- YUI:
- events are not published natively
- can only listen to whitelisted native events. Listening to custom native events is non-trivial
- cannot fire its events natively
- cannot delegate event listening where a YUI event is fired against a DOM Node.
- cannot fire events on a DOM Node in a way that they bubble up the DOM, i.e.:
Y.publish('someEvent', {bubbles: true});
Y.one(document).on('someEvent' function(e) {
window.console.log("I was fired");
});
Y.one(document).delegate('someEvent', function(e) {
window.console.log("I was fired");
});
Y.one(document.body).fire('someEvent', 'someData');
// The someEvent custom event will only be fired on the body, and _cannot_ be picked up either by {{.on}} or {{.delegate}} on anything except that _speciifc_ node, no matter how it is published.
- jQuery:
- events are not published natively
- can listen and respond to native events
- puts event arguments into a second argument of the function call, i.e.
$(document).on('someEvent', function(e, detail) {
window.console.log(detail); // abracadabra
});
$(document.body).trigger('someEvent', 'abracadabra');
- contain additional helper functions, including isDefaultPrevented()
- Native ES:
- events are triggered on a NodElement
- events bubble up the DOM
- events can cross the ShadowDOM boundary
- event arguments are provided in the Event.detail:
document.addEventListener('someEvent', e => window.console.log(e.detail)); // abracadabra
document.body.dispatchEvent(new CustomEvent('someEvent', {bubbles: true, detail: 'abracadabra'}));
- provides no way to have a second argument to the event handler
- provides cancelable events, but these are checked via the defaultPrevented readonly boolean var
Moving forward we need to standardise our use of events in Moodle and the only sensible approach is to make use of Native events across the board. These can be listened to by YUI, jQuery, and native JS and are available in all supported browsers natively. They can be configured to bubble up the DOM, cross the ShadowDOM, be cancelled, and of course they follow the ES specification.
Sadly this is not a straightforward transition as:
- YUI events are largely isolated from the DOM Events:
- An event fired natively does not fire as a YUI Event
- An event fired in YUI does not fire natively
- Some jQuery events can be transitioned, but:
- An event fired in jQuery does not fire natively; and
- Most of our jQuery events fire with a second param. This is the extraParameters var in https://api.jquery.com/trigger/ - it is not possible to pass additional parameters to native events and all extra additional data should be in the Event.detail
To do this we will have to:
- create new event names (because jQuery listeners pick up native events)
- update the internal uses of the events we know about to call the new events
- create listeners on the new events to trigger the old events
We are lucky in that several of the jQuery events that we have are only triggered in core via a notify function, i.e. notifyFormSubmitted and not with the events being fired directly. This means that we can retrofit these triggers to use native events easily. We are even luckier in that all but one of these takes no arguments, so we do not have to dance with moving the second argument to e.detail.
The problems that we will have to solve are:
- Moving the event detail from the second argument to e.detail for that one case
- Firing the YUI events where the previous event was fired on a specific node (that same case)
- Providing b/c for a contrib module firing a YUI event - this must be configured to additionally fire the native event
- preventing recursion of YUI -> native -> YUI -> native -> YUI -> etc
In order to solve the case with a specific node, we can make use of Mutation Observers to add the appropriate b/c triggers.
We also have an issue whereby we have a central core/event AMD module which includes events for a number of events relating to other subsystems. We should be creating an events module in the relevant subsystem instead to ensure both discoverability and compliance with the cross-component coding rules.
- blocks
-
MDL-71780 Adapt course event to the new format
- Open
-
MDL-70830 Rewrite form/shortforms as AMD module
- Development in progress
-
MDL-69918 Rewrite Form Change Checker in ES6
- Closed
- has a non-specific relationship to
-
MDL-71134 Create editor, mutations AMD modules to suport the new course editor
- Closed
-
MDL-72293 Trigger native JS events in sortable list module
- Closed
- has been marked as being related by
-
MDL-74228 Typos in core_filters events file
- Closed
- has to be done before
-
MDL-77167 Remove deprecation layer for MDL-70990 (YUI Events)
- Closed
- links to