mediawiki-extensions-Popups/resources/ext.popups/boot.js
joakin e976af78e2 Hygiene: #processLinks Only use global variables at the edges
Instead of defaulting the config to the global mw.config when the param
is not defined, always pass it in (it is called just once in application
code), that way there's no need to test for the optional argument
behavior and the function is pure.

Change-Id: Ib1addb3060826f58dce2d6f928252ce1888a4293
2016-11-30 17:01:49 +00:00

131 lines
3.1 KiB
JavaScript

( function ( mw, Redux, ReduxThunk, $ ) {
var BLACKLISTED_LINKS = [
'.extiw',
'.image',
'.new',
'.internal',
'.external',
'.oo-ui-buttonedElement-button',
'.cancelLink a'
];
/**
* Creates an experiment with sensible values for the depenencies.
*
* See `mw.popups.createExperiment`.
*
* @return {Function}
*/
function isUserInCondition() {
var userSettings = mw.popups.createUserSettings( mw.storage, mw.user );
return mw.popups.createExperiment(
mw.config,
mw.user,
userSettings
);
}
/**
* Creates a gateway with sensible values for the dependencies.
*
* See `mw.popups.createGateway`.
*
* @return {ext.popups.Gateway}
*/
function createGateway() {
return mw.popups.createGateway( new mw.Api() );
}
/**
* Subscribes the registered change listeners to the
* [store](http://redux.js.org/docs/api/Store.html#store).
*
* Change listeners are registered by setting a property on
* `mw.popups.changeListeners`.
*
* @param {Redux.Store} store
*/
function registerChangeListeners( store, actions ) {
$.each( mw.popups.changeListeners, function ( _, changeListenerFactory ) {
var changeListener = changeListenerFactory( actions );
mw.popups.registerChangeListener( store, changeListener );
} );
}
/**
* Binds the actions (or "action creators") to the
* [store](http://redux.js.org/docs/api/Store.html#store).
*
* @param {Redux.Store} store
* @return {Object}
*/
function createBoundActions( store ) {
return Redux.bindActionCreators( mw.popups.actions, store.dispatch );
}
/**
* Root reducer for all actions
*
* @param {Object} global state before action
* @param {Object} action Redux action that modified state.
* Must have `type` property.
* @return {Object} global state after action
*/
mw.popups.reducers.rootReducer = Redux.combineReducers( mw.popups.reducers );
// FIXME: Needs doc (or at least one comment line)
mw.requestIdleCallback( function () {
var compose = Redux.compose,
store,
actions,
generateToken = mw.user.generateRandomSessionId,
gateway = createGateway();
// If debug mode is enabled, then enable Redux DevTools.
if ( mw.config.get( 'debug' ) === true ) {
compose = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
}
store = Redux.createStore(
mw.popups.reducers.rootReducer,
compose( Redux.applyMiddleware(
ReduxThunk.default
) )
);
actions = createBoundActions( store );
registerChangeListeners( store, actions );
actions.boot(
isUserInCondition(),
mw.user.sessionId(),
generateToken
);
mw.hook( 'wikipage.content' ).add( function ( $container ) {
var previewLinks =
mw.popups.processLinks(
$container,
BLACKLISTED_LINKS,
mw.config
);
mw.popups.renderer.init();
previewLinks
.on( 'mouseover focus', function ( event ) {
actions.linkDwell( this, event, gateway );
} )
.on( 'mouseout blur', function () {
actions.linkAbandon( this );
} )
.on( 'click', function () {
actions.linkClick( this );
} );
} );
} );
}( mediaWiki, Redux, ReduxThunk, jQuery ) );