mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/VisualEditor
synced 2024-09-25 03:08:42 +00:00
Merge "Outline controls"
This commit is contained in:
commit
86406d5e48
|
@ -99,6 +99,8 @@ $messages['en'] = array(
|
|||
'visualeditor-notification-created' => '$1 has been created.',
|
||||
'visualeditor-notification-restored' => '$1 has been restored.',
|
||||
'visualeditor-notification-saved' => 'Your changes to $1 have been saved.',
|
||||
'visualeditor-outline-control-move-up' => 'Move item up',
|
||||
'visualeditor-outline-control-move-down' => 'Move item down',
|
||||
'visualeditor-preference-enable' => 'Enable VisualEditor (only in the [[{{MediaWiki:Visualeditor-mainnamespacepagelink}}|main]] and [[{{MediaWiki:Visualeditor-usernamespacepagelink}}|user]] namespaces)',
|
||||
'visualeditor-preference-nosectionedit' => 'Use the wikitext editor for editing sections while VisualEditor is in beta',
|
||||
'visualeditor-savedialog-label-create' => 'Create page',
|
||||
|
@ -279,6 +281,8 @@ Parameters:
|
|||
'visualeditor-notification-restored' => 'Shown after a user restores a page to a previous revision. Parameters:
|
||||
* $1 is a page name.',
|
||||
'visualeditor-notification-saved' => 'Shown after a user saves a page, $1 is a page name.',
|
||||
'visualeditor-outline-control-move-up' => 'Tool tip for a button that moves items in a list up one place',
|
||||
'visualeditor-outline-control-move-down' => 'Tool tip for a button that moves items in a list down one place',
|
||||
'visualeditor-preference-enable' => 'Label for the user preference to enable the VisualEditor.
|
||||
Links are in {{msg-mw|Visualeditor-mainnamespacepagelink}} and {{msg-mw|visualeditor-usernamespacepagelink}}.',
|
||||
'visualeditor-preference-nosectionedit' => 'Label for the user preference to make section edit links go to the old editor instead of VisualEditor.',
|
||||
|
|
|
@ -391,6 +391,7 @@ $wgResourceModules += array(
|
|||
've/ui/widgets/ve.ui.TextInputWidget.js',
|
||||
've/ui/widgets/ve.ui.OutlineItemWidget.js',
|
||||
've/ui/widgets/ve.ui.OutlineWidget.js',
|
||||
've/ui/widgets/ve.ui.OutlineControlsWidget.js',
|
||||
've/ui/widgets/ve.ui.MenuItemWidget.js',
|
||||
've/ui/widgets/ve.ui.MenuSectionItemWidget.js',
|
||||
've/ui/widgets/ve.ui.MenuWidget.js',
|
||||
|
@ -535,6 +536,8 @@ $wgResourceModules += array(
|
|||
'visualeditor-notification-created',
|
||||
'visualeditor-notification-restored',
|
||||
'visualeditor-notification-saved',
|
||||
'visualeditor-outline-control-move-up',
|
||||
'visualeditor-outline-control-move-down',
|
||||
'visualeditor-savedialog-label-create',
|
||||
'visualeditor-savedialog-label-report',
|
||||
'visualeditor-savedialog-label-resolve-conflict',
|
||||
|
|
|
@ -268,6 +268,7 @@ $html = file_get_contents( $page );
|
|||
<script src="../../modules/ve/ui/widgets/ve.ui.TextInputWidget.js"></script>
|
||||
<script src="../../modules/ve/ui/widgets/ve.ui.OutlineItemWidget.js"></script>
|
||||
<script src="../../modules/ve/ui/widgets/ve.ui.OutlineWidget.js"></script>
|
||||
<script src="../../modules/ve/ui/widgets/ve.ui.OutlineControlsWidget.js"></script>
|
||||
<script src="../../modules/ve/ui/widgets/ve.ui.MenuItemWidget.js"></script>
|
||||
<script src="../../modules/ve/ui/widgets/ve.ui.MenuSectionItemWidget.js"></script>
|
||||
<script src="../../modules/ve/ui/widgets/ve.ui.MenuWidget.js"></script>
|
||||
|
|
|
@ -205,8 +205,7 @@ ve.dm.MWTransclusionModel.prototype.getUniquePartId = function () {
|
|||
*/
|
||||
ve.dm.MWTransclusionModel.prototype.addContent = function ( value, index ) {
|
||||
var part = new ve.dm.MWTransclusionContentModel( this, value );
|
||||
this.parts.splice( index === undefined ? this.parts.length : index, 0, part );
|
||||
this.emit( 'add', part );
|
||||
this.addPart( part, index );
|
||||
return part;
|
||||
};
|
||||
|
||||
|
@ -224,16 +223,28 @@ ve.dm.MWTransclusionModel.prototype.addTemplate = function ( title, index ) {
|
|||
if ( this.specs.hasOwnProperty( title ) ) {
|
||||
part.getSpec().extend( this.specs[title] );
|
||||
}
|
||||
this.addPart( part, index );
|
||||
return part;
|
||||
};
|
||||
|
||||
/**
|
||||
* Add part.
|
||||
*
|
||||
* @method
|
||||
* @param {ve.dm.MWTransclusionPartModel} part Part to add
|
||||
* @param {number} [index] Specific index to add content at
|
||||
* @emits add
|
||||
*/
|
||||
ve.dm.MWTransclusionModel.prototype.addPart = function ( part, index ) {
|
||||
this.parts.splice( index === undefined ? this.parts.length : index, 0, part );
|
||||
this.emit( 'add', part );
|
||||
return part;
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove a part.
|
||||
*
|
||||
* @method
|
||||
* @param {ve.dm.MWTransclusionPartModel} part Template part
|
||||
* @param {ve.dm.MWTransclusionPartModel} part Part to remove
|
||||
* @emits remove
|
||||
*/
|
||||
ve.dm.MWTransclusionModel.prototype.removePart = function ( part ) {
|
||||
|
@ -254,6 +265,24 @@ ve.dm.MWTransclusionModel.prototype.getParts = function () {
|
|||
return this.parts;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get part by its ID.
|
||||
*
|
||||
* @method
|
||||
* @param {string} id Part ID
|
||||
* @returns {ve.dm.MWTransclusionPartModel|null} Part with matching ID, if found
|
||||
*/
|
||||
ve.dm.MWTransclusionModel.prototype.getPartFromId = function ( id ) {
|
||||
var i, len;
|
||||
|
||||
for ( i = 0, len = this.parts.length; i < len; i++ ) {
|
||||
if ( this.parts[i].getId() === id ) {
|
||||
return this.parts[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a template specification.
|
||||
*
|
||||
|
|
|
@ -221,6 +221,7 @@
|
|||
<script src="../../ve/ui/widgets/ve.ui.TextInputWidget.js"></script>
|
||||
<script src="../../ve/ui/widgets/ve.ui.OutlineItemWidget.js"></script>
|
||||
<script src="../../ve/ui/widgets/ve.ui.OutlineWidget.js"></script>
|
||||
<script src="../../ve/ui/widgets/ve.ui.OutlineControlsWidget.js"></script>
|
||||
<script src="../../ve/ui/widgets/ve.ui.MenuItemWidget.js"></script>
|
||||
<script src="../../ve/ui/widgets/ve.ui.MenuSectionItemWidget.js"></script>
|
||||
<script src="../../ve/ui/widgets/ve.ui.MenuWidget.js"></script>
|
||||
|
|
|
@ -19,6 +19,9 @@
|
|||
* @param {Object} [config] Config options
|
||||
*/
|
||||
ve.ui.MWTransclusionDialog = function VeUiMWTransclusionDialog( surface, config ) {
|
||||
// Configuration initialization
|
||||
config = ve.extendObject( {}, config, { 'editable': true } );
|
||||
|
||||
// Parent constructor
|
||||
ve.ui.PagedDialog.call( this, surface, config );
|
||||
|
||||
|
@ -41,6 +44,18 @@ ve.ui.MWTransclusionDialog.static.modelClasses = [ ve.dm.MWTransclusionNode ];
|
|||
|
||||
/* Methods */
|
||||
|
||||
/**
|
||||
* Handle frame ready events.
|
||||
*
|
||||
* @method
|
||||
*/
|
||||
ve.ui.MWTransclusionDialog.prototype.initialize = function () {
|
||||
// Call parent method
|
||||
ve.ui.PagedDialog.prototype.initialize.call( this );
|
||||
|
||||
this.outlineControlsWidget.connect( this, { 'move': 'onOutlineControlsMove' } );
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle frame open events.
|
||||
*
|
||||
|
@ -106,17 +121,27 @@ ve.ui.MWTransclusionDialog.prototype.onClose = function ( action ) {
|
|||
* @param {ve.dm.MWTransclusionPartModel} part Added part
|
||||
*/
|
||||
ve.ui.MWTransclusionDialog.prototype.onAddPart = function ( part ) {
|
||||
var page;
|
||||
var i, len, page, params, param, names;
|
||||
|
||||
if ( part instanceof ve.dm.MWTemplateModel ) {
|
||||
page = this.getTemplatePage( part );
|
||||
part.connect( this, { 'add': 'onAddParameter', 'remove': 'onRemoveParameter' } );
|
||||
} else if ( part instanceof ve.dm.MWTransclusionContentModel ) {
|
||||
page = this.getContentPage( part );
|
||||
}
|
||||
page.index = this.getPageIndex( part ) + 1;
|
||||
page.index = this.getPageIndex( part );
|
||||
if ( page ) {
|
||||
this.addPage( part.getId(), page );
|
||||
if ( part instanceof ve.dm.MWTemplateModel ) {
|
||||
names = part.getParameterNames();
|
||||
params = part.getParameters();
|
||||
for ( i = 0, len = names.length; i < len; i++ ) {
|
||||
param = params[names[i]];
|
||||
page = this.getParameterPage( param );
|
||||
page.index = this.getPageIndex( param );
|
||||
this.addPage( param.getId(), page );
|
||||
}
|
||||
part.connect( this, { 'add': 'onAddParameter', 'remove': 'onRemoveParameter' } );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -147,7 +172,7 @@ ve.ui.MWTransclusionDialog.prototype.onRemovePart = function ( part ) {
|
|||
*/
|
||||
ve.ui.MWTransclusionDialog.prototype.onAddParameter = function ( param ) {
|
||||
var page = this.getParameterPage( param );
|
||||
page.index = this.getPageIndex( param ) + 1;
|
||||
page.index = this.getPageIndex( param );
|
||||
this.addPage( param.getId(), page );
|
||||
};
|
||||
|
||||
|
@ -163,6 +188,27 @@ ve.ui.MWTransclusionDialog.prototype.onRemoveParameter = function ( param ) {
|
|||
this.setPageByName( param.getTemplate().getId() );
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle outline controls move events.
|
||||
*
|
||||
* @method
|
||||
* @param {number} places Number of places to move the selected item.
|
||||
*/
|
||||
ve.ui.MWTransclusionDialog.prototype.onOutlineControlsMove = function ( places ) {
|
||||
var part, index, name,
|
||||
parts = this.transclusion.getParts(),
|
||||
item = this.outlineWidget.getSelectedItem();
|
||||
|
||||
if ( item ) {
|
||||
name = item.getData();
|
||||
part = this.transclusion.getPartFromId( name );
|
||||
index = ve.indexOf( part, parts );
|
||||
this.transclusion.removePart( part );
|
||||
this.transclusion.addPart( part, index + places );
|
||||
this.setPageByName( name );
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the page by name.
|
||||
*
|
||||
|
@ -194,6 +240,7 @@ ve.ui.MWTransclusionDialog.prototype.getPageIndex = function ( item ) {
|
|||
if ( part === item ) {
|
||||
return index;
|
||||
}
|
||||
index++;
|
||||
if ( part instanceof ve.dm.MWTemplateModel ) {
|
||||
names = part.getParameterNames();
|
||||
for ( j = 0, jLen = names.length; j < jLen; j++ ) {
|
||||
|
@ -203,7 +250,6 @@ ve.ui.MWTransclusionDialog.prototype.getPageIndex = function ( item ) {
|
|||
index++;
|
||||
}
|
||||
}
|
||||
index++;
|
||||
}
|
||||
return -1;
|
||||
};
|
||||
|
@ -284,7 +330,8 @@ ve.ui.MWTransclusionDialog.prototype.getContentPage = function ( content ) {
|
|||
return {
|
||||
'label': ve.msg( 'visualeditor-dialog-transclusion-content' ),
|
||||
'icon': 'source',
|
||||
'$content': valueFieldset.$.add( optionsFieldset.$ )
|
||||
'$content': valueFieldset.$.add( optionsFieldset.$ ),
|
||||
'moveable': true
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -360,7 +407,8 @@ ve.ui.MWTransclusionDialog.prototype.getTemplatePage = function ( template ) {
|
|||
return {
|
||||
'label': label,
|
||||
'icon': 'template',
|
||||
'$content': infoFieldset.$.add( addParameterFieldset.$ ).add( optionsFieldset.$ )
|
||||
'$content': infoFieldset.$.add( addParameterFieldset.$ ).add( optionsFieldset.$ ),
|
||||
'moveable': true
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -19,12 +19,17 @@
|
|||
* @constructor
|
||||
* @param {ve.ui.Surface} surface
|
||||
* @param {Object} [config] Config options
|
||||
* @cfg {boolean} [editable] Show controls for adding, removing and reordering items in the outline
|
||||
*/
|
||||
ve.ui.PagedDialog = function VeUiPagedDialog( surface, config ) {
|
||||
// Configuration initialization
|
||||
config = config || {};
|
||||
|
||||
// Parent constructor
|
||||
ve.ui.Dialog.call( this, surface, config );
|
||||
|
||||
// Properties
|
||||
this.editable = !!config.editable;
|
||||
this.pages = {};
|
||||
this.currentPageName = null;
|
||||
};
|
||||
|
@ -51,12 +56,24 @@ ve.ui.PagedDialog.prototype.initialize = function () {
|
|||
[this.outlinePanel, this.pagesPanel], { '$$': this.frame.$$, 'widths': [1, 2] }
|
||||
);
|
||||
this.outlineWidget = new ve.ui.OutlineWidget( { '$$': this.frame.$$ } );
|
||||
if ( this.editable ) {
|
||||
this.outlineControlsWidget = new ve.ui.OutlineControlsWidget(
|
||||
this.outlineWidget, { '$$': this.frame.$$ }
|
||||
);
|
||||
}
|
||||
|
||||
// Events
|
||||
this.outlineWidget.connect( this, { 'select': 'onOutlineSelect' } );
|
||||
|
||||
// Initialization
|
||||
this.outlinePanel.$.append( this.outlineWidget.$ ).addClass( 've-ui-pagedDialog-outlinePanel' );
|
||||
this.outlinePanel.$
|
||||
.addClass( 've-ui-pagedDialog-outlinePanel' )
|
||||
.append( this.outlineWidget.$ );
|
||||
if ( this.editable ) {
|
||||
this.outlinePanel.$
|
||||
.addClass( 've-ui-pagedDialog-outlinePanel-editable' )
|
||||
.append( this.outlineControlsWidget.$ );
|
||||
}
|
||||
this.pagesPanel.$.addClass( 've-ui-pagedDialog-pagesPanel' );
|
||||
this.$body.append( this.layout.$ );
|
||||
};
|
||||
|
@ -84,6 +101,7 @@ ve.ui.PagedDialog.prototype.onOutlineSelect = function ( item ) {
|
|||
* @param {number} [config.level=0] Indentation level
|
||||
* @param {number} [config.index] Specific index to insert page at
|
||||
* @param {jQuery} [config.$content] Page content
|
||||
* @param {jQuery} [config.moveable] Allow page to be moved in the outline
|
||||
* @chainable
|
||||
*/
|
||||
ve.ui.PagedDialog.prototype.addPage = function ( name, config ) {
|
||||
|
@ -99,7 +117,8 @@ ve.ui.PagedDialog.prototype.addPage = function ( name, config ) {
|
|||
'$$': this.frame.$$,
|
||||
'label': config.label || name,
|
||||
'level': config.level || 0,
|
||||
'icon': config.icon
|
||||
'icon': config.icon,
|
||||
'moveable': config.moveable
|
||||
} )
|
||||
],
|
||||
config.index
|
||||
|
@ -169,7 +188,7 @@ ve.ui.PagedDialog.prototype.getPage = function ( name ) {
|
|||
* @param {string} name Symbolic name of page
|
||||
*/
|
||||
ve.ui.PagedDialog.prototype.setPage = function ( name ) {
|
||||
if ( name in this.pages ) {
|
||||
if ( this.pages[name] ) {
|
||||
this.currentPageName = name;
|
||||
this.pagesPanel.showItem( this.pages[name] );
|
||||
this.pages[name].$.find( ':input:first' ).focus();
|
||||
|
|
|
@ -42,15 +42,20 @@ ve.ui.GroupElement.prototype.getItems = function () {
|
|||
* @chainable
|
||||
*/
|
||||
ve.ui.GroupElement.prototype.addItems = function ( items, index ) {
|
||||
var i, len, item,
|
||||
var i, len, item, currentIndex,
|
||||
$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 ) {
|
||||
currentIndex = this.items.indexOf( item );
|
||||
if ( currentIndex >= 0 ) {
|
||||
this.removeItems( [ item ] );
|
||||
// Adjust index to compensate for removal
|
||||
if ( currentIndex < index ) {
|
||||
index--;
|
||||
}
|
||||
}
|
||||
// Add the item
|
||||
$items = $items.add( item.$ );
|
||||
|
|
|
@ -120,6 +120,23 @@
|
|||
border-right: solid 1px #ddd;
|
||||
}
|
||||
|
||||
.ve-ui-pagedDialog-outlinePanel-editable .ve-ui-outlineWidget {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 3em;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.ve-ui-pagedDialog-outlinePanel .ve-ui-outlineControlsWidget {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
box-shadow: 0 0 0.25em rgba(0,0,0,0.25);
|
||||
}
|
||||
|
||||
.ve-ui-pagedDialog-pagesPanel .ve-ui-panelLayout {
|
||||
padding: 1.5em;
|
||||
width: 100%;
|
||||
|
|
|
@ -239,3 +239,13 @@
|
|||
/* @embed */
|
||||
background-image: url(images/icons/search-big.png);
|
||||
}
|
||||
|
||||
.ve-ui-icon-expand {
|
||||
/* @embed */
|
||||
background-image: url(images/icons/expand.png);
|
||||
}
|
||||
|
||||
.ve-ui-icon-collapse {
|
||||
/* @embed */
|
||||
background-image: url(images/icons/collapse.png);
|
||||
}
|
||||
|
|
|
@ -239,3 +239,13 @@
|
|||
/* @embed */
|
||||
background-image: url(images/icons/search-big.svg);
|
||||
}
|
||||
|
||||
.ve-ui-icon-expand {
|
||||
/* @embed */
|
||||
background-image: url(images/icons/expand.svg);
|
||||
}
|
||||
|
||||
.ve-ui-icon-collapse {
|
||||
/* @embed */
|
||||
background-image: url(images/icons/collapse.svg);
|
||||
}
|
||||
|
|
|
@ -25,6 +25,10 @@
|
|||
opacity: 1;
|
||||
}
|
||||
|
||||
.ve-ui-iconButtonWidget.ve-ui-widget-disabled {
|
||||
opacity: 0.2;
|
||||
}
|
||||
|
||||
/* ve.ui.ButtonWidget */
|
||||
|
||||
.ve-ui-buttonWidget {
|
||||
|
@ -202,6 +206,26 @@
|
|||
text-shadow: 0 1px 1px rgba(255,255,255,0.5);
|
||||
}
|
||||
|
||||
/* ve.ui.OutlineControlsWidget */
|
||||
|
||||
.ve-ui-outlineControlsWidget {
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
height: 3em;
|
||||
padding: 0.5em;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.ve-ui-outlineControlsWidget-addButton {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.ve-ui-outlineControlsWidget-upButton,
|
||||
.ve-ui-outlineControlsWidget-downButton {
|
||||
float: right;
|
||||
}
|
||||
|
||||
/* ve.ui.InputLabelWidget */
|
||||
|
||||
.ve-ui-inputLabelWidget {
|
||||
|
|
85
modules/ve/ui/widgets/ve.ui.OutlineControlsWidget.js
Normal file
85
modules/ve/ui/widgets/ve.ui.OutlineControlsWidget.js
Normal file
|
@ -0,0 +1,85 @@
|
|||
/*!
|
||||
* VisualEditor UserInterface OutlineControlsWidget class.
|
||||
*
|
||||
* @copyright 2011-2013 VisualEditor Team and others; see AUTHORS.txt
|
||||
* @license The MIT License (MIT); see LICENSE.txt
|
||||
*/
|
||||
|
||||
/**
|
||||
* Creates an ve.ui.OutlineControlsWidget object.
|
||||
*
|
||||
* @class
|
||||
*
|
||||
* @constructor
|
||||
* @param {ve.ui.OutlineWidget} outline Outline to control
|
||||
* @param {Object} [config] Config options
|
||||
*/
|
||||
ve.ui.OutlineControlsWidget = function VeUiOutlineControlsWidget( outline, config ) {
|
||||
// Parent constructor
|
||||
ve.ui.Widget.call( this, config );
|
||||
|
||||
// Properties
|
||||
this.outline = outline;
|
||||
this.upButton = new ve.ui.IconButtonWidget( {
|
||||
'$$': this.$$, 'icon': 'collapse', 'title': ve.msg( 'visualeditor-outline-control-move-up' )
|
||||
} );
|
||||
this.downButton = new ve.ui.IconButtonWidget( {
|
||||
'$$': this.$$, 'icon': 'expand', 'title': ve.msg( 'visualeditor-outline-control-move-down' )
|
||||
} );
|
||||
|
||||
// Events
|
||||
outline.connect( this, {
|
||||
'select': 'onOutlineChange',
|
||||
'add': 'onOutlineChange',
|
||||
'remove': 'onOutlineChange'
|
||||
} );
|
||||
this.upButton.connect( this, { 'click': ['emit', 'move', -1] } );
|
||||
this.downButton.connect( this, { 'click': ['emit', 'move', 1] } );
|
||||
|
||||
// Initialization
|
||||
this.$.addClass( 've-ui-outlineControlsWidget' );
|
||||
this.upButton.$.addClass( 've-ui-outlineControlsWidget-upButton' );
|
||||
this.downButton.$.addClass( 've-ui-outlineControlsWidget-downButton' );
|
||||
this.$.append( this.upButton.$, this.downButton.$ );
|
||||
};
|
||||
|
||||
/* Inheritance */
|
||||
|
||||
ve.inheritClass( ve.ui.OutlineControlsWidget, ve.ui.Widget );
|
||||
|
||||
/* Events */
|
||||
|
||||
/**
|
||||
* @event move
|
||||
* @param {number} places Number of places to move
|
||||
*/
|
||||
|
||||
/* Methods */
|
||||
|
||||
ve.ui.OutlineControlsWidget.prototype.onOutlineChange = function () {
|
||||
var i, len, firstMoveable, lastMoveable,
|
||||
moveable = false,
|
||||
items = this.outline.getItems(),
|
||||
selectedItem = this.outline.getSelectedItem();
|
||||
|
||||
if ( selectedItem && selectedItem.isMoveable() ) {
|
||||
moveable = true;
|
||||
i = -1;
|
||||
len = items.length;
|
||||
while ( ++i < len ) {
|
||||
if ( items[i].isMoveable() ) {
|
||||
firstMoveable = items[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
i = len;
|
||||
while ( i-- ) {
|
||||
if ( items[i].isMoveable() ) {
|
||||
lastMoveable = items[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.upButton.setDisabled( !moveable || selectedItem === firstMoveable );
|
||||
this.downButton.setDisabled( !moveable || selectedItem === lastMoveable );
|
||||
};
|
|
@ -16,6 +16,7 @@
|
|||
* @param {Object} [config] Config options
|
||||
* @cfg {string} [icon] Symbolic name of icon
|
||||
* @cfg {number} [level] Indentation level
|
||||
* @cfg {boolean} [moveable] Allow modification from outline controls
|
||||
*/
|
||||
ve.ui.OutlineItemWidget = function VeUiOutlineItemWidget( data, config ) {
|
||||
// Config intialization
|
||||
|
@ -26,6 +27,7 @@ ve.ui.OutlineItemWidget = function VeUiOutlineItemWidget( data, config ) {
|
|||
|
||||
// Properties
|
||||
this.level = 0;
|
||||
this.moveable = !!config.moveable;
|
||||
|
||||
// Initialization
|
||||
this.$.addClass( 've-ui-outlineItemWidget' );
|
||||
|
@ -49,6 +51,17 @@ ve.ui.OutlineItemWidget.static.levels = 3;
|
|||
|
||||
/* Methods */
|
||||
|
||||
/**
|
||||
* Check if item is moveable.
|
||||
*
|
||||
* Moveablilty is used by outline controls.
|
||||
*
|
||||
* @returns {boolean} Item is moveable
|
||||
*/
|
||||
ve.ui.OutlineItemWidget.prototype.isMoveable = function () {
|
||||
return this.moveable;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get indentation level.
|
||||
*
|
||||
|
|
|
@ -56,6 +56,17 @@ ve.mixinClass( ve.ui.SelectWidget, ve.ui.GroupElement );
|
|||
* @param {ve.ui.OptionWidget|null} item Selected item or null if no item is selected
|
||||
*/
|
||||
|
||||
/**
|
||||
* @event add
|
||||
* @param {ve.ui.OptionWidget[]} items Added items
|
||||
* @param {number} index Index items were added at
|
||||
*/
|
||||
|
||||
/**
|
||||
* @event remove
|
||||
* @param {ve.ui.OptionWidget[]} items Removed items
|
||||
*/
|
||||
|
||||
/* Static Properties */
|
||||
|
||||
ve.ui.SelectWidget.static.tagName = 'ul';
|
||||
|
@ -347,6 +358,9 @@ ve.ui.SelectWidget.prototype.addItems = function ( items, index ) {
|
|||
}
|
||||
ve.ui.GroupElement.prototype.addItems.call( this, items, index );
|
||||
|
||||
// Always provide an index, even if it was omitted
|
||||
this.emit( 'add', items, index === undefined ? this.items.length - items.length - 1 : index );
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
|
@ -372,6 +386,8 @@ ve.ui.SelectWidget.prototype.removeItems = function ( items ) {
|
|||
}
|
||||
ve.ui.GroupElement.prototype.removeItems.call( this, items );
|
||||
|
||||
this.emit( 'remove', items );
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
|
@ -384,9 +400,13 @@ ve.ui.SelectWidget.prototype.removeItems = function ( items ) {
|
|||
* @chainable
|
||||
*/
|
||||
ve.ui.SelectWidget.prototype.clearItems = function () {
|
||||
var items = this.items.slice();
|
||||
|
||||
// Clear all items
|
||||
this.hashes = {};
|
||||
ve.ui.GroupElement.prototype.clearItems.call( this );
|
||||
|
||||
this.emit( 'remove', items );
|
||||
|
||||
return this;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue