* @private
*/
init: function () {
- var $topLinks,
- topSection,
- $watchlistDetails,
- namespaces,
+ var $topSection,
+ mainWrapperWidget,
conditionalViews = {},
savedQueriesPreferenceName = mw.config.get( 'wgStructuredChangeFiltersSavedQueriesPreferenceName' ),
daysPreferenceName = mw.config.get( 'wgStructuredChangeFiltersDaysPreferenceName' ),
filtersModel = new mw.rcfilters.dm.FiltersViewModel(),
changesListModel = new mw.rcfilters.dm.ChangesListViewModel(),
savedQueriesModel = new mw.rcfilters.dm.SavedQueriesModel( filtersModel ),
+ specialPage = mw.config.get( 'wgCanonicalSpecialPageName' ),
controller = new mw.rcfilters.Controller(
filtersModel, changesListModel, savedQueriesModel,
{
daysPreferenceName: daysPreferenceName,
limitPreferenceName: limitPreferenceName
}
- ),
- $overlay = $( '<div>' )
- .addClass( 'mw-rcfilters-ui-overlay' ),
- filtersWidget = new mw.rcfilters.ui.FilterWrapperWidget(
- controller, filtersModel, savedQueriesModel, changesListModel, { $overlay: $overlay } ),
- savedLinksListWidget = new mw.rcfilters.ui.SavedLinksListWidget(
- controller, savedQueriesModel, { $overlay: $overlay }
- ),
- specialPage = mw.config.get( 'wgCanonicalSpecialPageName' ),
- $changesListRoot = $( [
- '.mw-changeslist',
- '.mw-changeslist-empty',
- '.mw-changeslist-timeout',
- '.mw-changeslist-notargetpage'
- ].join( ', ' ) );
+ );
+
+ // TODO: The changesListWrapperWidget should be able to initialize
+ // after the model is ready.
- if ( specialPage === 'Recentchangeslinked' ) {
+ if ( specialPage === 'Recentchanges' ) {
+ $topSection = $( '.mw-recentchanges-toplinks' ).detach();
+ } else if ( specialPage === 'Watchlist' ) {
+ $( '#contentSub, form#mw-watchlist-resetbutton' ).remove();
+ $topSection = $( '.watchlistDetails' ).detach().contents();
+ } else if ( specialPage === 'Recentchangeslinked' ) {
conditionalViews.recentChangesLinked = {
groups: [
{
}
]
};
-
}
- // TODO: The changesListWrapperWidget should be able to initialize
- // after the model is ready.
-
- // eslint-disable-next-line no-new
- new mw.rcfilters.ui.ChangesListWrapperWidget(
- filtersModel, changesListModel, controller, $changesListRoot );
+ mainWrapperWidget = new mw.rcfilters.ui.MainWrapperWidget(
+ controller,
+ filtersModel,
+ savedQueriesModel,
+ changesListModel,
+ {
+ $topSection: $topSection,
+ $filtersContainer: $( '.rcfilters-container' ),
+ $changesListContainer: $( [
+ '.mw-changeslist',
+ '.mw-changeslist-empty',
+ '.mw-changeslist-timeout',
+ '.mw-changeslist-notargetpage'
+ ].join( ', ' ) ),
+ $formContainer: $( 'fieldset.cloptions' )
+ }
+ );
// Remove the -loading class that may have been added on the server side.
// If we are in fact going to load a default saved query, this .initialize()
// call will do that and add the -loading class right back.
$( 'body' ).removeClass( 'mw-rcfilters-ui-loading' );
- // Remove Media namespace
- namespaces = mw.config.get( 'wgFormattedNamespaces' );
- delete namespaces[ mw.config.get( 'wgNamespaceIds' ).media ];
-
controller.initialize(
mw.config.get( 'wgStructuredChangeFilters' ),
- namespaces,
+ // All namespaces without Media namespace
+ this.getNamespaces( [ 'Media' ] ),
mw.config.get( 'wgRCFiltersChangeTags' ),
conditionalViews
);
- // eslint-disable-next-line no-new
- new mw.rcfilters.ui.FormWrapperWidget(
- filtersModel, changesListModel, controller, $( 'fieldset.cloptions' ) );
-
- $( '.rcfilters-container' ).append( filtersWidget.$element );
- $( 'body' )
- .append( $overlay )
- .addClass( 'mw-rcfilters-ui-initialized' );
-
$( 'a.mw-helplink' ).attr(
'href',
'https://www.mediawiki.org/wiki/Special:MyLanguage/Help:New_filters_for_edit_review'
controller.replaceUrl();
- if ( specialPage === 'Recentchanges' ) {
- $topLinks = $( '.mw-recentchanges-toplinks' ).detach();
-
- topSection = new mw.rcfilters.ui.RcTopSectionWidget(
- savedLinksListWidget, $topLinks
- );
- filtersWidget.setTopSection( topSection.$element );
- } // end Recentchanges
-
- if ( specialPage === 'Recentchangeslinked' ) {
- topSection = new mw.rcfilters.ui.RclTopSectionWidget(
- savedLinksListWidget, controller,
- filtersModel.getGroup( 'toOrFrom' ).getItemByParamName( 'showlinkedto' ),
- filtersModel.getGroup( 'page' ).getItemByParamName( 'target' )
- );
- filtersWidget.setTopSection( topSection.$element );
- } // end Recentchangeslinked
-
- if ( specialPage === 'Watchlist' ) {
- $( '#contentSub, form#mw-watchlist-resetbutton' ).detach();
- $watchlistDetails = $( '.watchlistDetails' ).detach().contents();
-
- topSection = new mw.rcfilters.ui.WatchlistTopSectionWidget(
- controller, changesListModel, savedLinksListWidget, $watchlistDetails
- );
- filtersWidget.setTopSection( topSection.$element );
- } // end Watchlist
+ mainWrapperWidget.setTopSection( specialPage );
/**
* Fired when initialization of the filtering interface for changes list is complete.
* @member mw.hook
*/
mw.hook( 'structuredChangeFilters.ui.initialized' ).fire();
+ },
+
+ /**
+ * Get list of namespaces and remove unused ones
+ *
+ * @member mw.rcfilters
+ * @private
+ *
+ * @param {Array} unusedNamespaces Names of namespaces to remove
+ * @return {Array} Filtered array of namespaces
+ */
+ getNamespaces: function ( unusedNamespaces ) {
+ var i, length, name, id,
+ namespaceIds = mw.config.get( 'wgNamespaceIds' ),
+ namespaces = mw.config.get( 'wgFormattedNamespaces' );
+
+ for ( i = 0, length = unusedNamespaces.length; i < length; i++ ) {
+ name = unusedNamespaces[ i ];
+ id = namespaceIds[ name.toLowerCase() ];
+ delete namespaces[ id ];
+ }
+
+ return namespaces;
}
};
--- /dev/null
+( function ( $, mw ) {
+ /**
+ * Wrapper for changes list content
+ *
+ * @extends OO.ui.Widget
+ *
+ * @constructor
+ * @param {mw.rcfilters.Controller} controller Controller
+ * @param {mw.rcfilters.dm.FiltersViewModel} model View model
+ * @param {mw.rcfilters.dm.SavedQueriesModel} savedQueriesModel Saved queries model
+ * @param {mw.rcfilters.dm.ChangesListViewModel} changesListModel
+ * @param {Object} config Configuration object
+ * @cfg {jQuery} $topSection Top section container
+ * @cfg {jQuery} $filtersContainer
+ * @cfg {jQuery} $changesListContainer
+ * @cfg {jQuery} $formContainer
+ */
+ mw.rcfilters.ui.MainWrapperWidget = function MwRcfiltersUiMainWrapperWidget(
+ controller, model, savedQueriesModel, changesListModel, config
+ ) {
+ config = $.extend( {}, config );
+
+ // Parent
+ mw.rcfilters.ui.MainWrapperWidget.parent.call( this, config );
+
+ this.controller = controller;
+ this.model = model;
+ this.changesListModel = changesListModel;
+ this.$topSection = config.$topSection;
+ this.$filtersContainer = config.$filtersContainer;
+ this.$changesListContainer = config.$changesListContainer;
+ this.$formContainer = config.$formContainer;
+ this.$overlay = $( '<div>' ).addClass( 'mw-rcfilters-ui-overlay' );
+
+ this.savedLinksListWidget = new mw.rcfilters.ui.SavedLinksListWidget(
+ controller, savedQueriesModel, { $overlay: this.$overlay }
+ );
+
+ this.filtersWidget = new mw.rcfilters.ui.FilterWrapperWidget(
+ controller,
+ model,
+ savedQueriesModel,
+ changesListModel,
+ {
+ $overlay: this.$overlay
+ }
+ );
+
+ this.changesListWidget = new mw.rcfilters.ui.ChangesListWrapperWidget(
+ model, changesListModel, controller, this.$changesListContainer );
+
+ /* Events */
+
+ // Toggle changes list overlay when filters menu opens/closes. We use overlay on changes list
+ // to prevent users from accidentally clicking on links in results, while menu is opened.
+ // Overlay on changes list is not the same as this.$overlay
+ this.filtersWidget.connect( this, { menuToggle: this.onFilterMenuToggle.bind( this ) } );
+
+ // Initialize
+ this.$filtersContainer.append( this.filtersWidget.$element );
+ $( 'body' )
+ .append( this.$overlay )
+ .addClass( 'mw-rcfilters-ui-initialized' );
+ this.initFormWidget();
+ };
+
+ /* Initialization */
+
+ OO.inheritClass( mw.rcfilters.ui.MainWrapperWidget, OO.ui.Widget );
+
+ /* Methods */
+
+ /**
+ * Set the content of the top section, depending on the type of special page.
+ *
+ * @param {string} specialPage
+ */
+ mw.rcfilters.ui.MainWrapperWidget.prototype.setTopSection = function ( specialPage ) {
+ var topSection;
+
+ if ( specialPage === 'Recentchanges' ) {
+ topSection = new mw.rcfilters.ui.RcTopSectionWidget(
+ this.savedLinksListWidget, this.$topSection
+ );
+ this.filtersWidget.setTopSection( topSection.$element );
+ }
+
+ if ( specialPage === 'Recentchangeslinked' ) {
+ topSection = new mw.rcfilters.ui.RclTopSectionWidget(
+ this.savedLinksListWidget, this.controller,
+ this.model.getGroup( 'toOrFrom' ).getItemByParamName( 'showlinkedto' ),
+ this.model.getGroup( 'page' ).getItemByParamName( 'target' )
+ );
+
+ this.filtersWidget.setTopSection( topSection.$element );
+ }
+
+ if ( specialPage === 'Watchlist' ) {
+ topSection = new mw.rcfilters.ui.WatchlistTopSectionWidget(
+ this.controller, this.changesListModel, this.savedLinksListWidget, this.$topSection
+ );
+
+ this.filtersWidget.setTopSection( topSection.$element );
+ }
+ };
+
+ /**
+ * Filter menu toggle event listener
+ *
+ * @param {boolean} isVisible
+ */
+ mw.rcfilters.ui.MainWrapperWidget.prototype.onFilterMenuToggle = function ( isVisible ) {
+ this.changesListWidget.toggleOverlay( isVisible );
+ };
+
+ /**
+ * Initialize FormWrapperWidget
+ *
+ * @return {mw.rcfilters.ui.FormWrapperWidget} Form wrapper widget
+ */
+ mw.rcfilters.ui.MainWrapperWidget.prototype.initFormWidget = function () {
+ return new mw.rcfilters.ui.FormWrapperWidget(
+ this.model, this.changesListModel, this.controller, this.$formContainer );
+ };
+}( jQuery, mediaWiki ) );