From 971c5c9404081452b35b6d40bdd854ae53069ae0 Mon Sep 17 00:00:00 2001 From: Roan Kattouw Date: Fri, 6 Oct 2017 17:26:18 -0700 Subject: [PATCH] RCFilters: Share one color picker popup between all highlight dropdowns Add a PopupWidget subclass that wraps the color picker, and pass that down to the buttons in the menu items. Bug: T198142 Change-Id: I84dabce988f4c99835f503bb8c8eb492f7fbfde1 --- resources/Resources.php | 1 + ....rcfilters.ui.FilterItemHighlightButton.js | 30 ++++----- .../mw.rcfilters.ui.FilterMenuOptionWidget.js | 5 +- ...rcfilters.ui.HighlightColorPickerWidget.js | 27 +++++--- .../mw.rcfilters.ui.HighlightPopupWidget.js | 63 +++++++++++++++++++ .../mw.rcfilters.ui.ItemMenuOptionWidget.js | 4 +- .../ui/mw.rcfilters.ui.MenuSelectWidget.js | 5 ++ 7 files changed, 105 insertions(+), 30 deletions(-) create mode 100644 resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.HighlightPopupWidget.js diff --git a/resources/Resources.php b/resources/Resources.php index 44b028d86e..dea9293e96 100644 --- a/resources/Resources.php +++ b/resources/Resources.php @@ -1835,6 +1835,7 @@ return [ 'resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.SaveFiltersPopupButtonWidget.js', 'resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FormWrapperWidget.js', 'resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterItemHighlightButton.js', + 'resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.HighlightPopupWidget.js', 'resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.HighlightColorPickerWidget.js', 'resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.LiveUpdateButtonWidget.js', 'resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.MarkSeenButtonWidget.js', diff --git a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterItemHighlightButton.js b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterItemHighlightButton.js index c840d7c00b..e3de55e48c 100644 --- a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterItemHighlightButton.js +++ b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterItemHighlightButton.js @@ -7,34 +7,24 @@ * @constructor * @param {mw.rcfilters.Controller} controller RCFilters controller * @param {mw.rcfilters.dm.FilterItem} model Filter item model + * @param {mw.rcfilters.ui.HighlightPopupWidget} highlightPopup Shared highlight color picker * @param {Object} [config] Configuration object */ - mw.rcfilters.ui.FilterItemHighlightButton = function MwRcfiltersUiFilterItemHighlightButton( controller, model, config ) { + mw.rcfilters.ui.FilterItemHighlightButton = function MwRcfiltersUiFilterItemHighlightButton( controller, model, highlightPopup, config ) { config = config || {}; - this.colorPickerWidget = new mw.rcfilters.ui.HighlightColorPickerWidget( controller, model ); - // Parent mw.rcfilters.ui.FilterItemHighlightButton.parent.call( this, $.extend( true, {}, config, { icon: 'highlight', - indicator: 'down', - popup: { - anchor: false, - padded: true, - align: 'backwards', - horizontalPosition: 'end', - $floatableContainer: this.$element, - width: 290, - $content: this.colorPickerWidget.$element - } + indicator: 'down' } ) ); this.controller = controller; this.model = model; + this.popup = highlightPopup; // Event this.model.connect( this, { update: 'updateUiBasedOnModel' } ); - this.colorPickerWidget.connect( this, { chooseColor: 'onChooseColor' } ); // This lives inside a MenuOptionWidget, which intercepts mousedown // to select the item. We want to prevent that when we click the highlight // button @@ -59,6 +49,14 @@ /* Methods */ + mw.rcfilters.ui.FilterItemHighlightButton.prototype.onAction = function () { + this.popup.setAssociatedButton( this ); + this.popup.setFilterItem( this.model ); + + // Parent method + mw.rcfilters.ui.FilterItemHighlightButton.parent.prototype.onAction.call( this ); + }; + /** * Respond to item model update event */ @@ -79,8 +77,4 @@ ); } ); }; - - mw.rcfilters.ui.FilterItemHighlightButton.prototype.onChooseColor = function () { - this.popup.toggle( false ); - }; }( mediaWiki, jQuery ) ); diff --git a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterMenuOptionWidget.js b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterMenuOptionWidget.js index 926502d2fc..65b44202af 100644 --- a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterMenuOptionWidget.js +++ b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterMenuOptionWidget.js @@ -9,10 +9,11 @@ * @param {mw.rcfilters.dm.FiltersViewModel} filtersViewModel * @param {mw.rcfilters.dm.FilterItem} invertModel * @param {mw.rcfilters.dm.FilterItem} itemModel Filter item model + * @param {mw.rcfilters.ui.HighlightPopupWidget} highlightPopup Shared highlight color picker popup * @param {Object} config Configuration object */ mw.rcfilters.ui.FilterMenuOptionWidget = function MwRcfiltersUiFilterMenuOptionWidget( - controller, filtersViewModel, invertModel, itemModel, config + controller, filtersViewModel, invertModel, itemModel, highlightPopup, config ) { config = config || {}; @@ -21,7 +22,7 @@ this.model = itemModel; // Parent - mw.rcfilters.ui.FilterMenuOptionWidget.parent.call( this, controller, filtersViewModel, this.invertModel, itemModel, config ); + mw.rcfilters.ui.FilterMenuOptionWidget.parent.call( this, controller, filtersViewModel, this.invertModel, itemModel, highlightPopup, config ); // Event this.model.getGroupModel().connect( this, { update: 'onGroupModelUpdate' } ); diff --git a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.HighlightColorPickerWidget.js b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.HighlightColorPickerWidget.js index 64a7fcf08e..fda0772808 100644 --- a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.HighlightColorPickerWidget.js +++ b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.HighlightColorPickerWidget.js @@ -7,10 +7,9 @@ * * @constructor * @param {mw.rcfilters.Controller} controller RCFilters controller - * @param {mw.rcfilters.dm.FilterItem} model Filter item model * @param {Object} [config] Configuration object */ - mw.rcfilters.ui.HighlightColorPickerWidget = function MwRcfiltersUiHighlightColorPickerWidget( controller, model, config ) { + mw.rcfilters.ui.HighlightColorPickerWidget = function MwRcfiltersUiHighlightColorPickerWidget( controller, config ) { var colors = [ 'none' ].concat( mw.rcfilters.HighlightColors ); config = config || {}; @@ -22,7 +21,6 @@ } ) ); this.controller = controller; - this.model = model; this.currentSelection = 'none'; this.buttonSelect = new OO.ui.ButtonSelectWidget( { @@ -41,11 +39,8 @@ } ); // Event - this.model.connect( this, { update: 'updateUiBasedOnModel' } ); this.buttonSelect.connect( this, { choose: 'onChooseColor' } ); - this.updateUiBasedOnModel(); - this.$element .addClass( 'mw-rcfilters-ui-highlightColorPickerWidget' ) .append( @@ -71,11 +66,25 @@ /* Methods */ + /** + * Bind the color picker to an item + * @param {mw.rcfilters.dm.FilterItem} filterItem + */ + mw.rcfilters.ui.HighlightColorPickerWidget.prototype.setFilterItem = function ( filterItem ) { + if ( this.filterItem ) { + this.filterItem.disconnect( this ); + } + + this.filterItem = filterItem; + this.filterItem.connect( this, { update: 'updateUiBasedOnModel' } ); + this.updateUiBasedOnModel(); + }; + /** * Respond to item model update event */ mw.rcfilters.ui.HighlightColorPickerWidget.prototype.updateUiBasedOnModel = function () { - this.selectColor( this.model.getHighlightColor() || 'none' ); + this.selectColor( this.filterItem.getHighlightColor() || 'none' ); }; /** @@ -104,9 +113,9 @@ mw.rcfilters.ui.HighlightColorPickerWidget.prototype.onChooseColor = function ( button ) { var color = button.data; if ( color === 'none' ) { - this.controller.clearHighlightColor( this.model.getName() ); + this.controller.clearHighlightColor( this.filterItem.getName() ); } else { - this.controller.setHighlightColor( this.model.getName(), color ); + this.controller.setHighlightColor( this.filterItem.getName(), color ); } this.emit( 'chooseColor', color ); }; diff --git a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.HighlightPopupWidget.js b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.HighlightPopupWidget.js new file mode 100644 index 0000000000..aedecc44b1 --- /dev/null +++ b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.HighlightPopupWidget.js @@ -0,0 +1,63 @@ +( function ( mw, $ ) { + /** + * A popup containing a color picker, for setting highlight colors. + * + * @extends OO.ui.PopupWidget + * + * @constructor + * @param {mw.rcfilters.Controller} controller RCFilters controller + * @param {Object} [config] Configuration object + */ + mw.rcfilters.ui.HighlightPopupWidget = function MwRcfiltersUiHighlightPopupWidget( controller, config ) { + config = config || {}; + + // Parent + mw.rcfilters.ui.HighlightPopupWidget.parent.call( this, $.extend( { + autoClose: true, + anchor: false, + padded: true, + align: 'backwards', + horizontalPosition: 'end', + width: 290 + }, config ) ); + + this.colorPicker = new mw.rcfilters.ui.HighlightColorPickerWidget( controller ); + + this.colorPicker.connect( this, { chooseColor: 'onChooseColor' } ); + + this.$body.append( this.colorPicker.$element ); + }; + + /* Initialization */ + + OO.inheritClass( mw.rcfilters.ui.HighlightPopupWidget, OO.ui.PopupWidget ); + + /* Methods */ + + /** + * Set the button (or other widget) that this popup should hang off. + * + * @param {OO.ui.Widget} widget Widget the popup should orient itself to + */ + mw.rcfilters.ui.HighlightPopupWidget.prototype.setAssociatedButton = function ( widget ) { + this.setFloatableContainer( widget.$element ); + this.$autoCloseIgnore = widget.$element; + }; + + /** + * Set the filter item that this popup should control the highlight color for. + * + * @param {mw.rcfilters.dm.FilterItem} item + */ + mw.rcfilters.ui.HighlightPopupWidget.prototype.setFilterItem = function ( item ) { + this.colorPicker.setFilterItem( item ); + }; + + /** + * When the user chooses a color in the color picker, close the popup. + */ + mw.rcfilters.ui.HighlightPopupWidget.prototype.onChooseColor = function () { + this.toggle( false ); + }; + +}( mediaWiki, jQuery ) ); 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 8c349e5686..83d510bf2b 100644 --- a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.ItemMenuOptionWidget.js +++ b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.ItemMenuOptionWidget.js @@ -9,10 +9,11 @@ * @param {mw.rcfilters.dm.FiltersViewModel} filtersViewModel * @param {mw.rcfilters.dm.ItemModel} invertModel * @param {mw.rcfilters.dm.ItemModel} itemModel Item model + * @param {mw.rcfilters.ui.HighlightPopupWidget} highlightPopup Shared highlight color picker * @param {Object} config Configuration object */ mw.rcfilters.ui.ItemMenuOptionWidget = function MwRcfiltersUiItemMenuOptionWidget( - controller, filtersViewModel, invertModel, itemModel, config + controller, filtersViewModel, invertModel, itemModel, highlightPopup, config ) { var layout, classes = [], @@ -55,6 +56,7 @@ this.highlightButton = new mw.rcfilters.ui.FilterItemHighlightButton( this.controller, this.itemModel, + highlightPopup, { $overlay: config.$overlay || this.$element, title: mw.msg( 'rcfilters-highlightmenu-help' ) 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 d968f0c486..04b7709725 100644 --- a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.MenuSelectWidget.js +++ b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.MenuSelectWidget.js @@ -144,6 +144,10 @@ this.menuInitialized = true; + // Create shared popup for highlight buttons + this.highlightPopup = new mw.rcfilters.ui.HighlightPopupWidget( this.controller ); + this.$overlay.append( this.highlightPopup.$element ); + // Count groups per view $.each( groups, function ( groupName, groupModel ) { if ( !groupModel.isHidden() ) { @@ -180,6 +184,7 @@ widget.model, widget.model.getInvertModel(), filterItem, + widget.highlightPopup, { $overlay: widget.$overlay } -- 2.20.1