* @cfg {jQuery} [$overlay] A jQuery object serving as overlay for popups
*/
mw.rcfilters.ui.FilterCapsuleMultiselectWidget = function MwRcfiltersUiFilterCapsuleMultiselectWidget( controller, model, filterInput, config ) {
+ var title = new OO.ui.LabelWidget( {
+ label: mw.msg( 'rcfilters-activefilters' ),
+ classes: [ 'mw-rcfilters-ui-filterCapsuleMultiselectWidget-wrapper-content-title' ]
+ } ),
+ $contentWrapper = $( '<div>' )
+ .addClass( 'mw-rcfilters-ui-filterCapsuleMultiselectWidget-wrapper' );
+
+ this.$overlay = config.$overlay || this.$element;
+
// Parent
- mw.rcfilters.ui.FilterCapsuleMultiselectWidget.parent.call( this, $.extend( {
- $autoCloseIgnore: filterInput.$element
+ mw.rcfilters.ui.FilterCapsuleMultiselectWidget.parent.call( this, $.extend( true, {
+ popup: {
+ $autoCloseIgnore: filterInput.$element.add( this.$overlay ),
+ $floatableContainer: filterInput.$element
+ }
}, config ) );
this.controller = controller;
this.model = model;
- this.$overlay = config.$overlay || this.$element;
-
this.filterInput = filterInput;
-
- this.$content.prepend(
- $( '<div>' )
- .addClass( 'mw-rcfilters-ui-filterCapsuleMultiselectWidget-content-title' )
- .text( mw.msg( 'rcfilters-activefilters' ) )
- );
+ this.isSelecting = false;
+ this.selected = null;
this.resetButton = new OO.ui.ButtonWidget( {
icon: 'trash',
label: mw.msg( 'rcfilters-empty-filter' ),
classes: [ 'mw-rcfilters-ui-filterCapsuleMultiselectWidget-emptyFilters' ]
} );
+ this.$content.append( this.emptyFilterMessage.$element );
// Events
this.resetButton.connect( this, { click: 'onResetButtonClick' } );
- this.model.connect( this, { itemUpdate: 'onModelItemUpdate' } );
+ this.model.connect( this, {
+ itemUpdate: 'onModelItemUpdate',
+ highlightChange: 'onModelHighlightChange'
+ } );
+ this.aggregate( { click: 'capsuleItemClick' } );
+
// Add the filterInput as trigger
this.filterInput.$input
.on( 'focus', this.focus.bind( this ) );
+ // Build the content
+ $contentWrapper.append(
+ title.$element,
+ $( '<div>' )
+ .addClass( 'mw-rcfilters-ui-table' )
+ .append(
+ // The filter list and button should appear side by side regardless of how
+ // wide the button is; the button also changes its width depending
+ // on language and its state, so the safest way to present both side
+ // by side is with a table layout
+ $( '<div>' )
+ .addClass( 'mw-rcfilters-ui-row' )
+ .append(
+ this.$content
+ .addClass( 'mw-rcfilters-ui-cell' )
+ .addClass( 'mw-rcfilters-ui-filterCapsuleMultiselectWidget-cell-filters' ),
+ $( '<div>' )
+ .addClass( 'mw-rcfilters-ui-cell' )
+ .addClass( 'mw-rcfilters-ui-filterCapsuleMultiselectWidget-cell-reset' )
+ .append( this.resetButton.$element )
+ )
+ )
+ );
+
// Initialize
- this.$content.append( this.emptyFilterMessage.$element );
- this.$handle
- .append(
- // The content and button should appear side by side regardless of how
- // wide the button is; the button also changes its width depending
- // on language and its state, so the safest way to present both side
- // by side is with a table layout
- $( '<div>' )
- .addClass( 'mw-rcfilters-ui-filterCapsuleMultiselectWidget-table' )
- .append(
- $( '<div>' )
- .addClass( 'mw-rcfilters-ui-filterCapsuleMultiselectWidget-row' )
- .append(
- $( '<div>' )
- .addClass( 'mw-rcfilters-ui-filterCapsuleMultiselectWidget-content' )
- .addClass( 'mw-rcfilters-ui-filterCapsuleMultiselectWidget-cell' )
- .append( this.$content ),
- $( '<div>' )
- .addClass( 'mw-rcfilters-ui-filterCapsuleMultiselectWidget-cell' )
- .append( this.resetButton.$element )
- )
- )
- );
+ this.$handle.append( $contentWrapper );
this.$element
.addClass( 'mw-rcfilters-ui-filterCapsuleMultiselectWidget' );
* @param {mw.rcfilters.dm.FilterItem} item Filter item model
*/
mw.rcfilters.ui.FilterCapsuleMultiselectWidget.prototype.onModelItemUpdate = function ( item ) {
- if ( item.isSelected() ) {
+ if (
+ item.isSelected() ||
+ (
+ this.model.isHighlightEnabled() &&
+ item.isHighlightSupported() &&
+ item.getHighlightColor()
+ )
+ ) {
this.addItemByName( item.getName() );
} else {
this.removeItemByName( item.getName() );
this.reevaluateResetRestoreState();
};
+ /**
+ * Respond to highlightChange event
+ *
+ * @param {boolean} isHighlightEnabled Highlight is enabled
+ */
+ mw.rcfilters.ui.FilterCapsuleMultiselectWidget.prototype.onModelHighlightChange = function ( isHighlightEnabled ) {
+ var highlightedItems = this.model.getHighlightedItems();
+
+ if ( isHighlightEnabled ) {
+ // Add capsule widgets
+ highlightedItems.forEach( function ( filterItem ) {
+ this.addItemByName( filterItem.getName() );
+ }.bind( this ) );
+ } else {
+ // Remove capsule widgets if they're not selected
+ highlightedItems.forEach( function ( filterItem ) {
+ if ( !filterItem.isSelected() ) {
+ this.removeItemByName( filterItem.getName() );
+ }
+ }.bind( this ) );
+ }
+ };
+
/**
* Respond to click event on the reset button
*/
this.emptyFilterMessage.toggle( currFiltersAreEmpty );
};
+ /**
+ * Mark an item widget as selected
+ *
+ * @param {mw.rcfilters.ui.CapsuleItemWidget} item Capsule widget
+ */
+ mw.rcfilters.ui.FilterCapsuleMultiselectWidget.prototype.select = function ( item ) {
+ if ( this.selected !== item ) {
+ // Unselect previous
+ if ( this.selected ) {
+ this.selected.toggleSelected( false );
+ }
+
+ // Select new one
+ this.selected = item;
+ if ( this.selected ) {
+ item.toggleSelected( true );
+ }
+ }
+ };
+
+ /**
+ * Reset selection and remove selected states from all items
+ */
+ mw.rcfilters.ui.FilterCapsuleMultiselectWidget.prototype.resetSelection = function () {
+ if ( this.selected !== null ) {
+ this.selected = null;
+ this.getItems().forEach( function ( capsuleWidget ) {
+ capsuleWidget.toggleSelected( false );
+ } );
+ }
+ };
+
/**
* @inheritdoc
*/
this.menu.selectItem();
this.menu.highlightItem();
};
+
+ /**
+ * @inheritdoc
+ */
+ mw.rcfilters.ui.FilterCapsuleMultiselectWidget.prototype.removeItems = function ( items ) {
+ // Parent call
+ mw.rcfilters.ui.FilterCapsuleMultiselectWidget.parent.prototype.removeItems.call( this, items );
+
+ // Destroy the item widget when it is removed
+ // This is done because we re-add items by recreating them, rather than hiding them
+ // and items include popups, that will just continue to be created and appended
+ // unnecessarily.
+ items.forEach( function ( widget ) {
+ widget.destroy();
+ } );
+ };
+
+ /**
+ * Override 'editItem' since it tries to use $input which does
+ * not exist when a popup is available.
+ */
+ mw.rcfilters.ui.FilterCapsuleMultiselectWidget.prototype.editItem = function () {};
}( mediaWiki, jQuery ) );