jenkins-bot has submitted this change and it was merged.

Change subject: Refactor OutlineControlsWidget, add remove button
......................................................................


Refactor OutlineControlsWidget, add remove button

* Adders turn out to be very instance specific, so abstracting them
  makes things pretty awkward. Rather than generate adders from a
  configuration object, mix in GroupElement and use its API for managing
  items.
* Add remove button and event to OutlineControlsWidget
* Add removable state to OutlineItemWidget
* Use IconedElement to render + icon for adders, rather than faking it
  with a button that doesn't do anything
* Blur focused inputs on page change
* Add method for getting the closest page to another, taking into
  consideration depth when a booklet is outlined

Change-Id: I35ae249b0b1597188dc6d06cdaf78ba08027be80
---
M i18n/en.json
M i18n/qqq.json
M src/OO.ui.js
M src/layouts/OO.ui.BookletLayout.js
M src/styles/OO.ui.Widget.less
M src/widgets/OO.ui.OutlineControlsWidget.js
M src/widgets/OO.ui.OutlineItemWidget.js
7 files changed, 132 insertions(+), 61 deletions(-)

Approvals:
  Catrope: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/i18n/en.json b/i18n/en.json
index d402de8..5ff9915 100644
--- a/i18n/en.json
+++ b/i18n/en.json
@@ -19,5 +19,6 @@
     "ooui-dialog-action-close": "Close",
     "ooui-outline-control-move-down": "Move item down",
     "ooui-outline-control-move-up": "Move item up",
+    "ooui-outline-control-remove": "Remove item",
     "ooui-toolbar-more": "More"
 }
diff --git a/i18n/qqq.json b/i18n/qqq.json
index 78a70d9..c5b8ffa 100644
--- a/i18n/qqq.json
+++ b/i18n/qqq.json
@@ -22,5 +22,6 @@
     "ooui-dialog-action-close": "Label text for button to exit from 
dialog.\n\n{{Identical|Close}}",
     "ooui-outline-control-move-down": "Tool tip for a button that moves items 
in a list down one place",
     "ooui-outline-control-move-up": "Tool tip for a button that moves items in 
a list up one place",
+    "ooui-outline-control-remove": "Tool tip for a button that removes items 
from a list",
     "ooui-toolbar-more": "Label for the toolbar group that contains a list of 
all other available tools.\n{{Identical|More}}"
 }
\ No newline at end of file
diff --git a/src/OO.ui.js b/src/OO.ui.js
index 1480c83..59a9640 100644
--- a/src/OO.ui.js
+++ b/src/OO.ui.js
@@ -74,6 +74,8 @@
        'ooui-outline-control-move-down': 'Move item down',
        // Tool tip for a button that moves items in a list up one place
        'ooui-outline-control-move-up': 'Move item up',
+       // Tool tip for a button that removes items from a list
+       'ooui-outline-control-remove': 'Remove item',
        // Label for the toolbar group that contains a list of all other 
available tools
        'ooui-toolbar-more': 'More'
 };
diff --git a/src/layouts/OO.ui.BookletLayout.js 
b/src/layouts/OO.ui.BookletLayout.js
index f0ce75e..f110ba3 100644
--- a/src/layouts/OO.ui.BookletLayout.js
+++ b/src/layouts/OO.ui.BookletLayout.js
@@ -124,6 +124,7 @@
  */
 OO.ui.BookletLayout.prototype.onStackLayoutSet = function ( page ) {
        if ( page ) {
+               this.stackLayout.$element.find( ':focus' ).blur();
                page.scrollElementIntoView( { 'complete': OO.ui.bind( function 
() {
                        this.ignoreFocus = true;
                        if ( this.autoFocus ) {
@@ -164,6 +165,41 @@
  */
 OO.ui.BookletLayout.prototype.isEditable = function () {
        return this.editable;
+};
+
+/**
+ * Get the outline widget.
+ *
+ * @method
+ * @param {OO.ui.PageLayout} page Page to be selected
+ * @returns {OO.ui.PageLayout|null} Closest page to another
+ */
+OO.ui.BookletLayout.prototype.getClosestPage = function ( page ) {
+       var next, prev, level,
+               pages = this.stackLayout.getItems(),
+               index = $.inArray( page, pages );
+
+       if ( index !== -1 ) {
+               next = pages[index + 1];
+               prev = pages[index - 1];
+               // Prefer adjacent pages at the same level
+               if ( this.outlined ) {
+                       level = this.outlineWidget.getItemFromData( 
page.getName() ).getLevel();
+                       if (
+                               prev &&
+                               level === this.outlineWidget.getItemFromData( 
prev.getName() ).getLevel()
+                       ) {
+                               return prev;
+                       }
+                       if (
+                               next &&
+                               level === this.outlineWidget.getItemFromData( 
next.getName() ).getLevel()
+                       ) {
+                               return next;
+                       }
+               }
+       }
+       return prev || next || null;
 };
 
 /**
@@ -220,26 +256,39 @@
  * @chainable
  */
 OO.ui.BookletLayout.prototype.addPages = function ( pages, index ) {
-       var i, len, name, page, item,
-               items = [],
-               remove = [];
+       var i, len, name, page, item, currentIndex,
+               stackLayoutPages = this.stackLayout.getItems(),
+               remove = [],
+               items = [];
 
+       // Remove pages with same names
        for ( i = 0, len = pages.length; i < len; i++ ) {
                page = pages[i];
                name = page.getName();
-               if ( name in this.pages ) {
-                       // Remove page with same name
+
+               if ( Object.prototype.hasOwnProperty.call( this.pages, name ) ) 
{
+                       // Correct the insertion index
+                       currentIndex = $.inArray( this.pages[name], 
stackLayoutPages );
+                       if ( currentIndex !== -1 && currentIndex + 1 < index ) {
+                               index--;
+                       }
                        remove.push( this.pages[name] );
                }
+       }
+       if ( remove.length ) {
+               this.removePages( remove );
+       }
+
+       // Add new pages
+       for ( i = 0, len = pages.length; i < len; i++ ) {
+               page = pages[i];
+               name = page.getName();
                this.pages[page.getName()] = page;
                if ( this.outlined ) {
                        item = new OO.ui.OutlineItemWidget( name, page, { '$': 
this.$ } );
                        page.setOutlineItem( item );
                        items.push( item );
                }
-       }
-       if ( remove.length ) {
-               this.removePages( remove );
        }
 
        if ( this.outlined && items.length ) {
diff --git a/src/styles/OO.ui.Widget.less b/src/styles/OO.ui.Widget.less
index 61ff212..734fdb4 100644
--- a/src/styles/OO.ui.Widget.less
+++ b/src/styles/OO.ui.Widget.less
@@ -134,7 +134,11 @@
                opacity: 0.5;
        }
        &.oo-ui-flaggableElement-empty .oo-ui-labeledElement-label {
-               color: #698AA0;
+               color: #777;
+       }
+
+       &.oo-ui-indicatedElement .oo-ui-labeledElement-label {
+               padding-right: 1.5em;
        }
 
        &-level-0 {
@@ -173,21 +177,27 @@
                -webkit-box-sizing: border-box;
                -moz-box-sizing: border-box;
                box-sizing: border-box;
-               height: 3em;
-               padding: 0.5em;
+               height: 2em;
+               margin: 0.5em;
+               padding: 0;
+       }
+
+       > .oo-ui-iconedElement-icon {
+               float: left;
+               width: 1.5em;
+               height: 2em;
+               margin: 0.5em 0 0.5em 0.5em;
+               background-position: right center;
+               background-repeat: no-repeat;
+               opacity: 0.2;
        }
 
        &-adders {
                float: left;
+               margin-left: 0;
 
                .oo-ui-buttonWidget {
                        float: left;
-
-                       &:first-child,
-                       &:first-child:hover {
-                               opacity: 0.25;
-                               cursor: default;
-                       }
                }
        }
        &-movers {
diff --git a/src/widgets/OO.ui.OutlineControlsWidget.js 
b/src/widgets/OO.ui.OutlineControlsWidget.js
index 39c8826..d67c0d5 100644
--- a/src/widgets/OO.ui.OutlineControlsWidget.js
+++ b/src/widgets/OO.ui.OutlineControlsWidget.js
@@ -6,26 +6,21 @@
  * @constructor
  * @param {OO.ui.OutlineWidget} outline Outline to control
  * @param {Object} [config] Configuration options
- * @cfg {Object[]} [adders] List of icons to show as addable item types, each 
an object with
- *  name, title and icon properties
  */
 OO.ui.OutlineControlsWidget = function OoUiOutlineControlsWidget( outline, 
config ) {
        // Configuration initialization
-       config = config || {};
+       config = $.extend( { 'icon': 'add-item' }, config );
 
        // Parent constructor
        OO.ui.Widget.call( this, config );
 
+       // Mixin constructors
+       OO.ui.GroupElement.call( this, this.$( '<div>' ), config );
+       OO.ui.IconedElement.call( this, this.$( '<div>' ), config );
+
        // Properties
        this.outline = outline;
-       this.adders = {};
-       this.$adders = this.$( '<div>' );
        this.$movers = this.$( '<div>' );
-       this.addButton = new OO.ui.ButtonWidget( {
-               '$': this.$,
-               'frameless': true,
-               'icon': 'add-item'
-       } );
        this.upButton = new OO.ui.ButtonWidget( {
                '$': this.$,
                'frameless': true,
@@ -38,6 +33,12 @@
                'icon': 'expand',
                'title': OO.ui.msg( 'ooui-outline-control-move-down' )
        } );
+       this.removeButton = new OO.ui.ButtonWidget( {
+               '$': this.$,
+               'frameless': true,
+               'icon': 'remove',
+               'title': OO.ui.msg( 'ooui-outline-control-remove' )
+       } );
 
        // Events
        outline.connect( this, {
@@ -47,28 +48,33 @@
        } );
        this.upButton.connect( this, { 'click': ['emit', 'move', -1] } );
        this.downButton.connect( this, { 'click': ['emit', 'move', 1] } );
+       this.removeButton.connect( this, { 'click': ['emit', 'remove'] } );
 
        // Initialization
        this.$element.addClass( 'oo-ui-outlineControlsWidget' );
-       this.$adders.addClass( 'oo-ui-outlineControlsWidget-adders' );
+       this.$group.addClass( 'oo-ui-outlineControlsWidget-adders' );
        this.$movers
                .addClass( 'oo-ui-outlineControlsWidget-movers' )
-               .append( this.upButton.$element, this.downButton.$element );
-       this.$element.append( this.$adders, this.$movers );
-       if ( config.adders && config.adders.length ) {
-               this.setupAdders( config.adders );
-       }
+               .append( this.removeButton.$element, this.upButton.$element, 
this.downButton.$element );
+       this.$element.append( this.$icon, this.$group, this.$movers );
 };
 
 /* Inheritance */
 
 OO.inheritClass( OO.ui.OutlineControlsWidget, OO.ui.Widget );
 
+OO.mixinClass( OO.ui.OutlineControlsWidget, OO.ui.GroupElement );
+OO.mixinClass( OO.ui.OutlineControlsWidget, OO.ui.IconedElement );
+
 /* Events */
 
 /**
  * @event move
  * @param {number} places Number of places to move
+ */
+
+/**
+ * @event remove
  */
 
 /* Methods */
@@ -80,12 +86,12 @@
  */
 OO.ui.OutlineControlsWidget.prototype.onOutlineChange = function () {
        var i, len, firstMovable, lastMovable,
-               movable = false,
                items = this.outline.getItems(),
-               selectedItem = this.outline.getSelectedItem();
+               selectedItem = this.outline.getSelectedItem(),
+               movable = selectedItem && selectedItem.isMovable(),
+               removable = selectedItem && selectedItem.isRemovable();
 
-       if ( selectedItem && selectedItem.isMovable() ) {
-               movable = true;
+       if ( movable ) {
                i = -1;
                len = items.length;
                while ( ++i < len ) {
@@ -104,28 +110,5 @@
        }
        this.upButton.setDisabled( !movable || selectedItem === firstMovable );
        this.downButton.setDisabled( !movable || selectedItem === lastMovable );
-};
-
-/**
- * Setup adders icons.
- *
- * @method
- * @param {Object[]} adders List of configuations for adder buttons, each 
containing a name, title
- *  and icon property
- */
-OO.ui.OutlineControlsWidget.prototype.setupAdders = function ( adders ) {
-       var i, len, addition, button,
-               $buttons = this.$( [] );
-
-       this.$adders.append( this.addButton.$element );
-       for ( i = 0, len = adders.length; i < len; i++ ) {
-               addition = adders[i];
-               button = new OO.ui.ButtonWidget( {
-                       '$': this.$, 'frameless': true, 'icon': addition.icon, 
'title': addition.title
-               } );
-               button.connect( this, { 'click': ['emit', 'add', addition.name] 
} );
-               this.adders[addition.name] = button;
-               this.$adders.append( button.$element );
-               $buttons = $buttons.add( button.$element );
-       }
+       this.removeButton.setDisabled( !removable );
 };
diff --git a/src/widgets/OO.ui.OutlineItemWidget.js 
b/src/widgets/OO.ui.OutlineItemWidget.js
index 48f9c39..3d0bd93 100644
--- a/src/widgets/OO.ui.OutlineItemWidget.js
+++ b/src/widgets/OO.ui.OutlineItemWidget.js
@@ -20,6 +20,7 @@
        // Properties
        this.level = 0;
        this.movable = !!config.movable;
+       this.removable = !!config.removable;
 
        // Initialization
        this.$element.addClass( 'oo-ui-outlineItemWidget' );
@@ -54,6 +55,17 @@
 };
 
 /**
+ * Check if item is removable.
+ *
+ * Removablilty is used by outline controls.
+ *
+ * @returns {boolean} Item is removable
+ */
+OO.ui.OutlineItemWidget.prototype.isRemovable = function () {
+       return this.removable;
+};
+
+/**
  * Get indentation level.
  *
  * @returns {number} Indentation level
@@ -76,6 +88,19 @@
 };
 
 /**
+ * Set removability.
+ *
+ * Removablilty is used by outline controls.
+ *
+ * @param {boolean} movable Item is removable
+ * @chainable
+ */
+OO.ui.OutlineItemWidget.prototype.setRemovable = function ( removable ) {
+       this.removable = !!removable;
+       return this;
+};
+
+/**
  * Set indentation level.
  *
  * @method

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

Gerrit-MessageType: merged
Gerrit-Change-Id: I35ae249b0b1597188dc6d06cdaf78ba08027be80
Gerrit-PatchSet: 4
Gerrit-Project: oojs/ui
Gerrit-Branch: master
Gerrit-Owner: Trevor Parscal <tpars...@wikimedia.org>
Gerrit-Reviewer: Catrope <roan.katt...@gmail.com>
Gerrit-Reviewer: Esanders <esand...@wikimedia.org>
Gerrit-Reviewer: Jforrester <jforres...@wikimedia.org>
Gerrit-Reviewer: Krinkle <krinklem...@gmail.com>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to