diff options
Diffstat (limited to 'vendor/oojs/oojs-ui/src/layouts/StackLayout.js')
-rw-r--r-- | vendor/oojs/oojs-ui/src/layouts/StackLayout.js | 214 |
1 files changed, 214 insertions, 0 deletions
diff --git a/vendor/oojs/oojs-ui/src/layouts/StackLayout.js b/vendor/oojs/oojs-ui/src/layouts/StackLayout.js new file mode 100644 index 00000000..58f35d31 --- /dev/null +++ b/vendor/oojs/oojs-ui/src/layouts/StackLayout.js @@ -0,0 +1,214 @@ +/** + * StackLayouts contain a series of {@link OO.ui.PanelLayout panel layouts}. By default, only one panel is displayed + * at a time, though the stack layout can also be configured to show all contained panels, one after another, + * by setting the #continuous option to 'true'. + * + * @example + * // A stack layout with two panels, configured to be displayed continously + * var myStack = new OO.ui.StackLayout( { + * items: [ + * new OO.ui.PanelLayout( { + * $content: $( '<p>Panel One</p>' ), + * padded: true, + * framed: true + * } ), + * new OO.ui.PanelLayout( { + * $content: $( '<p>Panel Two</p>' ), + * padded: true, + * framed: true + * } ) + * ], + * continuous: true + * } ); + * $( 'body' ).append( myStack.$element ); + * + * @class + * @extends OO.ui.PanelLayout + * @mixins OO.ui.GroupElement + * + * @constructor + * @param {Object} [config] Configuration options + * @cfg {boolean} [continuous=false] Show all panels, one after another. By default, only one panel is displayed at a time. + * @cfg {OO.ui.Layout[]} [items] Panel layouts to add to the stack layout. + */ +OO.ui.StackLayout = function OoUiStackLayout( config ) { + // Configuration initialization + config = $.extend( { scrollable: true }, config ); + + // Parent constructor + OO.ui.StackLayout.super.call( this, config ); + + // Mixin constructors + OO.ui.GroupElement.call( this, $.extend( {}, config, { $group: this.$element } ) ); + + // Properties + this.currentItem = null; + this.continuous = !!config.continuous; + + // Initialization + this.$element.addClass( 'oo-ui-stackLayout' ); + if ( this.continuous ) { + this.$element.addClass( 'oo-ui-stackLayout-continuous' ); + } + if ( Array.isArray( config.items ) ) { + this.addItems( config.items ); + } +}; + +/* Setup */ + +OO.inheritClass( OO.ui.StackLayout, OO.ui.PanelLayout ); +OO.mixinClass( OO.ui.StackLayout, OO.ui.GroupElement ); + +/* Events */ + +/** + * A 'set' event is emitted when panels are {@link #addItems added}, {@link #removeItems removed}, + * {@link #clearItems cleared} or {@link #setItem displayed}. + * + * @event set + * @param {OO.ui.Layout|null} item Current panel or `null` if no panel is shown + */ + +/* Methods */ + +/** + * Get the current panel. + * + * @return {OO.ui.Layout|null} + */ +OO.ui.StackLayout.prototype.getCurrentItem = function () { + return this.currentItem; +}; + +/** + * Unset the current item. + * + * @private + * @param {OO.ui.StackLayout} layout + * @fires set + */ +OO.ui.StackLayout.prototype.unsetCurrentItem = function () { + var prevItem = this.currentItem; + if ( prevItem === null ) { + return; + } + + this.currentItem = null; + this.emit( 'set', null ); +}; + +/** + * Add panel layouts to the stack layout. + * + * Panels will be added to the end of the stack layout array unless the optional index parameter specifies a different + * insertion point. Adding a panel that is already in the stack will move it to the end of the array or the point specified + * by the index. + * + * @param {OO.ui.Layout[]} items Panels to add + * @param {number} [index] Index of the insertion point + * @chainable + */ +OO.ui.StackLayout.prototype.addItems = function ( items, index ) { + // Update the visibility + this.updateHiddenState( items, this.currentItem ); + + // Mixin method + OO.ui.GroupElement.prototype.addItems.call( this, items, index ); + + if ( !this.currentItem && items.length ) { + this.setItem( items[ 0 ] ); + } + + return this; +}; + +/** + * Remove the specified panels from the stack layout. + * + * Removed panels are detached from the DOM, not removed, so that they may be reused. To remove all panels, + * you may wish to use the #clearItems method instead. + * + * @param {OO.ui.Layout[]} items Panels to remove + * @chainable + * @fires set + */ +OO.ui.StackLayout.prototype.removeItems = function ( items ) { + // Mixin method + OO.ui.GroupElement.prototype.removeItems.call( this, items ); + + if ( $.inArray( this.currentItem, items ) !== -1 ) { + if ( this.items.length ) { + this.setItem( this.items[ 0 ] ); + } else { + this.unsetCurrentItem(); + } + } + + return this; +}; + +/** + * Clear all panels from the stack layout. + * + * Cleared panels are detached from the DOM, not removed, so that they may be reused. To remove only + * a subset of panels, use the #removeItems method. + * + * @chainable + * @fires set + */ +OO.ui.StackLayout.prototype.clearItems = function () { + this.unsetCurrentItem(); + OO.ui.GroupElement.prototype.clearItems.call( this ); + + return this; +}; + +/** + * Show the specified panel. + * + * If another panel is currently displayed, it will be hidden. + * + * @param {OO.ui.Layout} item Panel to show + * @chainable + * @fires set + */ +OO.ui.StackLayout.prototype.setItem = function ( item ) { + if ( item !== this.currentItem ) { + this.updateHiddenState( this.items, item ); + + if ( $.inArray( item, this.items ) !== -1 ) { + this.currentItem = item; + this.emit( 'set', item ); + } else { + this.unsetCurrentItem(); + } + } + + return this; +}; + +/** + * Update the visibility of all items in case of non-continuous view. + * + * Ensure all items are hidden except for the selected one. + * This method does nothing when the stack is continuous. + * + * @private + * @param {OO.ui.Layout[]} items Item list iterate over + * @param {OO.ui.Layout} [selectedItem] Selected item to show + */ +OO.ui.StackLayout.prototype.updateHiddenState = function ( items, selectedItem ) { + var i, len; + + if ( !this.continuous ) { + for ( i = 0, len = items.length; i < len; i++ ) { + if ( !selectedItem || selectedItem !== items[ i ] ) { + items[ i ].$element.addClass( 'oo-ui-element-hidden' ); + } + } + if ( selectedItem ) { + selectedItem.$element.removeClass( 'oo-ui-element-hidden' ); + } + } +}; |