jenkins-bot has submitted this change and it was merged. (
https://gerrit.wikimedia.org/r/397996 )
Change subject: RCFilters: Create one single source of truth for item display
......................................................................
RCFilters: Create one single source of truth for item display
Synchronize the search input, filter view and all view selection into
a single source of truth through the model.
- Stop using OO.ui.MenuSelectWidget's internal filtering logic, and
use our own filtering logic in the model instead.
- Add a concept of 'search' to the model, that is synchronized with
the current search term of the systme. The search dictates the view
and the visible items in the filters.
-- Whenever the search changes for whatever reason,
the model automatically updates the visibility of all items and
groups in the filter list.
-- This means that after changing view or search, the widgets can
always trust that they have the most updated visible item list
to scroll to or select.
- Make the view model's findMatches
as the ultimate source of truth as to what should be visible.
The items are now **always** all included in the menu, but they
change their visibility according to the logic in the findMatches.
If there is a search term, the function will account for that and
the selected view, so we can be sure that search results also
change between changing views.
This allows us to simplify the operation of selecting a tag, where
we know that the order of operation is bound to switching the views,
that will also show us the relevant results. We can bind to the display
event and properly select -- and scroll to -- the item.
Bug: T182720
Bug: T178540
Change-Id: If575f348705d863b9d68d19761ded55a4d453550
---
M resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FilterGroup.js
M resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FilterItem.js
M resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FiltersViewModel.js
M resources/src/mediawiki.rcfilters/mw.rcfilters.Controller.js
M resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.MenuSelectWidget.less
M resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterMenuHeaderWidget.js
M
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterMenuSectionOptionWidget.js
M
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterTagMultiselectWidget.js
M resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.ItemMenuOptionWidget.js
M resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.MenuSelectWidget.js
10 files changed, 241 insertions(+), 156 deletions(-)
Approvals:
Sbisson: Looks good to me, approved
jenkins-bot: Verified
diff --git
a/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FilterGroup.js
b/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FilterGroup.js
index f4cdae3..bb29b36 100644
--- a/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FilterGroup.js
+++ b/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FilterGroup.js
@@ -34,6 +34,7 @@
* @cfg {string} [whatsThis.body] The body of the whatsThis popup
message
* @cfg {string} [whatsThis.url] The url for the link in the whatsThis
popup message
* @cfg {string} [whatsThis.linkMessage] The text for the link in the
whatsThis popup message
+ * @cfg {boolean} [visible=true] The visibility of the group
*/
mw.rcfilters.dm.FilterGroup = function MwRcfiltersDmFilterGroup( name,
config ) {
config = config || {};
@@ -52,6 +53,7 @@
this.numericRange = config.range;
this.separator = config.separator || '|';
this.labelPrefixKey = config.labelPrefixKey;
+ this.visible = config.visible === undefined ? true :
!!config.visible;
this.currSelected = null;
this.active = !!config.active;
@@ -944,4 +946,38 @@
return value;
};
+
+ /**
+ * Toggle the visibility of this group
+ *
+ * @param {boolean} [isVisible] Item is visible
+ */
+ mw.rcfilters.dm.FilterGroup.prototype.toggleVisible = function (
isVisible ) {
+ isVisible = isVisible === undefined ? !this.visible : isVisible;
+
+ if ( this.visible !== isVisible ) {
+ this.visible = isVisible;
+ this.emit( 'update' );
+ }
+ };
+
+ /**
+ * Check whether the group is visible
+ *
+ * @return {boolean} Group is visible
+ */
+ mw.rcfilters.dm.FilterGroup.prototype.isVisible = function () {
+ return this.visible;
+ };
+
+ /**
+ * Set the visibility of the items under this group by the given items
array
+ *
+ * @param {mw.rcfilters.dm.ItemModel[]} visibleItems An array of
visible items
+ */
+ mw.rcfilters.dm.FilterGroup.prototype.setVisibleItems = function (
visibleItems ) {
+ this.getItems().forEach( function ( itemModel ) {
+ itemModel.toggleVisible( visibleItems.indexOf(
itemModel ) !== -1 );
+ } );
+ };
}( mediaWiki ) );
diff --git a/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FilterItem.js
b/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FilterItem.js
index 4e2079d..682a937 100644
--- a/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FilterItem.js
+++ b/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FilterItem.js
@@ -12,6 +12,7 @@
* selected, makes inactive.
* @cfg {string[]} [subset] Defining the names of filters that are a
subset of this filter
* @cfg {Object} [conflicts] Defines the conflicts for this filter
+ * @cfg {boolean} [visible=true] The visibility of the group
*/
mw.rcfilters.dm.FilterItem = function MwRcfiltersDmFilterItem( param,
groupModel, config ) {
config = config || {};
@@ -29,6 +30,7 @@
this.subset = config.subset || [];
this.conflicts = config.conflicts || {};
this.superset = [];
+ this.visible = config.visible === undefined ? true :
!!config.visible;
// Interaction states
this.included = false;
@@ -369,4 +371,28 @@
this.emit( 'update' );
}
};
+
+ /**
+ * Toggle the visibility of this item
+ *
+ * @param {boolean} [isVisible] Item is visible
+ */
+ mw.rcfilters.dm.FilterItem.prototype.toggleVisible = function (
isVisible ) {
+ isVisible = isVisible === undefined ? !this.visible :
!!isVisible;
+
+ if ( this.visible !== isVisible ) {
+ this.visible = isVisible;
+ this.emit( 'update' );
+ }
+ };
+
+ /**
+ * Check whether the item is visible
+ *
+ * @return {boolean} Item is visible
+ */
+ mw.rcfilters.dm.FilterItem.prototype.isVisible = function () {
+ return this.visible;
+ };
+
}( mediaWiki ) );
diff --git
a/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FiltersViewModel.js
b/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FiltersViewModel.js
index 8d22c23..b690bbd 100644
--- a/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FiltersViewModel.js
+++ b/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FiltersViewModel.js
@@ -20,6 +20,7 @@
this.views = {};
this.currentView = 'default';
+ this.searchQuery = null;
// Events
this.aggregate( { update: 'filterItemUpdate' } );
@@ -401,7 +402,7 @@
}
} );
- this.currentView = 'default';
+ this.setSearch( '' );
this.updateHighlightedState();
@@ -1096,19 +1097,6 @@
};
/**
- * Switch the current view
- *
- * @param {string} view View name
- * @fires update
- */
- mw.rcfilters.dm.FiltersViewModel.prototype.switchView = function ( view
) {
- if ( this.views[ view ] && this.currentView !== view ) {
- this.currentView = view;
- this.emit( 'update' );
- }
- };
-
- /**
* Get the current view
*
* @return {string} Current view
@@ -1145,6 +1133,82 @@
} );
return result;
+ };
+
+ /**
+ * Return a version of the given string that is without any
+ * view triggers.
+ *
+ * @param {string} str Given string
+ * @return {string} Result
+ */
+ mw.rcfilters.dm.FiltersViewModel.prototype.removeViewTriggers =
function ( str ) {
+ if ( this.getViewFromString( str ) !== 'default' ) {
+ str = str.substr( 1 );
+ }
+
+ return str;
+ };
+
+ /**
+ * Get the view from the given string by a trigger, if it exists
+ *
+ * @param {string} str Given string
+ * @return {string} View name
+ */
+ mw.rcfilters.dm.FiltersViewModel.prototype.getViewFromString = function
( str ) {
+ return this.getViewByTrigger( str.substr( 0, 1 ) );
+ };
+
+ /**
+ * Set the current search for the system.
+ * This also dictates what items and groups are visible according
+ * to the search in #findMatches
+ *
+ * @param {string} searchQuery Search query, including triggers
+ * @fires searchChange
+ */
+ mw.rcfilters.dm.FiltersViewModel.prototype.setSearch = function (
searchQuery ) {
+ var visibleGroups, visibleGroupNames;
+
+ if ( this.searchQuery !== searchQuery ) {
+ // Check if the view changed
+ this.switchView( this.getViewFromString( searchQuery )
);
+
+ visibleGroups = this.findMatches( searchQuery );
+ visibleGroupNames = Object.keys( visibleGroups );
+
+ // Update visibility of items and groups
+ $.each( this.getFilterGroups(), function ( groupName,
groupModel ) {
+ // Check if the group is visible at all
+ groupModel.toggleVisible(
visibleGroupNames.indexOf( groupName ) !== -1 );
+ groupModel.setVisibleItems( visibleGroups[
groupName ] || [] );
+ } );
+
+ this.searchQuery = searchQuery;
+ this.emit( 'searchChange', this.searchQuery );
+ }
+ };
+
+ /**
+ * Get the current search
+ *
+ * @return {string} Current search query
+ */
+ mw.rcfilters.dm.FiltersViewModel.prototype.getSearch = function () {
+ return this.searchQuery;
+ };
+
+ /**
+ * Switch the current view
+ *
+ * @private
+ * @param {string} view View name
+ */
+ mw.rcfilters.dm.FiltersViewModel.prototype.switchView = function ( view
) {
+ if ( this.views[ view ] && this.currentView !== view ) {
+ this.currentView = view;
+ }
};
/**
@@ -1209,18 +1273,4 @@
this.getItemByName( filterName ).clearHighlightColor();
};
- /**
- * Return a version of the given string that is without any
- * view triggers.
- *
- * @param {string} str Given string
- * @return {string} Result
- */
- mw.rcfilters.dm.FiltersViewModel.prototype.removeViewTriggers =
function ( str ) {
- if ( this.getViewByTrigger( str.substr( 0, 1 ) ) !== 'default'
) {
- str = str.substr( 1 );
- }
-
- return str;
- };
}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.rcfilters/mw.rcfilters.Controller.js
b/resources/src/mediawiki.rcfilters/mw.rcfilters.Controller.js
index 79546b4..cec570c 100644
--- a/resources/src/mediawiki.rcfilters/mw.rcfilters.Controller.js
+++ b/resources/src/mediawiki.rcfilters/mw.rcfilters.Controller.js
@@ -406,15 +406,6 @@
};
/**
- * Switch the view of the filters model
- *
- * @param {string} view Requested view
- */
- mw.rcfilters.Controller.prototype.switchView = function ( view ) {
- this.filtersModel.switchView( view );
- };
-
- /**
* Reset to default filters
*/
mw.rcfilters.Controller.prototype.resetToDefaults = function () {
@@ -1169,4 +1160,40 @@
this.updateChangesList( null, 'markSeen' );
}.bind( this ) );
};
+
+ /**
+ * Set the current search for the system.
+ *
+ * @param {string} searchQuery Search query, including triggers
+ */
+ mw.rcfilters.Controller.prototype.setSearch = function ( searchQuery ) {
+ this.filtersModel.setSearch( searchQuery );
+ };
+
+ /**
+ * Switch the view by changing the search query trigger
+ * without changing the search term
+ *
+ * @param {string} view View to change to
+ */
+ mw.rcfilters.Controller.prototype.switchView = function ( view ) {
+ this.setSearch(
+ this.filtersModel.getViewTrigger( view ) +
+ this.filtersModel.removeViewTriggers(
this.filtersModel.getSearch() )
+ );
+ };
+
+ /**
+ * Reset the search for a specific view. This means we null the search
query
+ * and replace it with the relevant trigger for the requested view
+ *
+ * @param {string} [view='default'] View to change to
+ */
+ mw.rcfilters.Controller.prototype.resetSearchForView = function ( view
) {
+ view = view || 'default';
+
+ this.setSearch(
+ this.filtersModel.getViewTrigger( view )
+ );
+ };
}( mediaWiki, jQuery ) );
diff --git
a/resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.MenuSelectWidget.less
b/resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.MenuSelectWidget.less
index 7dd78e7..0906d68 100644
---
a/resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.MenuSelectWidget.less
+++
b/resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.MenuSelectWidget.less
@@ -10,13 +10,8 @@
}
&-noresults {
- display: none;
padding: 0.5em;
color: @colorGray5;
-
- .oo-ui-menuSelectWidget-invisible & {
- display: inline-block;
- }
}
&-body {
diff --git
a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterMenuHeaderWidget.js
b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterMenuHeaderWidget.js
index dceb132..c047e83 100644
---
a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterMenuHeaderWidget.js
+++
b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterMenuHeaderWidget.js
@@ -68,9 +68,10 @@
.connect( this, { click:
'onInvertNamespacesButtonClick' } );
this.model.connect( this, {
highlightChange: 'onModelHighlightChange',
- update: 'onModelUpdate',
+ searchChange: 'onModelSearchChange',
initialize: 'onModelInitialize'
} );
+ this.view = this.model.getCurrentView();
// Initialize
this.$element
@@ -127,14 +128,17 @@
/**
* Respond to model update event
*/
- mw.rcfilters.ui.FilterMenuHeaderWidget.prototype.onModelUpdate =
function () {
+ mw.rcfilters.ui.FilterMenuHeaderWidget.prototype.onModelSearchChange =
function () {
var currentView = this.model.getCurrentView();
- this.setLabel( this.model.getViewTitle( currentView ) );
+ if ( this.view !== currentView ) {
+ this.setLabel( this.model.getViewTitle( currentView ) );
- this.invertNamespacesButton.toggle( currentView ===
'namespaces' );
- this.backButton.toggle( currentView !== 'default' );
- this.helpIcon.toggle( currentView === 'tags' );
+ this.invertNamespacesButton.toggle( currentView ===
'namespaces' );
+ this.backButton.toggle( currentView !== 'default' );
+ this.helpIcon.toggle( currentView === 'tags' );
+ this.view = currentView;
+ }
};
/**
diff --git
a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterMenuSectionOptionWidget.js
b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterMenuSectionOptionWidget.js
index e053914..20bf73f 100644
---
a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterMenuSectionOptionWidget.js
+++
b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterMenuSectionOptionWidget.js
@@ -86,13 +86,14 @@
}
// Events
- this.model.connect( this, { update: 'onModelUpdate' } );
+ this.model.connect( this, { update: 'updateUiBasedOnState' } );
// Initialize
this.$element
.addClass(
'mw-rcfilters-ui-filterMenuSectionOptionWidget' )
.addClass(
'mw-rcfilters-ui-filterMenuSectionOptionWidget-name-' + this.model.getName() )
.append( $header );
+ this.updateUiBasedOnState();
};
/* Initialize */
@@ -104,11 +105,12 @@
/**
* Respond to model update event
*/
- mw.rcfilters.ui.FilterMenuSectionOptionWidget.prototype.onModelUpdate =
function () {
+
mw.rcfilters.ui.FilterMenuSectionOptionWidget.prototype.updateUiBasedOnState =
function () {
this.$element.toggleClass(
'mw-rcfilters-ui-filterMenuSectionOptionWidget-active',
this.model.isActive()
);
+ this.toggle( this.model.isVisible() );
};
/**
diff --git
a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterTagMultiselectWidget.js
b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterTagMultiselectWidget.js
index 91a2d5f..3f47df2 100644
---
a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterTagMultiselectWidget.js
+++
b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterTagMultiselectWidget.js
@@ -41,6 +41,8 @@
allowReordering: false,
$overlay: this.$overlay,
menu: {
+ // Our filtering is done through the model
+ filterFromInput: false,
hideWhenOutOfView: false,
hideOnChoose: false,
width: 650,
@@ -121,6 +123,7 @@
this.model.connect( this, {
initialize: 'onModelInitialize',
update: 'onModelUpdate',
+ searchChange: 'onModelSearchChange',
itemUpdate: 'onModelItemUpdate',
highlightChange: 'onModelHighlightChange'
} );
@@ -238,19 +241,23 @@
};
/**
+ * Respond to model search change event
+ *
+ * @param {string} value Search value
+ */
+
mw.rcfilters.ui.FilterTagMultiselectWidget.prototype.onModelSearchChange =
function ( value ) {
+ this.input.setValue( value );
+ };
+
+ /**
* Respond to input change event
*
* @param {string} value Value of the input
*/
mw.rcfilters.ui.FilterTagMultiselectWidget.prototype.onInputChange =
function ( value ) {
- var view;
-
- value = value.trim();
-
- view = this.model.getViewByTrigger( value.substr( 0, 1 ) );
-
- this.controller.switchView( view );
+ this.controller.setSearch( value );
};
+
/**
* Respond to query button click
*/
@@ -304,13 +311,8 @@
// Clear selection
this.selectTag( null );
- // Clear input if the only thing in the input is the
prefix
- if (
- this.input.getValue().trim() ===
this.model.getViewTrigger( this.model.getCurrentView() )
- ) {
- // Clear the input
- this.input.setValue( '' );
- }
+ // Clear the search
+ this.controller.setSearch( '' );
// Log filter grouping
this.controller.trackFilterGroupings( 'filtermenu' );
@@ -508,42 +510,19 @@
* @inheritdoc
*/
mw.rcfilters.ui.FilterTagMultiselectWidget.prototype.onTagSelect =
function ( tagItem ) {
- var widget = this,
- menuOption = this.menu.getItemFromModel(
tagItem.getModel() ),
- oldInputValue = this.input.getValue().trim();
+ var menuOption = this.menu.getItemFromModel( tagItem.getModel()
);
this.menu.setUserSelecting( true );
-
- // Reset input
- this.input.setValue( '' );
-
- // Switch view
- this.controller.switchView( tagItem.getView() );
-
// Parent method
mw.rcfilters.ui.FilterTagMultiselectWidget.parent.prototype.onTagSelect.call(
this, tagItem );
- this.menu.selectItem( menuOption );
+ // Switch view
+ this.controller.resetSearchForView( tagItem.getView() );
+
this.selectTag( tagItem );
+ this.scrollToTop( menuOption.$element );
- // Scroll to the item
- if ( this.model.removeViewTriggers( oldInputValue ) ) {
- // We're binding a 'once' to the itemVisibilityChange
event
- // so this happens when the menu is ready after the
items
- // are visible again, in case this is done right after
the
- // user filtered the results
- this.getMenu().once(
- 'itemVisibilityChange',
- function () {
- widget.scrollToTop( menuOption.$element
);
- widget.menu.setUserSelecting( false );
- }
- );
- } else {
- this.scrollToTop( menuOption.$element );
- this.menu.setUserSelecting( false );
- }
-
+ this.menu.setUserSelecting( false );
};
/**
@@ -618,9 +597,7 @@
return new mw.rcfilters.ui.MenuSelectWidget(
this.controller,
this.model,
- $.extend( {
- filterFromInput: true
- }, menuConfig )
+ menuConfig
);
};
diff --git
a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.ItemMenuOptionWidget.js
b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.ItemMenuOptionWidget.js
index 51fc9bc..1508510 100644
---
a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.ItemMenuOptionWidget.js
+++
b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.ItemMenuOptionWidget.js
@@ -117,6 +117,8 @@
this.$element.addClass( classes.join( ' ' ) );
}
+
+ this.updateUiBasedOnState();
};
/* Initialization */
@@ -142,6 +144,7 @@
this.itemModel.isSelected() &&
this.invertModel.isSelected()
);
+ this.toggle( this.itemModel.isVisible() );
};
/**
diff --git
a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.MenuSelectWidget.js
b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.MenuSelectWidget.js
index 98acab0..07d8c88 100644
--- a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.MenuSelectWidget.js
+++ b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.MenuSelectWidget.js
@@ -33,7 +33,6 @@
this.userSelecting = false;
this.menuInitialized = false;
- this.inputValue = '';
this.$overlay = config.$overlay || this.$element;
this.$body = $( '<div>' ).addClass(
'mw-rcfilters-ui-menuSelectWidget-body' );
this.footers = [];
@@ -41,7 +40,9 @@
// Parent
mw.rcfilters.ui.MenuSelectWidget.parent.call( this, $.extend( {
$autoCloseIgnore: this.$overlay,
- width: 650
+ width: 650,
+ // Our filtering is done through the model
+ filterFromInput: false
}, config ) );
this.setGroupElement(
$( '<div>' )
@@ -65,8 +66,8 @@
// Events
this.model.connect( this, {
- update: 'onModelUpdate',
- initialize: 'onModelInitialize'
+ initialize: 'onModelInitialize',
+ searchChange: 'onModelSearchChange'
} );
// Initialization
@@ -104,7 +105,7 @@
}.bind( this ) );
// Switch to the correct view
- this.switchView( this.model.getCurrentView() );
+ this.updateView();
};
/* Initialize */
@@ -113,20 +114,9 @@
/* Events */
- /**
- * @event itemVisibilityChange
- *
- * Item visibility has changed
- */
-
/* Methods */
-
- /**
- * Respond to model update event
- */
- mw.rcfilters.ui.MenuSelectWidget.prototype.onModelUpdate = function () {
- // Change view
- this.switchView( this.model.getCurrentView() );
+ mw.rcfilters.ui.MenuSelectWidget.prototype.onModelSearchChange =
function () {
+ this.updateView();
};
/**
@@ -144,6 +134,7 @@
*/
mw.rcfilters.ui.MenuSelectWidget.prototype.lazyMenuCreation = function
() {
var widget = this,
+ items = [],
viewGroupCount = {},
groups = this.model.getFilterGroups();
@@ -152,8 +143,6 @@
}
this.menuInitialized = true;
- // Reset
- this.clearItems();
// Count groups per view
$.each( groups, function ( groupName, groupModel ) {
@@ -202,10 +191,12 @@
// without rebuilding the widgets each time
widget.views[ view ] = widget.views[ view ] ||
[];
widget.views[ view ] = widget.views[ view
].concat( currentItems );
+ items = items.concat( currentItems );
}
} );
- this.switchView( this.model.getCurrentView() );
+ this.addItems( items );
+ this.updateView();
};
/**
@@ -216,16 +207,12 @@
};
/**
- * Switch view
- *
- * @param {string} [viewName] View name. If not given, default is used.
+ * Update view
*/
- mw.rcfilters.ui.MenuSelectWidget.prototype.switchView = function (
viewName ) {
- viewName = viewName || 'default';
+ mw.rcfilters.ui.MenuSelectWidget.prototype.updateView = function () {
+ var viewName = this.model.getCurrentView();
if ( this.views[ viewName ] && this.currentView !== viewName ) {
- this.clearItems();
- this.addItems( this.views[ viewName ] );
this.updateFooterVisibility( viewName );
this.$element
@@ -235,8 +222,10 @@
this.currentView = viewName;
this.scrollToTop();
- this.clip();
}
+
+ this.postProcessItems();
+ this.clip();
};
/**
@@ -258,24 +247,18 @@
};
/**
- * @fires itemVisibilityChange
- * @inheritdoc
+ * Post-process items after the visibility changed. Make sure
+ * that we always have an item selected, and that the no-results
+ * widget appears if the menu is empty.
*/
- mw.rcfilters.ui.MenuSelectWidget.prototype.updateItemVisibility =
function () {
+ mw.rcfilters.ui.MenuSelectWidget.prototype.postProcessItems = function
() {
var i,
itemWasSelected = false,
- inputVal = this.$input.val(),
items = this.getItems();
- // Since the method hides/shows items, we don't want to
- // call it unless the input actually changed
- if (
- !this.userSelecting &&
- this.inputValue !== inputVal
- ) {
- // Parent method
-
mw.rcfilters.ui.MenuSelectWidget.parent.prototype.updateItemVisibility.call(
this );
-
+ // If we are not already selecting an item, always make sure
+ // that the top item is selected
+ if ( !this.userSelecting ) {
// Select the first item in the list
for ( i = 0; i < items.length; i++ ) {
if (
@@ -291,11 +274,6 @@
if ( !itemWasSelected ) {
this.selectItem( null );
}
-
- // Cache value
- this.inputValue = inputVal;
-
- this.emit( 'itemVisibilityChange' );
}
this.noResults.toggle( !this.getItems().some( function ( item )
{
@@ -314,19 +292,6 @@
return this.views[ model.getGroupModel().getView() ].filter(
function ( item ) {
return item.getName() === model.getName();
} )[ 0 ];
- };
-
- /**
- * Override the item matcher to use the model's match process
- *
- * @inheritdoc
- */
- mw.rcfilters.ui.MenuSelectWidget.prototype.getItemMatcher = function (
s ) {
- var results = this.model.findMatches( s, true );
-
- return function ( item ) {
- return results.indexOf( item.getModel() ) > -1;
- };
};
/**
--
To view, visit https://gerrit.wikimedia.org/r/397996
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: If575f348705d863b9d68d19761ded55a4d453550
Gerrit-PatchSet: 9
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Mooeypoo <[email protected]>
Gerrit-Reviewer: Mooeypoo <[email protected]>
Gerrit-Reviewer: Petar.petkovic <[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