RCFilters: Share one color picker popup between all highlight dropdowns
authorRoan Kattouw <roan.kattouw@gmail.com>
Sat, 7 Oct 2017 00:26:18 +0000 (17:26 -0700)
committerRoan Kattouw <roan.kattouw@gmail.com>
Tue, 26 Jun 2018 20:28:49 +0000 (13:28 -0700)
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
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterItemHighlightButton.js
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterMenuOptionWidget.js
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.HighlightColorPickerWidget.js
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.HighlightPopupWidget.js [new file with mode: 0644]
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.ItemMenuOptionWidget.js
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.MenuSelectWidget.js

index 44b028d..dea9293 100644 (file)
@@ -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',
index c840d7c..e3de55e 100644 (file)
@@ -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
 
        /* 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 ) );
index 926502d..65b4420 100644 (file)
@@ -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' } );
index 64a7fcf..fda0772 100644 (file)
@@ -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( {
                } );
 
                // Event
-               this.model.connect( this, { update: 'updateUiBasedOnModel' } );
                this.buttonSelect.connect( this, { choose: 'onChooseColor' } );
 
-               this.updateUiBasedOnModel();
-
                this.$element
                        .addClass( 'mw-rcfilters-ui-highlightColorPickerWidget' )
                        .append(
 
        /* 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' );
        };
 
        /**
        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 (file)
index 0000000..aedecc4
--- /dev/null
@@ -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 ) );
index 8c349e5..83d510b 100644 (file)
@@ -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' )
index d968f0c..04b7709 100644 (file)
 
                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() ) {
                                                        widget.model,
                                                        widget.model.getInvertModel(),
                                                        filterItem,
+                                                       widget.highlightPopup,
                                                        {
                                                                $overlay: widget.$overlay
                                                        }