mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/VisualEditor
synced 2024-11-24 22:35:41 +00:00
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
This commit is contained in:
parent
2cbc5045b6
commit
e888d7b985
|
@ -23,7 +23,7 @@ $messages['en'] = array(
|
||||||
'visualeditor-ca-editsource' => 'Edit source',
|
'visualeditor-ca-editsource' => 'Edit source',
|
||||||
'visualeditor-ca-ve-edit' => 'VisualEditor',
|
'visualeditor-ca-ve-edit' => 'VisualEditor',
|
||||||
'visualeditor-ca-ve-create' => '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-category-settings-label' => 'Category settings',
|
||||||
'visualeditor-dialog-meta-title' => 'Page settings',
|
'visualeditor-dialog-meta-title' => 'Page settings',
|
||||||
'visualeditor-dialog-content-title' => 'Content settings',
|
'visualeditor-dialog-content-title' => 'Content settings',
|
||||||
|
|
|
@ -46,7 +46,8 @@ ve.ui.MWMetaDialog.static.icon = 'settings';
|
||||||
* @method
|
* @method
|
||||||
*/
|
*/
|
||||||
ve.ui.MWMetaDialog.prototype.onOpen = function () {
|
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
|
// Force all previous transactions to be separate from this history state
|
||||||
surfaceModel.breakpoint();
|
surfaceModel.breakpoint();
|
||||||
|
@ -54,6 +55,11 @@ ve.ui.MWMetaDialog.prototype.onOpen = function () {
|
||||||
|
|
||||||
// Parent method
|
// Parent method
|
||||||
ve.ui.PagedDialog.prototype.onOpen.call( this );
|
ve.ui.PagedDialog.prototype.onOpen.call( this );
|
||||||
|
|
||||||
|
// Update input position once visible
|
||||||
|
setTimeout( function () {
|
||||||
|
categoryWidget.fitInput();
|
||||||
|
} );
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -175,15 +181,11 @@ ve.ui.MWMetaDialog.prototype.onNewCategory = function ( item ) {
|
||||||
* @param {Object} item
|
* @param {Object} item
|
||||||
*/
|
*/
|
||||||
ve.ui.MWMetaDialog.prototype.onUpdateSortKey = function ( item ) {
|
ve.ui.MWMetaDialog.prototype.onUpdateSortKey = function ( item ) {
|
||||||
// Store the offset and index before removing
|
var offset = item.metaItem.getOffset(),
|
||||||
var offset = item.metaItem.offset,
|
index = item.metaItem.getIndex();
|
||||||
index = item.metaItem.index;
|
|
||||||
|
|
||||||
|
// Replace meta item with updated one
|
||||||
item.metaItem.remove();
|
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 );
|
this.metaList.insertMeta( this.getCategoryItemForInsertion( item ), offset, index );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -194,9 +196,12 @@ ve.ui.MWMetaDialog.prototype.onUpdateSortKey = function ( item ) {
|
||||||
* @param {Object} ve.dm.MetaItem
|
* @param {Object} ve.dm.MetaItem
|
||||||
*/
|
*/
|
||||||
ve.ui.MWMetaDialog.prototype.onMetaListInsert = function ( metaItem ) {
|
ve.ui.MWMetaDialog.prototype.onMetaListInsert = function ( metaItem ) {
|
||||||
// Responsible for adding UI components.
|
// Responsible for adding UI components
|
||||||
if ( metaItem.element.type === 'MWcategory' ) {
|
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' )
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -38,24 +38,37 @@ ve.ui.GroupElement.prototype.getItems = function () {
|
||||||
*
|
*
|
||||||
* @method
|
* @method
|
||||||
* @param {ve.ui.Element[]} items Item
|
* @param {ve.ui.Element[]} items Item
|
||||||
|
* @param {number} [index] Index to insert items after
|
||||||
* @chainable
|
* @chainable
|
||||||
*/
|
*/
|
||||||
ve.ui.GroupElement.prototype.addItems = function ( items ) {
|
ve.ui.GroupElement.prototype.addItems = function ( items, index ) {
|
||||||
var i, len, item;
|
var i, len, item,
|
||||||
|
$items = $( [] );
|
||||||
|
|
||||||
for ( i = 0, len = items.length; i < len; i++ ) {
|
for ( i = 0, len = items.length; i < len; i++ ) {
|
||||||
item = items[i];
|
item = items[i];
|
||||||
|
|
||||||
// Check if item exists then remove it first, effectively "moving" it
|
// Check if item exists then remove it first, effectively "moving" it
|
||||||
if ( this.items.indexOf( item ) !== -1 ) {
|
if ( this.items.indexOf( item ) !== -1 ) {
|
||||||
this.removeItems( [item] );
|
this.removeItems( [ item ] );
|
||||||
}
|
}
|
||||||
// Add the item
|
// Add the item
|
||||||
this.items.push( item );
|
$items = $items.add( item.$ );
|
||||||
this.$.append( item.$ );
|
|
||||||
this.$items = this.$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;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ ve.ui.PagePanelLayout = function VeUiPagePanelLayout( config ) {
|
||||||
|
|
||||||
// Initialization
|
// Initialization
|
||||||
this.$label.addClass( 've-ui-icon-' + config.icon + '-big' );
|
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 */
|
/* Inheritance */
|
||||||
|
|
|
@ -48,9 +48,10 @@ ve.mixinClass( ve.ui.StackPanelLayout, ve.ui.GroupElement );
|
||||||
*
|
*
|
||||||
* @method
|
* @method
|
||||||
* @param {ve.ui.PanelLayout[]} items Items to add
|
* @param {ve.ui.PanelLayout[]} items Items to add
|
||||||
|
* @param {number} [index] Index to insert items after
|
||||||
* @chainable
|
* @chainable
|
||||||
*/
|
*/
|
||||||
ve.ui.StackPanelLayout.prototype.addItems = function ( items ) {
|
ve.ui.StackPanelLayout.prototype.addItems = function ( items, index ) {
|
||||||
var i, len;
|
var i, len;
|
||||||
|
|
||||||
for ( i = 0, len = items.length; i < len; i++ ) {
|
for ( i = 0, len = items.length; i < len; i++ ) {
|
||||||
|
@ -60,7 +61,7 @@ ve.ui.StackPanelLayout.prototype.addItems = function ( items ) {
|
||||||
items[i].$.hide();
|
items[i].$.hide();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ve.ui.GroupElement.prototype.addItems.call( this, items );
|
ve.ui.GroupElement.prototype.addItems.call( this, items, index );
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
|
@ -25,7 +25,7 @@ ve.ui.PanelLayout = function VeUiPanelLayout( config ) {
|
||||||
// Initialization
|
// Initialization
|
||||||
this.$.addClass( 've-ui-panelLayout' );
|
this.$.addClass( 've-ui-panelLayout' );
|
||||||
if ( config.scroll ) {
|
if ( config.scroll ) {
|
||||||
this.$.css( 'overflow-x', 'auto' );
|
this.$.css( 'overflow-y', 'auto' );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -43,10 +43,7 @@
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ve-ui-window-body .ve-ui-textInputWidget input {
|
.ve-ui-window-body .ve-ui-textInputWidget {
|
||||||
-webkit-box-sizing: border-box;
|
|
||||||
-moz-box-sizing: border-box;
|
|
||||||
box-sizing: border-box;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,15 +23,16 @@
|
||||||
|
|
||||||
/* ve.ui.EditorPanelLayout */
|
/* ve.ui.EditorPanelLayout */
|
||||||
|
|
||||||
.ve-ui-editorPanelLayout {
|
.ve-ui-pagedPanelLayout {
|
||||||
padding: 1.5em;
|
padding: 1.5em;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
-webkit-box-sizing:border-box;
|
-webkit-box-sizing: border-box;
|
||||||
-moz-box-sizing:border-box;
|
-moz-box-sizing: border-box;
|
||||||
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;
|
font-size: 1.5em;
|
||||||
padding-left: 1.75em;
|
padding-left: 1.75em;
|
||||||
margin-bottom: 1em;
|
margin-bottom: 1em;
|
||||||
|
|
|
@ -194,6 +194,14 @@
|
||||||
|
|
||||||
/* ve.ui.TextInputWidget */
|
/* 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,
|
||||||
.ve-ui-textInputWidget input:focus[readonly],
|
.ve-ui-textInputWidget input:focus[readonly],
|
||||||
.ve-ui-widget-disabled.ve-ui-textInputWidget input:focus {
|
.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;
|
box-shadow: 0 0 0 white, inset 0 0.1em 0.2em #ddd;
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
border-radius: 0.25em;
|
border-radius: 0.25em;
|
||||||
|
-webkit-box-sizing: border-box;
|
||||||
|
-moz-box-sizing: border-box;
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
/* Animation */
|
/* Animation */
|
||||||
-webkit-transition: border-color 200ms, box-shadow 200ms, background-color 200ms;
|
-webkit-transition: border-color 200ms, box-shadow 200ms, background-color 200ms;
|
||||||
|
@ -354,7 +366,8 @@
|
||||||
.ve-ui-mwCategoryListItemWidget {
|
.ve-ui-mwCategoryListItemWidget {
|
||||||
position: relative;
|
position: relative;
|
||||||
float: left;
|
float: left;
|
||||||
margin: .25em;
|
margin-right: 0.5em;
|
||||||
|
margin-top: 0.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ve-ui-mwCategoryListItemButton {
|
.ve-ui-mwCategoryListItemButton {
|
||||||
|
@ -425,17 +438,17 @@
|
||||||
|
|
||||||
.ve-ui-mwCategoryInputWidget {
|
.ve-ui-mwCategoryInputWidget {
|
||||||
float: left;
|
float: left;
|
||||||
|
width: 15em;
|
||||||
|
margin-top: 0.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ve-ui-mwCategoryInputWidget input {
|
.ve-ui-mwCategoryInputWidget input {
|
||||||
display: inline-block;
|
border-radius: 2em;
|
||||||
font-size: 1.1em;
|
font-size: 1.05em;
|
||||||
font-family: sans-serif;
|
margin-top: 0;
|
||||||
background: none;
|
padding-left: 0.75em;
|
||||||
/* HACK: to match the categoryListItem height */
|
padding-right: 0.75em;
|
||||||
border: 1px solid #fff;
|
background-color: #fff;
|
||||||
outline: none;
|
|
||||||
padding: 0.5em;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.ve-ui-mwCategoryPopupMenu {
|
.ve-ui-mwCategoryPopupMenu {
|
||||||
|
@ -445,7 +458,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.ve-ui-mwCategoryPopupMenu .ve-ui-iconButtonWidget {
|
.ve-ui-mwCategoryPopupMenu .ve-ui-iconButtonWidget {
|
||||||
display:block;
|
display: block;
|
||||||
float: left;
|
float: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -491,4 +504,4 @@
|
||||||
/* @noflip */
|
/* @noflip */
|
||||||
.ve-ui-ltr {
|
.ve-ui-ltr {
|
||||||
direction: ltr;
|
direction: ltr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
* Creates an ve.ui.MWCategoryInputWidget object.
|
* Creates an ve.ui.MWCategoryInputWidget object.
|
||||||
*
|
*
|
||||||
* @class
|
* @class
|
||||||
* @extends ve.ui.InputWidget
|
* @extends ve.ui.TextInputWidget
|
||||||
* @mixins ve.ui.PendingInputWidget
|
* @mixins ve.ui.PendingInputWidget
|
||||||
* @mixins ve.ui.LookupInputWidget
|
* @mixins ve.ui.LookupInputWidget
|
||||||
*
|
*
|
||||||
|
@ -25,7 +25,7 @@ ve.ui.MWCategoryInputWidget = function VeUiMWCategoryInputWidget( categoryWidget
|
||||||
}, config );
|
}, config );
|
||||||
|
|
||||||
// Parent constructor
|
// Parent constructor
|
||||||
ve.ui.InputWidget.call( this, config );
|
ve.ui.TextInputWidget.call( this, config );
|
||||||
|
|
||||||
// Mixin constructors
|
// Mixin constructors
|
||||||
ve.ui.PendingInputWidget.call( this );
|
ve.ui.PendingInputWidget.call( this );
|
||||||
|
@ -43,15 +43,11 @@ ve.ui.MWCategoryInputWidget = function VeUiMWCategoryInputWidget( categoryWidget
|
||||||
|
|
||||||
/* Inheritance */
|
/* 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.PendingInputWidget );
|
||||||
ve.mixinClass( ve.ui.MWCategoryInputWidget, ve.ui.LookupInputWidget );
|
ve.mixinClass( ve.ui.MWCategoryInputWidget, ve.ui.LookupInputWidget );
|
||||||
|
|
||||||
/* Static Properties */
|
|
||||||
|
|
||||||
ve.ui.MWCategoryInputWidget.static.inputType = 'text';
|
|
||||||
|
|
||||||
/* Methods */
|
/* Methods */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
* @class
|
* @class
|
||||||
* @abstract
|
* @abstract
|
||||||
* @extends ve.ui.Widget
|
* @extends ve.ui.Widget
|
||||||
|
* @mixin ve.ui.GroupElement
|
||||||
*
|
*
|
||||||
* @constructor
|
* @constructor
|
||||||
* @param {Object} [config] Config options
|
* @param {Object} [config] Config options
|
||||||
|
@ -22,21 +23,23 @@ ve.ui.MWCategoryWidget = function VeUiMWCategoryWidget( config ) {
|
||||||
// Parent constructor
|
// Parent constructor
|
||||||
ve.ui.Widget.call( this, config );
|
ve.ui.Widget.call( this, config );
|
||||||
|
|
||||||
|
// Mixin constructors
|
||||||
|
ve.ui.GroupElement.call( this, this.$$( '<div>' ), config );
|
||||||
|
|
||||||
// Properties
|
// Properties
|
||||||
this.categories = {};
|
this.categories = {};
|
||||||
this.$categories = this.$$( '<div>' );
|
|
||||||
this.popupState = false;
|
this.popupState = false;
|
||||||
this.savedPopupState = false;
|
this.savedPopupState = false;
|
||||||
this.popup = new ve.ui.MWCategoryPopupWidget( {
|
this.popup = new ve.ui.MWCategoryPopupWidget( {
|
||||||
'$$': this.$$, 'align': 'right', '$overlay': config.$overlay
|
'$$': 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.$
|
'$$': this.$$, '$overlay': config.$overlay, '$container': this.$
|
||||||
} );
|
} );
|
||||||
|
|
||||||
// Events
|
// Events
|
||||||
this.categoryInput.$input.on( 'keydown', ve.bind( this.onLookupInputKeyDown, this ) );
|
this.input.$input.on( 'keydown', ve.bind( this.onLookupInputKeyDown, this ) );
|
||||||
this.categoryInput.lookupMenu.connect( this, { 'select': 'onLookupMenuItemSelect' } );
|
this.input.lookupMenu.connect( this, { 'select': 'onLookupMenuItemSelect' } );
|
||||||
this.popup.connect( this, {
|
this.popup.connect( this, {
|
||||||
'removeCategory': 'onRemoveCategory',
|
'removeCategory': 'onRemoveCategory',
|
||||||
'updateSortkey': 'onUpdateSortkey',
|
'updateSortkey': 'onUpdateSortkey',
|
||||||
|
@ -46,8 +49,8 @@ ve.ui.MWCategoryWidget = function VeUiMWCategoryWidget( config ) {
|
||||||
// Initialization
|
// Initialization
|
||||||
this.$.addClass( 've-ui-mwCategoryListWidget' )
|
this.$.addClass( 've-ui-mwCategoryListWidget' )
|
||||||
.append(
|
.append(
|
||||||
this.$categories,
|
this.$group,
|
||||||
this.categoryInput.$,
|
this.input.$,
|
||||||
this.$$( '<div>' ).css( 'clear', 'both' )
|
this.$$( '<div>' ).css( 'clear', 'both' )
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -77,12 +80,12 @@ ve.inheritClass( ve.ui.MWCategoryWidget, ve.ui.Widget );
|
||||||
* @param {jQuery.Event} e Input key down event
|
* @param {jQuery.Event} e Input key down event
|
||||||
*/
|
*/
|
||||||
ve.ui.MWCategoryWidget.prototype.onLookupInputKeyDown = function ( e ) {
|
ve.ui.MWCategoryWidget.prototype.onLookupInputKeyDown = function ( e ) {
|
||||||
if ( this.categoryInput.getValue() !== '' && e.which === 13 ) {
|
if ( this.input.getValue() !== '' && e.which === 13 ) {
|
||||||
this.emit(
|
this.emit(
|
||||||
'newCategory',
|
'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.onLookupInputKeyDown = function ( e ) {
|
||||||
*/
|
*/
|
||||||
ve.ui.MWCategoryWidget.prototype.onLookupMenuItemSelect = function ( item ) {
|
ve.ui.MWCategoryWidget.prototype.onLookupMenuItemSelect = function ( item ) {
|
||||||
if ( item && item.getData() !== '' ) {
|
if ( item && item.getData() !== '' ) {
|
||||||
this.emit( 'newCategory', this.categoryInput.getCategoryItemFromValue( item.getData() ) );
|
this.emit( 'newCategory', this.input.getCategoryItemFromValue( item.getData() ) );
|
||||||
this.categoryInput.setValue( '' );
|
this.input.setValue( '' );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -161,37 +164,53 @@ ve.ui.MWCategoryWidget.prototype.getCategories = function () {
|
||||||
* Adds category items.
|
* Adds category items.
|
||||||
*
|
*
|
||||||
* @method
|
* @method
|
||||||
* @param {Object[]} items [description]
|
* @param {Object[]} items Items to add
|
||||||
|
* @param {number} [index] Index to insert items after
|
||||||
* @chainable
|
* @chainable
|
||||||
*/
|
*/
|
||||||
ve.ui.MWCategoryWidget.prototype.addItems = function ( items ) {
|
ve.ui.MWCategoryWidget.prototype.addItems = function ( items, index ) {
|
||||||
var i, len, item, categoryGroupItem,
|
var i, len, item, categoryItem,
|
||||||
existingCategoryGroupItem = null;
|
categoryItems = [],
|
||||||
|
existingCategoryItem = null;
|
||||||
|
|
||||||
for ( i = 0, len = items.length; i < len; i++ ) {
|
for ( i = 0, len = items.length; i < len; i++ ) {
|
||||||
item = items[i];
|
item = items[i];
|
||||||
|
|
||||||
// Filter out categories derived from aliens.
|
// HACK: Filter out categories derived from aliens
|
||||||
// TODO: Remove the block below once aliens no longer add items to metalist.
|
// TODO: Remove this bit once aliens no longer add items to metalist
|
||||||
if( 'html/0/about' in item.metaItem.element.attributes ) {
|
if ( 'html/0/about' in item.metaItem.element.attributes ) {
|
||||||
return this;
|
continue;
|
||||||
}
|
}
|
||||||
categoryGroupItem = new ve.ui.MWCategoryItemWidget( { '$$': this.$$, 'item': item } );
|
|
||||||
// Bind category item events.
|
// Create a widget using the item data
|
||||||
categoryGroupItem.connect( this, {
|
categoryItem = new ve.ui.MWCategoryItemWidget( { '$$': this.$$, 'item': item } );
|
||||||
|
categoryItem.connect( this, {
|
||||||
'savePopupState': 'onSavePopupState',
|
'savePopupState': 'onSavePopupState',
|
||||||
'togglePopupMenu': 'onTogglePoupupMenu'
|
'togglePopupMenu': 'onTogglePoupupMenu'
|
||||||
} );
|
} );
|
||||||
|
// Auto-remove existing items by value
|
||||||
if ( item.value in this.categories ) {
|
if ( item.value in this.categories ) {
|
||||||
existingCategoryGroupItem = this.categories[item.value];
|
// Save reference to item
|
||||||
this.categories[item.value].metaItem.remove();
|
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;
|
// Index item by value
|
||||||
if ( existingCategoryGroupItem ) {
|
this.categories[item.value] = categoryItem;
|
||||||
categoryGroupItem.sortKey = existingCategoryGroupItem.sortKey;
|
// 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;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -202,10 +221,46 @@ ve.ui.MWCategoryWidget.prototype.addItems = function ( items ) {
|
||||||
* @param {string[]} names Names of categories to remove
|
* @param {string[]} names Names of categories to remove
|
||||||
*/
|
*/
|
||||||
ve.ui.MWCategoryWidget.prototype.removeItems = function ( names ) {
|
ve.ui.MWCategoryWidget.prototype.removeItems = function ( names ) {
|
||||||
var i, len;
|
var i, len, categoryItem,
|
||||||
|
items = [];
|
||||||
|
|
||||||
for ( i = 0, len = names.length; i < len; i++ ) {
|
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]];
|
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' } );
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -132,12 +132,13 @@ ve.ui.MenuWidget.prototype.selectItem = function ( item, silent ) {
|
||||||
*
|
*
|
||||||
* @method
|
* @method
|
||||||
* @param {ve.ui.MenuItemWidget[]} items Items to add
|
* @param {ve.ui.MenuItemWidget[]} items Items to add
|
||||||
|
* @param {number} [index] Index to insert items after
|
||||||
* @chainable
|
* @chainable
|
||||||
*/
|
*/
|
||||||
ve.ui.MenuWidget.prototype.addItems = function ( items ) {
|
ve.ui.MenuWidget.prototype.addItems = function ( items, index ) {
|
||||||
var i, len, item;
|
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++ ) {
|
for ( i = 0, len = items.length; i < len; i++ ) {
|
||||||
item = items[i];
|
item = items[i];
|
||||||
|
|
|
@ -328,9 +328,10 @@ ve.ui.SelectWidget.prototype.getClosestSelectableItem = function ( index ) {
|
||||||
*
|
*
|
||||||
* @method
|
* @method
|
||||||
* @param {ve.ui.OptionWidget[]} items Items to add
|
* @param {ve.ui.OptionWidget[]} items Items to add
|
||||||
|
* @param {number} [index] Index to insert items after
|
||||||
* @chainable
|
* @chainable
|
||||||
*/
|
*/
|
||||||
ve.ui.SelectWidget.prototype.addItems = function ( items ) {
|
ve.ui.SelectWidget.prototype.addItems = function ( items, index ) {
|
||||||
var i, len, item, hash;
|
var i, len, item, hash;
|
||||||
|
|
||||||
for ( i = 0, len = items.length; i < len; i++ ) {
|
for ( i = 0, len = items.length; i < len; i++ ) {
|
||||||
|
@ -344,7 +345,7 @@ ve.ui.SelectWidget.prototype.addItems = function ( items ) {
|
||||||
this.hashes[hash] = item;
|
this.hashes[hash] = item;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ve.ui.GroupElement.prototype.addItems.call( this, items );
|
ve.ui.GroupElement.prototype.addItems.call( this, items, index );
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue