sstephenson · GitHub

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:

  1. adding an index property to Action, representing the action’s position in the data-action attribute
  2. separating event listener registration from invocation, moving registration from the Context level up to the Application level
  3. grouping bound actions by event target and name, then invoking them in order using a single listener

Implementation-wise, this branch:

  • Changes TokenObserver to emit Tokens, which have an index property in addition to a string content. Introduces ValueObserver as a high-level interface for observing tokens with value semantics (scopes and actions, in Stimulus’ case).
  • Removes TokenListObserver and 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 index property to Action, representing the index of its corresponding token in the data-action attribute. Replaces Action.forElementWithDescriptorString() with Action.forToken().
  • Moves most of EventListener to a new class, Binding, which represents the connection between a Context and an Action. A Binding is responsible for invoking an action but not for registering the underlying DOM event listener.
  • Introduces a new EventListener class which wraps an EventTarget and an event name and maintains a set of Bindings. When invoked, an EventListener subsequently invokes each of its bindings in index order. It also extends the Event object in order to detect and support calls to stopImmediatePropagation().
  • Replaces ActionObserver with BindingObserver, whose delegate receives notifications when bindings connect and disconnect.
  • Introduces Dispatcher, which manages an app-wide registry mapping Bindings to EventListeners. Each Application has a single Dispatcher instance which acts as the delegate for all ActionObservers.

Read the original on github.com ↗