Trevor Parscal has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/113068

Change subject: Make disabled state inheritable
......................................................................

Make disabled state inheritable

Introduce ItemWidget and GroupWidget, which together with some small changes in 
GroupElement and Widget make it possible for the disabled state of a widget to 
be inherited. This is used in Select and Option widgets to allow either 
disabling particular options, or disabling the entire control.

Demo has been updated to excercise these changes.

Also made it consistent that when a widget is disabled, we use the default 
cursor, and removed a no longer valid example from the demo.

Change-Id: I02b933d1d51d10aa4fbd2e7ab3ba3e71d260a2f1
---
M build/modules.json
M demos/widgets.js
M src/OO.ui.Element.js
M src/OO.ui.Widget.js
M src/elements/OO.ui.GroupElement.js
M src/styles/OO.ui.Element.css
M src/styles/OO.ui.Widget.css
A src/widgets/OO.ui.GroupWidget.js
A src/widgets/OO.ui.ItemWidget.js
M src/widgets/OO.ui.OptionWidget.js
M src/widgets/OO.ui.SelectWidget.js
11 files changed, 194 insertions(+), 15 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/oojs/ui refs/changes/68/113068/1

diff --git a/build/modules.json b/build/modules.json
index 8caa0f8..fd6f84d 100644
--- a/build/modules.json
+++ b/build/modules.json
@@ -34,6 +34,8 @@
                        "src/toolgroups/OO.ui.ListToolGroup.js",
                        "src/toolgroups/OO.ui.MenuToolGroup.js",
                        "src/tools/OO.ui.PopupTool.js",
+                       "src/widgets/OO.ui.GroupWidget.js",
+                       "src/widgets/OO.ui.ItemWidget.js",
                        "src/widgets/OO.ui.ButtonGroupWidget.js",
                        "src/widgets/OO.ui.ButtonWidget.js",
                        "src/widgets/OO.ui.InputWidget.js",
diff --git a/demos/widgets.js b/demos/widgets.js
index c2edaec..fe4a21e 100644
--- a/demos/widgets.js
+++ b/demos/widgets.js
@@ -104,6 +104,44 @@
                                        ]
                                },
                                {
+                                       'widget': new OO.ui.ButtonSelectWidget( 
{
+                                               'disabled': true
+                                       } ),
+                                       'items': [
+                                               new OO.ui.ButtonOptionWidget( 
1, {
+                                                       'label': 'Disabled',
+                                               } ),
+                                               new OO.ui.ButtonOptionWidget( 
2, {
+                                                       'label': 'state',
+                                               } ),
+                                               new OO.ui.ButtonOptionWidget( 
3, {
+                                                       'label': 'is',
+                                               } ),
+                                               new OO.ui.ButtonOptionWidget( 
3, {
+                                                       'label': 'inherited',
+                                               } )
+                                       ]
+                               },
+                               {
+                                       'widget': new 
OO.ui.ButtonSelectWidget(),
+                                       'items': [
+                                               new OO.ui.ButtonOptionWidget( 
1, {
+                                                       'label': 'Disabled',
+                                                       'disabled': true
+                                               } ),
+                                               new OO.ui.ButtonOptionWidget( 
2, {
+                                                       'label': 'Enabled'
+                                               } ),
+                                               new OO.ui.ButtonOptionWidget( 
3, {
+                                                       'label': 'Disabled',
+                                                       'disabled': true
+                                               } ),
+                                               new OO.ui.ButtonOptionWidget( 
3, {
+                                                       'label': 'Enabled'
+                                               } )
+                                       ]
+                               },
+                               {
                                        'label': 'ToggleButtonWidget',
                                        'widget': new OO.ui.ToggleButtonWidget( 
{ 'label': 'Toggle' } )
                                },
@@ -115,12 +153,6 @@
                                {
                                        'label': 'ToggleSwitchWidget',
                                        'widget': new OO.ui.ToggleSwitchWidget()
-                               },
-                               {
-                                       'widget': new OO.ui.ToggleSwitchWidget( 
{
-                                               'onLabel': 'Any',
-                                               'offLabel': 'Label'
-                                       } )
                                },
                                {
                                        'widget': new OO.ui.ToggleSwitchWidget( 
{
diff --git a/src/OO.ui.Element.js b/src/OO.ui.Element.js
index 0e4c5c3..5e76b8e 100644
--- a/src/OO.ui.Element.js
+++ b/src/OO.ui.Element.js
@@ -17,6 +17,7 @@
        // Properties
        this.$ = config.$ || OO.ui.Element.getJQuery( document );
        this.$element = this.$( this.$.context.createElement( this.getTagName() 
) );
+       this.elementGroup = null;
 
        // Initialization
        if ( Array.isArray( config.classes ) ) {
@@ -401,6 +402,26 @@
 };
 
 /**
+ * Get group element is in.
+ *
+ * @returns {OO.ui.GroupElement|null} Group element, null if none
+ */
+OO.ui.Element.prototype.getElementGroup = function () {
+       return this.elementGroup;
+};
+
+/**
+ * Set group element is in.
+ *
+ * @param {OO.ui.GroupElement|null} group Group element, null if none
+ * @chainable
+ */
+OO.ui.Element.prototype.setElementGroup = function ( group ) {
+       this.elementGroup = group;
+       return this;
+};
+
+/**
  * Scroll element into view
  *
  * @method
diff --git a/src/OO.ui.Widget.js b/src/OO.ui.Widget.js
index 98f22ee..8ed052c 100644
--- a/src/OO.ui.Widget.js
+++ b/src/OO.ui.Widget.js
@@ -21,11 +21,12 @@
        OO.EventEmitter.call( this );
 
        // Properties
-       this.disabled = config.disabled;
+       this.disabled = null;
+       this.wasDisabled = null;
 
        // Initialization
        this.$element.addClass( 'oo-ui-widget' );
-       this.setDisabled( this.disabled );
+       this.setDisabled( !!config.disabled );
 };
 
 /* Inheritance */
@@ -33,6 +34,13 @@
 OO.inheritClass( OO.ui.Widget, OO.ui.Element );
 
 OO.mixinClass( OO.ui.Widget, OO.EventEmitter );
+
+/* Events */
+
+/**
+ * @event disable
+ * @param {boolean} disabled Widget is disabled
+ */
 
 /* Methods */
 
@@ -47,20 +55,34 @@
 };
 
 /**
+ * Update the disabled state, in case of changes in parent widget.
+ *
+ * @method
+ * @chainable
+ */
+OO.ui.Widget.prototype.updateDisabled = function () {
+       this.setDisabled( this.disabled );
+       return this;
+};
+
+/**
  * Set the disabled state of the widget.
  *
  * This should probably change the widgets's appearance and prevent it from 
being used.
  *
  * @method
- * @param {boolean} disabled Disable button
+ * @param {boolean} disabled Disable widget
  * @chainable
  */
 OO.ui.Widget.prototype.setDisabled = function ( disabled ) {
+       var isDisabled;
+
        this.disabled = !!disabled;
-       if ( this.disabled ) {
-               this.$element.addClass( 'oo-ui-widget-disabled' );
-       } else {
-               this.$element.removeClass( 'oo-ui-widget-disabled' );
+       isDisabled = this.isDisabled();
+       if ( isDisabled !== this.wasDisabled ) {
+               this.$element.toggleClass( 'oo-ui-widget-disabled', isDisabled 
);
+               this.emit( 'disable', isDisabled );
        }
+       this.wasDisabled = isDisabled;
        return this;
 };
diff --git a/src/elements/OO.ui.GroupElement.js 
b/src/elements/OO.ui.GroupElement.js
index ff02209..6761ae1 100644
--- a/src/elements/OO.ui.GroupElement.js
+++ b/src/elements/OO.ui.GroupElement.js
@@ -65,6 +65,7 @@
                        }
                        item.connect( this, events );
                }
+               item.setElementGroup( this );
                $items = $items.add( item.$element );
        }
 
@@ -104,6 +105,7 @@
                        if ( this.aggregate ) {
                                item.disconnect( this );
                        }
+                       item.setElementGroup( null );
                        this.items.splice( index, 1 );
                        item.$element.detach();
                        this.$items = this.$items.not( item.$element );
@@ -130,6 +132,7 @@
                        item.disconnect( this );
                }
        }
+       item.setElementGroup( null );
        this.items = [];
        this.$items.detach();
        this.$items = this.$( [] );
diff --git a/src/styles/OO.ui.Element.css b/src/styles/OO.ui.Element.css
index dd83152..8373e8f 100644
--- a/src/styles/OO.ui.Element.css
+++ b/src/styles/OO.ui.Element.css
@@ -35,6 +35,9 @@
 .oo-ui-buttonedElement .oo-ui-buttonedElement-button > 
.oo-ui-indicatedElement-indicator {
        margin-right: -0.75em;
 }
+.oo-ui-buttonedElement.oo-ui-widget-disabled .oo-ui-buttonedElement-button {
+       cursor: default;
+}
 
 .oo-ui-buttonedElement-frameless {
        display: inline-block;
diff --git a/src/styles/OO.ui.Widget.css b/src/styles/OO.ui.Widget.css
index 4ef0889..11f258d 100644
--- a/src/styles/OO.ui.Widget.css
+++ b/src/styles/OO.ui.Widget.css
@@ -506,6 +506,7 @@
 
 .oo-ui-toggleSwitchWidget.oo-ui-widget-disabled {
        opacity: 0.5;
+       cursor: default;
 }
 
 .oo-ui-toggleSwitchWidget-grip {
@@ -567,7 +568,6 @@
        left: 0;
        border-radius: 1em;
        box-shadow: inset 0 1px 4px 0 rgba(0, 0, 0, 0.07);
-       cursor: pointer;
        -webkit-touch-callout: none;
        -webkit-user-select: none;
        -moz-user-select: none;
diff --git a/src/widgets/OO.ui.GroupWidget.js b/src/widgets/OO.ui.GroupWidget.js
new file mode 100644
index 0000000..f1f5acc
--- /dev/null
+++ b/src/widgets/OO.ui.GroupWidget.js
@@ -0,0 +1,48 @@
+/**
+ * Group widget.
+ *
+ * Use together with OO.ui.ItemWidget to make disabled state inheritable.
+ *
+ * @class
+ * @abstract
+ * @extends OO.ui.GroupElement
+ *
+ * @constructor
+ * @param {jQuery} $group Container node, assigned to #$group
+ * @param {Object} [config] Configuration options
+ */
+OO.ui.GroupWidget = function OoUiGroupWidget( $element, config ) {
+       // Parent constructor
+       OO.ui.GroupElement.call( this, $element, config );
+};
+
+/* Inheritance */
+
+OO.inheritClass( OO.ui.GroupWidget, OO.ui.GroupElement );
+
+/* Methods */
+
+/**
+ * Set the disabled state of the widget.
+ *
+ * This will also update the disabled state of child widgets.
+ *
+ * @method
+ * @param {boolean} disabled Disable widget
+ * @chainable
+ */
+OO.ui.GroupWidget.prototype.setDisabled = function ( disabled ) {
+       var i, len;
+
+       // Parent method
+       OO.ui.Widget.prototype.setDisabled.call( this, disabled );
+
+       // Durring construction, #setDisabled is called before the 
OO.ui.GroupElement constructor
+       if ( this.items ) {
+               for ( i = 0, len = this.items.length; i < len; i++ ) {
+                       this.items[i].updateDisabled();
+               }
+       }
+
+       return this;
+};
diff --git a/src/widgets/OO.ui.ItemWidget.js b/src/widgets/OO.ui.ItemWidget.js
new file mode 100644
index 0000000..919da75
--- /dev/null
+++ b/src/widgets/OO.ui.ItemWidget.js
@@ -0,0 +1,43 @@
+/**
+ * Item widget.
+ *
+ * Use together with OO.ui.GroupWidget to make disabled state inheritable.
+ *
+ * @class
+ * @abstract
+ *
+ * @constructor
+ */
+OO.ui.ItemWidget = function OoUiItemWidget() {
+       //
+};
+
+/* Methods */
+
+/**
+ * Check if widget is disabled.
+ *
+ * Checks parent if present, making disabled state inheritable.
+ *
+ * @returns {boolean} Widget is disabled
+ */
+OO.ui.ItemWidget.prototype.isDisabled = function () {
+       return this.disabled ||
+               ( this.elementGroup instanceof OO.ui.Widget && 
this.elementGroup.isDisabled() );
+};
+
+/**
+ * Set group element is in.
+ *
+ * @param {OO.ui.GroupElement|null} group Group element, null if none
+ * @chainable
+ */
+OO.ui.ItemWidget.prototype.setElementGroup = function ( group ) {
+       // Parent method
+       OO.ui.Element.prototype.setElementGroup.call( this, group );
+
+       // Initialize item disabled states
+       this.updateDisabled();
+
+       return this;
+};
diff --git a/src/widgets/OO.ui.OptionWidget.js 
b/src/widgets/OO.ui.OptionWidget.js
index 2ac253a..4c404df 100644
--- a/src/widgets/OO.ui.OptionWidget.js
+++ b/src/widgets/OO.ui.OptionWidget.js
@@ -23,6 +23,7 @@
        OO.ui.Widget.call( this, config );
 
        // Mixin constructors
+       OO.ui.ItemWidget.call( this );
        OO.ui.IconedElement.call( this, this.$( '<span>' ), config );
        OO.ui.LabeledElement.call( this, this.$( '<span>' ), config );
        OO.ui.IndicatedElement.call( this, this.$( '<span>' ), config );
@@ -51,6 +52,7 @@
 
 OO.inheritClass( OO.ui.OptionWidget, OO.ui.Widget );
 
+OO.mixinClass( OO.ui.OptionWidget, OO.ui.ItemWidget );
 OO.mixinClass( OO.ui.OptionWidget, OO.ui.IconedElement );
 OO.mixinClass( OO.ui.OptionWidget, OO.ui.LabeledElement );
 OO.mixinClass( OO.ui.OptionWidget, OO.ui.IndicatedElement );
diff --git a/src/widgets/OO.ui.SelectWidget.js 
b/src/widgets/OO.ui.SelectWidget.js
index 270b533..9c15e9c 100644
--- a/src/widgets/OO.ui.SelectWidget.js
+++ b/src/widgets/OO.ui.SelectWidget.js
@@ -17,7 +17,7 @@
        OO.ui.Widget.call( this, config );
 
        // Mixin constructors
-       OO.ui.GroupElement.call( this, this.$element, config );
+       OO.ui.GroupWidget.call( this, this.$element, config );
 
        // Properties
        this.pressed = false;
@@ -41,8 +41,11 @@
 
 OO.inheritClass( OO.ui.SelectWidget, OO.ui.Widget );
 
+// Need to mixin base class as well
 OO.mixinClass( OO.ui.SelectWidget, OO.ui.GroupElement );
 
+OO.mixinClass( OO.ui.SelectWidget, OO.ui.GroupWidget );
+
 /* Events */
 
 /**

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I02b933d1d51d10aa4fbd2e7ab3ba3e71d260a2f1
Gerrit-PatchSet: 1
Gerrit-Project: oojs/ui
Gerrit-Branch: master
Gerrit-Owner: Trevor Parscal <[email protected]>

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

Reply via email to