This pull request changes Stimulus to respect the ordering of action descriptors in data-action attributes, guaranteeing that actions are invoked from left to right, and that an action on the left can stop an event to prevent invocation of actions on the right.
At a high level, we do this by:
- adding an
indexproperty toAction, representing the action’s position in thedata-actionattribute - separating event listener registration from invocation, moving registration from the
Contextlevel up to theApplicationlevel - grouping bound actions by event target and name, then invoking them in order using a single listener
Implementation-wise, this branch:
- Changes
TokenObserverto emitTokens, which have anindexproperty in addition to a stringcontent. IntroducesValueObserveras a high-level interface for observing tokens with value semantics (scopes and actions, in Stimulus’ case). - Removes
TokenListObserverand obviates much of the work in TokenObserver #110, which was designed to support a particular implementation of the abstract class names feature planned for Stimulus 1.1 that we ultimately decided not to use. - Adds an
indexproperty toAction, representing the index of its corresponding token in thedata-actionattribute. ReplacesAction.forElementWithDescriptorString()withAction.forToken(). - Moves most of
EventListenerto a new class,Binding, which represents the connection between aContextand anAction. ABindingis responsible for invoking an action but not for registering the underlying DOM event listener. - Introduces a new
EventListenerclass which wraps anEventTargetand an event name and maintains a set ofBindings. When invoked, anEventListenersubsequently invokes each of its bindings in index order. It also extends theEventobject in order to detect and support calls tostopImmediatePropagation(). - Replaces
ActionObserverwithBindingObserver, whose delegate receives notifications when bindings connect and disconnect. - Introduces
Dispatcher, which manages an app-wide registry mappingBindings toEventListeners. EachApplicationhas a singleDispatcherinstance which acts as the delegate for allActionObservers.