== Plan (YMMV)
# Remove all module definitions from the codebase.
# The code for `ext.popups.renderer.mobileRenderer` and move `ext.popups.targets.mobileTarget` module (defined in `PopupsHooks#onResourceLoaderRegisterModules`(defined in `PopupsHooks#onResourceLoaderRegisterModules`) should be removed from the codebase.
# Add the `ext.popups.lib` module, which contains [Redux@3.6.0](https://unpkg.com/redux@3.6.0/dist/redux.min.js).
# Define and document the set of events that Hovercards should respond to.
# Run QUnit tests in Node.js by repurposing [I00045bb9: Add isolated unit testing with npm run test:unit](https://gerrit.wikimedia.org/r/#/q/I00045bb914d101ff67398a891c9b42f387e5332c)Create actions for those events.
# Move all DOM event handlers into a single file and add unit tests.
# Each handler is a pure function that takes a DOM event and producesshould dispatch an object to be tracked with `mw.track`, e.gaction against the store.
```lang=javascript
$( 'a' ).on(
'popups.mouseenter',
(event) => mw.track( 'ext.popups.event' onMouseEnter( event ) )
);
```# Run QUnit tests in Node.js by repurposing [I00045bb9: Add isolated unit testing with npm run test:unit](https://gerrit.wikimedia.org/r/#/q/I00045bb914d101ff67398a891c9b42f387e5332c).
5.# Create the `controller` module, which contains the code responsible for maintaining the entire state of the system (which link is being interacted with, whether the link's title attribute should be scrubbed, timers, the render cache, the popup element and if it's visible or is being animated, etc.) by consuming `ext.popups.event` events and triggering actions when certain state transitions occur, i.e.
```lang=javascript
var controller = createController( /* initialState = */ {} );
mw.trackSubscribe(
'ext.popups.event',
event => controller.onEvent( event )
);
```
68. Extract the API-related code from `ext.popups.renderer.article` to the `api` module.
# `api` subscribes to updates from the `controller` and makes an API request if the state has the correct shape. An event is dispatched when the API request is made, completes, or encounters an error.
# Ensure that anchor `title` attribute manipulation and hook firing code is removed.
# Extract the rendering code from the `ext.popups.renderer.article` module to the `renderer` module.
# `renderer` subscribes to updates from the `controller` and renders a Hovercard if the state has the correct shape.
# `mw.popups.render( data )` returns a DOM element ready to be inserted into the DOM.
# The results of `mw.popups.render` may be cached in order to improve rendering performance but the caching behaviour should be distinct from the rendering behaviour.
== Considerations
# Hovercards is event driven. We should consider using [RxJS](https://github.com/Reactive-Extensions/RxJS) to simplify a lot of the logic around subscribing to streams of DOM events and timers.
# We should strongly consider using [Redux](http://redux.js.org/) to implement `controller`.
# It has [a well-defined language that we can use to talk about modelling applications](http://redux.js.org/docs/basics/).
# It's battle tested.
# It's 2kB.
# It's incredibly well documented. Indeed, I wish I could write documentation like that…