Trevor Parscal has uploaded a new change for review.

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


Change subject: Category UI improvements
......................................................................

Category UI improvements

Objectives:
* Ensure items don't get moved to the end when their sort-key is edited
* Add placeholder text and pending styling to input
* Auto-expand input to the end of the line
* Make the minimum input width smaller

Changes:

ve.ui.MWMetaDialog.js
* Added calls to fitInput on initialize
* Fixed sort key update and insert handlers to maintain item position when 
updating

ve.ui.GroupElement.js
* Added index argument to addItems, allowing items to be inserted at a specific 
location

ve.ui.PagePanelLayout.js
* Fixed CSS class name

ve.ui.StackPanelLayout.js, ve.ui.MenuWidget.js, ve.ui.SelectWidget.js
* Passed index argument through to group element

ve.ui.PanelLayout.js
* Fixed overflow direction for scrolling option

ve.ui.Inspector.css
* Moved border-box properties to text input widget class
* Set input widget within inspectors to be 100% by default

ve.ui.Layout.css
* Updated CSS class name
* Whitespace fixes

ve.ui.Widget.css
* Made text input widgets's wrapper default to 20em wide and the input inside 
it be 100%, using border-box to ensure proper sizing
* Adjusted category list item and input styles to make input appear more like a 
category item
* Whitespace fixes

ve.ui.MWCategoryInputWidget.js
* Made category input widget inherit text input widget, rather than just input 
widget

ve.ui.MWCategoryWidget.js
* Replaced group functionality by mixing in group element
* Added fitInput, which automatically make the input fill the rest of the line 
or take up the entire next line depending on how much space is left

VisualEditor.i18n.php
* Adjusted placeholder text for category input

Change-Id: I79a18a7b849804027473084a42c36133fdacad57
---
M VisualEditor.i18n.php
M modules/ve/ui/dialogs/ve.ui.MWMetaDialog.js
M modules/ve/ui/elements/ve.ui.GroupElement.js
M modules/ve/ui/layouts/panels/ve.ui.PagePanelLayout.js
M modules/ve/ui/layouts/panels/ve.ui.StackPanelLayout.js
M modules/ve/ui/layouts/ve.ui.PanelLayout.js
M modules/ve/ui/styles/ve.ui.Inspector.css
M modules/ve/ui/styles/ve.ui.Layout.css
M modules/ve/ui/styles/ve.ui.Widget.css
M modules/ve/ui/widgets/ve.ui.MWCategoryInputWidget.js
M modules/ve/ui/widgets/ve.ui.MWCategoryWidget.js
M modules/ve/ui/widgets/ve.ui.MenuWidget.js
M modules/ve/ui/widgets/ve.ui.SelectWidget.js
13 files changed, 165 insertions(+), 82 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/VisualEditor 
refs/changes/76/62176/1

diff --git a/VisualEditor.i18n.php b/VisualEditor.i18n.php
index abead98..22ac354 100644
--- a/VisualEditor.i18n.php
+++ b/VisualEditor.i18n.php
@@ -23,7 +23,7 @@
        'visualeditor-ca-editsource' => 'Edit source',
        'visualeditor-ca-ve-edit' => 'VisualEditor',
        'visualeditor-ca-ve-create' => 'VisualEditor',
-       'visualeditor-category-input-placeholder' => 'Category name',
+       'visualeditor-category-input-placeholder' => 'Add category',
        'visualeditor-category-settings-label' => 'Category settings',
        'visualeditor-dialog-meta-title' => 'Page settings',
        'visualeditor-dialog-content-title' => 'Content settings',
diff --git a/modules/ve/ui/dialogs/ve.ui.MWMetaDialog.js 
b/modules/ve/ui/dialogs/ve.ui.MWMetaDialog.js
index 886fb4d..afac2e0 100644
--- a/modules/ve/ui/dialogs/ve.ui.MWMetaDialog.js
+++ b/modules/ve/ui/dialogs/ve.ui.MWMetaDialog.js
@@ -46,7 +46,8 @@
  * @method
  */
 ve.ui.MWMetaDialog.prototype.onOpen = function () {
-       var surfaceModel = this.surface.getModel();
+       var surfaceModel = this.surface.getModel(),
+               categoryWidget = this.categoryWidget;
 
        // Force all previous transactions to be separate from this history 
state
        surfaceModel.breakpoint();
@@ -54,6 +55,11 @@
 
        // Parent method
        ve.ui.PagedDialog.prototype.onOpen.call( this );
+
+       // Update input position once visible
+       setTimeout( function () {
+               categoryWidget.fitInput();
+       } );
 };
 
 /**
@@ -175,15 +181,11 @@
  * @param {Object} item
  */
 ve.ui.MWMetaDialog.prototype.onUpdateSortKey = function ( item ) {
-       // Store the offset and index before removing
-       var offset = item.metaItem.offset,
-               index = item.metaItem.index;
+       var offset = item.metaItem.getOffset(),
+               index = item.metaItem.getIndex();
 
+       // Replace meta item with updated one
        item.metaItem.remove();
-       // It would seem as if insertItem happens before the onRemove event is 
sent to CategoryWidget,
-       // Remove the reference there so it doesn't try to get removed again 
onMetaListInsert
-       delete this.categoryWidget.categories[item.name];
-       // Insert updated meta item at same offset and index
        this.metaList.insertMeta( this.getCategoryItemForInsertion( item ), 
offset, index );
 };
 
@@ -194,9 +196,12 @@
  * @param {Object} ve.dm.MetaItem
  */
 ve.ui.MWMetaDialog.prototype.onMetaListInsert = function ( metaItem ) {
-       // Responsible for adding UI components.
+       // Responsible for adding UI components
        if ( metaItem.element.type === 'MWcategory' ) {
-               this.categoryWidget.addItems( [ 
this.getCategoryItemFromMetaListItem( metaItem ) ] );
+               this.categoryWidget.addItems(
+                       [ this.getCategoryItemFromMetaListItem( metaItem ) ],
+                       this.metaList.findItem( metaItem.getOffset(), 
metaItem.getIndex(), 'MWcategory' )
+               );
        }
 };
 
diff --git a/modules/ve/ui/elements/ve.ui.GroupElement.js 
b/modules/ve/ui/elements/ve.ui.GroupElement.js
index 9a0fed5..be95d54 100644
--- a/modules/ve/ui/elements/ve.ui.GroupElement.js
+++ b/modules/ve/ui/elements/ve.ui.GroupElement.js
@@ -38,24 +38,37 @@
  *
  * @method
  * @param {ve.ui.Element[]} items Item
+ * @param {number} [index] Index to insert items after
  * @chainable
  */
-ve.ui.GroupElement.prototype.addItems = function ( items ) {
-       var i, len, item;
+ve.ui.GroupElement.prototype.addItems = function ( items, index ) {
+       var i, len, item,
+               $items = $( [] );
 
        for ( i = 0, len = items.length; i < len; i++ ) {
                item = items[i];
 
                // Check if item exists then remove it first, effectively 
"moving" it
                if ( this.items.indexOf( item ) !== -1 ) {
-                       this.removeItems( [item] );
+                       this.removeItems( [ item ] );
                }
                // Add the item
-               this.items.push( item );
-               this.$.append( item.$ );
-               this.$items = this.$items.add( item.$ );
+               $items = $items.add( item.$ );
        }
 
+       if ( index === undefined || index < 0 || index >= this.items.length ) {
+               this.$group.append( $items );
+               this.items.push.apply( this.items, items );
+       } else if ( index === 0 ) {
+               this.$group.prepend( $items );
+               this.items.unshift.apply( this.items, items );
+       } else {
+               this.$items.eq( index ).before( $items );
+               this.items.splice.apply( this.items, [ index, 0 ].concat( items 
) );
+       }
+
+       this.$items = this.$items.add( $items );
+
        return this;
 };
 
diff --git a/modules/ve/ui/layouts/panels/ve.ui.PagePanelLayout.js 
b/modules/ve/ui/layouts/panels/ve.ui.PagePanelLayout.js
index c783b59..93c9017 100644
--- a/modules/ve/ui/layouts/panels/ve.ui.PagePanelLayout.js
+++ b/modules/ve/ui/layouts/panels/ve.ui.PagePanelLayout.js
@@ -31,7 +31,7 @@
 
        // Initialization
        this.$label.addClass( 've-ui-icon-' + config.icon + '-big' );
-       this.$.append( this.$label ).addClass( 've-ui-editorPanelLayout' );
+       this.$.append( this.$label ).addClass( 've-ui-pagedPanelLayout' );
 };
 
 /* Inheritance */
diff --git a/modules/ve/ui/layouts/panels/ve.ui.StackPanelLayout.js 
b/modules/ve/ui/layouts/panels/ve.ui.StackPanelLayout.js
index 5bf34ac..6e72cf6 100644
--- a/modules/ve/ui/layouts/panels/ve.ui.StackPanelLayout.js
+++ b/modules/ve/ui/layouts/panels/ve.ui.StackPanelLayout.js
@@ -48,9 +48,10 @@
  *
  * @method
  * @param {ve.ui.PanelLayout[]} items Items to add
+ * @param {number} [index] Index to insert items after
  * @chainable
  */
-ve.ui.StackPanelLayout.prototype.addItems = function ( items ) {
+ve.ui.StackPanelLayout.prototype.addItems = function ( items, index ) {
        var i, len;
 
        for ( i = 0, len = items.length; i < len; i++ ) {
@@ -60,7 +61,7 @@
                        items[i].$.hide();
                }
        }
-       ve.ui.GroupElement.prototype.addItems.call( this, items );
+       ve.ui.GroupElement.prototype.addItems.call( this, items, index );
 
        return this;
 };
diff --git a/modules/ve/ui/layouts/ve.ui.PanelLayout.js 
b/modules/ve/ui/layouts/ve.ui.PanelLayout.js
index bea6fef..baecce5 100644
--- a/modules/ve/ui/layouts/ve.ui.PanelLayout.js
+++ b/modules/ve/ui/layouts/ve.ui.PanelLayout.js
@@ -25,7 +25,7 @@
        // Initialization
        this.$.addClass( 've-ui-panelLayout' );
        if ( config.scroll ) {
-               this.$.css( 'overflow-x', 'auto' );
+               this.$.css( 'overflow-y', 'auto' );
        }
 };
 
diff --git a/modules/ve/ui/styles/ve.ui.Inspector.css 
b/modules/ve/ui/styles/ve.ui.Inspector.css
index 0be51ee..514f869 100644
--- a/modules/ve/ui/styles/ve.ui.Inspector.css
+++ b/modules/ve/ui/styles/ve.ui.Inspector.css
@@ -43,10 +43,7 @@
        white-space: nowrap;
 }
 
-.ve-ui-window-body .ve-ui-textInputWidget input {
-       -webkit-box-sizing: border-box;
-       -moz-box-sizing: border-box;
-       box-sizing: border-box;
+.ve-ui-window-body .ve-ui-textInputWidget {
        width: 100%;
 }
 
diff --git a/modules/ve/ui/styles/ve.ui.Layout.css 
b/modules/ve/ui/styles/ve.ui.Layout.css
index 8e647c1..a0da18f 100644
--- a/modules/ve/ui/styles/ve.ui.Layout.css
+++ b/modules/ve/ui/styles/ve.ui.Layout.css
@@ -23,15 +23,16 @@
 
 /* ve.ui.EditorPanelLayout */
 
-.ve-ui-editorPanelLayout {
+.ve-ui-pagedPanelLayout {
        padding: 1.5em;
        width: 100%;
-       -webkit-box-sizing:border-box;
-       -moz-box-sizing:border-box;
-       box-sizing:border-box;
+       -webkit-box-sizing: border-box;
+       -moz-box-sizing: border-box;
+       box-sizing: border-box;
+       overflow: hidden;
 }
 
-.ve-ui-editorPanelLayout > .ve-ui-labeledElement-label {
+.ve-ui-pagedPanelLayout > .ve-ui-labeledElement-label {
        font-size: 1.5em;
        padding-left: 1.75em;
        margin-bottom: 1em;
diff --git a/modules/ve/ui/styles/ve.ui.Widget.css 
b/modules/ve/ui/styles/ve.ui.Widget.css
index 7eeef79..1d9e17a 100644
--- a/modules/ve/ui/styles/ve.ui.Widget.css
+++ b/modules/ve/ui/styles/ve.ui.Widget.css
@@ -194,6 +194,14 @@
 
 /* ve.ui.TextInputWidget */
 
+.ve-ui-textInputWidget {
+       -webkit-box-sizing: border-box;
+       -moz-box-sizing: border-box;
+       box-sizing: border-box;
+       width: 20em;
+       position: relative;
+}
+
 .ve-ui-textInputWidget input,
 .ve-ui-textInputWidget input:focus[readonly],
 .ve-ui-widget-disabled.ve-ui-textInputWidget input:focus {
@@ -205,6 +213,10 @@
        box-shadow: 0 0 0 white, inset 0 0.1em 0.2em #ddd;
        padding: 0.5em;
        border-radius: 0.25em;
+       -webkit-box-sizing: border-box;
+       -moz-box-sizing: border-box;
+       box-sizing: border-box;
+       width: 100%;
 
        /* Animation */
        -webkit-transition: border-color 200ms, box-shadow 200ms, 
background-color 200ms;
@@ -354,7 +366,8 @@
 .ve-ui-mwCategoryListItemWidget {
        position: relative;
        float: left;
-       margin: .25em;
+       margin-right: 0.5em;
+       margin-top: 0.5em;
 }
 
 .ve-ui-mwCategoryListItemButton {
@@ -425,17 +438,17 @@
 
 .ve-ui-mwCategoryInputWidget {
        float: left;
+       width: 15em;
+       margin-top: 0.5em;
 }
 
 .ve-ui-mwCategoryInputWidget input {
-       display: inline-block;
-       font-size: 1.1em;
-       font-family: sans-serif;
-       background: none;
-       /* HACK: to match the categoryListItem height */
-       border: 1px solid #fff;
-       outline: none;
-       padding: 0.5em;
+       border-radius: 2em;
+       font-size: 1.05em;
+       margin-top: 0;
+       padding-left: 0.75em;
+       padding-right: 0.75em;
+       background-color: #fff;
 }
 
 .ve-ui-mwCategoryPopupMenu {
@@ -445,7 +458,7 @@
 }
 
 .ve-ui-mwCategoryPopupMenu .ve-ui-iconButtonWidget {
-       display:block;
+       display: block;
        float: left;
 }
 
@@ -491,4 +504,4 @@
 /* @noflip */
 .ve-ui-ltr {
        direction: ltr;
-}
\ No newline at end of file
+}
diff --git a/modules/ve/ui/widgets/ve.ui.MWCategoryInputWidget.js 
b/modules/ve/ui/widgets/ve.ui.MWCategoryInputWidget.js
index aa0e372..f3a6dea 100644
--- a/modules/ve/ui/widgets/ve.ui.MWCategoryInputWidget.js
+++ b/modules/ve/ui/widgets/ve.ui.MWCategoryInputWidget.js
@@ -11,7 +11,7 @@
  * Creates an ve.ui.MWCategoryInputWidget object.
  *
  * @class
- * @extends ve.ui.InputWidget
+ * @extends ve.ui.TextInputWidget
  * @mixins ve.ui.PendingInputWidget
  * @mixins ve.ui.LookupInputWidget
  *
@@ -25,7 +25,7 @@
        }, config );
 
        // Parent constructor
-       ve.ui.InputWidget.call( this, config );
+       ve.ui.TextInputWidget.call( this, config );
 
        // Mixin constructors
        ve.ui.PendingInputWidget.call( this );
@@ -43,14 +43,10 @@
 
 /* Inheritance */
 
-ve.inheritClass( ve.ui.MWCategoryInputWidget, ve.ui.InputWidget );
+ve.inheritClass( ve.ui.MWCategoryInputWidget, ve.ui.TextInputWidget );
 
 ve.mixinClass( ve.ui.MWCategoryInputWidget, ve.ui.PendingInputWidget );
 ve.mixinClass( ve.ui.MWCategoryInputWidget, ve.ui.LookupInputWidget );
-
-/* Static Properties */
-
-ve.ui.MWCategoryInputWidget.static.inputType = 'text';
 
 /* Methods */
 
diff --git a/modules/ve/ui/widgets/ve.ui.MWCategoryWidget.js 
b/modules/ve/ui/widgets/ve.ui.MWCategoryWidget.js
index 251ce83..3edfd03 100644
--- a/modules/ve/ui/widgets/ve.ui.MWCategoryWidget.js
+++ b/modules/ve/ui/widgets/ve.ui.MWCategoryWidget.js
@@ -11,6 +11,7 @@
  * @class
  * @abstract
  * @extends ve.ui.Widget
+ * @mixin ve.ui.GroupElement
  *
  * @constructor
  * @param {Object} [config] Config options
@@ -22,21 +23,23 @@
        // Parent constructor
        ve.ui.Widget.call( this, config );
 
+       // Mixin constructors
+       ve.ui.GroupElement.call( this, this.$$( '<div>' ), config );
+
        // Properties
        this.categories = {};
-       this.$categories = this.$$( '<div>' );
        this.popupState = false;
        this.savedPopupState = false;
        this.popup = new ve.ui.MWCategoryPopupWidget( {
                '$$': this.$$, 'align': 'right', '$overlay': config.$overlay
        } );
-       this.categoryInput = new ve.ui.MWCategoryInputWidget( this, {
+       this.input = new ve.ui.MWCategoryInputWidget( this, {
                '$$': this.$$, '$overlay': config.$overlay, '$container': this.$
        } );
 
        // Events
-       this.categoryInput.$input.on( 'keydown', ve.bind( 
this.onLookupInputKeyDown, this ) );
-       this.categoryInput.lookupMenu.connect( this, { 'select': 
'onLookupMenuItemSelect' } );
+       this.input.$input.on( 'keydown', ve.bind( this.onLookupInputKeyDown, 
this ) );
+       this.input.lookupMenu.connect( this, { 'select': 
'onLookupMenuItemSelect' } );
        this.popup.connect( this, {
                'removeCategory': 'onRemoveCategory',
                'updateSortkey': 'onUpdateSortkey',
@@ -46,8 +49,8 @@
        // Initialization
        this.$.addClass( 've-ui-mwCategoryListWidget' )
                .append(
-                       this.$categories,
-                       this.categoryInput.$,
+                       this.$group,
+                       this.input.$,
                        this.$$( '<div>' ).css( 'clear', 'both' )
                );
 };
@@ -77,12 +80,12 @@
  * @param {jQuery.Event} e Input key down event
  */
 ve.ui.MWCategoryWidget.prototype.onLookupInputKeyDown = function ( e ) {
-       if ( this.categoryInput.getValue() !== '' && e.which === 13 ) {
+       if ( this.input.getValue() !== '' && e.which === 13 ) {
                this.emit(
                        'newCategory',
-                       this.categoryInput.getCategoryItemFromValue( 
this.categoryInput.getValue() )
+                       this.input.getCategoryItemFromValue( 
this.input.getValue() )
                );
-               this.categoryInput.setValue( '' );
+               this.input.setValue( '' );
        }
 };
 
@@ -94,8 +97,8 @@
  */
 ve.ui.MWCategoryWidget.prototype.onLookupMenuItemSelect = function ( item ) {
        if ( item && item.getData() !== '' ) {
-               this.emit( 'newCategory',  
this.categoryInput.getCategoryItemFromValue( item.getData() ) );
-               this.categoryInput.setValue( '' );
+               this.emit( 'newCategory',  this.input.getCategoryItemFromValue( 
item.getData() ) );
+               this.input.setValue( '' );
        }
 };
 
@@ -161,37 +164,53 @@
  * Adds category items.
  *
  * @method
- * @param {Object[]} items [description]
+ * @param {Object[]} items Items to add
+ * @param {number} [index] Index to insert items after
  * @chainable
  */
-ve.ui.MWCategoryWidget.prototype.addItems = function ( items ) {
-       var i, len, item, categoryGroupItem,
-               existingCategoryGroupItem = null;
+ve.ui.MWCategoryWidget.prototype.addItems = function ( items, index ) {
+       var i, len, item, categoryItem,
+               categoryItems = [],
+               existingCategoryItem = null;
 
        for ( i = 0, len = items.length; i < len; i++ ) {
                item = items[i];
 
-               // Filter out categories derived from aliens.
-               // TODO: Remove the block below once aliens no longer add items 
to metalist.
-               if( 'html/0/about' in item.metaItem.element.attributes ) {
-                       return this;
+               // HACK: Filter out categories derived from aliens
+               // TODO: Remove this bit once aliens no longer add items to 
metalist
+               if ( 'html/0/about' in item.metaItem.element.attributes ) {
+                       continue;
                }
-               categoryGroupItem = new ve.ui.MWCategoryItemWidget( { '$$': 
this.$$, 'item': item } );
-               // Bind category item events.
-               categoryGroupItem.connect( this, {
+
+               // Create a widget using the item data
+               categoryItem = new ve.ui.MWCategoryItemWidget( { '$$': this.$$, 
'item': item } );
+               categoryItem.connect( this, {
                        'savePopupState': 'onSavePopupState',
                        'togglePopupMenu': 'onTogglePoupupMenu'
                } );
+               // Auto-remove existing items by value
                if ( item.value in this.categories ) {
-                       existingCategoryGroupItem = this.categories[item.value];
-                       this.categories[item.value].metaItem.remove();
+                       // Save reference to item
+                       existingCategoryItem = this.categories[item.value];
+                       // Removal in model will trigger #removeItems in widget
+                       existingCategoryItem.metaItem.remove();
+                       // Adjust index to compensate for removal
+                       index = Math.max( index - 1, 0 );
                }
-               this.categories[item.value] = categoryGroupItem;
-               if ( existingCategoryGroupItem ) {
-                       categoryGroupItem.sortKey = 
existingCategoryGroupItem.sortKey;
+               // Index item by value
+               this.categories[item.value] = categoryItem;
+               // Copy sortKey from old item when "moving"
+               if ( existingCategoryItem ) {
+                       categoryItem.sortKey = existingCategoryItem.sortKey;
                }
-               this.$categories.append( categoryGroupItem.$ );
+
+               categoryItems.push( categoryItem );
        }
+
+       ve.ui.GroupElement.prototype.addItems.call( this, categoryItems, index 
);
+
+       this.fitInput();
+
        return this;
 };
 
@@ -202,10 +221,46 @@
  * @param {string[]} names Names of categories to remove
  */
 ve.ui.MWCategoryWidget.prototype.removeItems = function ( names ) {
-       var i, len;
+       var i, len, categoryItem,
+               items = [];
 
        for ( i = 0, len = names.length; i < len; i++ ) {
-               this.categories[names[i]].$.remove();
+               categoryItem = this.categories[names[i]];
+               categoryItem.disconnect( this );
+               items.push( categoryItem );
                delete this.categories[names[i]];
        }
+
+       ve.ui.GroupElement.prototype.removeItems.call( this, items );
+
+       this.fitInput();
+};
+
+/**
+ * Auto-fit the input.
+ *
+ * @method
+ */
+ve.ui.MWCategoryWidget.prototype.fitInput = function () {
+       var gap, min, margin, $lastItem,
+               $input = this.input.$;
+
+       if ( !$input.is( ':visible') ) {
+               return;
+       }
+
+       $input.css( { 'width': 'inherit' } );
+       min = $input.outerWidth();
+
+       $input.css( { 'width': '100%' } );
+       $lastItem = this.$.find( '.ve-ui-mwCategoryListItemWidget:last' );
+       if ( $lastItem.length ) {
+               margin = $input.offset().left - this.$.offset().left;
+               // Try to fit to the right of the last item
+               gap = ( $input.offset().left + $input.outerWidth() ) -
+                               ( $lastItem.offset().left + 
$lastItem.outerWidth() );
+               if ( gap >= min ) {
+                       $input.css( { 'width': Math.round( gap - ( ( margin ) * 
2 ) ) + 'px' } );
+               }
+       }
 };
diff --git a/modules/ve/ui/widgets/ve.ui.MenuWidget.js 
b/modules/ve/ui/widgets/ve.ui.MenuWidget.js
index 25332e8..e33c213 100644
--- a/modules/ve/ui/widgets/ve.ui.MenuWidget.js
+++ b/modules/ve/ui/widgets/ve.ui.MenuWidget.js
@@ -132,12 +132,13 @@
  *
  * @method
  * @param {ve.ui.MenuItemWidget[]} items Items to add
+ * @param {number} [index] Index to insert items after
  * @chainable
  */
-ve.ui.MenuWidget.prototype.addItems = function ( items ) {
+ve.ui.MenuWidget.prototype.addItems = function ( items, index ) {
        var i, len, item;
 
-       ve.ui.SelectWidget.prototype.addItems.call( this, items );
+       ve.ui.SelectWidget.prototype.addItems.call( this, items, index );
 
        for ( i = 0, len = items.length; i < len; i++ ) {
                item = items[i];
diff --git a/modules/ve/ui/widgets/ve.ui.SelectWidget.js 
b/modules/ve/ui/widgets/ve.ui.SelectWidget.js
index 218cbf1..a41d949 100644
--- a/modules/ve/ui/widgets/ve.ui.SelectWidget.js
+++ b/modules/ve/ui/widgets/ve.ui.SelectWidget.js
@@ -328,9 +328,10 @@
  *
  * @method
  * @param {ve.ui.OptionWidget[]} items Items to add
+ * @param {number} [index] Index to insert items after
  * @chainable
  */
-ve.ui.SelectWidget.prototype.addItems = function ( items ) {
+ve.ui.SelectWidget.prototype.addItems = function ( items, index ) {
        var i, len, item, hash;
 
        for ( i = 0, len = items.length; i < len; i++ ) {
@@ -344,7 +345,7 @@
                        this.hashes[hash] = item;
                }
        }
-       ve.ui.GroupElement.prototype.addItems.call( this, items );
+       ve.ui.GroupElement.prototype.addItems.call( this, items, index );
 
        return this;
 };

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I79a18a7b849804027473084a42c36133fdacad57
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/VisualEditor
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