jenkins-bot has submitted this change and it was merged. ( 
https://gerrit.wikimedia.org/r/328676 )

Change subject: RC filters: AJAX and pushState/popState
......................................................................


RC filters: AJAX and pushState/popState

Selecting/unselecting a filter now refreshes the results list using AJAX.

Also added pushState to update the URL, and popstate handling
to make the back button work.

Bug: T153949
Change-Id: I8c1ec557ccfe4b1d20aaaab3ef0d3182a1993f24
---
M resources/Resources.php
A resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.ChangesListViewModel.js
M resources/src/mediawiki.rcfilters/mw.rcfilters.Controller.js
M resources/src/mediawiki.rcfilters/mw.rcfilters.init.js
M resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.CapsuleItemWidget.js
A 
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.ChangesListWrapperWidget.js
A resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.CheckboxInputWidget.js
M 
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterCapsuleMultiselectWidget.js
M resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterItemWidget.js
M resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterWrapperWidget.js
A resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FormWrapperWidget.js
11 files changed, 313 insertions(+), 79 deletions(-)

Approvals:
  Catrope: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/resources/Resources.php b/resources/Resources.php
index 7961139..02487ea 100644
--- a/resources/Resources.php
+++ b/resources/Resources.php
@@ -1757,12 +1757,16 @@
                        
'resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FilterItem.js',
                        
'resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FilterGroup.js',
                        
'resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FiltersViewModel.js',
+                       
'resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.ChangesListViewModel.js',
+                       
'resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.CheckboxInputWidget.js',
                        
'resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FiltersListWidget.js',
                        
'resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterGroupWidget.js',
                        
'resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterItemWidget.js',
                        
'resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.CapsuleItemWidget.js',
                        
'resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterCapsuleMultiselectWidget.js',
                        
'resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterWrapperWidget.js',
+                       
'resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.ChangesListWrapperWidget.js',
+                       
'resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FormWrapperWidget.js',
                        
'resources/src/mediawiki.rcfilters/mw.rcfilters.Controller.js',
                        
'resources/src/mediawiki.rcfilters/mw.rcfilters.init.js',
                ],
@@ -1820,6 +1824,7 @@
                        'rcfilters-filter-categorization-description',
                        'rcfilters-filter-logactions-label',
                        'rcfilters-filter-logactions-description',
+                       'recentchanges-noresult',
                ],
                'dependencies' => [
                        'oojs-ui',
diff --git 
a/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.ChangesListViewModel.js 
b/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.ChangesListViewModel.js
new file mode 100644
index 0000000..edb6744
--- /dev/null
+++ 
b/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.ChangesListViewModel.js
@@ -0,0 +1,59 @@
+( function ( mw ) {
+       /**
+        * View model for the changes list
+        *
+        * @mixins OO.EventEmitter
+        *
+        * @constructor
+        */
+       mw.rcfilters.dm.ChangesListViewModel = function 
MwRcfiltersDmChangesListViewModel() {
+               // Mixin constructor
+               OO.EventEmitter.call( this );
+
+               this.valid = true;
+       };
+
+       /* Initialization */
+       OO.initClass( mw.rcfilters.dm.ChangesListViewModel );
+       OO.mixinClass( mw.rcfilters.dm.ChangesListViewModel, OO.EventEmitter );
+
+       /* Events */
+
+       /**
+        * @event invalidate
+        *
+        * The list of changes is now invalid (out of date)
+        */
+
+       /**
+        * @event update
+        * @param {jQuery|string} changesListContent
+        *
+        * The list of change is now up to date
+        */
+
+       /* Methods */
+
+       /**
+        * Invalidate the list of changes
+        *
+        * @fires invalidate
+        */
+       mw.rcfilters.dm.ChangesListViewModel.prototype.invalidate = function () 
{
+               if ( this.valid ) {
+                       this.valid = false;
+                       this.emit( 'invalidate' );
+               }
+       };
+
+       /**
+        * Update the model with an updated list of changes
+        *
+        * @param {jQuery|string} changesListContent
+        */
+       mw.rcfilters.dm.ChangesListViewModel.prototype.update = function ( 
changesListContent ) {
+               this.valid = true;
+               this.emit( 'update', changesListContent );
+       };
+
+}( mediaWiki ) );
diff --git a/resources/src/mediawiki.rcfilters/mw.rcfilters.Controller.js 
b/resources/src/mediawiki.rcfilters/mw.rcfilters.Controller.js
index 28d9f28..88f32b4 100644
--- a/resources/src/mediawiki.rcfilters/mw.rcfilters.Controller.js
+++ b/resources/src/mediawiki.rcfilters/mw.rcfilters.Controller.js
@@ -1,13 +1,14 @@
-( function ( mw ) {
+( function ( mw, $ ) {
        /**
         * Controller for the filters in Recent Changes
         *
-        * @param {mw.rcfilters.dm.FiltersViewModel} model View model
+        * @param {mw.rcfilters.dm.FiltersViewModel} filtersModel Filters view 
model
+        * @param {mw.rcfilters.dm.ChangesListViewModel} changesListModel 
Changes list view model
         */
-       mw.rcfilters.Controller = function MwRcfiltersController( model ) {
-               this.model = model;
-               // TODO: When we are ready, update the URL when a filter is 
updated
-               // this.model.connect( this, { itemUpdate: 'updateURL' } );
+       mw.rcfilters.Controller = function MwRcfiltersController( filtersModel, 
changesListModel ) {
+               this.filtersModel = filtersModel;
+               this.changesListModel = changesListModel;
+               this.requestCounter = 0;
        };
 
        /* Initialization */
@@ -17,13 +18,18 @@
         * Initialize the filter and parameter states
         */
        mw.rcfilters.Controller.prototype.initialize = function () {
+               this.updateFromURL();
+       };
+
+       /**
+        * Update the model state based on the URL parameters.
+        */
+       mw.rcfilters.Controller.prototype.updateFromURL = function () {
                var uri = new mw.Uri();
 
-               // Give the model a full parameter state from which to
-               // update the filters
-               this.model.updateFilters(
+               this.filtersModel.updateFilters(
                        // Translate the url params to filter select states
-                       this.model.getFiltersFromParameters( uri.query )
+                       this.filtersModel.getFiltersFromParameters( uri.query )
                );
        };
 
@@ -31,14 +37,18 @@
         * Reset to default filters
         */
        mw.rcfilters.Controller.prototype.resetToDefaults = function () {
-               this.model.setFiltersToDefaults();
+               this.filtersModel.setFiltersToDefaults();
+               this.updateURL();
+               this.updateChangesList();
        };
 
        /**
         * Empty all selected filters
         */
        mw.rcfilters.Controller.prototype.emptyFilters = function () {
-               this.model.emptyAllFilters();
+               this.filtersModel.emptyAllFilters();
+               this.updateURL();
+               this.updateChangesList();
        };
 
        /**
@@ -51,7 +61,9 @@
                var obj = {};
 
                obj[ filterName ] = isSelected;
-               this.model.updateFilters( obj );
+               this.filtersModel.updateFilters( obj );
+               this.updateURL();
+               this.updateChangesList();
        };
 
        /**
@@ -64,9 +76,44 @@
                // TODO: Clean up the list of filters; perhaps 'falsy' filters
                // shouldn't appear at all? Or compare to existing query string
                // and see if current state of a specific filter is needed?
-               uri.extend( this.model.getParametersFromFilters() );
+               uri.extend( this.filtersModel.getParametersFromFilters() );
 
                // Update the URL itself
                window.history.pushState( { tag: 'rcfilters' }, document.title, 
uri.toString() );
        };
-}( mediaWiki ) );
+
+       /**
+        * Fetch the list of changes from the server for the current filters
+        *
+        * @returns {jQuery.Promise} Promise object that will resolve with the 
changes list
+        */
+       mw.rcfilters.Controller.prototype.fetchChangesList = function () {
+               var uri = new mw.Uri(),
+                       requestId = ++this.requestCounter,
+                       latestRequest = function () {
+                               return requestId === this.requestCounter;
+                       }.bind( this );
+               uri.extend( this.filtersModel.getParametersFromFilters() );
+               return $.ajax( uri.toString(), { contentType: 'html' } )
+                       .then( function ( html ) {
+                               return latestRequest() ?
+                                       $( $.parseHTML( html ) ).find( 
'.mw-changeslist' ).first().contents() :
+                                       null;
+                       } ).then( null, function () {
+                               return latestRequest() ? 'NO_RESULTS' : null;
+                       } );
+       };
+
+       /**
+        * Update the list of changes and notify the model
+        */
+       mw.rcfilters.Controller.prototype.updateChangesList = function () {
+               this.changesListModel.invalidate();
+               this.fetchChangesList()
+                       .always( function ( changesListContent ) {
+                               if ( changesListContent ) {
+                                       this.changesListModel.update( 
changesListContent );
+                               }
+                       }.bind( this ) );
+       };
+}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.rcfilters/mw.rcfilters.init.js 
b/resources/src/mediawiki.rcfilters/mw.rcfilters.init.js
index 94fc959..ef0489c 100644
--- a/resources/src/mediawiki.rcfilters/mw.rcfilters.init.js
+++ b/resources/src/mediawiki.rcfilters/mw.rcfilters.init.js
@@ -9,13 +9,23 @@
        var rcfilters = {
                /** */
                init: function () {
-                       var model = new mw.rcfilters.dm.FiltersViewModel(),
-                               controller = new mw.rcfilters.Controller( model 
),
+                       var filtersModel = new 
mw.rcfilters.dm.FiltersViewModel(),
+                               changesListModel = new 
mw.rcfilters.dm.ChangesListViewModel(),
+                               controller = new mw.rcfilters.Controller( 
filtersModel, changesListModel ),
                                $overlay = $( '<div>' )
                                        .addClass( 'mw-rcfilters-ui-overlay' ),
-                               widget = new 
mw.rcfilters.ui.FilterWrapperWidget( controller, model, { $overlay: $overlay } 
);
+                               filtersWidget = new 
mw.rcfilters.ui.FilterWrapperWidget(
+                                       controller, filtersModel, { $overlay: 
$overlay } );
 
-                       model.initializeFilters( {
+                       // eslint-disable-next-line no-new
+                       new mw.rcfilters.ui.ChangesListWrapperWidget(
+                               changesListModel, $( '.mw-changeslist, 
.mw-changeslist-empty' ) );
+
+                       // eslint-disable-next-line no-new
+                       new mw.rcfilters.ui.FormWrapperWidget(
+                               changesListModel, $( '.rcoptions form' ) );
+
+                       filtersModel.initializeFilters( {
                                registration: {
                                        title: mw.msg( 
'rcfilters-filtergroup-registration' ),
                                        type: 'send_unselected_if_any',
@@ -149,7 +159,7 @@
                                }
                        } );
 
-                       $( '.rcoptions' ).before( widget.$element );
+                       $( '.rcoptions' ).before( filtersWidget.$element );
                        $( 'body' ).append( $overlay );
 
                        // Initialize values
@@ -179,7 +189,7 @@
                                        name = 'hidemyself';
                                }
                                // This span corresponds to a filter that's in 
our model, so remove it
-                               if ( model.getItemByName( name ) ) {
+                               if ( filtersModel.getItemByName( name ) ) {
                                        // HACK: Remove the text node after the 
span.
                                        // If there isn't one, we're at the 
end, so remove the text node before the span.
                                        // This would be unnecessary if we 
added separators with CSS.
@@ -193,31 +203,9 @@
                                }
                        } );
 
-                       $( '.rcoptions form' ).submit( function () {
-                               var $form = $( this );
-
-                               // Get current filter values
-                               $.each( model.getParametersFromFilters(), 
function ( paramName, paramValue ) {
-                                       var $existingInput = $form.find( 
'input[name=' + paramName + ']' );
-                                       // Check if the hidden input already 
exists
-                                       // This happens if the parameter was 
already given
-                                       // on load
-                                       if ( $existingInput.length ) {
-                                               // Update the value
-                                               $existingInput.val( paramValue 
);
-                                       } else {
-                                               // Append hidden fields with 
filter values
-                                               $form.append(
-                                                       $( '<input>' )
-                                                               .attr( 'type', 
'hidden' )
-                                                               .attr( 'name', 
paramName )
-                                                               .val( 
paramValue )
-                                               );
-                                       }
-                               } );
-
-                               // Continue the submission process
-                               return true;
+                       window.addEventListener( 'popstate', function () {
+                               controller.updateFromURL();
+                               controller.updateChangesList();
                        } );
                }
        };
diff --git 
a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.CapsuleItemWidget.js 
b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.CapsuleItemWidget.js
index 547db1b..ca47f16 100644
--- a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.CapsuleItemWidget.js
+++ b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.CapsuleItemWidget.js
@@ -7,11 +7,12 @@
         * @mixins OO.ui.mixin.PopupElement
         *
         * @constructor
+        * @param {mw.rcfilters.Controller} controller
         * @param {mw.rcfilters.dm.FilterItem} model Item model
         * @param {Object} config Configuration object
         * @cfg {jQuery} [$overlay] A jQuery object serving as overlay for 
popups
         */
-       mw.rcfilters.ui.CapsuleItemWidget = function 
MwRcfiltersUiCapsuleItemWidget( model, config ) {
+       mw.rcfilters.ui.CapsuleItemWidget = function 
MwRcfiltersUiCapsuleItemWidget( controller, model, config ) {
                var $popupContent = $( '<div>' )
                        .addClass( 'mw-rcfilters-ui-capsuleItemWidget-popup' ),
                        descLabelWidget = new OO.ui.LabelWidget();
@@ -19,6 +20,7 @@
                // Configuration initialization
                config = config || {};
 
+               this.controller = controller;
                this.model = model;
                this.$overlay = config.$overlay || this.$element;
                this.positioned = false;
@@ -45,6 +47,8 @@
 
                // Events
                this.model.connect( this, { update: 'onModelUpdate' } );
+
+               this.closeButton.connect( this, { click: 
'onCapsuleRemovedByUser' } );
 
                // Initialization
                this.$overlay.append( this.popup.$element );
@@ -86,4 +90,11 @@
                        }
                }
        };
+
+       /**
+        * Respond to the user removing the capsule with the close button
+        */
+       mw.rcfilters.ui.CapsuleItemWidget.prototype.onCapsuleRemovedByUser = 
function () {
+               this.controller.updateFilter( this.model.getName(), false );
+       };
 }( mediaWiki, jQuery ) );
diff --git 
a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.ChangesListWrapperWidget.js
 
b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.ChangesListWrapperWidget.js
new file mode 100644
index 0000000..f929eb2
--- /dev/null
+++ 
b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.ChangesListWrapperWidget.js
@@ -0,0 +1,60 @@
+( function ( mw ) {
+       /**
+        * List of changes
+        *
+        * @extends OO.ui.Widget
+        * @mixins OO.ui.mixin.PendingElement
+        *
+        * @constructor
+        * @param {mw.rcfilters.dm.ChangesListViewModel} model View model
+        * @param {jQuery} $changesListRoot Root element of the changes list to 
attach to
+        * @param {Object} config Configuration object
+        */
+       mw.rcfilters.ui.ChangesListWrapperWidget = function 
MwRcfiltersUiChangesListWrapperWidget( model, $changesListRoot, config ) {
+               config = config || {};
+
+               // Parent
+               mw.rcfilters.ui.ChangesListWrapperWidget.parent.call( this, 
$.extend( {}, config, {
+                       $element: $changesListRoot
+               } ) );
+               // Mixin constructors
+               OO.ui.mixin.PendingElement.call( this, config );
+
+               this.model = model;
+
+               // Events
+               this.model.connect( this, {
+                       invalidate: 'onModelInvalidate',
+                       update: 'onModelUpdate'
+               } );
+       };
+
+       /* Initialization */
+
+       OO.inheritClass( mw.rcfilters.ui.ChangesListWrapperWidget, OO.ui.Widget 
);
+       OO.mixinClass( mw.rcfilters.ui.ChangesListWrapperWidget, 
OO.ui.mixin.PendingElement );
+
+       /**
+        * Respond to model invalidate
+        */
+       mw.rcfilters.ui.ChangesListWrapperWidget.prototype.onModelInvalidate = 
function () {
+               this.pushPending();
+       };
+
+       /**
+        * Respond to model update
+        *
+        * @param {jQuery|string} changesListContent The content of the updated 
changes list
+        */
+       mw.rcfilters.ui.ChangesListWrapperWidget.prototype.onModelUpdate = 
function ( changesListContent ) {
+               var isEmpty = changesListContent === 'NO_RESULTS';
+               this.$element.toggleClass( 'mw-changeslist', !isEmpty );
+               this.$element.toggleClass( 'mw-changeslist-empty', isEmpty );
+               this.$element.empty().append(
+                       isEmpty ?
+                       document.createTextNode( mw.message( 
'recentchanges-noresult' ).text() ) :
+                       changesListContent
+               );
+               this.popPending();
+       };
+}( mediaWiki ) );
diff --git 
a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.CheckboxInputWidget.js 
b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.CheckboxInputWidget.js
new file mode 100644
index 0000000..86b3b11
--- /dev/null
+++ 
b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.CheckboxInputWidget.js
@@ -0,0 +1,41 @@
+( function ( mw ) {
+       /**
+        * A widget representing a single toggle filter
+        *
+        * @extends OO.ui.CheckboxInputWidget
+        *
+        * @constructor
+        * @param {Object} config Configuration object
+        */
+       mw.rcfilters.ui.CheckboxInputWidget = function 
MwRcfiltersUiCheckboxInputWidget( config ) {
+               config = config || {};
+
+               // Parent
+               mw.rcfilters.ui.CheckboxInputWidget.parent.call( this, config );
+
+               // Event
+               this.$input.on( 'change', this.onUserChange.bind( this ) );
+       };
+
+       /* Initialization */
+
+       OO.inheritClass( mw.rcfilters.ui.CheckboxInputWidget, 
OO.ui.CheckboxInputWidget );
+
+       /* Events */
+
+       /**
+        * @event userChange
+        * @param {boolean} Current state of the checkbox
+        *
+        * The user has checked or unchecked this checkbox
+        */
+
+       /* Methods */
+
+       /**
+        * Respond to checkbox change by a user and emit 'userChange'.
+        */
+       mw.rcfilters.ui.CheckboxInputWidget.prototype.onUserChange = function 
() {
+               this.emit( 'userChange', this.$input.prop( 'checked' ) );
+       };
+}( mediaWiki ) );
diff --git 
a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterCapsuleMultiselectWidget.js
 
b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterCapsuleMultiselectWidget.js
index bf80cd6..56303d5 100644
--- 
a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterCapsuleMultiselectWidget.js
+++ 
b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterCapsuleMultiselectWidget.js
@@ -154,7 +154,11 @@
                        return;
                }
 
-               return new mw.rcfilters.ui.CapsuleItemWidget( item, { $overlay: 
this.$overlay } );
+               return new mw.rcfilters.ui.CapsuleItemWidget(
+                       this.controller,
+                       item,
+                       { $overlay: this.$overlay }
+               );
        };
 
        /**
@@ -203,23 +207,6 @@
        
mw.rcfilters.ui.FilterCapsuleMultiselectWidget.prototype.onFocusForPopup = 
function () {
                // HACK can be removed once I21b8cff4048 is merged in oojs-ui
                this.focus();
-       };
-
-       /**
-        * @inheritdoc
-        */
-       mw.rcfilters.ui.FilterCapsuleMultiselectWidget.prototype.removeItems = 
function ( items ) {
-               var filterData = {};
-
-               // Parent
-               
mw.rcfilters.ui.FilterCapsuleMultiselectWidget.parent.prototype.removeItems.call(
 this, items );
-
-               items.forEach( function ( itemWidget ) {
-                       filterData[ itemWidget.getData() ] = false;
-               } );
-
-               // Update the model
-               this.model.updateFilters( filterData );
        };
 
        /**
diff --git 
a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterItemWidget.js 
b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterItemWidget.js
index f353051..f9829d4 100644
--- a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterItemWidget.js
+++ b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterItemWidget.js
@@ -22,7 +22,7 @@
                this.controller = controller;
                this.model = model;
 
-               this.checkboxWidget = new OO.ui.CheckboxInputWidget( {
+               this.checkboxWidget = new mw.rcfilters.ui.CheckboxInputWidget( {
                        value: this.model.getName(),
                        selected: this.model.isSelected()
                } );
@@ -46,7 +46,7 @@
                } );
 
                // Event
-               this.checkboxWidget.connect( this, { change: 'onCheckboxChange' 
} );
+               this.checkboxWidget.connect( this, { userChange: 
'onCheckboxChange' } );
                this.model.connect( this, { update: 'onModelUpdate' } );
 
                this.$element
diff --git 
a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterWrapperWidget.js 
b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterWrapperWidget.js
index c863f2f..315ca86 100644
--- 
a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterWrapperWidget.js
+++ 
b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterWrapperWidget.js
@@ -8,7 +8,7 @@
         * @constructor
         * @param {mw.rcfilters.Controller} controller Controller
         * @param {mw.rcfilters.dm.FiltersViewModel} model View model
-        * @param {Object} config Configuration object
+        * @param {Object} [config] Configuration object
         * @cfg {Object} [filters] A definition of the filter groups in this 
list
         * @cfg {jQuery} [$overlay] A jQuery object serving as overlay for 
popups
         */
@@ -23,8 +23,6 @@
                this.controller = controller;
                this.model = model;
                this.$overlay = config.$overlay || this.$element;
-
-               this.filtersInCapsule = [];
 
                this.filterPopup = new mw.rcfilters.ui.FiltersListWidget(
                        this.controller,
@@ -92,14 +90,5 @@
                                wrapper.capsule.addItemByName( 
filterItem.getName() );
                        }
                } );
-       };
-
-       /**
-        * Add a capsule item by its filter name
-        *
-        * @param {string} itemName Filter name
-        */
-       mw.rcfilters.ui.FilterWrapperWidget.prototype.addCapsuleItemFromName = 
function ( itemName ) {
-               this.capsule.addItemByName( [ itemName ] );
        };
 }( mediaWiki ) );
diff --git 
a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FormWrapperWidget.js 
b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FormWrapperWidget.js
new file mode 100644
index 0000000..2513b07
--- /dev/null
+++ b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FormWrapperWidget.js
@@ -0,0 +1,47 @@
+( function ( mw ) {
+       /**
+        * Wrapper for the RC form with hide/show links
+        *
+        * @extends OO.ui.Widget
+        *
+        * @constructor
+        * @param {mw.rcfilters.dm.ChangesListViewModel} model Changes list 
view model
+        * @param {jQuery} $formRoot Root element of the form to attach to
+        * @param {Object} config Configuration object
+        */
+       mw.rcfilters.ui.FormWrapperWidget = function 
MwRcfiltersUiFormWrapperWidget( model, $formRoot, config ) {
+               config = config || {};
+
+               // Parent
+               mw.rcfilters.ui.FormWrapperWidget.parent.call( this, $.extend( 
{}, config, {
+                       $element: $formRoot
+               } ) );
+
+               this.model = model;
+               this.$submitButton = this.$element.find( 'input[type=submit]' );
+
+               // Events
+               this.model.connect( this, {
+                       invalidate: 'onModelInvalidate',
+                       update: 'onModelUpdate'
+               } );
+       };
+
+       /* Initialization */
+
+       OO.inheritClass( mw.rcfilters.ui.FormWrapperWidget, OO.ui.Widget );
+
+       /**
+        * Respond to model invalidate
+        */
+       mw.rcfilters.ui.FormWrapperWidget.prototype.onModelInvalidate = 
function () {
+               this.$submitButton.prop( 'disabled', true );
+       };
+
+       /**
+        * Respond to model update
+        */
+       mw.rcfilters.ui.FormWrapperWidget.prototype.onModelUpdate = function () 
{
+               this.$submitButton.prop( 'disabled', false );
+       };
+}( mediaWiki ) );

-- 
To view, visit https://gerrit.wikimedia.org/r/328676
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I8c1ec557ccfe4b1d20aaaab3ef0d3182a1993f24
Gerrit-PatchSet: 16
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Catrope <[email protected]>
Gerrit-Reviewer: Catrope <[email protected]>
Gerrit-Reviewer: Jack Phoenix <[email protected]>
Gerrit-Reviewer: Mooeypoo <[email protected]>
Gerrit-Reviewer: Sbisson <[email protected]>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to